新增条码映射编辑功能图形化界面

This commit is contained in:
侯欢 2025-05-10 11:39:11 +08:00
parent 7b7d491663
commit 5c0b709528
46 changed files with 2510 additions and 499 deletions

117
README.md
View File

@ -4,8 +4,8 @@
## 版本信息 ## 版本信息
- **当前版本**: v1.1 - **当前版本**: v1.5
- **发布日期**: 2025-05-07 - **发布日期**: 2025-05-09
- **作者**: OCR订单处理团队 - **作者**: OCR订单处理团队
## 功能特点 ## 功能特点
@ -17,6 +17,11 @@
- **批量处理**:支持批量处理多张图片 - **批量处理**:支持批量处理多张图片
- **图形界面**:提供简洁直观的图形界面,方便操作 - **图形界面**:提供简洁直观的图形界面,方便操作
- **命令行支持**:支持命令行方式调用,便于自动化处理 - **命令行支持**:支持命令行方式调用,便于自动化处理
- **OCR识别**: 支持图片中表格的自动识别和提取
- **Excel处理**: 将OCR识别结果处理为规范的Excel表格
- **订单合并**: 将多个采购单自动合并为一个总表
- **完整流程**: 一键执行从OCR识别到订单合并的完整处理流程
- **烟草订单处理**: 专门处理烟草公司特定格式的订单明细文件,生成银豹采购单
## 系统架构 ## 系统架构
@ -95,33 +100,56 @@ template_file = templates/银豹-采购单模板.xls
## 使用方法 ## 使用方法
### 图形界面 1. **启动系统**
- 双击运行 `启动器.py` 文件,启动图形界面
- 或者通过命令行运行 `python run.py <命令> [选项]`
运行`启动器.py`启动图形界面: 2. **图形界面操作**
- **处理Excel文件**: 处理指定的Excel文件或最新的Excel文件
- **OCR批量识别**: 批量处理input目录下的所有图片
- **完整处理流程**: 一键执行OCR识别、Excel处理和订单合并
- **处理单个图片**: 处理指定的单张图片
- **合并采购单**: 合并多个采购单为一个总表
- **处理烟草订单**: 处理烟草公司特定格式的订单明细文件,生成银豹采购单格式
- **整理项目文件**: 整理项目文件结构
- **清除处理缓存**: 清除处理缓存,使系统重新处理所有文件
- **清理文件**: 清理所有数据文件
- **切换主题**: 在浅色和深色主题之间切换
```bash ## 命令行使用
python 启动器.py
系统支持通过命令行操作,基本用法:
```
python run.py <命令> [选项]
``` ```
图形界面包括以下功能: 支持的命令:
- **处理单个文件**:选择并处理单个图片文件
- **批量处理**处理data/input目录中的所有图片文件
- **合并处理**:合并多个采购单
- **清理文件**清理input和output目录中的文件
- **查看日志**:实时显示处理日志
### 命令行模式 1. **ocr**: OCR识别
```
python run.py ocr [--input 图片路径] [--batch] [--batch-size 批大小] [--max-workers 最大线程数]
```
```bash 2. **excel**: Excel处理
# 处理单个文件 ```
python run.py --file=image.jpg python run.py excel [--input Excel文件路径]
```
# 批量处理目录中的所有文件 3. **merge**: 订单合并
python run.py --batch ```
python run.py merge [--input 采购单文件路径列表,以逗号分隔]
```
# 合并采购单 4. **pipeline**: 完整流程
python run.py --merge ```
``` python run.py pipeline [--input 图片路径]
```
5. **tobacco**: 烟草订单处理
```
python run.py tobacco [--input 烟草订单明细文件路径]
```
## 单位处理规则 ## 单位处理规则
@ -267,6 +295,53 @@ MIT License
## 更新日志 ## 更新日志
### v1.5 (2025-05-09)
#### 功能改进
- 烟草订单处理结果展示:改进烟草订单处理完成后的结果展示界面
- 美化结果 展示界面,显示订单时间、总金额和处理条目数
- 添加文件信息展示,包括文件大小和创建时间
- 提供打开文件、打开所在文件夹等便捷操作按钮
- 统一与Excel处理结果展示风格提升用户体验
- 增强结果文件路径解析能力,确保正确找到并显示结果文件
- 条码映射编辑功能:
- 添加图形化条码映射编辑工具,方便管理条码映射和特殊处理规则
- 支持添加、修改和删除条码映射关系
- 支持配置特殊处理规则,如乘数、目标单位、固定单价等
- 自动保存到配置文件,便于后续使用
#### 问题修复
- 修复烟草订单处理时出现双重弹窗问题
- 修复烟草订单处理完成后结果展示弹窗无法正常显示的问题
- 修复ConfigParser兼容性问题支持标准ConfigParser对象
- 修复百度OCR客户端中getint方法调用不兼容问题
- 修复OCRService中缺少batch_process方法的问题确保OCR功能正常工作
- 改进日志管理,确保所有日志正确关闭
- 优化UI界面统一按钮样式
- 修复启动器中处理烟草订单按钮的显示样式
- 修复run.py中close_logger调用缺少参数的问题
#### 代码改进
- 改进TobaccoService类对配置的处理方式使用标准get方法
- 添加fallback机制以增强配置健壮性
- 优化启动器中结果预览逻辑,避免重复弹窗
- 统一UI组件风格提升用户体验
- 增强错误处理,提供更清晰的错误信息
### v1.4 (2025-05-09)
#### 新功能
- 烟草订单处理:新增烟草公司特定格式订单明细文件处理功能
- 支持自动处理标准烟草订单明细格式
- 根据烟草公司"盒码"作为条码生成银豹采购单
- 自动将"订单量"转换为"采购量"并计算采购单价
- 处理结果以银豹采购单格式保存,方便直接导入
#### 功能优化
- 配置兼容性优化配置处理逻辑兼容标准ConfigParser对象
- 启动器优化:启动器界面增加"处理烟草订单"功能按钮
- 代码结构优化:将烟草订单处理功能模块化,集成到整体服务架构
### v1.3 (2025-07-20) ### v1.3 (2025-07-20)
#### 功能优化 #### 功能优化

View File

@ -6,6 +6,8 @@
import re import re
import logging import logging
import os
import json
from typing import Dict, Tuple, Optional, Any, List, Union from typing import Dict, Tuple, Optional, Any, List, Union
from ..utils.log_utils import get_logger from ..utils.log_utils import get_logger
@ -18,6 +20,9 @@ from .validators import ProductValidator
logger = get_logger(__name__) logger = get_logger(__name__)
# 条码映射配置文件路径
BARCODE_MAPPING_CONFIG = "config/barcode_mappings.json"
class UnitConverter: class UnitConverter:
""" """
单位转换器处理不同单位之间的转换支持从商品名称推断规格 单位转换器处理不同单位之间的转换支持从商品名称推断规格
@ -27,60 +32,8 @@ class UnitConverter:
""" """
初始化单位转换器 初始化单位转换器
""" """
# 特殊条码配置 # 加载特殊条码配置
self.special_barcodes = { self.special_barcodes = self.load_barcode_mappings()
'6925019900087': {
'multiplier': 10, # 数量乘以10
'target_unit': '', # 目标单位
'description': '特殊处理:数量*10单位转换为瓶'
},
'6921168593804': {
'multiplier': 30, # 数量乘以30
'target_unit': '', # 目标单位
'description': 'NFC产品特殊处理每箱30瓶'
},
'6901826888138': {
'multiplier': 30, # 数量乘以30
'target_unit': '', # 目标单位
'fixed_price': 112/30, # 固定单价为112/30
'specification': '1*30', # 固定规格
'description': '特殊处理: 规格1*30数量*30单价=112/30'
},
# 条码映射转换配置
'6920584471055': {
'map_to': '6920584471017', # 映射到新条码
'description': '条码映射6920584471055 -> 6920584471017'
},
'6925861571159': {
'map_to': '69021824', # 映射到新条码
'description': '条码映射6925861571159 -> 69021824'
},
'6923644268923': {
'map_to': '6923644268480', # 映射到新条码
'description': '条码映射6923644268923 -> 6923644268480'
},
'6907992501819': {
'map_to': '6907992500133', # 映射到新条码
'description': '条码映射6907992501819 -> 6907992500133'
},
'6923644268916': {
'map_to': '6923644268503', # 映射到新条码
'description': '条码映射6923644268916 -> 6923644268503'
},
'6923644283582': {
'map_to': '6923644283575', # 映射到新条码
'description': '条码映射6923644283582 -> 6923644283575'
},
'6923644268930': {
'map_to': '6923644268497', # 映射到新条码
'description': '条码映射6923644268930 -> 6923644268497'
},
'6923644210151': {
'map_to': '6923644223458', # 映射到新条码
'description': '条码映射6923644210151 -> 6923644223458'
}
# 可以添加更多特殊条码的配置
}
# 规格推断的正则表达式模式 # 规格推断的正则表达式模式
self.spec_patterns = [ self.spec_patterns = [
@ -447,4 +400,98 @@ class UnitConverter:
# 没有找到适用的处理程序,保持不变 # 没有找到适用的处理程序,保持不变
logger.info(f"其他单位处理: 保持原样 数量: {result.get('quantity', 0)}, 单价: {result.get('price', 0)}, 单位: {result.get('unit', '')}") logger.info(f"其他单位处理: 保持原样 数量: {result.get('quantity', 0)}, 单价: {result.get('price', 0)}, 单位: {result.get('unit', '')}")
return result return result
def load_barcode_mappings(self) -> Dict[str, Dict[str, Any]]:
"""
从配置文件加载条码映射
Returns:
条码映射字典
"""
# 默认映射
default_mappings = {
'6925019900087': {
'multiplier': 10,
'target_unit': '',
'description': '特殊处理:数量*10单位转换为瓶'
},
'6921168593804': {
'multiplier': 30,
'target_unit': '',
'description': 'NFC产品特殊处理每箱30瓶'
},
'6901826888138': {
'multiplier': 30,
'target_unit': '',
'fixed_price': 112/30,
'specification': '1*30',
'description': '特殊处理: 规格1*30数量*30单价=112/30'
},
# 条码映射配置
'6920584471055': {
'map_to': '6920584471017',
'description': '条码映射6920584471055 -> 6920584471017'
},
'6925861571159': {
'map_to': '69021824',
'description': '条码映射6925861571159 -> 69021824'
},
'6923644268923': {
'map_to': '6923644268480',
'description': '条码映射6923644268923 -> 6923644268480'
}
}
try:
# 检查配置文件是否存在
if os.path.exists(BARCODE_MAPPING_CONFIG):
with open(BARCODE_MAPPING_CONFIG, 'r', encoding='utf-8') as file:
mappings = json.load(file)
logger.info(f"成功加载条码映射配置,共{len(mappings)}")
return mappings
else:
# 创建默认配置文件
self.save_barcode_mappings(default_mappings)
logger.info(f"创建默认条码映射配置,共{len(default_mappings)}")
return default_mappings
except Exception as e:
logger.error(f"加载条码映射配置失败: {e}")
return default_mappings
def save_barcode_mappings(self, mappings: Dict[str, Dict[str, Any]]) -> bool:
"""
保存条码映射到配置文件
Args:
mappings: 条码映射字典
Returns:
保存是否成功
"""
try:
# 确保配置目录存在
os.makedirs(os.path.dirname(BARCODE_MAPPING_CONFIG), exist_ok=True)
# 写入配置文件
with open(BARCODE_MAPPING_CONFIG, 'w', encoding='utf-8') as file:
json.dump(mappings, file, ensure_ascii=False, indent=2)
logger.info(f"条码映射配置保存成功,共{len(mappings)}")
return True
except Exception as e:
logger.error(f"保存条码映射配置失败: {e}")
return False
def update_barcode_mappings(self, new_mappings: Dict[str, Dict[str, Any]]) -> bool:
"""
更新条码映射配置
Args:
new_mappings: 新的条码映射字典
Returns:
更新是否成功
"""
self.special_barcodes = new_mappings
return self.save_barcode_mappings(new_mappings)

View File

@ -36,35 +36,44 @@ class PurchaseOrderMerger:
采购单合并器将多个采购单Excel文件合并成一个文件 采购单合并器将多个采购单Excel文件合并成一个文件
""" """
def __init__(self, config: Optional[ConfigManager] = None): def __init__(self, config):
""" """
初始化采购单合并器 初始化采购单合并器
Args: Args:
config: 配置管理器如果为None则创建新的 config: 配置信息
""" """
logger.info("初始化PurchaseOrderMerger") self.config = config
self.config = config or ConfigManager()
# 获取配置 # 修复ConfigParser对象没有get_path方法的问题
self.output_dir = self.config.get_path('Paths', 'output_folder', 'data/output', create=True) try:
# 获取输出目录
# 获取模板文件路径 self.output_dir = config.get('Paths', 'output_folder', fallback='data/output')
template_folder = self.config.get('Paths', 'template_folder', 'templates')
template_name = self.config.get('Templates', 'purchase_order', '银豹-采购单模板.xls') # 确保目录存在
os.makedirs(self.output_dir, exist_ok=True)
self.template_path = os.path.join(template_folder, template_name)
# 记录实际路径
# 检查模板文件是否存在 logger.info(f"使用输出目录: {os.path.abspath(self.output_dir)}")
if not os.path.exists(self.template_path):
logger.error(f"模板文件不存在: {self.template_path}") # 获取模板文件路径
raise FileNotFoundError(f"模板文件不存在: {self.template_path}") template_folder = config.get('Paths', 'template_folder', fallback='templates')
template_name = config.get('Templates', 'purchase_order', fallback='银豹-采购单模板.xls')
# 用于记录已合并的文件
self.cache_file = os.path.join(self.output_dir, "merged_files.json") self.template_path = os.path.join(template_folder, template_name)
self.merged_files = self._load_merged_files()
# 检查模板文件是否存在
logger.info(f"初始化完成,模板文件: {self.template_path}") if not os.path.exists(self.template_path):
logger.warning(f"模板文件不存在: {self.template_path}")
# 用于记录已合并的文件
self.merged_files_json = os.path.join(self.output_dir, "merged_files.json")
self.merged_files = self._load_merged_files()
logger.info(f"初始化PurchaseOrderMerger完成模板文件: {self.template_path}")
except Exception as e:
logger.error(f"初始化PurchaseOrderMerger失败: {e}")
raise
def _load_merged_files(self) -> Dict[str, str]: def _load_merged_files(self) -> Dict[str, str]:
""" """
@ -73,11 +82,11 @@ class PurchaseOrderMerger:
Returns: Returns:
合并记录字典 合并记录字典
""" """
return load_json(self.cache_file, {}) return load_json(self.merged_files_json, {})
def _save_merged_files(self) -> None: def _save_merged_files(self) -> None:
"""保存已合并文件的缓存""" """保存已合并文件的缓存"""
save_json(self.merged_files, self.cache_file) save_json(self.merged_files, self.merged_files_json)
def get_purchase_orders(self) -> List[str]: def get_purchase_orders(self) -> List[str]:
""" """

View File

@ -39,39 +39,44 @@ class ExcelProcessor:
提取条码单价和数量并按照采购单模板的格式填充 提取条码单价和数量并按照采购单模板的格式填充
""" """
def __init__(self, config: Optional[ConfigManager] = None): def __init__(self, config):
""" """
初始化Excel处理器 初始化Excel处理器
Args: Args:
config: 配置管理器如果为None则创建新的 config: 配置信息
""" """
logger.info("初始化ExcelProcessor") self.config = config
self.config = config or ConfigManager()
# 获取配置 # 修复ConfigParser对象没有get_path方法的问题
self.output_dir = self.config.get_path('Paths', 'output_folder', 'data/output', create=True) try:
self.temp_dir = self.config.get_path('Paths', 'temp_folder', 'data/temp', create=True) # 获取输入和输出目录
self.output_dir = config.get('Paths', 'output_folder', fallback='data/output')
# 获取模板文件路径 self.temp_dir = config.get('Paths', 'temp_folder', fallback='data/temp')
template_folder = self.config.get('Paths', 'template_folder', 'templates')
template_name = self.config.get('Templates', 'purchase_order', '银豹-采购单模板.xls') # 获取模板文件路径
self.template_path = config.get('Paths', 'template_file', fallback='templates/银豹-采购单模板.xls')
self.template_path = os.path.join(template_folder, template_name) if not os.path.exists(self.template_path):
logger.warning(f"模板文件不存在: {self.template_path}")
# 检查模板文件是否存在
if not os.path.exists(self.template_path): # 设置缓存文件路径
logger.error(f"模板文件不存在: {self.template_path}") self.cache_file = os.path.join(self.output_dir, "processed_files.json")
raise FileNotFoundError(f"模板文件不存在: {self.template_path}") self.processed_files = self._load_processed_files()
# 用于记录已处理的文件 # 确保目录存在
self.cache_file = os.path.join(self.output_dir, "processed_files.json") os.makedirs(self.output_dir, exist_ok=True)
self.processed_files = self._load_processed_files() os.makedirs(self.temp_dir, exist_ok=True)
# 创建单位转换器 # 记录实际路径
self.unit_converter = UnitConverter() logger.info(f"使用输出目录: {os.path.abspath(self.output_dir)}")
logger.info(f"使用临时目录: {os.path.abspath(self.temp_dir)}")
logger.info(f"初始化完成,模板文件: {self.template_path}")
# 加载单位转换器和配置
self.unit_converter = UnitConverter()
logger.info(f"初始化ExcelProcessor完成模板文件: {self.template_path}")
except Exception as e:
logger.error(f"初始化ExcelProcessor失败: {e}")
raise
def _load_processed_files(self) -> Dict[str, str]: def _load_processed_files(self) -> Dict[str, str]:
""" """

View File

@ -105,34 +105,53 @@ class BaiduOCRClient:
百度OCR API客户端 百度OCR API客户端
""" """
def __init__(self, config: Optional[ConfigManager] = None): def __init__(self, config):
""" """
初始化百度OCR客户端 初始化百度OCR客户端
Args: Args:
config: 配置管理器如果为None则创建新的 config: 配置信息
""" """
self.config = config or ConfigManager() self.config = config
# 获取配置 # 从配置中读取API信息
self.api_key = self.config.get('API', 'api_key') try:
self.secret_key = self.config.get('API', 'secret_key') # 修复getint调用方式
self.timeout = self.config.getint('API', 'timeout', 30) self.timeout = config.get('API', 'timeout', fallback=30)
self.max_retries = self.config.getint('API', 'max_retries', 3) if isinstance(self.timeout, str):
self.retry_delay = self.config.getint('API', 'retry_delay', 2) self.timeout = int(self.timeout)
self.api_url = self.config.get('API', 'api_url', 'https://aip.baidubce.com/rest/2.0/ocr/v1/table')
self.api_key = config.get('API', 'api_key', fallback='')
# 创建令牌管理器 self.secret_key = config.get('API', 'secret_key', fallback='')
self.token_manager = TokenManager(
self.api_key, # 使用fallback而不是位置参数
self.secret_key, try:
self.max_retries, self.max_retries = config.getint('API', 'max_retries', fallback=3)
self.retry_delay except (TypeError, AttributeError):
) # 如果getint不支持fallback则使用get再转换
self.max_retries = int(config.get('API', 'max_retries', fallback='3'))
# 验证API配置
if not self.api_key or not self.secret_key: try:
logger.warning("API密钥未设置请在配置文件中设置API密钥") self.retry_delay = config.getint('API', 'retry_delay', fallback=2)
except (TypeError, AttributeError):
# 如果getint不支持fallback则使用get再转换
self.retry_delay = int(config.get('API', 'retry_delay', fallback='2'))
self.api_url = config.get('API', 'api_url', fallback='https://aip.baidubce.com/rest/2.0/ocr/v1/table')
# 创建令牌管理器
self.token_manager = TokenManager(
self.api_key,
self.secret_key,
self.max_retries,
self.retry_delay
)
# 验证API配置
if not self.api_key or not self.secret_key:
logger.warning("API密钥未设置请在配置文件中设置API密钥")
except Exception as e:
logger.error(f"初始化失败: {e}")
def read_image(self, image_path: str) -> Optional[bytes]: def read_image(self, image_path: str) -> Optional[bytes]:
""" """

View File

@ -103,51 +103,65 @@ class ProcessedRecordManager:
class OCRProcessor: class OCRProcessor:
""" """
OCR处理器用于表格识别与处理 OCR处理器负责协调OCR识别和结果处理
""" """
def __init__(self, config: Optional[ConfigManager] = None): def __init__(self, config):
""" """
初始化OCR处理器 初始化OCR处理器
Args: Args:
config: 配置管理器如果为None则创建新的 config: 配置信息
""" """
self.config = config or ConfigManager() self.config = config
# 创建百度OCR客户端 # 修复ConfigParser对象没有get_path方法的问题
self.ocr_client = BaiduOCRClient(self.config) try:
# 获取输入和输出目录
self.input_folder = config.get('Paths', 'input_folder', fallback='data/input')
self.output_folder = config.get('Paths', 'output_folder', fallback='data/output')
self.temp_folder = config.get('Paths', 'temp_folder', fallback='data/temp')
# 确保目录存在
os.makedirs(self.input_folder, exist_ok=True)
os.makedirs(self.output_folder, exist_ok=True)
os.makedirs(self.temp_folder, exist_ok=True)
# 获取文件类型列表
allowed_extensions_str = config.get('File', 'allowed_extensions', fallback='.jpg,.jpeg,.png,.bmp')
self.file_types = [ext.strip() for ext in allowed_extensions_str.split(',') if ext.strip()]
if not self.file_types:
self.file_types = ['.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tif', '.tiff']
# 初始化OCR客户端
self.ocr_client = BaiduOCRClient(self.config)
# 记录实际路径
logger.info(f"使用输入目录: {os.path.abspath(self.input_folder)}")
logger.info(f"使用输出目录: {os.path.abspath(self.output_folder)}")
logger.info(f"使用临时目录: {os.path.abspath(self.temp_folder)}")
logger.info(f"允许的文件类型: {self.file_types}")
# 初始化processed_files_json和record_manager
self.processed_files_json = os.path.join(self.output_folder, 'processed_files.json')
self.record_manager = ProcessedRecordManager(self.processed_files_json)
# 加载已处理文件记录
self.processed_files = self._load_processed_files()
logger.info(f"初始化OCRProcessor完成输入目录={self.input_folder}, 输出目录={self.output_folder}")
except Exception as e:
logger.error(f"初始化OCRProcessor失败: {e}")
raise
def _load_processed_files(self) -> Dict[str, str]:
"""
加载已处理的文件记录
# 获取配置 Returns:
self.input_folder = self.config.get_path('Paths', 'input_folder', 'data/input', create=True) 已处理的文件记录字典键为输入文件路径值为输出文件路径
self.output_folder = self.config.get_path('Paths', 'output_folder', 'data/output', create=True) """
self.temp_folder = self.config.get_path('Paths', 'temp_folder', 'data/temp', create=True) return load_json(self.processed_files_json, {})
# 确保目录结构正确
for folder in [self.input_folder, self.output_folder, self.temp_folder]:
if not os.path.exists(folder):
os.makedirs(folder, exist_ok=True)
logger.info(f"创建目录: {folder}")
# 记录实际路径
logger.info(f"使用输入目录: {os.path.abspath(self.input_folder)}")
logger.info(f"使用输出目录: {os.path.abspath(self.output_folder)}")
logger.info(f"使用临时目录: {os.path.abspath(self.temp_folder)}")
self.allowed_extensions = self.config.get_list('File', 'allowed_extensions', '.jpg,.jpeg,.png,.bmp')
self.max_file_size_mb = self.config.getfloat('File', 'max_file_size_mb', 4.0)
self.excel_extension = self.config.get('File', 'excel_extension', '.xlsx')
# 处理性能配置
self.max_workers = self.config.getint('Performance', 'max_workers', 4)
self.batch_size = self.config.getint('Performance', 'batch_size', 5)
self.skip_existing = self.config.getboolean('Performance', 'skip_existing', True)
# 初始化处理记录管理器
record_file = self.config.get('Paths', 'processed_record', 'data/processed_files.json')
self.record_manager = ProcessedRecordManager(record_file)
logger.info(f"OCR处理器初始化完成输入目录: {self.input_folder}, 输出目录: {self.output_folder}")
def get_unprocessed_images(self) -> List[str]: def get_unprocessed_images(self) -> List[str]:
""" """
@ -157,10 +171,16 @@ class OCRProcessor:
未处理的图片文件路径列表 未处理的图片文件路径列表
""" """
# 获取所有图片文件 # 获取所有图片文件
image_files = get_files_by_extensions(self.input_folder, self.allowed_extensions) image_files = get_files_by_extensions(self.input_folder, self.file_types)
# 如果需要跳过已存在的文件 # 如果需要跳过已存在的文件
if self.skip_existing: skip_existing = True
try:
skip_existing = self.config.getboolean('Performance', 'skip_existing', fallback=True)
except:
pass
if skip_existing:
# 过滤已处理的文件 # 过滤已处理的文件
unprocessed_files = self.record_manager.get_unprocessed_files(image_files) unprocessed_files = self.record_manager.get_unprocessed_files(image_files)
logger.info(f"找到 {len(image_files)} 个图片文件,其中 {len(unprocessed_files)} 个未处理") logger.info(f"找到 {len(image_files)} 个图片文件,其中 {len(unprocessed_files)} 个未处理")
@ -186,13 +206,19 @@ class OCRProcessor:
# 检查文件扩展名 # 检查文件扩展名
ext = get_file_extension(image_path) ext = get_file_extension(image_path)
if ext not in self.allowed_extensions: if ext not in self.file_types:
logger.warning(f"不支持的文件类型: {ext}, 文件: {image_path}") logger.warning(f"不支持的文件类型: {ext}, 文件: {image_path}")
return False return False
# 检查文件大小 # 检查文件大小
if not is_file_size_valid(image_path, self.max_file_size_mb): max_size_mb = 4.0
logger.warning(f"文件大小超过限制 ({self.max_file_size_mb}MB): {image_path}") try:
max_size_mb = float(self.config.get('File', 'max_file_size_mb', fallback='4.0'))
except:
pass
if not is_file_size_valid(image_path, max_size_mb):
logger.warning(f"文件大小超过限制 ({max_size_mb}MB): {image_path}")
return False return False
return True return True
@ -211,8 +237,15 @@ class OCRProcessor:
if not self.validate_image(image_path): if not self.validate_image(image_path):
return None return None
# 获取是否跳过已处理文件的配置
skip_existing = True
try:
skip_existing = self.config.getboolean('Performance', 'skip_existing', fallback=True)
except:
pass
# 如果需要跳过已处理的文件 # 如果需要跳过已处理的文件
if self.skip_existing and self.record_manager.is_processed(image_path): if skip_existing and self.record_manager.is_processed(image_path):
output_file = self.record_manager.get_output_file(image_path) output_file = self.record_manager.get_output_file(image_path)
logger.info(f"图片已处理,跳过: {image_path}, 输出文件: {output_file}") logger.info(f"图片已处理,跳过: {image_path}, 输出文件: {output_file}")
return output_file return output_file
@ -220,12 +253,19 @@ class OCRProcessor:
logger.info(f"开始处理图片: {image_path}") logger.info(f"开始处理图片: {image_path}")
try: try:
# 获取Excel扩展名
excel_extension = '.xlsx'
try:
excel_extension = self.config.get('File', 'excel_extension', fallback='.xlsx')
except:
pass
# 生成输出文件路径 # 生成输出文件路径
file_name = os.path.splitext(os.path.basename(image_path))[0] file_name = os.path.splitext(os.path.basename(image_path))[0]
output_file = os.path.join(self.output_folder, f"{file_name}{self.excel_extension}") output_file = os.path.join(self.output_folder, f"{file_name}{excel_extension}")
# 检查是否已存在对应的Excel文件 # 检查是否已存在对应的Excel文件
if os.path.exists(output_file) and self.skip_existing: if os.path.exists(output_file) and skip_existing:
logger.info(f"已存在对应的Excel文件跳过处理: {os.path.basename(image_path)} -> {os.path.basename(output_file)}") logger.info(f"已存在对应的Excel文件跳过处理: {os.path.basename(image_path)} -> {os.path.basename(output_file)}")
# 记录处理结果 # 记录处理结果
self.record_manager.mark_as_processed(image_path, output_file) self.record_manager.mark_as_processed(image_path, output_file)
@ -304,31 +344,38 @@ class OCRProcessor:
(总处理数, 成功处理数)元组 (总处理数, 成功处理数)元组
""" """
# 使用配置值或参数值 # 使用配置值或参数值
batch_size = batch_size or self.batch_size if batch_size is None:
max_workers = max_workers or self.max_workers try:
batch_size = self.config.getint('Performance', 'batch_size', fallback=5)
except:
batch_size = 5
if max_workers is None:
try:
max_workers = self.config.getint('Performance', 'max_workers', fallback=4)
except:
max_workers = 4
# 获取未处理的图片 # 获取未处理的图片
unprocessed_images = self.get_unprocessed_images() unprocessed_images = self.get_unprocessed_images()
if not unprocessed_images: if not unprocessed_images:
logger.warning("没有需要处理的图片") logger.warning("没有需要处理的图片")
return 0, 0 return 0, 0
total = len(unprocessed_images) total = len(unprocessed_images)
success = 0 success_count = 0
# 按批次处理 # 按批次处理
for i in range(0, total, batch_size): for i in range(0, total, batch_size):
batch = unprocessed_images[i:i + batch_size] batch = unprocessed_images[i:i+batch_size]
logger.info(f"处理批次 {i//batch_size + 1}/{(total-1)//batch_size + 1}, 大小: {len(batch)}") logger.info(f"处理批次 {i//batch_size+1}/{(total+batch_size-1)//batch_size}: {len(batch)} 个文件")
# 使用线程池并行处理 # 使用线程处理批次
with ThreadPoolExecutor(max_workers=max_workers) as executor: with ThreadPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(self.process_image, batch)) results = list(executor.map(self.process_image, batch))
# 统计成功数 # 统计成功数
success += sum(1 for result in results if result is not None) success_count += sum(1 for result in results if result is not None)
logger.info(f"批次处理完成, 成功: {sum(1 for result in results if result is not None)}/{len(batch)}") logger.info(f"所有图片处理完成, 总计: {total}, 成功: {success_count}")
return total, success_count
logger.info(f"所有图片处理完成, 总计: {total}, 成功: {success}")
return total, success

Binary file not shown.

View File

@ -0,0 +1,468 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
对话框工具模块
-------------
提供各种弹窗和对话框显示功能
"""
import os
import tkinter as tk
from tkinter import messagebox, ttk
from datetime import datetime
def create_custom_dialog(title="提示", message="", result_file=None, time_info=None,
count_info=None, amount_info=None, additional_info=None):
"""
创建自定义结果对话框
Args:
title: 对话框标题
message: 主要消息
result_file: 结果文件路径如果有
time_info: 时间信息订单时间
count_info: 数量信息处理条目数
amount_info: 金额信息总金额
additional_info: 其他附加信息字典格式
Returns:
dialog: 对话框对象
"""
# 创建对话框
dialog = tk.Toplevel()
dialog.title(title)
dialog.geometry("450x320")
dialog.resizable(False, False)
# 使弹窗居中显示
center_window(dialog)
# 添加标题
tk.Label(dialog, text=message, font=("Arial", 16, "bold")).pack(pady=10)
# 创建内容框架
result_frame = tk.Frame(dialog)
result_frame.pack(pady=10, fill=tk.BOTH, expand=True)
# 添加时间、数量、金额等信息
if time_info:
tk.Label(result_frame, text=f"时间信息: {time_info}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
if count_info:
tk.Label(result_frame, text=f"处理数量: {count_info}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
if amount_info:
tk.Label(result_frame, text=f"金额信息: {amount_info}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
# 添加其他附加信息
if additional_info and isinstance(additional_info, dict):
for key, value in additional_info.items():
tk.Label(result_frame, text=f"{key}: {value}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
# 如果有结果文件,显示文件信息
if result_file and os.path.exists(result_file):
tk.Label(result_frame, text=f"输出文件: {os.path.basename(result_file)}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
# 成功提示
tk.Label(result_frame, text="处理已成功完成!", font=("Arial", 12, "bold"), fg="#28a745").pack(pady=10)
# 文件信息框
file_frame = tk.Frame(result_frame, relief=tk.GROOVE, borderwidth=1)
file_frame.pack(fill=tk.X, padx=15, pady=5)
tk.Label(file_frame, text="文件信息", font=("Arial", 10, "bold")).pack(anchor=tk.W, padx=10, pady=5)
# 获取文件大小和时间
try:
file_size = os.path.getsize(result_file)
file_time = datetime.fromtimestamp(os.path.getmtime(result_file))
size_text = f"{file_size / 1024:.1f} KB" if file_size < 1024*1024 else f"{file_size / (1024*1024):.1f} MB"
tk.Label(file_frame, text=f"文件大小: {size_text}", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2)
tk.Label(file_frame, text=f"创建时间: {file_time.strftime('%Y-%m-%d %H:%M:%S')}", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2)
except:
tk.Label(file_frame, text="无法获取文件信息", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2)
# 添加按钮
button_frame = tk.Frame(dialog)
button_frame.pack(pady=10)
tk.Button(button_frame, text="打开文件", command=lambda: os.startfile(result_file)).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="打开所在文件夹", command=lambda: os.startfile(os.path.dirname(result_file))).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="关闭", command=dialog.destroy).pack(side=tk.LEFT, padx=5)
else:
# 如果没有结果文件或文件不存在
if result_file:
tk.Label(result_frame, text="未找到输出文件", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
tk.Label(result_frame, text="请检查输出目录", font=("Arial", 12, "bold"), fg="#dc3545").pack(pady=10)
# 添加按钮
button_frame = tk.Frame(dialog)
button_frame.pack(pady=10)
tk.Button(button_frame, text="打开输出目录", command=lambda: os.startfile(os.path.abspath("data/output"))).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="关闭", command=dialog.destroy).pack(side=tk.LEFT, padx=5)
# 确保窗口显示在最前
dialog.lift()
dialog.attributes('-topmost', True)
dialog.after_idle(lambda: dialog.attributes('-topmost', False))
return dialog
def show_custom_dialog(*args, **kwargs):
"""
显示自定义对话框
参数与create_custom_dialog相同
Returns:
dialog: 对话框对象
"""
return create_custom_dialog(*args, **kwargs)
def center_window(window):
"""使窗口居中显示"""
window.update_idletasks()
width = window.winfo_width()
height = window.winfo_height()
x = (window.winfo_screenwidth() // 2) - (width // 2)
y = (window.winfo_screenheight() // 2) - (height // 2)
window.geometry('{}x{}+{}+{}'.format(width, height, x, y))
def create_barcode_mapping_dialog(parent=None, on_save=None, current_mappings=None):
"""
创建条码映射编辑弹窗
Args:
parent: 父窗口
on_save: 保存回调函数接收修改后的映射数据
current_mappings: 当前的映射数据
Returns:
dialog: 对话框对象
"""
dialog = tk.Toplevel(parent)
dialog.title("条码映射编辑")
dialog.geometry("600x500")
dialog.resizable(True, True)
# 使弹窗居中显示
center_window(dialog)
# 创建主框架
main_frame = tk.Frame(dialog)
main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 创建选项卡控件
tab_control = ttk.Notebook(main_frame)
# 创建两个选项卡页面
tab1 = tk.Frame(tab_control)
tab2 = tk.Frame(tab_control)
tab_control.add(tab1, text="条码映射")
tab_control.add(tab2, text="特殊处理")
tab_control.pack(expand=True, fill=tk.BOTH)
# ========= 条码映射选项卡 =========
# 顶部输入区域
input_frame = tk.Frame(tab1)
input_frame.pack(fill=tk.X, padx=5, pady=5)
tk.Label(input_frame, text="源条码:").grid(row=0, column=0, padx=5, pady=5)
source_entry = tk.Entry(input_frame, width=20)
source_entry.grid(row=0, column=1, padx=5, pady=5)
tk.Label(input_frame, text="目标条码:").grid(row=0, column=2, padx=5, pady=5)
target_entry = tk.Entry(input_frame, width=20)
target_entry.grid(row=0, column=3, padx=5, pady=5)
# 存储映射列表的变量
mapping_list = []
# 映射列表显示区域
list_frame = tk.Frame(tab1)
list_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
columns = ("源条码", "目标条码")
mapping_tree = ttk.Treeview(list_frame, columns=columns, show="headings", selectmode="browse")
for col in columns:
mapping_tree.heading(col, text=col)
mapping_tree.column(col, width=100)
mapping_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# 添加滚动条
scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=mapping_tree.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
mapping_tree.configure(yscrollcommand=scrollbar.set)
# ========= 特殊处理选项卡 =========
# 顶部输入区域
special_input_frame = tk.Frame(tab2)
special_input_frame.pack(fill=tk.X, padx=5, pady=5)
tk.Label(special_input_frame, text="条码:").grid(row=0, column=0, padx=5, pady=5)
special_barcode_entry = tk.Entry(special_input_frame, width=20)
special_barcode_entry.grid(row=0, column=1, padx=5, pady=5)
tk.Label(special_input_frame, text="乘数:").grid(row=1, column=0, padx=5, pady=5)
multiplier_entry = tk.Entry(special_input_frame, width=10)
multiplier_entry.grid(row=1, column=1, padx=5, pady=5)
tk.Label(special_input_frame, text="目标单位:").grid(row=1, column=2, padx=5, pady=5)
unit_entry = tk.Entry(special_input_frame, width=10)
unit_entry.grid(row=1, column=3, padx=5, pady=5)
tk.Label(special_input_frame, text="固定单价:").grid(row=2, column=0, padx=5, pady=5)
price_entry = tk.Entry(special_input_frame, width=10)
price_entry.grid(row=2, column=1, padx=5, pady=5)
tk.Label(special_input_frame, text="规格:").grid(row=2, column=2, padx=5, pady=5)
spec_entry = tk.Entry(special_input_frame, width=10)
spec_entry.grid(row=2, column=3, padx=5, pady=5)
tk.Label(special_input_frame, text="描述:").grid(row=3, column=0, padx=5, pady=5)
desc_entry = tk.Entry(special_input_frame, width=40)
desc_entry.grid(row=3, column=1, columnspan=3, padx=5, pady=5)
# 特殊处理列表显示区域
special_list_frame = tk.Frame(tab2)
special_list_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
special_columns = ("条码", "乘数", "目标单位", "固定单价", "规格", "描述")
special_tree = ttk.Treeview(special_list_frame, columns=special_columns, show="headings", selectmode="browse")
for col in special_columns:
special_tree.heading(col, text=col)
special_tree.column(col, width=80)
special_tree.column("描述", width=200)
special_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# 添加滚动条
special_scrollbar = ttk.Scrollbar(special_list_frame, orient=tk.VERTICAL, command=special_tree.yview)
special_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
special_tree.configure(yscrollcommand=special_scrollbar.set)
# 存储特殊处理列表的变量
special_list = []
# 按钮区域
def add_mapping():
source = source_entry.get().strip()
target = target_entry.get().strip()
if not source or not target:
messagebox.showwarning("输入错误", "源条码和目标条码不能为空")
return
# 检查是否已存在
for item in mapping_list:
if item[0] == source:
messagebox.showwarning("重复条码", f"条码 {source} 已存在映射")
return
# 添加到列表
mapping_list.append((source, target))
mapping_tree.insert("", tk.END, values=(source, target))
# 清空输入框
source_entry.delete(0, tk.END)
target_entry.delete(0, tk.END)
def remove_mapping():
selected = mapping_tree.selection()
if not selected:
messagebox.showwarning("未选择", "请先选择要删除的条目")
return
# 获取选中项的索引
item = mapping_tree.item(selected[0])
source = item['values'][0]
# 从列表中移除
for i, (s, _) in enumerate(mapping_list):
if s == source:
mapping_list.pop(i)
break
# 从树中移除
mapping_tree.delete(selected[0])
def add_special():
barcode = special_barcode_entry.get().strip()
multiplier = multiplier_entry.get().strip()
unit = unit_entry.get().strip()
price = price_entry.get().strip()
spec = spec_entry.get().strip()
desc = desc_entry.get().strip()
if not barcode:
messagebox.showwarning("输入错误", "条码不能为空")
return
# 检查是否已存在
for item in special_list:
if item[0] == barcode:
messagebox.showwarning("重复条码", f"条码 {barcode} 已存在特殊处理")
return
# 添加到列表
special_list.append((barcode, multiplier, unit, price, spec, desc))
special_tree.insert("", tk.END, values=(barcode, multiplier, unit, price, spec, desc))
# 清空输入框
special_barcode_entry.delete(0, tk.END)
multiplier_entry.delete(0, tk.END)
unit_entry.delete(0, tk.END)
price_entry.delete(0, tk.END)
spec_entry.delete(0, tk.END)
desc_entry.delete(0, tk.END)
def remove_special():
selected = special_tree.selection()
if not selected:
messagebox.showwarning("未选择", "请先选择要删除的条目")
return
# 获取选中项的索引
item = special_tree.item(selected[0])
barcode = item['values'][0]
# 从列表中移除
for i, (b, _, _, _, _, _) in enumerate(special_list):
if b == barcode:
special_list.pop(i)
break
# 从树中移除
special_tree.delete(selected[0])
# 条码映射按钮
btn_frame = tk.Frame(tab1)
btn_frame.pack(fill=tk.X, padx=5, pady=5)
add_btn = tk.Button(btn_frame, text="添加映射", command=add_mapping)
add_btn.pack(side=tk.LEFT, padx=5)
remove_btn = tk.Button(btn_frame, text="删除映射", command=remove_mapping)
remove_btn.pack(side=tk.LEFT, padx=5)
# 特殊处理按钮
special_btn_frame = tk.Frame(tab2)
special_btn_frame.pack(fill=tk.X, padx=5, pady=5)
add_special_btn = tk.Button(special_btn_frame, text="添加特殊处理", command=add_special)
add_special_btn.pack(side=tk.LEFT, padx=5)
remove_special_btn = tk.Button(special_btn_frame, text="删除特殊处理", command=remove_special)
remove_special_btn.pack(side=tk.LEFT, padx=5)
# 底部按钮区域
bottom_frame = tk.Frame(dialog)
bottom_frame.pack(fill=tk.X, padx=10, pady=10)
def save_mappings():
# 构建保存数据
mappings = {}
# 添加条码映射
for source, target in mapping_list:
mappings[source] = {
'map_to': target,
'description': f'条码映射:{source} -> {target}'
}
# 添加特殊处理
for barcode, multiplier, unit, price, spec, desc in special_list:
mappings[barcode] = {}
if multiplier:
try:
# 安全地转换multiplier为数字
if isinstance(multiplier, str):
if '.' in multiplier:
mappings[barcode]['multiplier'] = float(multiplier)
else:
mappings[barcode]['multiplier'] = int(multiplier)
else:
# 已经是数字类型
mappings[barcode]['multiplier'] = multiplier
except ValueError:
# 如果转换失败,保持原始字符串
mappings[barcode]['multiplier'] = multiplier
if unit:
mappings[barcode]['target_unit'] = unit
if price:
try:
# 安全地转换price为浮点数
mappings[barcode]['fixed_price'] = float(price)
except ValueError:
# 如果转换失败,保持原始字符串
mappings[barcode]['fixed_price'] = price
if spec:
mappings[barcode]['specification'] = spec
if desc:
mappings[barcode]['description'] = desc
# 调用保存回调
if on_save:
on_save(mappings)
messagebox.showinfo("保存成功", f"已保存{len(mapping_list)}个条码映射和{len(special_list)}个特殊处理规则")
dialog.destroy()
def cancel():
dialog.destroy()
save_btn = tk.Button(bottom_frame, text="保存", command=save_mappings)
save_btn.pack(side=tk.RIGHT, padx=5)
cancel_btn = tk.Button(bottom_frame, text="取消", command=cancel)
cancel_btn.pack(side=tk.RIGHT, padx=5)
# 导入当前映射数据
if current_mappings:
for barcode, data in current_mappings.items():
if 'map_to' in data:
# 这是条码映射
mapping_list.append((barcode, data['map_to']))
mapping_tree.insert("", tk.END, values=(barcode, data['map_to']))
else:
# 这是特殊处理
multiplier = data.get('multiplier', '')
unit = data.get('target_unit', '')
price = data.get('fixed_price', '')
spec = data.get('specification', '')
desc = data.get('description', '')
special_list.append((barcode, multiplier, unit, price, spec, desc))
special_tree.insert("", tk.END, values=(barcode, multiplier, unit, price, spec, desc))
# 确保窗口显示在最前
dialog.transient(parent)
dialog.grab_set()
return dialog
def show_barcode_mapping_dialog(*args, **kwargs):
"""
显示条码映射编辑弹窗
参数与create_barcode_mapping_dialog相同
Returns:
dialog: 对话框对象
"""
# 确保已导入ttk
import tkinter.ttk as ttk
return create_barcode_mapping_dialog(*args, **kwargs)

View File

@ -97,6 +97,36 @@ def get_logger(name: str) -> logging.Logger:
return setup_logger(name) return setup_logger(name)
return logger return logger
def set_log_level(level: str) -> None:
"""
设置所有日志记录器的级别
Args:
level: 日志级别(DEBUG, INFO, WARNING, ERROR, CRITICAL)
"""
level_map = {
'debug': logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARNING,
'error': logging.ERROR,
'critical': logging.CRITICAL
}
# 获取对应的日志级别
log_level = level_map.get(level.lower(), logging.INFO)
# 获取所有记录器
loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]
# 设置每个记录器的级别
for logger in loggers:
logger.setLevel(log_level)
# 设置根记录器的级别
logging.getLogger().setLevel(log_level)
print(f"所有日志记录器级别已设置为: {logging.getLevelName(log_level)}")
def close_logger(name: str) -> None: def close_logger(name: str) -> None:
""" """
关闭日志记录器的所有处理器 关闭日志记录器的所有处理器
@ -113,6 +143,25 @@ def close_logger(name: str) -> None:
_handlers.pop(f"{name}_file", None) _handlers.pop(f"{name}_file", None)
_handlers.pop(f"{name}_console", None) _handlers.pop(f"{name}_console", None)
def close_all_loggers() -> None:
"""
关闭所有日志记录器的处理器
"""
# 获取所有记录器
loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]
# 关闭每个记录器的处理器
for logger in loggers:
if hasattr(logger, 'handlers'):
for handler in logger.handlers[:]:
handler.close()
logger.removeHandler(handler)
# 清空处理器缓存
_handlers.clear()
print("所有日志记录器已关闭")
def cleanup_active_marker(name: str) -> None: def cleanup_active_marker(name: str) -> None:
""" """
清理日志活跃标记 清理日志活跃标记

View File

@ -75,6 +75,21 @@ class OCRService:
logger.info(f"OCRService开始批量处理图片, batch_size={batch_size}, max_workers={max_workers}") logger.info(f"OCRService开始批量处理图片, batch_size={batch_size}, max_workers={max_workers}")
return self.ocr_processor.process_images_batch(batch_size, max_workers) return self.ocr_processor.process_images_batch(batch_size, max_workers)
# 添加batch_process作为process_images_batch的别名确保兼容性
def batch_process(self, batch_size: int = None, max_workers: int = None) -> Tuple[int, int]:
"""
批量处理图片别名方法与process_images_batch功能相同
Args:
batch_size: 批处理大小
max_workers: 最大线程数
Returns:
(总处理数, 成功处理数)元组
"""
logger.info(f"OCRService.batch_process被调用转发到process_images_batch")
return self.process_images_batch(batch_size, max_workers)
def validate_image(self, image_path: str) -> bool: def validate_image(self, image_path: str) -> bool:
""" """
验证图片是否有效 验证图片是否有效

View File

@ -0,0 +1,255 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
烟草公司订单处理服务
----------------
处理烟草公司特定格式的订单明细文件生成银豹采购单
"""
import os
import glob
import datetime
import pandas as pd
import xlrd
import xlwt
import re
from xlutils.copy import copy
from openpyxl import load_workbook
from typing import Optional, Dict, Any, List, Tuple
from app.core.utils.log_utils import get_logger
from app.core.utils.dialog_utils import show_custom_dialog # 导入自定义弹窗工具
from ..config.settings import ConfigManager
logger = get_logger(__name__)
class TobaccoService:
"""烟草公司订单处理服务"""
def __init__(self, config: Dict[str, Any]):
"""
初始化服务
Args:
config: 配置信息
"""
self.config = config
# 修复配置获取方式使用fallback机制
self.output_dir = config.get('Paths', 'output_folder', fallback='data/output')
self.template_file = config.get('Paths', 'template_file', fallback='templates/银豹-采购单模板.xls')
self.output_file = os.path.join(self.output_dir, '银豹采购单_烟草公司.xls')
def get_latest_tobacco_order(self) -> Optional[str]:
"""
获取最新的烟草订单明细文件
Returns:
文件路径或None
"""
# 获取今日开始时间戳
today = datetime.date.today()
today_start = datetime.datetime.combine(today, datetime.time.min).timestamp()
# 查找订单明细文件
file_pattern = os.path.join(self.output_dir, "订单明细*.xlsx")
candidates = glob.glob(file_pattern)
if not candidates:
logger.warning("未找到烟草公司订单明细文件")
return None
# 按创建时间排序
candidates.sort(key=os.path.getctime, reverse=True)
latest_file = candidates[0]
# 检查是否是今天的文件
if os.path.getctime(latest_file) >= today_start:
logger.info(f"找到最新烟草订单明细文件: {latest_file}")
return latest_file
else:
logger.warning(f"找到的烟草订单明细文件不是今天创建的: {latest_file}")
return latest_file # 仍然返回最新文件,但给出警告
def process_tobacco_order(self, input_file=None):
"""
处理烟草订单
Args:
input_file: 输入文件路径如果为None则自动查找最新文件
Returns:
输出文件路径或None如果处理失败
"""
try:
# 如果没有指定输入文件,查找最新的文件
if input_file is None:
input_file = self.get_latest_tobacco_order()
if input_file is None:
logger.warning("未找到烟草公司订单明细文件")
logger.error("未找到可处理的烟草订单明细文件")
return None
logger.info(f"开始处理烟草公司订单: {input_file}")
# 读取订单时间和总金额
order_info = self._read_order_info(input_file)
if not order_info:
logger.error(f"读取订单信息失败: {input_file}")
return None
order_time, total_amount = order_info
# 读取订单数据
order_data = self._read_order_data(input_file)
if not order_data:
logger.error(f"读取订单数据失败: {input_file}")
return None
# 生成银豹采购单
output_file = self._generate_pospal_order(order_data, order_time)
if not output_file:
logger.error("生成银豹采购单失败")
return None
# 获取处理条目数
total_count = len(order_data)
# 输出处理结果
logger.info(f"烟草公司订单处理成功,订单时间: {order_time}, 总金额: {total_amount}, 处理条目: {total_count}")
logger.info(f"采购单已生成: {output_file}")
# 显示处理结果对话框
self.show_result_dialog(output_file, order_time, total_count, total_amount)
return output_file
except Exception as e:
logger.error(f"处理烟草公司订单时发生错误: {e}", exc_info=True)
return None
def _read_order_info(self, file_path: str) -> Optional[Tuple[str, float]]:
"""
读取订单信息时间和总金额
Args:
file_path: 文件路径
Returns:
包含订单时间和总金额的元组或None
"""
try:
wb_info = load_workbook(file_path, data_only=True)
ws_info = wb_info.active
order_time = ws_info["H1"].value or "(空)"
total_amount = ws_info["H3"].value or 0
return (order_time, total_amount)
except Exception as e:
logger.error(f"读取订单信息出错: {e}")
return None
def _read_order_data(self, file_path: str) -> Optional[pd.DataFrame]:
"""
读取订单数据
Args:
file_path: 文件路径
Returns:
订单数据DataFrame或None
"""
columns = ['商品', '盒码', '条码', '建议零售价', '批发价', '需求量', '订单量', '金额']
try:
# 读取Excel文件
df_old = pd.read_excel(file_path, header=None, skiprows=3, names=columns)
# 过滤订单量不为0的数据并计算采购量和单价
df_filtered = df_old[df_old['订单量'] != 0].copy()
df_filtered['采购量'] = df_filtered['订单量'] * 10
df_filtered['采购单价'] = df_filtered['金额'] / df_filtered['采购量']
df_filtered = df_filtered.reset_index(drop=True)
return df_filtered
except Exception as e:
logger.error(f"读取订单数据失败: {e}")
return None
def _generate_pospal_order(self, order_data: pd.DataFrame, order_time: str) -> Optional[str]:
"""
生成银豹采购单
Args:
order_data: 订单数据
order_time: 订单时间
Returns:
输出文件路径或None
"""
try:
# 检查模板文件是否存在
if not os.path.exists(self.template_file):
logger.error(f"采购单模板文件不存在: {self.template_file}")
return None
# 打开模板,准备写入
template_rd = xlrd.open_workbook(self.template_file, formatting_info=True)
template_wb = copy(template_rd)
template_ws = template_wb.get_sheet(0)
# 获取模板中的表头列索引
header_row = template_rd.sheet_by_index(0).row_values(0)
barcode_col = header_row.index("条码(必填)")
amount_col = header_row.index("采购量(必填)")
gift_col = header_row.index("赠送量")
price_col = header_row.index("采购单价(必填)")
# 写入数据到模板
for i, row in order_data.iterrows():
template_ws.write(i + 1, barcode_col, row['盒码']) # 商品条码
template_ws.write(i + 1, amount_col, int(row['采购量'])) # 采购量
template_ws.write(i + 1, gift_col, "") # 赠送量为空
template_ws.write(i + 1, price_col, round(row['采购单价'], 2)) # 采购单价保留两位小数
# 确保输出目录存在
os.makedirs(os.path.dirname(self.output_file), exist_ok=True)
# 保存输出文件
template_wb.save(self.output_file)
logger.info(f"采购单生成成功: {self.output_file}")
return self.output_file
except Exception as e:
logger.error(f"生成银豹采购单失败: {e}")
return None
def show_result_dialog(self, output_file, order_time, total_count, total_amount):
"""
显示处理结果对话框
Args:
output_file: 输出文件路径
order_time: 订单时间
total_count: 总处理条目
total_amount: 总金额
"""
# 创建附加信息
additional_info = {
"订单来源": "烟草公司",
"处理时间": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
# 显示自定义对话框
show_custom_dialog(
title="烟草订单处理结果",
message="烟草订单处理完成",
result_file=output_file,
time_info=order_time,
count_info=f"{total_count}个商品",
amount_info=f"¥{total_amount:.2f}",
additional_info=additional_info
)
# 记录日志
logger.info(f"烟草公司订单处理成功,订单时间: {order_time}, 总金额: {total_amount}, 处理条目: {total_count}")

View File

@ -0,0 +1,35 @@
{
"6920584471055": {
"map_to": "6920584471017",
"description": "条码映射6920584471055 -> 6920584471017"
},
"6925861571159": {
"map_to": "69021824",
"description": "条码映射6925861571159 -> 69021824"
},
"6923644268923": {
"map_to": "6923644268480",
"description": "条码映射6923644268923 -> 6923644268480"
},
"6925861571466": {
"map_to": "6925861571459",
"description": "条码映射6925861571466 -> 6925861571459"
},
"6925019900087": {
"multiplier": 10,
"target_unit": "瓶",
"description": "特殊处理:数量*10单位转换为瓶"
},
"6921168593804": {
"multiplier": 30,
"target_unit": "瓶",
"description": "NFC产品特殊处理每箱30瓶"
},
"6901826888138": {
"multiplier": 30,
"target_unit": "瓶",
"fixed_price": 3.7333333333333334,
"specification": "1*30",
"description": "特殊处理: 规格1*30数量*30单价=112/30"
}
}

1
logs/__main__.active Normal file
View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:39

View File

@ -385,3 +385,57 @@
2025-05-08 20:04:14,985 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls 2025-05-08 20:04:14,985 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 20:46:00,701 - __main__ - INFO - 处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx 2025-05-08 20:46:00,701 - __main__ - INFO - 处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 20:46:07,564 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls 2025-05-08 20:46:07,564 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-09 11:55:03,576 - __main__ - INFO - 配置信息: <configparser.ConfigParser object at 0x000002AD48FC6310>
2025-05-09 11:58:49,250 - __main__ - INFO - 配置信息: <configparser.ConfigParser object at 0x000002784E8172E0>
2025-05-09 12:02:05,165 - __main__ - INFO - 配置信息: <configparser.ConfigParser object at 0x0000029382E282B0>
2025-05-09 12:07:05,179 - __main__ - INFO - 配置信息: <configparser.ConfigParser object at 0x000001B1A2BE82E0>
2025-05-09 12:07:54,655 - __main__ - INFO - 配置信息: <configparser.ConfigParser object at 0x0000014A9D9D8400>
2025-05-09 12:12:42,101 - __main__ - INFO - 配置信息: <configparser.ConfigParser object at 0x00000263F3448400>
2025-05-09 12:13:52,578 - __main__ - INFO - 配置信息: <configparser.ConfigParser object at 0x00000244BAAA73D0>
2025-05-09 12:45:35,994 - __main__ - INFO - 配置信息: <configparser.ConfigParser object at 0x000001E499EA73A0>
2025-05-09 12:45:35,999 - __main__ - INFO - 开始烟草公司订单处理
2025-05-09 12:45:36,000 - __main__ - INFO - 处理最新的烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 12:45:36,103 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:21:53,249 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:22:48,497 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:25:59,111 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:29:28,837 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:30:21,973 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:30:43,780 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:34:49,132 - __main__ - INFO - 开始烟草公司订单处理
2025-05-09 13:34:49,291 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:34:49,291 - __main__ - INFO - 烟草订单处理完成,绝对路径: D:\My Documents\python\orc-order-v2\data\output\银豹采购单_烟草公司.xls
2025-05-09 13:37:56,253 - __main__ - INFO - 开始烟草公司订单处理
2025-05-09 13:37:56,482 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:37:56,482 - __main__ - INFO - 烟草订单处理完成,绝对路径: D:\My Documents\python\orc-order-v2\data\output\银豹采购单_烟草公司.xls
2025-05-09 13:39:38,187 - __main__ - ERROR - 执行过程中发生错误: 'OrderService' object has no attribute 'merge_all_purchase_orders'
Traceback (most recent call last):
File "D:\My Documents\python\orc-order-v2\run.py", line 128, in main
result = order_service.merge_all_purchase_orders()
AttributeError: 'OrderService' object has no attribute 'merge_all_purchase_orders'
2025-05-09 13:39:52,436 - __main__ - INFO - 开始烟草公司订单处理
2025-05-09 13:39:52,581 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:39:52,581 - __main__ - INFO - 烟草订单处理完成,绝对路径: D:\My Documents\python\orc-order-v2\data\output\银豹采购单_烟草公司.xls
2025-05-09 13:50:34,352 - __main__ - INFO - 开始烟草公司订单处理
2025-05-09 13:50:34,773 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:50:34,773 - __main__ - INFO - 烟草订单处理完成,绝对路径: D:\My Documents\python\orc-order-v2\data\output\银豹采购单_烟草公司.xls
2025-05-09 13:52:17,577 - __main__ - INFO - 开始烟草公司订单处理
2025-05-09 13:52:17,706 - __main__ - INFO - 烟草订单处理成功,输出文件: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:52:17,707 - __main__ - INFO - 烟草订单处理完成,绝对路径: D:\My Documents\python\orc-order-v2\data\output\银豹采购单_烟草公司.xls
2025-05-09 14:26:54,513 - __main__ - ERROR - 执行过程中发生错误: 'OrderService' object has no attribute 'process_latest_excel'
Traceback (most recent call last):
File "D:\My Documents\python\orc-order-v2\run.py", line 116, in main
result = order_service.process_latest_excel()
AttributeError: 'OrderService' object has no attribute 'process_latest_excel'
2025-05-09 14:27:08,881 - __main__ - ERROR - 执行过程中发生错误: 'OCRService' object has no attribute 'batch_process'
Traceback (most recent call last):
File "D:\My Documents\python\orc-order-v2\run.py", line 98, in main
total, success = ocr_service.batch_process(
AttributeError: 'OCRService' object has no attribute 'batch_process'
2025-05-09 14:27:31,662 - __main__ - ERROR - 执行过程中发生错误: 'OCRService' object has no attribute 'batch_process'
Traceback (most recent call last):
File "D:\My Documents\python\orc-order-v2\run.py", line 98, in main
total, success = ocr_service.batch_process(
AttributeError: 'OCRService' object has no attribute 'batch_process'
2025-05-09 14:32:56,697 - __main__ - INFO - 开始烟草公司订单处理
2025-05-09 14:32:56,706 - __main__ - ERROR - 烟草订单处理失败

View File

@ -0,0 +1 @@
Active since: 2025-05-10 11:21:12

View File

@ -1871,3 +1871,109 @@
2025-05-08 20:46:01,871 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15 2025-05-08 20:46:01,871 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 20:46:01,872 - app.core.excel.converter - INFO - 解析容量(ml)规格: 480ml*15 -> 1*15 2025-05-08 20:46:01,872 - app.core.excel.converter - INFO - 解析容量(ml)规格: 480ml*15 -> 1*15
2025-05-08 20:46:01,873 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15 2025-05-08 20:46:01,873 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-09 14:08:44,053 - app.core.excel.converter - INFO - 解析二级规格: 1*20 -> 1*20
2025-05-09 14:08:44,053 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 10.0, 单位: 瓶
2025-05-09 14:08:44,055 - app.core.excel.converter - INFO - 解析二级规格: 1*48 -> 1*48
2025-05-09 14:08:44,055 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 10.0, 单价: 2.3, 单位: 杯
2025-05-09 14:08:44,056 - app.core.excel.converter - INFO - 解析二级规格: 1*10组*5瓶 -> 1*10
2025-05-09 14:08:44,056 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 9.0, 单位: 组
2025-05-09 14:08:44,057 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:08:44,057 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 3.0, 单位: 袋
2025-05-09 14:08:44,057 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:08:44,058 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 3.0, 单位: 袋
2025-05-09 14:08:44,058 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:08:44,058 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 3.0, 单位: 袋
2025-05-09 14:08:44,060 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:08:44,060 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 3.0, 单位: 袋
2025-05-09 14:08:44,106 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:08:44,106 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 10.0, 单位: 瓶
2025-05-09 14:08:44,107 - app.core.excel.converter - INFO - 解析二级规格: 1*20 -> 1*20
2025-05-09 14:08:44,107 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 7.5, 单位: 瓶
2025-05-09 14:08:44,108 - app.core.excel.converter - INFO - 解析二级规格: 1*20 -> 1*20
2025-05-09 14:08:44,108 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 6.3, 单位: 瓶
2025-05-09 14:08:44,108 - app.core.excel.converter - INFO - 解析二级规格: 1*20 -> 1*20
2025-05-09 14:08:44,108 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 6.3, 单位: 瓶
2025-05-09 14:08:44,109 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
2025-05-09 14:08:44,109 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 7.1, 单位: 瓶
2025-05-09 14:08:44,110 - app.core.excel.converter - INFO - 解析二级规格: 1*16 -> 1*16
2025-05-09 14:08:44,110 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 8.0, 单价: 3.0, 单位: 袋
2025-05-09 14:08:44,111 - app.core.excel.converter - INFO - 解析二级规格: 1*16 -> 1*16
2025-05-09 14:08:44,111 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 6.5, 单位: 杯
2025-05-09 14:08:44,111 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
2025-05-09 14:08:44,111 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 5.5, 单位: 瓶
2025-05-09 14:23:40,858 - app.core.excel.converter - INFO - 解析二级规格: 1*20 -> 1*20
2025-05-09 14:23:40,865 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 10.0, 单位: 瓶
2025-05-09 14:23:40,878 - app.core.excel.converter - INFO - 解析二级规格: 1*48 -> 1*48
2025-05-09 14:23:40,878 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 10.0, 单价: 2.3, 单位: 杯
2025-05-09 14:23:40,879 - app.core.excel.converter - INFO - 解析二级规格: 1*10组*5瓶 -> 1*10
2025-05-09 14:23:40,880 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 9.0, 单位: 组
2025-05-09 14:23:40,888 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:23:40,888 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 3.0, 单位: 袋
2025-05-09 14:23:40,890 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:23:40,890 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 3.0, 单位: 袋
2025-05-09 14:23:40,896 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:23:40,896 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 3.0, 单位: 袋
2025-05-09 14:23:40,897 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:23:40,897 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 3.0, 单位: 袋
2025-05-09 14:23:40,898 - app.core.excel.converter - INFO - 解析二级规格: 1*12 -> 1*12
2025-05-09 14:23:40,899 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 10.0, 单位: 瓶
2025-05-09 14:23:40,900 - app.core.excel.converter - INFO - 解析二级规格: 1*20 -> 1*20
2025-05-09 14:23:40,900 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 7.5, 单位: 瓶
2025-05-09 14:23:41,461 - app.core.excel.converter - INFO - 解析二级规格: 1*20 -> 1*20
2025-05-09 14:23:41,461 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 6.3, 单位: 瓶
2025-05-09 14:23:41,462 - app.core.excel.converter - INFO - 解析二级规格: 1*20 -> 1*20
2025-05-09 14:23:41,462 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 6.3, 单位: 瓶
2025-05-09 14:23:41,462 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
2025-05-09 14:23:41,463 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 7.1, 单位: 瓶
2025-05-09 14:23:41,463 - app.core.excel.converter - INFO - 解析二级规格: 1*16 -> 1*16
2025-05-09 14:23:41,464 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 8.0, 单价: 3.0, 单位: 袋
2025-05-09 14:23:41,465 - app.core.excel.converter - INFO - 解析二级规格: 1*16 -> 1*16
2025-05-09 14:23:41,465 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 6.5, 单位: 杯
2025-05-09 14:23:41,466 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
2025-05-09 14:23:41,466 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 5.5, 单位: 瓶
2025-05-09 14:31:54,333 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 14:31:54,334 - app.core.excel.converter - INFO - 解析容量(ml)规格: 260ML*24 -> 1*24
2025-05-09 14:31:54,338 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 14:31:54,339 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 14:31:54,341 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 14:31:54,342 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 14:31:54,432 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 14:31:54,432 - app.core.excel.converter - INFO - 解析容量(ml)规格: 245ML*12 -> 1*12
2025-05-09 14:31:54,433 - app.core.excel.converter - INFO - 解析容量(ml)规格: 125ML*36 -> 1*36
2025-05-09 14:31:54,434 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 14:31:54,434 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*24 -> 1*24
2025-05-09 14:31:54,435 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*24 -> 1*24
2025-05-09 14:31:54,435 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*24 -> 1*24
2025-05-09 14:31:54,436 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 14:32:21,071 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-09 14:32:21,077 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,081 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,082 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,083 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,086 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,214 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,215 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,217 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,218 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 14:32:21,219 - app.core.excel.converter - INFO - 解析容量(L)规格: 1L*12 -> 1*12
2025-05-09 15:15:10,369 - app.core.excel.converter - INFO - 条码映射配置保存成功共6项
2025-05-09 15:15:10,377 - app.core.excel.converter - INFO - 创建默认条码映射配置共6项
2025-05-09 16:01:39,293 - app.core.excel.converter - INFO - 成功加载条码映射配置共6项
2025-05-09 16:01:39,480 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 16:01:39,481 - app.core.excel.converter - INFO - 解析容量(ml)规格: 260ML*24 -> 1*24
2025-05-09 16:01:39,482 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 16:01:39,483 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 16:01:39,484 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 16:01:39,484 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 16:01:39,485 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 16:01:39,711 - app.core.excel.converter - INFO - 解析容量(ml)规格: 245ML*12 -> 1*12
2025-05-09 16:01:39,712 - app.core.excel.converter - INFO - 解析容量(ml)规格: 125ML*36 -> 1*36
2025-05-09 16:01:39,713 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 16:01:39,714 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*24 -> 1*24
2025-05-09 16:01:39,715 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*24 -> 1*24
2025-05-09 16:01:39,716 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*24 -> 1*24
2025-05-09 16:01:39,717 - app.core.excel.converter - INFO - 解析容量(ml)规格: 250ML*12 -> 1*12
2025-05-09 16:03:48,340 - app.core.excel.converter - INFO - 成功加载条码映射配置共6项
2025-05-09 16:07:24,661 - app.core.excel.converter - INFO - 成功加载条码映射配置共6项
2025-05-09 16:08:24,335 - app.core.excel.converter - INFO - 条码映射配置保存成功共7项
2025-05-09 16:08:28,902 - app.core.excel.converter - INFO - 成功加载条码映射配置共7项

View File

@ -0,0 +1 @@
Active since: 2025-05-10 11:21:12

View File

@ -0,0 +1,9 @@
2025-05-09 14:31:54,337 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6923644283582 -> 6923644283575
2025-05-09 14:31:54,340 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6923644268930 -> 6923644268497
2025-05-09 14:31:54,341 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6923644268916 -> 6923644268503
2025-05-09 14:31:54,432 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6920584471055 -> 6920584471017
2025-05-09 14:31:54,433 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6925861571159 -> 69021824
2025-05-09 14:31:54,434 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6923644210151 -> 6923644223458
2025-05-09 14:31:54,435 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6907992501819 -> 6907992500133
2025-05-09 16:01:39,710 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6920584471055 -> 6920584471017
2025-05-09 16:01:39,712 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6925861571159 -> 69021824

View File

@ -0,0 +1 @@
Active since: 2025-05-10 11:21:12

View File

@ -33,3 +33,42 @@
2025-05-08 20:46:01,871 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 2.0, 单价: 0, 单位: 瓶 2025-05-08 20:46:01,871 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 2.0, 单价: 0, 单位: 瓶
2025-05-08 20:46:01,872 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 1.0, 单价: 0, 单位: 瓶 2025-05-08 20:46:01,872 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 1.0, 单价: 0, 单位: 瓶
2025-05-08 20:46:03,157 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 9.0, 单价: 0, 单位: 瓶 2025-05-08 20:46:03,157 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 9.0, 单价: 0, 单位: 瓶
2025-05-09 14:31:54,333 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 52.0 -> 4.333333333333333, 单位: 件 -> 瓶
2025-05-09 14:31:54,334 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 3.0 -> 72.0, 单价: 50.0 -> 2.0833333333333335, 单位: 件 -> 瓶
2025-05-09 14:31:54,338 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 30.0 -> 2.5, 单位: 件 -> 瓶
2025-05-09 14:31:54,340 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 30.0 -> 2.5, 单位: 件 -> 瓶
2025-05-09 14:31:54,341 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 30.0 -> 2.5, 单位: 件 -> 瓶
2025-05-09 14:31:54,342 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 30.0 -> 2.5, 单位: 件 -> 瓶
2025-05-09 14:31:54,432 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 4.0 -> 48.0, 单价: 45.0 -> 3.75, 单位: 件 -> 瓶
2025-05-09 14:31:54,433 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 50.0 -> 4.166666666666667, 单位: 件 -> 瓶
2025-05-09 14:31:54,433 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 72.0, 单价: 65.0 -> 1.8055555555555556, 单位: 件 -> 瓶
2025-05-09 14:31:54,434 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 45.0 -> 3.75, 单位: 件 -> 瓶
2025-05-09 14:31:54,435 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 3.0 -> 72.0, 单价: 55.0 -> 2.2916666666666665, 单位: 件 -> 瓶
2025-05-09 14:31:54,435 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 3.0 -> 72.0, 单价: 63.0 -> 2.625, 单位: 件 -> 瓶
2025-05-09 14:31:54,436 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 3.0 -> 72.0, 单价: 54.0 -> 2.25, 单位: 件 -> 瓶
2025-05-09 14:31:54,436 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,072 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 33.0 -> 2.2, 单位: 件 -> 瓶
2025-05-09 14:32:21,077 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,081 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,082 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,084 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,086 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,214 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,215 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,217 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶
2025-05-09 14:32:21,218 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品件单位处理: 数量: 1.0 -> 12.0, 单价: 0, 单位: 件 -> 瓶
2025-05-09 14:32:21,219 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 1.0, 单价: 0, 单位: 瓶
2025-05-09 16:01:39,480 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 52.0 -> 4.333333333333333, 单位: 件 -> 瓶
2025-05-09 16:01:39,481 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 3.0 -> 72.0, 单价: 50.0 -> 2.0833333333333335, 单位: 件 -> 瓶
2025-05-09 16:01:39,482 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 30.0 -> 2.5, 单位: 件 -> 瓶
2025-05-09 16:01:39,483 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 30.0 -> 2.5, 单位: 件 -> 瓶
2025-05-09 16:01:39,484 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 30.0 -> 2.5, 单位: 件 -> 瓶
2025-05-09 16:01:39,485 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 30.0 -> 2.5, 单位: 件 -> 瓶
2025-05-09 16:01:39,485 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 4.0 -> 48.0, 单价: 45.0 -> 3.75, 单位: 件 -> 瓶
2025-05-09 16:01:39,711 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 50.0 -> 4.166666666666667, 单位: 件 -> 瓶
2025-05-09 16:01:39,712 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 72.0, 单价: 65.0 -> 1.8055555555555556, 单位: 件 -> 瓶
2025-05-09 16:01:39,713 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 12.0, 单价: 45.0 -> 3.75, 单位: 件 -> 瓶
2025-05-09 16:01:39,714 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 3.0 -> 72.0, 单价: 55.0 -> 2.2916666666666665, 单位: 件 -> 瓶
2025-05-09 16:01:39,715 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 3.0 -> 72.0, 单价: 63.0 -> 2.625, 单位: 件 -> 瓶
2025-05-09 16:01:39,716 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 3.0 -> 72.0, 单价: 54.0 -> 2.25, 单位: 件 -> 瓶
2025-05-09 16:01:39,717 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 2.0 -> 24.0, 单价: 42.0 -> 3.5, 单位: 件 -> 瓶

View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:38

View File

@ -493,3 +493,22 @@
2025-05-08 20:04:06,909 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls 2025-05-08 20:04:06,909 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 20:46:00,700 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger 2025-05-08 20:46:00,700 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger
2025-05-08 20:46:00,701 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls 2025-05-08 20:46:00,701 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-09 12:12:42,109 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger
2025-05-09 12:13:52,585 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:13:52,585 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls
2025-05-09 12:45:35,998 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:45:35,998 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls
2025-05-09 13:39:38,184 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 13:39:38,186 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls
2025-05-09 14:08:43,903 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:08:43,903 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls
2025-05-09 14:23:40,515 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:23:40,515 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls
2025-05-09 14:26:54,510 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:26:54,511 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls
2025-05-09 14:31:54,258 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:31:54,259 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls
2025-05-09 14:32:20,941 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:32:20,942 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls
2025-05-09 16:01:39,294 - app.core.excel.merger - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 16:01:39,294 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成模板文件: templates\银豹-采购单模板.xls

View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:38

View File

@ -5753,3 +5753,448 @@ ValueError: could not convert string to float: '2\n96'
2025-05-08 20:46:07,559 - app.core.excel.processor - INFO - 条码 6975176782460 填充:仅有赠品,采购量=0赠品数量=9.0 2025-05-08 20:46:07,559 - app.core.excel.processor - INFO - 条码 6975176782460 填充:仅有赠品,采购量=0赠品数量=9.0
2025-05-08 20:46:07,563 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls 2025-05-08 20:46:07,563 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 20:46:07,564 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls 2025-05-08 20:46:07,564 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-09 12:07:05,182 - app.core.excel.processor - INFO - 初始化ExcelProcessor
2025-05-09 12:07:54,661 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:07:54,661 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:07:54,661 - app.core.excel.processor - ERROR - 初始化ExcelProcessor失败: name 'TableHeaderFinder' is not defined
2025-05-09 12:12:42,106 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:12:42,107 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:12:42,108 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 12:13:52,582 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:13:52,582 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:13:52,584 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 12:45:35,997 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:45:35,998 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:45:35,998 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 13:39:38,182 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 13:39:38,183 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 13:39:38,183 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 14:08:43,902 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:08:43,902 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 14:08:43,902 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 14:08:43,903 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/高新-益选便利店销售单2025-05-09.xlsx
2025-05-09 14:08:43,986 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/高新-益选便利店销售单2025-05-09.xlsx, 共 21 行
2025-05-09 14:08:43,992 - app.core.excel.processor - INFO - 找到可能的表头行: 第5行评分: 60
2025-05-09 14:08:43,992 - app.core.excel.processor - INFO - 识别到表头在第 5 行
2025-05-09 14:08:44,045 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 16 行有效数据
2025-05-09 14:08:44,045 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-09 14:08:44,045 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-09 14:08:44,045 - app.core.excel.processor - INFO - 找到name列: 商品名称
2025-05-09 14:08:44,045 - app.core.excel.processor - INFO - 找到specification列: 规格
2025-05-09 14:08:44,046 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-09 14:08:44,046 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-09 14:08:44,046 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-09 14:08:44,046 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品名称', 'specification': '规格', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-09 14:08:44,046 - app.core.excel.processor - INFO - 是否存在规格列: True
2025-05-09 14:08:44,047 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6901209255021, 名称=光明look噜渴458ml, 规格=, 数量=2.0, 单位=瓶, 单价=10.0
2025-05-09 14:08:44,050 - app.core.excel.processor - INFO - 解析规格: 1*20 -> 包装数量=20
2025-05-09 14:08:44,054 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6907992103587, 名称=伊利U形红枣杯160g, 规格=, 数量=10.0, 单位=杯, 单价=2.3
2025-05-09 14:08:44,054 - app.core.excel.processor - INFO - 解析规格: 1*48 -> 包装数量=48
2025-05-09 14:08:44,055 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6907992102726, 名称=伊利每益添100ml, 规格=, 数量=2.0, 单位=组, 单价=9.0
2025-05-09 14:08:44,056 - app.core.excel.processor - INFO - 解析规格: 1*10组*5瓶 -> 包装数量=10
2025-05-09 14:08:44,057 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6975382530176, 名称=海河草莓味牛奶220ml, 规格=, 数量=6.0, 单位=袋, 单价=3.0
2025-05-09 14:08:44,057 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:08:44,057 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6975382531333, 名称=海河玫瑰荔枝味220g, 规格=, 数量=6.0, 单位=袋, 单价=3.0
2025-05-09 14:08:44,057 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:08:44,058 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6975382531142, 名称=海河樱花白桃牛奶220ml, 规格=, 数量=6.0, 单位=袋, 单价=3.0
2025-05-09 14:08:44,058 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:08:44,058 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6975382530350, 名称=海河可可牛奶220ml, 规格=, 数量=6.0, 单位=袋, 单价=3.0
2025-05-09 14:08:44,060 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:08:44,106 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6907992106915, 名称=伊利天然牧场鲜牛奶405ml, 规格=, 数量=2.0, 单位=瓶, 单价=10.0
2025-05-09 14:08:44,106 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:08:44,106 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6907992103594, 名称=伊利桶红枣酸牛奶450ml, 规格=, 数量=2.0, 单位=瓶, 单价=7.5
2025-05-09 14:08:44,106 - app.core.excel.processor - INFO - 解析规格: 1*20 -> 包装数量=20
2025-05-09 14:08:44,107 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6907992108018, 名称=伊利每益添果蔬益生菌饮品羽衣甘蓝+猕猴桃330ml, 规格=, 数量=2.0, 单位=瓶, 单价=6.3
2025-05-09 14:08:44,107 - app.core.excel.processor - INFO - 解析规格: 1*20 -> 包装数量=20
2025-05-09 14:08:44,108 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6907992108025, 名称=伊利每益添果蔬益生菌饮品红甜菜+樱桃330ml, 规格=, 数量=2.0, 单位=瓶, 单价=6.3
2025-05-09 14:08:44,108 - app.core.excel.processor - INFO - 解析规格: 1*20 -> 包装数量=20
2025-05-09 14:08:44,109 - app.core.excel.processor - INFO - 第12行: 提取商品信息 条码=6907992107639, 名称=伊利250ml畅轻西柚芒果+青稞爆珠风味发酵乳, 规格=, 数量=2.0, 单位=瓶, 单价=7.1
2025-05-09 14:08:44,109 - app.core.excel.processor - INFO - 解析规格: 1*24 -> 包装数量=24
2025-05-09 14:08:44,110 - app.core.excel.processor - INFO - 第13行: 提取商品信息 条码=6903979800999, 名称=菊乐嚼酸奶(燕麦百香果味)170g*16, 规格=, 数量=8.0, 单位=袋, 单价=3.0
2025-05-09 14:08:44,110 - app.core.excel.processor - INFO - 解析规格: 1*16 -> 包装数量=16
2025-05-09 14:08:44,110 - app.core.excel.processor - INFO - 第14行: 提取商品信息 条码=6907992106861, 名称=伊利-大口嚼180克, 规格=, 数量=4.0, 单位=杯, 单价=6.5
2025-05-09 14:08:44,110 - app.core.excel.processor - INFO - 解析规格: 1*16 -> 包装数量=16
2025-05-09 14:08:44,111 - app.core.excel.processor - INFO - 第15行: 提取商品信息 条码=6934665087653, 名称=蒙牛优益c原味340, 规格=, 数量=6.0, 单位=瓶, 单价=5.5
2025-05-09 14:08:44,111 - app.core.excel.processor - INFO - 解析规格: 1*24 -> 包装数量=24
2025-05-09 14:08:44,112 - app.core.excel.processor - INFO - 提取到 15 个商品信息
2025-05-09 14:08:44,125 - app.core.excel.processor - INFO - 开始处理15 个产品信息
2025-05-09 14:08:44,125 - app.core.excel.processor - INFO - 处理商品: 条码=6901209255021, 数量=2.0, 单价=10.0, 是否赠品=False
2025-05-09 14:08:44,126 - app.core.excel.processor - INFO - 发现正常商品条码6901209255021, 数量=2.0, 单价=10.0
2025-05-09 14:08:47,592 - app.core.excel.processor - INFO - 处理商品: 条码=6907992103587, 数量=10.0, 单价=2.3, 是否赠品=False
2025-05-09 14:08:47,592 - app.core.excel.processor - INFO - 发现正常商品条码6907992103587, 数量=10.0, 单价=2.3
2025-05-09 14:08:47,592 - app.core.excel.processor - INFO - 处理商品: 条码=6907992102726, 数量=2.0, 单价=9.0, 是否赠品=False
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 发现正常商品条码6907992102726, 数量=2.0, 单价=9.0
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 处理商品: 条码=6975382530176, 数量=6.0, 单价=3.0, 是否赠品=False
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 发现正常商品条码6975382530176, 数量=6.0, 单价=3.0
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 处理商品: 条码=6975382531333, 数量=6.0, 单价=3.0, 是否赠品=False
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 发现正常商品条码6975382531333, 数量=6.0, 单价=3.0
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 处理商品: 条码=6975382531142, 数量=6.0, 单价=3.0, 是否赠品=False
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 发现正常商品条码6975382531142, 数量=6.0, 单价=3.0
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 处理商品: 条码=6975382530350, 数量=6.0, 单价=3.0, 是否赠品=False
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 发现正常商品条码6975382530350, 数量=6.0, 单价=3.0
2025-05-09 14:08:47,593 - app.core.excel.processor - INFO - 处理商品: 条码=6907992106915, 数量=2.0, 单价=10.0, 是否赠品=False
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 发现正常商品条码6907992106915, 数量=2.0, 单价=10.0
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 处理商品: 条码=6907992103594, 数量=2.0, 单价=7.5, 是否赠品=False
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 发现正常商品条码6907992103594, 数量=2.0, 单价=7.5
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 处理商品: 条码=6907992108018, 数量=2.0, 单价=6.3, 是否赠品=False
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 发现正常商品条码6907992108018, 数量=2.0, 单价=6.3
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 处理商品: 条码=6907992108025, 数量=2.0, 单价=6.3, 是否赠品=False
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 发现正常商品条码6907992108025, 数量=2.0, 单价=6.3
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 处理商品: 条码=6907992107639, 数量=2.0, 单价=7.1, 是否赠品=False
2025-05-09 14:08:47,594 - app.core.excel.processor - INFO - 发现正常商品条码6907992107639, 数量=2.0, 单价=7.1
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 处理商品: 条码=6903979800999, 数量=8.0, 单价=3.0, 是否赠品=False
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 发现正常商品条码6903979800999, 数量=8.0, 单价=3.0
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 处理商品: 条码=6907992106861, 数量=4.0, 单价=6.5, 是否赠品=False
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 发现正常商品条码6907992106861, 数量=4.0, 单价=6.5
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 处理商品: 条码=6934665087653, 数量=6.0, 单价=5.5, 是否赠品=False
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 发现正常商品条码6934665087653, 数量=6.0, 单价=5.5
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 分组后共15 个不同条码的商品
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 条码 6901209255021 处理结果正常商品数量2.0单价10.0赠品数量0
2025-05-09 14:08:47,595 - app.core.excel.processor - INFO - 条码 6907992103587 处理结果正常商品数量10.0单价2.3赠品数量0
2025-05-09 14:08:47,596 - app.core.excel.processor - INFO - 条码 6907992102726 处理结果正常商品数量2.0单价9.0赠品数量0
2025-05-09 14:08:47,596 - app.core.excel.processor - INFO - 条码 6975382530176 处理结果正常商品数量6.0单价3.0赠品数量0
2025-05-09 14:08:47,596 - app.core.excel.processor - INFO - 条码 6975382531333 处理结果正常商品数量6.0单价3.0赠品数量0
2025-05-09 14:08:47,596 - app.core.excel.processor - INFO - 条码 6975382531142 处理结果正常商品数量6.0单价3.0赠品数量0
2025-05-09 14:08:51,773 - app.core.excel.processor - INFO - 条码 6975382530350 处理结果正常商品数量6.0单价3.0赠品数量0
2025-05-09 14:08:51,773 - app.core.excel.processor - INFO - 条码 6907992106915 处理结果正常商品数量2.0单价10.0赠品数量0
2025-05-09 14:08:51,773 - app.core.excel.processor - INFO - 条码 6907992103594 处理结果正常商品数量2.0单价7.5赠品数量0
2025-05-09 14:08:51,774 - app.core.excel.processor - INFO - 条码 6907992108018 处理结果正常商品数量2.0单价6.3赠品数量0
2025-05-09 14:08:51,774 - app.core.excel.processor - INFO - 条码 6907992108025 处理结果正常商品数量2.0单价6.3赠品数量0
2025-05-09 14:08:51,774 - app.core.excel.processor - INFO - 条码 6907992107639 处理结果正常商品数量2.0单价7.1赠品数量0
2025-05-09 14:08:51,774 - app.core.excel.processor - INFO - 条码 6903979800999 处理结果正常商品数量8.0单价3.0赠品数量0
2025-05-09 14:08:51,774 - app.core.excel.processor - INFO - 条码 6907992106861 处理结果正常商品数量4.0单价6.5赠品数量0
2025-05-09 14:08:51,774 - app.core.excel.processor - INFO - 条码 6934665087653 处理结果正常商品数量6.0单价5.5赠品数量0
2025-05-09 14:08:51,778 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_高新-益选便利店销售单2025-05-09.xls
2025-05-09 14:08:51,780 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_高新-益选便利店销售单2025-05-09.xls
2025-05-09 14:23:40,514 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:23:40,514 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 14:23:40,514 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 14:23:40,516 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/高新-益选便利店销售单2025-05-09.xlsx
2025-05-09 14:23:40,658 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/高新-益选便利店销售单2025-05-09.xlsx, 共 21 行
2025-05-09 14:23:40,668 - app.core.excel.processor - INFO - 找到可能的表头行: 第5行评分: 60
2025-05-09 14:23:40,669 - app.core.excel.processor - INFO - 识别到表头在第 5 行
2025-05-09 14:23:40,841 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 16 行有效数据
2025-05-09 14:23:40,841 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-09 14:23:40,841 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-09 14:23:40,842 - app.core.excel.processor - INFO - 找到name列: 商品名称
2025-05-09 14:23:40,842 - app.core.excel.processor - INFO - 找到specification列: 规格
2025-05-09 14:23:40,842 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-09 14:23:40,843 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-09 14:23:40,843 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-09 14:23:40,843 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品名称', 'specification': '规格', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-09 14:23:40,843 - app.core.excel.processor - INFO - 是否存在规格列: True
2025-05-09 14:23:40,845 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6901209255021, 名称=光明look噜渴458ml, 规格=, 数量=2.0, 单位=瓶, 单价=10.0
2025-05-09 14:23:40,851 - app.core.excel.processor - INFO - 解析规格: 1*20 -> 包装数量=20
2025-05-09 14:23:40,877 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6907992103587, 名称=伊利U形红枣杯160g, 规格=, 数量=10.0, 单位=杯, 单价=2.3
2025-05-09 14:23:40,877 - app.core.excel.processor - INFO - 解析规格: 1*48 -> 包装数量=48
2025-05-09 14:23:40,879 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6907992102726, 名称=伊利每益添100ml, 规格=, 数量=2.0, 单位=组, 单价=9.0
2025-05-09 14:23:40,879 - app.core.excel.processor - INFO - 解析规格: 1*10组*5瓶 -> 包装数量=10
2025-05-09 14:23:40,880 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6975382530176, 名称=海河草莓味牛奶220ml, 规格=, 数量=6.0, 单位=袋, 单价=3.0
2025-05-09 14:23:40,888 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:23:40,889 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6975382531333, 名称=海河玫瑰荔枝味220g, 规格=, 数量=6.0, 单位=袋, 单价=3.0
2025-05-09 14:23:40,890 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:23:40,891 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6975382531142, 名称=海河樱花白桃牛奶220ml, 规格=, 数量=6.0, 单位=袋, 单价=3.0
2025-05-09 14:23:40,896 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:23:40,897 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6975382530350, 名称=海河可可牛奶220ml, 规格=, 数量=6.0, 单位=袋, 单价=3.0
2025-05-09 14:23:40,897 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:23:40,898 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6907992106915, 名称=伊利天然牧场鲜牛奶405ml, 规格=, 数量=2.0, 单位=瓶, 单价=10.0
2025-05-09 14:23:40,898 - app.core.excel.processor - INFO - 解析规格: 1*12 -> 包装数量=12
2025-05-09 14:23:40,899 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6907992103594, 名称=伊利桶红枣酸牛奶450ml, 规格=, 数量=2.0, 单位=瓶, 单价=7.5
2025-05-09 14:23:40,899 - app.core.excel.processor - INFO - 解析规格: 1*20 -> 包装数量=20
2025-05-09 14:23:40,900 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6907992108018, 名称=伊利每益添果蔬益生菌饮品羽衣甘蓝+猕猴桃330ml, 规格=, 数量=2.0, 单位=瓶, 单价=6.3
2025-05-09 14:23:40,900 - app.core.excel.processor - INFO - 解析规格: 1*20 -> 包装数量=20
2025-05-09 14:23:41,461 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6907992108025, 名称=伊利每益添果蔬益生菌饮品红甜菜+樱桃330ml, 规格=, 数量=2.0, 单位=瓶, 单价=6.3
2025-05-09 14:23:41,461 - app.core.excel.processor - INFO - 解析规格: 1*20 -> 包装数量=20
2025-05-09 14:23:41,462 - app.core.excel.processor - INFO - 第12行: 提取商品信息 条码=6907992107639, 名称=伊利250ml畅轻西柚芒果+青稞爆珠风味发酵乳, 规格=, 数量=2.0, 单位=瓶, 单价=7.1
2025-05-09 14:23:41,462 - app.core.excel.processor - INFO - 解析规格: 1*24 -> 包装数量=24
2025-05-09 14:23:41,463 - app.core.excel.processor - INFO - 第13行: 提取商品信息 条码=6903979800999, 名称=菊乐嚼酸奶(燕麦百香果味)170g*16, 规格=, 数量=8.0, 单位=袋, 单价=3.0
2025-05-09 14:23:41,463 - app.core.excel.processor - INFO - 解析规格: 1*16 -> 包装数量=16
2025-05-09 14:23:41,464 - app.core.excel.processor - INFO - 第14行: 提取商品信息 条码=6907992106861, 名称=伊利-大口嚼180克, 规格=, 数量=4.0, 单位=杯, 单价=6.5
2025-05-09 14:23:41,464 - app.core.excel.processor - INFO - 解析规格: 1*16 -> 包装数量=16
2025-05-09 14:23:41,466 - app.core.excel.processor - INFO - 第15行: 提取商品信息 条码=6934665087653, 名称=蒙牛优益c原味340, 规格=, 数量=6.0, 单位=瓶, 单价=5.5
2025-05-09 14:23:41,466 - app.core.excel.processor - INFO - 解析规格: 1*24 -> 包装数量=24
2025-05-09 14:23:41,467 - app.core.excel.processor - INFO - 提取到 15 个商品信息
2025-05-09 14:23:41,480 - app.core.excel.processor - INFO - 开始处理15 个产品信息
2025-05-09 14:23:41,480 - app.core.excel.processor - INFO - 处理商品: 条码=6901209255021, 数量=2.0, 单价=10.0, 是否赠品=False
2025-05-09 14:23:41,481 - app.core.excel.processor - INFO - 发现正常商品条码6901209255021, 数量=2.0, 单价=10.0
2025-05-09 14:23:41,481 - app.core.excel.processor - INFO - 处理商品: 条码=6907992103587, 数量=10.0, 单价=2.3, 是否赠品=False
2025-05-09 14:23:41,481 - app.core.excel.processor - INFO - 发现正常商品条码6907992103587, 数量=10.0, 单价=2.3
2025-05-09 14:23:41,481 - app.core.excel.processor - INFO - 处理商品: 条码=6907992102726, 数量=2.0, 单价=9.0, 是否赠品=False
2025-05-09 14:23:41,481 - app.core.excel.processor - INFO - 发现正常商品条码6907992102726, 数量=2.0, 单价=9.0
2025-05-09 14:23:41,481 - app.core.excel.processor - INFO - 处理商品: 条码=6975382530176, 数量=6.0, 单价=3.0, 是否赠品=False
2025-05-09 14:23:41,481 - app.core.excel.processor - INFO - 发现正常商品条码6975382530176, 数量=6.0, 单价=3.0
2025-05-09 14:23:41,481 - app.core.excel.processor - INFO - 处理商品: 条码=6975382531333, 数量=6.0, 单价=3.0, 是否赠品=False
2025-05-09 14:23:41,482 - app.core.excel.processor - INFO - 发现正常商品条码6975382531333, 数量=6.0, 单价=3.0
2025-05-09 14:23:41,482 - app.core.excel.processor - INFO - 处理商品: 条码=6975382531142, 数量=6.0, 单价=3.0, 是否赠品=False
2025-05-09 14:23:41,482 - app.core.excel.processor - INFO - 发现正常商品条码6975382531142, 数量=6.0, 单价=3.0
2025-05-09 14:23:45,553 - app.core.excel.processor - INFO - 处理商品: 条码=6975382530350, 数量=6.0, 单价=3.0, 是否赠品=False
2025-05-09 14:23:45,553 - app.core.excel.processor - INFO - 发现正常商品条码6975382530350, 数量=6.0, 单价=3.0
2025-05-09 14:23:45,553 - app.core.excel.processor - INFO - 处理商品: 条码=6907992106915, 数量=2.0, 单价=10.0, 是否赠品=False
2025-05-09 14:23:45,553 - app.core.excel.processor - INFO - 发现正常商品条码6907992106915, 数量=2.0, 单价=10.0
2025-05-09 14:23:45,553 - app.core.excel.processor - INFO - 处理商品: 条码=6907992103594, 数量=2.0, 单价=7.5, 是否赠品=False
2025-05-09 14:23:45,553 - app.core.excel.processor - INFO - 发现正常商品条码6907992103594, 数量=2.0, 单价=7.5
2025-05-09 14:23:45,553 - app.core.excel.processor - INFO - 处理商品: 条码=6907992108018, 数量=2.0, 单价=6.3, 是否赠品=False
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 发现正常商品条码6907992108018, 数量=2.0, 单价=6.3
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 处理商品: 条码=6907992108025, 数量=2.0, 单价=6.3, 是否赠品=False
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 发现正常商品条码6907992108025, 数量=2.0, 单价=6.3
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 处理商品: 条码=6907992107639, 数量=2.0, 单价=7.1, 是否赠品=False
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 发现正常商品条码6907992107639, 数量=2.0, 单价=7.1
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 处理商品: 条码=6903979800999, 数量=8.0, 单价=3.0, 是否赠品=False
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 发现正常商品条码6903979800999, 数量=8.0, 单价=3.0
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 处理商品: 条码=6907992106861, 数量=4.0, 单价=6.5, 是否赠品=False
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 发现正常商品条码6907992106861, 数量=4.0, 单价=6.5
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 处理商品: 条码=6934665087653, 数量=6.0, 单价=5.5, 是否赠品=False
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 发现正常商品条码6934665087653, 数量=6.0, 单价=5.5
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 分组后共15 个不同条码的商品
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 条码 6901209255021 处理结果正常商品数量2.0单价10.0赠品数量0
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 条码 6907992103587 处理结果正常商品数量10.0单价2.3赠品数量0
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 条码 6907992102726 处理结果正常商品数量2.0单价9.0赠品数量0
2025-05-09 14:23:45,554 - app.core.excel.processor - INFO - 条码 6975382530176 处理结果正常商品数量6.0单价3.0赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6975382531333 处理结果正常商品数量6.0单价3.0赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6975382531142 处理结果正常商品数量6.0单价3.0赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6975382530350 处理结果正常商品数量6.0单价3.0赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6907992106915 处理结果正常商品数量2.0单价10.0赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6907992103594 处理结果正常商品数量2.0单价7.5赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6907992108018 处理结果正常商品数量2.0单价6.3赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6907992108025 处理结果正常商品数量2.0单价6.3赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6907992107639 处理结果正常商品数量2.0单价7.1赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6903979800999 处理结果正常商品数量8.0单价3.0赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6907992106861 处理结果正常商品数量4.0单价6.5赠品数量0
2025-05-09 14:23:45,555 - app.core.excel.processor - INFO - 条码 6934665087653 处理结果正常商品数量6.0单价5.5赠品数量0
2025-05-09 14:23:49,343 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_高新-益选便利店销售单2025-05-09.xls
2025-05-09 14:23:49,345 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_高新-益选便利店销售单2025-05-09.xls
2025-05-09 14:26:54,509 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:26:54,509 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 14:26:54,509 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 14:31:54,257 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:31:54,258 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 14:31:54,258 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 14:31:54,259 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142624.xlsx
2025-05-09 14:31:54,289 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142624.xlsx, 共 16 行
2025-05-09 14:31:54,293 - app.core.excel.processor - INFO - 找到可能的表头行: 第1行评分: 45
2025-05-09 14:31:54,294 - app.core.excel.processor - INFO - 识别到表头在第 1 行
2025-05-09 14:31:54,326 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 15 行有效数据
2025-05-09 14:31:54,327 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-09 14:31:54,327 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-09 14:31:54,327 - app.core.excel.processor - INFO - 找到name列(部分匹配): 商品条码
2025-05-09 14:31:54,327 - app.core.excel.processor - INFO - 找到specification列: 规格
2025-05-09 14:31:54,327 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-09 14:31:54,327 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-09 14:31:54,327 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-09 14:31:54,328 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品条码', 'specification': '规格', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-09 14:31:54,328 - app.core.excel.processor - INFO - 是否存在规格列: True
2025-05-09 14:31:54,329 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6907992508344, 名称=6907992508344.0, 规格=, 数量=1.0, 单位=件, 单价=52.0
2025-05-09 14:31:54,334 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6903979000979, 名称=6903979000979.0, 规格=, 数量=3.0, 单位=件, 单价=50.0
2025-05-09 14:31:54,335 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6923644283582, 名称=6923644283582.0, 规格=, 数量=1.0, 单位=件, 单价=30.0
2025-05-09 14:31:54,338 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6923644268909, 名称=6923644268909.0, 规格=, 数量=2.0, 单位=件, 单价=30.0
2025-05-09 14:31:54,340 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6923644268930, 名称=6923644268930.0, 规格=, 数量=2.0, 单位=件, 单价=30.0
2025-05-09 14:31:54,341 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6923644268916, 名称=6923644268916.0, 规格=, 数量=2.0, 单位=件, 单价=30.0
2025-05-09 14:31:54,342 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6923644266318, 名称=6923644266318.0, 规格=, 数量=4.0, 单位=件, 单价=45.0
2025-05-09 14:31:54,432 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6920584471055, 名称=6920584471055.0, 规格=, 数量=2.0, 单位=件, 单价=50.0
2025-05-09 14:31:54,433 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6925861571159, 名称=6925861571159.0, 规格=, 数量=2.0, 单位=件, 单价=65.0
2025-05-09 14:31:54,434 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6925861571466, 名称=6925861571466.0, 规格=, 数量=1.0, 单位=件, 单价=45.0
2025-05-09 14:31:54,434 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6923644210151, 名称=6923644210151.0, 规格=, 数量=3.0, 单位=件, 单价=55.0
2025-05-09 14:31:54,435 - app.core.excel.processor - INFO - 第12行: 提取商品信息 条码=6907992501819, 名称=6907992501819.0, 规格=, 数量=3.0, 单位=件, 单价=63.0
2025-05-09 14:31:54,435 - app.core.excel.processor - INFO - 第13行: 提取商品信息 条码=6907992502052, 名称=6907992502052.0, 规格=, 数量=3.0, 单位=件, 单价=54.0
2025-05-09 14:31:54,436 - app.core.excel.processor - INFO - 第14行: 提取商品信息 条码=6907992507385, 名称=6907992507385.0, 规格=, 数量=2.0, 单位=件, 单价=42.0
2025-05-09 14:31:54,436 - app.core.excel.processor - INFO - 提取到 14 个商品信息
2025-05-09 14:31:54,446 - app.core.excel.processor - INFO - 开始处理14 个产品信息
2025-05-09 14:31:54,447 - app.core.excel.processor - INFO - 处理商品: 条码=6907992508344, 数量=12.0, 单价=4.333333333333333, 是否赠品=False
2025-05-09 14:31:54,448 - app.core.excel.processor - INFO - 发现正常商品条码6907992508344, 数量=12.0, 单价=4.333333333333333
2025-05-09 14:31:54,448 - app.core.excel.processor - INFO - 处理商品: 条码=6903979000979, 数量=72.0, 单价=2.0833333333333335, 是否赠品=False
2025-05-09 14:31:57,685 - app.core.excel.processor - INFO - 发现正常商品条码6903979000979, 数量=72.0, 单价=2.0833333333333335
2025-05-09 14:31:57,685 - app.core.excel.processor - INFO - 处理商品: 条码=6923644283575, 数量=12.0, 单价=2.5, 是否赠品=False
2025-05-09 14:31:57,685 - app.core.excel.processor - INFO - 发现正常商品条码6923644283575, 数量=12.0, 单价=2.5
2025-05-09 14:31:57,685 - app.core.excel.processor - INFO - 处理商品: 条码=6923644268909, 数量=24.0, 单价=2.5, 是否赠品=False
2025-05-09 14:31:57,685 - app.core.excel.processor - INFO - 发现正常商品条码6923644268909, 数量=24.0, 单价=2.5
2025-05-09 14:31:57,686 - app.core.excel.processor - INFO - 处理商品: 条码=6923644268497, 数量=24.0, 单价=2.5, 是否赠品=False
2025-05-09 14:31:57,686 - app.core.excel.processor - INFO - 发现正常商品条码6923644268497, 数量=24.0, 单价=2.5
2025-05-09 14:31:57,686 - app.core.excel.processor - INFO - 处理商品: 条码=6923644268503, 数量=24.0, 单价=2.5, 是否赠品=False
2025-05-09 14:31:57,686 - app.core.excel.processor - INFO - 发现正常商品条码6923644268503, 数量=24.0, 单价=2.5
2025-05-09 14:31:57,686 - app.core.excel.processor - INFO - 处理商品: 条码=6923644266318, 数量=48.0, 单价=3.75, 是否赠品=False
2025-05-09 14:31:57,686 - app.core.excel.processor - INFO - 发现正常商品条码6923644266318, 数量=48.0, 单价=3.75
2025-05-09 14:31:57,687 - app.core.excel.processor - INFO - 处理商品: 条码=6920584471017, 数量=24.0, 单价=4.166666666666667, 是否赠品=False
2025-05-09 14:31:57,687 - app.core.excel.processor - INFO - 发现正常商品条码6920584471017, 数量=24.0, 单价=4.166666666666667
2025-05-09 14:31:57,687 - app.core.excel.processor - INFO - 处理商品: 条码=69021824, 数量=72.0, 单价=1.8055555555555556, 是否赠品=False
2025-05-09 14:31:57,687 - app.core.excel.processor - INFO - 发现正常商品条码69021824, 数量=72.0, 单价=1.8055555555555556
2025-05-09 14:31:57,687 - app.core.excel.processor - INFO - 处理商品: 条码=6925861571466, 数量=12.0, 单价=3.75, 是否赠品=False
2025-05-09 14:31:57,687 - app.core.excel.processor - INFO - 发现正常商品条码6925861571466, 数量=12.0, 单价=3.75
2025-05-09 14:31:57,687 - app.core.excel.processor - INFO - 处理商品: 条码=6923644223458, 数量=72.0, 单价=2.2916666666666665, 是否赠品=False
2025-05-09 14:31:57,687 - app.core.excel.processor - INFO - 发现正常商品条码6923644223458, 数量=72.0, 单价=2.2916666666666665
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 处理商品: 条码=6907992500133, 数量=72.0, 单价=2.625, 是否赠品=False
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 发现正常商品条码6907992500133, 数量=72.0, 单价=2.625
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 处理商品: 条码=6907992502052, 数量=72.0, 单价=2.25, 是否赠品=False
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 发现正常商品条码6907992502052, 数量=72.0, 单价=2.25
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 处理商品: 条码=6907992507385, 数量=24.0, 单价=3.5, 是否赠品=False
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 发现正常商品条码6907992507385, 数量=24.0, 单价=3.5
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 分组后共14 个不同条码的商品
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 条码 6907992508344 处理结果正常商品数量12.0单价4.333333333333333赠品数量0
2025-05-09 14:31:57,688 - app.core.excel.processor - INFO - 条码 6903979000979 处理结果正常商品数量72.0单价2.0833333333333335赠品数量0
2025-05-09 14:31:57,689 - app.core.excel.processor - INFO - 条码 6923644283575 处理结果正常商品数量12.0单价2.5赠品数量0
2025-05-09 14:31:57,689 - app.core.excel.processor - INFO - 条码 6923644268909 处理结果正常商品数量24.0单价2.5赠品数量0
2025-05-09 14:31:57,689 - app.core.excel.processor - INFO - 条码 6923644268497 处理结果正常商品数量24.0单价2.5赠品数量0
2025-05-09 14:31:57,689 - app.core.excel.processor - INFO - 条码 6923644268503 处理结果正常商品数量24.0单价2.5赠品数量0
2025-05-09 14:31:57,689 - app.core.excel.processor - INFO - 条码 6923644266318 处理结果正常商品数量48.0单价3.75赠品数量0
2025-05-09 14:32:02,676 - app.core.excel.processor - INFO - 条码 6920584471017 处理结果正常商品数量24.0单价4.166666666666667赠品数量0
2025-05-09 14:32:02,677 - app.core.excel.processor - INFO - 条码 69021824 处理结果正常商品数量72.0单价1.8055555555555556赠品数量0
2025-05-09 14:32:02,677 - app.core.excel.processor - INFO - 条码 6925861571466 处理结果正常商品数量12.0单价3.75赠品数量0
2025-05-09 14:32:02,677 - app.core.excel.processor - INFO - 条码 6923644223458 处理结果正常商品数量72.0单价2.2916666666666665赠品数量0
2025-05-09 14:32:02,677 - app.core.excel.processor - INFO - 条码 6907992500133 处理结果正常商品数量72.0单价2.625赠品数量0
2025-05-09 14:32:02,677 - app.core.excel.processor - INFO - 条码 6907992502052 处理结果正常商品数量72.0单价2.25赠品数量0
2025-05-09 14:32:02,677 - app.core.excel.processor - INFO - 条码 6907992507385 处理结果正常商品数量24.0单价3.5赠品数量0
2025-05-09 14:32:02,682 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_微信图片_20250509142624.xls
2025-05-09 14:32:02,684 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_微信图片_20250509142624.xls
2025-05-09 14:32:20,938 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:32:20,939 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 14:32:20,940 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 14:32:20,954 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142700.xlsx
2025-05-09 14:32:21,010 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142700.xlsx, 共 13 行
2025-05-09 14:32:21,017 - app.core.excel.processor - INFO - 找到可能的表头行: 第1行评分: 45
2025-05-09 14:32:21,018 - app.core.excel.processor - INFO - 识别到表头在第 1 行
2025-05-09 14:32:21,057 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 12 行有效数据
2025-05-09 14:32:21,057 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-09 14:32:21,057 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-09 14:32:21,058 - app.core.excel.processor - INFO - 找到name列(部分匹配): 商品条码
2025-05-09 14:32:21,058 - app.core.excel.processor - INFO - 找到specification列: 规格
2025-05-09 14:32:21,066 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-09 14:32:21,066 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-09 14:32:21,066 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-09 14:32:21,066 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品条码', 'specification': '规格', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-09 14:32:21,066 - app.core.excel.processor - INFO - 是否存在规格列: True
2025-05-09 14:32:21,068 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6922456805012, 名称=6922456805012.0, 规格=, 数量=1.0, 单位=件, 单价=33.0
2025-05-09 14:32:21,068 - app.core.excel.processor - INFO - 解析规格: 500ml*15 -> 包装数量=15
2025-05-09 14:32:21,073 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6922456892067, 名称=6922456892067.0, 规格=, 数量=2.0, 单位=件, 单价=42.0
2025-05-09 14:32:21,075 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,078 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6922456891985, 名称=6922456891985.0, 规格=, 数量=1.0, 单位=件, 单价=42.0
2025-05-09 14:32:21,078 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,082 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6922456889944, 名称=6922456889944.0, 规格=, 数量=1.0, 单位=件, 单价=42.0
2025-05-09 14:32:21,082 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,083 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6922456896362, 名称=6922456896362.0, 规格=, 数量=1.0, 单位=件, 单价=42.0
2025-05-09 14:32:21,083 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,086 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6922456889920, 名称=6922456889920.0, 规格=, 数量=1.0, 单位=件, 单价=42.0
2025-05-09 14:32:21,086 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,087 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6922456843571, 名称=6922456843571.0, 规格=, 数量=1.0, 单位=件, 单价=42.0
2025-05-09 14:32:21,088 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,215 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6922456840259, 名称=6922456840259.0, 规格=, 数量=1.0, 单位=件, 单价=42.0
2025-05-09 14:32:21,215 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,216 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6922456889982, 名称=6922456889982.0, 规格=, 数量=1.0, 单位=件, 单价=42.0
2025-05-09 14:32:21,216 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,217 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6922456896362, 名称=6922456896362.0, 规格=, 数量=1.0, 单位=件, 单价=0
2025-05-09 14:32:21,218 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,218 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6922456896362, 名称=6922456896362.0, 规格=, 数量=1.0, 单位=瓶, 单价=0
2025-05-09 14:32:21,218 - app.core.excel.processor - INFO - 解析规格: 1L*12 -> 包装数量=12
2025-05-09 14:32:21,219 - app.core.excel.processor - INFO - 提取到 11 个商品信息
2025-05-09 14:32:21,230 - app.core.excel.processor - INFO - 开始处理11 个产品信息
2025-05-09 14:32:21,231 - app.core.excel.processor - INFO - 处理商品: 条码=6922456805012, 数量=15.0, 单价=2.2, 是否赠品=False
2025-05-09 14:32:21,231 - app.core.excel.processor - INFO - 发现正常商品条码6922456805012, 数量=15.0, 单价=2.2
2025-05-09 14:32:21,231 - app.core.excel.processor - INFO - 处理商品: 条码=6922456892067, 数量=24.0, 单价=3.5, 是否赠品=False
2025-05-09 14:32:21,231 - app.core.excel.processor - INFO - 发现正常商品条码6922456892067, 数量=24.0, 单价=3.5
2025-05-09 14:32:21,231 - app.core.excel.processor - INFO - 处理商品: 条码=6922456891985, 数量=12.0, 单价=3.5, 是否赠品=False
2025-05-09 14:32:21,232 - app.core.excel.processor - INFO - 发现正常商品条码6922456891985, 数量=12.0, 单价=3.5
2025-05-09 14:32:21,232 - app.core.excel.processor - INFO - 处理商品: 条码=6922456889944, 数量=12.0, 单价=3.5, 是否赠品=False
2025-05-09 14:32:21,232 - app.core.excel.processor - INFO - 发现正常商品条码6922456889944, 数量=12.0, 单价=3.5
2025-05-09 14:32:21,232 - app.core.excel.processor - INFO - 处理商品: 条码=6922456896362, 数量=12.0, 单价=3.5, 是否赠品=False
2025-05-09 14:32:21,232 - app.core.excel.processor - INFO - 发现正常商品条码6922456896362, 数量=12.0, 单价=3.5
2025-05-09 14:32:21,232 - app.core.excel.processor - INFO - 处理商品: 条码=6922456889920, 数量=12.0, 单价=3.5, 是否赠品=False
2025-05-09 14:32:21,232 - app.core.excel.processor - INFO - 发现正常商品条码6922456889920, 数量=12.0, 单价=3.5
2025-05-09 14:32:21,233 - app.core.excel.processor - INFO - 处理商品: 条码=6922456843571, 数量=12.0, 单价=3.5, 是否赠品=False
2025-05-09 14:32:21,233 - app.core.excel.processor - INFO - 发现正常商品条码6922456843571, 数量=12.0, 单价=3.5
2025-05-09 14:32:21,233 - app.core.excel.processor - INFO - 处理商品: 条码=6922456840259, 数量=12.0, 单价=3.5, 是否赠品=False
2025-05-09 14:32:24,203 - app.core.excel.processor - INFO - 发现正常商品条码6922456840259, 数量=12.0, 单价=3.5
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 处理商品: 条码=6922456889982, 数量=12.0, 单价=3.5, 是否赠品=False
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 发现正常商品条码6922456889982, 数量=12.0, 单价=3.5
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 处理商品: 条码=6922456896362, 数量=12.0, 单价=0, 是否赠品=True
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 发现赠品条码6922456896362, 数量=12.0
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 处理商品: 条码=6922456896362, 数量=1.0, 单价=0, 是否赠品=True
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 发现赠品条码6922456896362, 数量=1.0
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 分组后共9 个不同条码的商品
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 条码 6922456805012 处理结果正常商品数量15.0单价2.2赠品数量0
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 条码 6922456892067 处理结果正常商品数量24.0单价3.5赠品数量0
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 条码 6922456891985 处理结果正常商品数量12.0单价3.5赠品数量0
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 条码 6922456889944 处理结果正常商品数量12.0单价3.5赠品数量0
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 条码 6922456896362 处理结果正常商品数量12.0单价3.5赠品数量13.0
2025-05-09 14:32:24,204 - app.core.excel.processor - INFO - 条码 6922456889920 处理结果正常商品数量12.0单价3.5赠品数量0
2025-05-09 14:32:24,205 - app.core.excel.processor - INFO - 条码 6922456843571 处理结果正常商品数量12.0单价3.5赠品数量0
2025-05-09 14:32:24,205 - app.core.excel.processor - INFO - 条码 6922456840259 处理结果正常商品数量12.0单价3.5赠品数量0
2025-05-09 14:32:24,205 - app.core.excel.processor - INFO - 条码 6922456889982 处理结果正常商品数量12.0单价3.5赠品数量0
2025-05-09 14:32:24,205 - app.core.excel.processor - INFO - 条码 6922456896362 填充:采购量=12.0赠品数量13.0
2025-05-09 14:32:24,299 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_微信图片_20250509142700.xls
2025-05-09 14:32:24,300 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_微信图片_20250509142700.xls
2025-05-09 16:01:39,292 - app.core.excel.processor - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 16:01:39,292 - app.core.excel.processor - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 16:01:39,293 - app.core.excel.processor - INFO - 初始化ExcelProcessor完成模板文件: templates/银豹-采购单模板.xls
2025-05-09 16:01:39,295 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142624.xlsx
2025-05-09 16:01:39,349 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142624.xlsx, 共 16 行
2025-05-09 16:01:39,363 - app.core.excel.processor - INFO - 找到可能的表头行: 第1行评分: 45
2025-05-09 16:01:39,363 - app.core.excel.processor - INFO - 识别到表头在第 1 行
2025-05-09 16:01:39,469 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 15 行有效数据
2025-05-09 16:01:39,469 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-09 16:01:39,469 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-09 16:01:39,469 - app.core.excel.processor - INFO - 找到name列(部分匹配): 商品条码
2025-05-09 16:01:39,469 - app.core.excel.processor - INFO - 找到specification列: 规格
2025-05-09 16:01:39,469 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-09 16:01:39,470 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-09 16:01:39,470 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-09 16:01:39,470 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品条码', 'specification': '规格', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-09 16:01:39,470 - app.core.excel.processor - INFO - 是否存在规格列: True
2025-05-09 16:01:39,474 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6907992508344, 名称=6907992508344.0, 规格=, 数量=1.0, 单位=件, 单价=52.0
2025-05-09 16:01:39,481 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6903979000979, 名称=6903979000979.0, 规格=, 数量=3.0, 单位=件, 单价=50.0
2025-05-09 16:01:39,481 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6923644283582, 名称=6923644283582.0, 规格=, 数量=1.0, 单位=件, 单价=30.0
2025-05-09 16:01:39,482 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6923644268909, 名称=6923644268909.0, 规格=, 数量=2.0, 单位=件, 单价=30.0
2025-05-09 16:01:39,483 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6923644268930, 名称=6923644268930.0, 规格=, 数量=2.0, 单位=件, 单价=30.0
2025-05-09 16:01:39,484 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6923644268916, 名称=6923644268916.0, 规格=, 数量=2.0, 单位=件, 单价=30.0
2025-05-09 16:01:39,485 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6923644266318, 名称=6923644266318.0, 规格=, 数量=4.0, 单位=件, 单价=45.0
2025-05-09 16:01:39,487 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6920584471055, 名称=6920584471055.0, 规格=, 数量=2.0, 单位=件, 单价=50.0
2025-05-09 16:01:39,712 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6925861571159, 名称=6925861571159.0, 规格=, 数量=2.0, 单位=件, 单价=65.0
2025-05-09 16:01:39,713 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6925861571466, 名称=6925861571466.0, 规格=, 数量=1.0, 单位=件, 单价=45.0
2025-05-09 16:01:39,714 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6923644210151, 名称=6923644210151.0, 规格=, 数量=3.0, 单位=件, 单价=55.0
2025-05-09 16:01:39,715 - app.core.excel.processor - INFO - 第12行: 提取商品信息 条码=6907992501819, 名称=6907992501819.0, 规格=, 数量=3.0, 单位=件, 单价=63.0
2025-05-09 16:01:39,715 - app.core.excel.processor - INFO - 第13行: 提取商品信息 条码=6907992502052, 名称=6907992502052.0, 规格=, 数量=3.0, 单位=件, 单价=54.0
2025-05-09 16:01:39,716 - app.core.excel.processor - INFO - 第14行: 提取商品信息 条码=6907992507385, 名称=6907992507385.0, 规格=, 数量=2.0, 单位=件, 单价=42.0
2025-05-09 16:01:39,717 - app.core.excel.processor - INFO - 提取到 14 个商品信息
2025-05-09 16:01:39,730 - app.core.excel.processor - INFO - 开始处理14 个产品信息
2025-05-09 16:01:39,731 - app.core.excel.processor - INFO - 处理商品: 条码=6907992508344, 数量=12.0, 单价=4.333333333333333, 是否赠品=False
2025-05-09 16:01:39,731 - app.core.excel.processor - INFO - 发现正常商品条码6907992508344, 数量=12.0, 单价=4.333333333333333
2025-05-09 16:01:39,731 - app.core.excel.processor - INFO - 处理商品: 条码=6903979000979, 数量=72.0, 单价=2.0833333333333335, 是否赠品=False
2025-05-09 16:01:39,731 - app.core.excel.processor - INFO - 发现正常商品条码6903979000979, 数量=72.0, 单价=2.0833333333333335
2025-05-09 16:01:39,731 - app.core.excel.processor - INFO - 处理商品: 条码=6923644283582, 数量=12.0, 单价=2.5, 是否赠品=False
2025-05-09 16:01:39,731 - app.core.excel.processor - INFO - 发现正常商品条码6923644283582, 数量=12.0, 单价=2.5
2025-05-09 16:01:39,731 - app.core.excel.processor - INFO - 处理商品: 条码=6923644268909, 数量=24.0, 单价=2.5, 是否赠品=False
2025-05-09 16:01:39,731 - app.core.excel.processor - INFO - 发现正常商品条码6923644268909, 数量=24.0, 单价=2.5
2025-05-09 16:01:44,609 - app.core.excel.processor - INFO - 处理商品: 条码=6923644268930, 数量=24.0, 单价=2.5, 是否赠品=False
2025-05-09 16:01:44,609 - app.core.excel.processor - INFO - 发现正常商品条码6923644268930, 数量=24.0, 单价=2.5
2025-05-09 16:01:44,609 - app.core.excel.processor - INFO - 处理商品: 条码=6923644268916, 数量=24.0, 单价=2.5, 是否赠品=False
2025-05-09 16:01:44,609 - app.core.excel.processor - INFO - 发现正常商品条码6923644268916, 数量=24.0, 单价=2.5
2025-05-09 16:01:44,609 - app.core.excel.processor - INFO - 处理商品: 条码=6923644266318, 数量=48.0, 单价=3.75, 是否赠品=False
2025-05-09 16:01:44,609 - app.core.excel.processor - INFO - 发现正常商品条码6923644266318, 数量=48.0, 单价=3.75
2025-05-09 16:01:44,610 - app.core.excel.processor - INFO - 处理商品: 条码=6920584471017, 数量=24.0, 单价=4.166666666666667, 是否赠品=False
2025-05-09 16:01:44,610 - app.core.excel.processor - INFO - 发现正常商品条码6920584471017, 数量=24.0, 单价=4.166666666666667
2025-05-09 16:01:44,610 - app.core.excel.processor - INFO - 处理商品: 条码=69021824, 数量=72.0, 单价=1.8055555555555556, 是否赠品=False
2025-05-09 16:01:44,610 - app.core.excel.processor - INFO - 发现正常商品条码69021824, 数量=72.0, 单价=1.8055555555555556
2025-05-09 16:01:44,610 - app.core.excel.processor - INFO - 处理商品: 条码=6925861571466, 数量=12.0, 单价=3.75, 是否赠品=False
2025-05-09 16:01:44,610 - app.core.excel.processor - INFO - 发现正常商品条码6925861571466, 数量=12.0, 单价=3.75
2025-05-09 16:01:44,610 - app.core.excel.processor - INFO - 处理商品: 条码=6923644210151, 数量=72.0, 单价=2.2916666666666665, 是否赠品=False
2025-05-09 16:01:44,610 - app.core.excel.processor - INFO - 发现正常商品条码6923644210151, 数量=72.0, 单价=2.2916666666666665
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 处理商品: 条码=6907992501819, 数量=72.0, 单价=2.625, 是否赠品=False
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 发现正常商品条码6907992501819, 数量=72.0, 单价=2.625
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 处理商品: 条码=6907992502052, 数量=72.0, 单价=2.25, 是否赠品=False
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 发现正常商品条码6907992502052, 数量=72.0, 单价=2.25
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 处理商品: 条码=6907992507385, 数量=24.0, 单价=3.5, 是否赠品=False
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 发现正常商品条码6907992507385, 数量=24.0, 单价=3.5
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 分组后共14 个不同条码的商品
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 条码 6907992508344 处理结果正常商品数量12.0单价4.333333333333333赠品数量0
2025-05-09 16:01:44,611 - app.core.excel.processor - INFO - 条码 6903979000979 处理结果正常商品数量72.0单价2.0833333333333335赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 6923644283582 处理结果正常商品数量12.0单价2.5赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 6923644268909 处理结果正常商品数量24.0单价2.5赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 6923644268930 处理结果正常商品数量24.0单价2.5赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 6923644268916 处理结果正常商品数量24.0单价2.5赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 6923644266318 处理结果正常商品数量48.0单价3.75赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 6920584471017 处理结果正常商品数量24.0单价4.166666666666667赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 69021824 处理结果正常商品数量72.0单价1.8055555555555556赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 6925861571466 处理结果正常商品数量12.0单价3.75赠品数量0
2025-05-09 16:01:44,612 - app.core.excel.processor - INFO - 条码 6923644210151 处理结果正常商品数量72.0单价2.2916666666666665赠品数量0
2025-05-09 16:01:44,613 - app.core.excel.processor - INFO - 条码 6907992501819 处理结果正常商品数量72.0单价2.625赠品数量0
2025-05-09 16:01:51,983 - app.core.excel.processor - INFO - 条码 6907992502052 处理结果正常商品数量72.0单价2.25赠品数量0
2025-05-09 16:01:51,983 - app.core.excel.processor - INFO - 条码 6907992507385 处理结果正常商品数量24.0单价3.5赠品数量0
2025-05-09 16:01:51,987 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_微信图片_20250509142624.xls
2025-05-09 16:01:51,989 - app.core.excel.processor - INFO - 采购单已保存到: data/output\采购单_微信图片_20250509142624.xls

View File

@ -0,0 +1 @@
Active since: 2025-05-10 11:21:12

View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:37

View File

@ -69,3 +69,14 @@
2025-05-07 21:54:55,605 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌 2025-05-07 21:54:55,605 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
2025-05-07 22:28:51,887 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌 2025-05-07 22:28:51,887 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
2025-05-08 19:45:41,386 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌 2025-05-08 19:45:41,386 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
2025-05-09 11:58:49,251 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 12:02:05,168 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 12:07:05,181 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 12:07:54,656 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 12:12:42,103 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 12:13:52,580 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 12:45:35,995 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 14:27:08,879 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 14:27:31,660 - app.core.ocr.baidu_ocr - ERROR - 初始化失败: getint() takes 3 positional arguments but 4 were given
2025-05-09 14:31:02,533 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
2025-05-09 14:31:02,581 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌

View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:37

View File

@ -680,3 +680,54 @@
2025-05-08 20:46:00,694 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output 2025-05-08 20:46:00,694 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 20:46:00,694 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp 2025-05-08 20:46:00,694 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-08 20:46:00,695 - app.core.ocr.table_ocr - INFO - OCR处理器初始化完成输入目录: D:\My Documents\python\orc-order-v2\data\input, 输出目录: D:\My Documents\python\orc-order-v2\data\output 2025-05-08 20:46:00,695 - app.core.ocr.table_ocr - INFO - OCR处理器初始化完成输入目录: D:\My Documents\python\orc-order-v2\data\input, 输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:02:05,168 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 12:02:05,169 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 12:02:05,169 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:02:05,170 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:07:05,181 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 12:07:05,181 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:07:05,181 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:07:05,181 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
2025-05-09 12:07:05,182 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 12:07:54,657 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 12:07:54,657 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:07:54,657 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:07:54,657 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
2025-05-09 12:07:54,657 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 12:12:42,103 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 12:12:42,104 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:12:42,104 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:12:42,104 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
2025-05-09 12:12:42,104 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 12:13:52,580 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 12:13:52,581 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:13:52,581 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:13:52,581 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
2025-05-09 12:13:52,581 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 12:45:35,996 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 12:45:35,996 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 12:45:35,996 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 12:45:35,996 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
2025-05-09 12:45:35,996 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 14:27:08,879 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 14:27:08,880 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:27:08,880 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 14:27:08,880 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
2025-05-09 14:27:08,880 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 14:27:31,661 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 14:27:31,661 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:27:31,661 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 14:27:31,662 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
2025-05-09 14:27:31,662 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 14:31:02,077 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-09 14:31:02,077 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-09 14:31:02,078 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-09 14:31:02,078 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
2025-05-09 14:31:02,078 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成输入目录=data/input, 输出目录=data/output
2025-05-09 14:31:02,079 - app.core.ocr.table_ocr - INFO - 找到 2 个图片文件,其中 2 个未处理
2025-05-09 14:31:02,079 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 2 个文件
2025-05-09 14:31:02,085 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20250509142624.jpg
2025-05-09 14:31:02,105 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20250509142700.jpg
2025-05-09 14:31:04,140 - app.core.ocr.table_ocr - INFO - 图片处理成功: data/input\微信图片_20250509142624.jpg, 输出文件: data/output\微信图片_20250509142624.xlsx
2025-05-09 14:31:04,271 - app.core.ocr.table_ocr - INFO - 图片处理成功: data/input\微信图片_20250509142700.jpg, 输出文件: data/output\微信图片_20250509142700.xlsx
2025-05-09 14:31:04,274 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 2, 成功: 2

View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:36

View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:37

View File

@ -275,3 +275,24 @@
2025-05-08 20:04:06,907 - app.services.ocr_service - INFO - OCRService初始化完成 2025-05-08 20:04:06,907 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-08 20:46:00,690 - app.services.ocr_service - INFO - 初始化OCRService 2025-05-08 20:46:00,690 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-08 20:46:00,696 - app.services.ocr_service - INFO - OCRService初始化完成 2025-05-08 20:46:00,696 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 11:55:03,577 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 11:58:49,250 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 12:02:05,166 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 12:07:05,179 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 12:07:05,182 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 12:07:54,655 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 12:07:54,658 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 12:12:42,102 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 12:12:42,104 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 12:13:52,579 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 12:13:52,581 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 12:45:35,994 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 12:45:35,996 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 14:27:08,878 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 14:27:08,880 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 14:27:31,659 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 14:27:31,662 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 14:31:02,076 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-09 14:31:02,078 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-09 14:31:02,078 - app.services.ocr_service - INFO - OCRService.batch_process被调用转发到process_images_batch
2025-05-09 14:31:02,078 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=5, max_workers=4

View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:38

View File

@ -315,3 +315,29 @@
2025-05-08 20:46:00,697 - app.services.order_service - INFO - 初始化OrderService 2025-05-08 20:46:00,697 - app.services.order_service - INFO - 初始化OrderService
2025-05-08 20:46:00,701 - app.services.order_service - INFO - OrderService初始化完成 2025-05-08 20:46:00,701 - app.services.order_service - INFO - OrderService初始化完成
2025-05-08 20:46:00,750 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx 2025-05-08 20:46:00,750 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-09 12:07:05,182 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 12:07:54,658 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 12:12:42,104 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 12:13:52,581 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 12:13:52,586 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 12:45:35,997 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 12:45:35,999 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 13:39:38,178 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 13:39:38,187 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 14:08:43,900 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 14:08:43,903 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 14:08:43,903 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/高新-益选便利店销售单2025-05-09.xlsx
2025-05-09 14:23:40,512 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 14:23:40,516 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 14:23:40,516 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/高新-益选便利店销售单2025-05-09.xlsx
2025-05-09 14:26:54,507 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 14:26:54,511 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 14:31:54,256 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 14:31:54,259 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 14:31:54,259 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142624.xlsx
2025-05-09 14:32:20,936 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 14:32:20,942 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 14:32:20,954 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142700.xlsx
2025-05-09 16:01:39,291 - app.services.order_service - INFO - 初始化OrderService
2025-05-09 16:01:39,294 - app.services.order_service - INFO - OrderService初始化完成
2025-05-09 16:01:39,295 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250509142624.xlsx

View File

@ -0,0 +1 @@
Active since: 2025-05-09 16:01:39

View File

@ -0,0 +1,97 @@
2025-05-09 12:45:35,999 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 12:45:36,000 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 12:45:36,102 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 12:45:36,103 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 12:45:36,103 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:11:06,843 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:11:06,844 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:11:06,923 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:11:06,924 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:11:06,925 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:11:53,142 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:11:53,143 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:11:53,195 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:11:53,196 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:11:53,196 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:13:30,197 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:13:30,197 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:13:30,253 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:13:30,256 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:13:30,256 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:16:20,406 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:16:20,407 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:16:20,583 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:16:20,584 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:16:20,596 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:18:16,271 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:18:16,271 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:18:16,334 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:18:16,335 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:18:16,336 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:19:40,681 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:19:40,681 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:19:40,735 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:19:40,736 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:19:40,736 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:21:06,878 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:21:06,879 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:21:06,918 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:21:06,919 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:21:06,920 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:21:53,150 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:21:53,150 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:21:53,248 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:21:53,248 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:21:53,249 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:22:48,435 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:22:48,435 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:22:48,496 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:22:48,497 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:22:48,497 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:25:59,038 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:25:59,038 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:25:59,110 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:25:59,110 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:25:59,110 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:29:28,788 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:29:28,788 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:29:28,834 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:29:28,835 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:29:28,836 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:30:21,809 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:30:21,809 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:30:21,940 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:30:21,966 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:30:21,972 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:30:43,719 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:30:43,719 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:30:43,779 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:30:43,779 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:30:43,780 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:34:49,133 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:34:49,136 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:34:49,289 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:34:49,290 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:34:49,291 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:37:56,254 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:37:56,254 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:37:56,481 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:37:56,481 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:37:56,481 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:39:52,438 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509114847.xlsx
2025-05-09 13:39:52,438 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509114847.xlsx
2025-05-09 13:39:52,580 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:39:52,581 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-05-06, 总金额: 12836.76, 处理条目: 36
2025-05-09 13:39:52,581 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:50:34,355 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509134955.xlsx
2025-05-09 13:50:34,355 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509134955.xlsx
2025-05-09 13:50:34,766 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:50:34,766 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-04-27, 总金额: 10844.48, 处理条目: 34
2025-05-09 13:50:34,772 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:52:17,578 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20250509135149.xlsx
2025-05-09 13:52:17,579 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20250509135149.xlsx
2025-05-09 13:52:17,705 - app.services.tobacco_service - INFO - 采购单生成成功: data/output\银豹采购单_烟草公司.xls
2025-05-09 13:52:17,705 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-04-21, 总金额: 9550.10, 处理条目: 30
2025-05-09 13:52:17,706 - app.services.tobacco_service - INFO - 采购单已生成: data/output\银豹采购单_烟草公司.xls
2025-05-09 14:32:56,705 - app.services.tobacco_service - WARNING - 未找到烟草公司订单明细文件
2025-05-09 14:32:56,706 - app.services.tobacco_service - ERROR - 未找到可处理的烟草订单明细文件

423
run.py
View File

@ -13,318 +13,193 @@ import argparse
from typing import List, Optional from typing import List, Optional
from app.config.settings import ConfigManager from app.config.settings import ConfigManager
from app.core.utils.log_utils import get_logger, close_logger from app.core.utils.log_utils import get_logger, close_all_loggers, set_log_level
from app.services.ocr_service import OCRService from app.services.ocr_service import OCRService
from app.services.order_service import OrderService from app.services.order_service import OrderService
from app.services.tobacco_service import TobaccoService
logger = get_logger(__name__) logger = get_logger(__name__)
def create_parser() -> argparse.ArgumentParser: def parse_args():
""" """
创建命令行参数解析器 解析命令行参数
Returns: Returns:
参数解析器 解析后的参数
""" """
parser = argparse.ArgumentParser(description='OCR订单处理系统') parser = argparse.ArgumentParser(description='OCR订单处理系统')
# 通用选项 # 通用选项
parser.add_argument('--config', type=str, help='配置文件路径') parser.add_argument('--config', type=str, help='配置文件路径')
parser.add_argument('--log-level', type=str, choices=['debug', 'info', 'warning', 'error', 'critical'], help='日志级别')
# 子命令 # 子命令
subparsers = parser.add_subparsers(dest='command', help='子命令') subparsers = parser.add_subparsers(dest='command', help='子命令')
# OCR识别命令 # OCR识别命令
ocr_parser = subparsers.add_parser('ocr', help='OCR识别') ocr_parser = subparsers.add_parser('ocr', help='OCR识别')
ocr_parser.add_argument('--input', type=str, help='输入图片文件路径') ocr_parser.add_argument('--input', type=str, help='输入图片路径')
ocr_parser.add_argument('--batch', action='store_true', help='批量处理模式') ocr_parser.add_argument('--batch', action='store_true', help='批量处理')
ocr_parser.add_argument('--batch-size', type=int, help='批处理大小') ocr_parser.add_argument('--batch-size', type=int, default=5, help='批处理大小')
ocr_parser.add_argument('--max-workers', type=int, help='最大线程数') ocr_parser.add_argument('--max-workers', type=int, default=4, help='最大线程数')
# Excel处理命令 # Excel处理命令
excel_parser = subparsers.add_parser('excel', help='Excel处理') excel_parser = subparsers.add_parser('excel', help='Excel处理')
excel_parser.add_argument('--input', type=str, help='输入Excel文件路径,如果不指定则处理最新的文件') excel_parser.add_argument('--input', type=str, help='输入Excel文件路径')
# 订单合并命令 # 合并命令
merge_parser = subparsers.add_parser('merge', help='订单合并') merge_parser = subparsers.add_parser('merge', help='合并采购单')
merge_parser.add_argument('--input', type=str, help='输入采购单文件路径列表,以逗号分隔,如果不指定则合并所有采购单') merge_parser.add_argument('--input', type=str, help='输入采购单文件路径(逗号分隔)')
# 完整流程命令 # 完整流程命令
pipeline_parser = subparsers.add_parser('pipeline', help='完整流程') pipeline_parser = subparsers.add_parser('pipeline', help='完整处理流程')
pipeline_parser.add_argument('--input', type=str, help='输入图片文件路径,如果不指定则处理所有图片') pipeline_parser.add_argument('--input', type=str, help='输入图片路径')
pipeline_parser.add_argument('--merge', action='store_true', help='是否合并采购单')
return parser # 烟草订单处理
tobacco_parser = subparsers.add_parser('tobacco', help='处理烟草订单')
tobacco_parser.add_argument('--input', type=str, help='输入订单明细文件路径')
# 解析参数
parsed_args = parser.parse_args()
return parsed_args
def run_ocr(ocr_service: OCRService, args) -> bool: def main():
""" """
运行OCR识别 主函数入口
Args:
ocr_service: OCR服务
args: 命令行参数
Returns: Returns:
处理是否成功 退出码
""" """
if args.input: # 解析命令行参数
if not os.path.exists(args.input): args = parse_args()
logger.error(f"输入文件不存在: {args.input}")
return False
if not ocr_service.validate_image(args.input):
logger.error(f"输入文件无效: {args.input}")
return False
logger.info(f"处理单个图片: {args.input}")
result = ocr_service.process_image(args.input)
if result:
logger.info(f"OCR处理成功输出文件: {result}")
return True
else:
logger.error("OCR处理失败")
return False
elif args.batch:
logger.info("批量处理模式")
total, success = ocr_service.process_images_batch(args.batch_size, args.max_workers)
if total == 0:
logger.warning("没有找到需要处理的文件")
return False
logger.info(f"批量处理完成,总计: {total},成功: {success}")
return success > 0
else:
# 列出未处理的文件
files = ocr_service.get_unprocessed_images()
if not files:
logger.info("没有未处理的文件")
return True
logger.info(f"未处理的文件 ({len(files)}):")
for file in files:
logger.info(f" {file}")
return True
def run_excel(order_service: OrderService, args) -> bool:
"""
运行Excel处理
Args: if not args.command:
order_service: 订单服务 argparse.ArgumentParser().print_help()
args: 命令行参数
Returns:
处理是否成功
"""
if args.input:
if not os.path.exists(args.input):
logger.error(f"输入文件不存在: {args.input}")
return False
logger.info(f"处理Excel文件: {args.input}")
result = order_service.process_excel(args.input)
else:
latest_file = order_service.get_latest_excel()
if not latest_file:
logger.warning("未找到可处理的Excel文件")
return False
logger.info(f"处理最新的Excel文件: {latest_file}")
result = order_service.process_excel(latest_file)
if result:
logger.info(f"Excel处理成功输出文件: {result}")
return True
else:
logger.error("Excel处理失败")
return False
def run_merge(order_service: OrderService, args) -> bool:
"""
运行订单合并
Args:
order_service: 订单服务
args: 命令行参数
Returns:
处理是否成功
"""
if args.input:
# 分割输入文件列表
file_paths = [path.strip() for path in args.input.split(',')]
# 检查文件是否存在
for path in file_paths:
if not os.path.exists(path):
logger.error(f"输入文件不存在: {path}")
return False
logger.info(f"合并指定的采购单文件: {file_paths}")
result = order_service.merge_orders(file_paths)
else:
# 获取所有采购单文件
file_paths = order_service.get_purchase_orders()
if not file_paths:
logger.warning("未找到采购单文件")
return False
logger.info(f"合并所有采购单文件: {len(file_paths)}")
result = order_service.merge_orders()
if result:
logger.info(f"订单合并成功,输出文件: {result}")
return True
else:
logger.error("订单合并失败")
return False
def run_pipeline(ocr_service: OCRService, order_service: OrderService, args) -> bool:
"""
运行完整流程
Args:
ocr_service: OCR服务
order_service: 订单服务
args: 命令行参数
Returns:
处理是否成功
"""
# 1. OCR识别
logger.info("=== 流程步骤 1: OCR识别 ===")
if args.input:
if not os.path.exists(args.input):
logger.error(f"输入文件不存在: {args.input}")
return False
if not ocr_service.validate_image(args.input):
logger.error(f"输入文件无效: {args.input}")
return False
logger.info(f"处理单个图片: {args.input}")
ocr_result = ocr_service.process_image(args.input)
if not ocr_result:
logger.error("OCR处理失败")
return False
logger.info(f"OCR处理成功输出文件: {ocr_result}")
else:
# 批量处理所有图片
logger.info("批量处理所有图片")
total, success = ocr_service.process_images_batch()
if total == 0:
logger.warning("没有找到需要处理的图片")
# 继续下一步因为可能已经有处理好的Excel文件
elif success == 0:
logger.error("OCR处理失败没有成功处理的图片")
return False
else:
logger.info(f"OCR处理完成总计: {total},成功: {success}")
# 2. Excel处理
logger.info("=== 流程步骤 2: Excel处理 ===")
latest_file = order_service.get_latest_excel()
if not latest_file:
logger.warning("未找到可处理的Excel文件")
return False
logger.info(f"处理最新的Excel文件: {latest_file}")
excel_result = order_service.process_excel(latest_file)
if not excel_result:
logger.error("Excel处理失败")
return False
logger.info(f"Excel处理成功输出文件: {excel_result}")
# 3. 订单合并
logger.info("=== 流程步骤 3: 订单合并 ===")
# 获取所有采购单文件
file_paths = order_service.get_purchase_orders()
if not file_paths:
logger.warning("未找到采购单文件,跳过合并步骤")
logger.info("=== 完整流程处理成功(未执行合并步骤)===")
# 非错误状态,继续执行
return True
# 有文件需要合并
logger.info(f"发现 {len(file_paths)} 个采购单文件")
if len(file_paths) == 1:
logger.warning(f"只有1个采购单文件 {file_paths[0]},无需合并")
logger.info("=== 完整流程处理成功(只有一个文件,跳过合并)===")
return True
logger.info(f"合并所有采购单文件: {len(file_paths)}")
merge_result = order_service.merge_orders()
if not merge_result:
logger.error("订单合并失败")
return False
logger.info(f"订单合并成功,输出文件: {merge_result}")
logger.info("=== 完整流程处理成功 ===")
return True
def main(args: Optional[List[str]] = None) -> int:
"""
主函数
Args:
args: 命令行参数如果为None则使用sys.argv
Returns:
退出状态码
"""
parser = create_parser()
parsed_args = parser.parse_args(args)
if parsed_args.command is None:
parser.print_help()
return 1 return 1
# 加载配置
config_path = args.config
config_manager = ConfigManager(config_path)
config = config_manager.config
# 设置日志级别
log_level = getattr(args, 'log_level', None)
if log_level:
set_log_level(log_level)
try: try:
# 创建配置管理器 if args.command == 'ocr':
config = ConfigManager(parsed_args.config) if parsed_args.config else ConfigManager() # OCR识别处理
ocr_service = OCRService(config)
# 创建服务 if args.batch:
ocr_service = OCRService(config) # 批量处理
order_service = OrderService(config) total, success = ocr_service.batch_process(
batch_size=args.batch_size,
# 根据命令执行不同功能 max_workers=args.max_workers
if parsed_args.command == 'ocr': )
success = run_ocr(ocr_service, parsed_args) return 0 if success > 0 else 1
elif parsed_args.command == 'excel': else:
success = run_excel(order_service, parsed_args) # 处理单个文件
elif parsed_args.command == 'merge': result = ocr_service.process_image(args.input)
success = run_merge(order_service, parsed_args) return 0 if result else 1
elif parsed_args.command == 'pipeline':
success = run_pipeline(ocr_service, order_service, parsed_args) elif args.command == 'excel':
else: # Excel处理
parser.print_help() order_service = OrderService(config)
return 1 if args.input:
# 处理指定文件
result = order_service.process_excel(args.input)
else:
# 处理最新文件
result = order_service.process_latest_excel()
return 0 if result else 1
return 0 if success else 1 elif args.command == 'merge':
# 合并采购单
order_service = OrderService(config)
if args.input:
# 合并指定文件
file_list = args.input.split(',')
result = order_service.merge_purchase_orders(file_list)
else:
# 合并所有采购单
result = order_service.merge_all_purchase_orders()
return 0 if result else 1
elif args.command == 'pipeline':
# 完整流程
ocr_service = OCRService(config)
order_service = OrderService(config)
# 1. OCR处理
if args.input:
# 处理单个文件
excel_file = ocr_service.process_image(args.input)
else:
# 批量处理
total, success = ocr_service.batch_process()
if success == 0:
logger.error("OCR处理失败没有成功处理任何文件")
return 1
excel_file = None # 批量处理不返回具体文件
# 2. Excel处理
if excel_file:
# 处理指定的Excel文件
result = order_service.process_excel(excel_file)
else:
# 处理最新的Excel文件
result = order_service.process_latest_excel()
if not result:
logger.error("Excel处理失败")
return 1
# 3. 合并采购单(可选)
if args.merge:
result = order_service.merge_all_purchase_orders()
if not result:
logger.warning("合并采购单失败")
# 不影响整体流程,继续执行
return 0
elif args.command == 'tobacco':
# 烟草订单处理
tobacco_service = TobaccoService(config)
if args.input:
# 处理指定文件
logger.info(f"开始处理烟草订单,输入文件: {args.input}")
result = tobacco_service.process_tobacco_order(args.input)
else:
# 处理最新文件
logger.info("开始烟草公司订单处理")
result = tobacco_service.process_tobacco_order()
# 检查结果是否为None
if result is None:
logger.error("烟草订单处理失败")
return 1
else:
logger.info(f"烟草订单处理成功,输出文件: {result}")
# 确保result是绝对路径
if not os.path.isabs(result):
result = os.path.abspath(result)
logger.info(f"烟草订单处理完成,绝对路径: {result}")
return 0
else:
logger.error(f"未知命令: {args.command}")
return 1
except Exception as e: except Exception as e:
logger.error(f"执行过程中发生错误: {e}") logger.error(f"执行过程中发生错误: {e}", exc_info=True)
import traceback
logger.error(traceback.format_exc())
return 1 return 1
finally: finally:
# 关闭日志 # 关闭所有日志记录器
close_logger(__name__) close_all_loggers()
if __name__ == '__main__': if __name__ == "__main__":
sys.exit(main()) sys.exit(main())

View File

@ -21,6 +21,10 @@ import json
import re import re
from typing import Dict, List, Optional, Any from typing import Dict, List, Optional, Any
# 导入自定义对话框工具
from app.core.utils.dialog_utils import show_custom_dialog, show_barcode_mapping_dialog
from app.core.excel.converter import UnitConverter
# 全局变量,用于跟踪任务状态 # 全局变量,用于跟踪任务状态
RUNNING_TASK = None RUNNING_TASK = None
THEME_MODE = "light" # 默认浅色主题 THEME_MODE = "light" # 默认浅色主题
@ -200,8 +204,8 @@ def run_command_with_logging(command, log_widget, status_bar=None, on_complete=N
if on_complete: if on_complete:
log_widget.after(0, lambda: on_complete(process.returncode, output_text)) log_widget.after(0, lambda: on_complete(process.returncode, output_text))
# 如果处理成功,显示成功信息 # 如果处理成功且没有指定on_complete回调函数显示默认成功信息
if process.returncode == 0: elif process.returncode == 0:
if status_bar: if status_bar:
log_widget.after(0, lambda: status_bar.set_status("处理完成", 100)) log_widget.after(0, lambda: status_bar.set_status("处理完成", 100))
log_widget.after(0, lambda: show_result_preview(command, output_text)) log_widget.after(0, lambda: show_result_preview(command, output_text))
@ -434,7 +438,7 @@ def show_pipeline_result_preview(output):
# 添加处理结果提示(即使没有可合并文件也显示成功) # 添加处理结果提示(即使没有可合并文件也显示成功)
no_files_match = re.search(r'未找到可合并的文件', output) no_files_match = re.search(r'未找到可合并的文件', output)
if no_files_match: if no_files_match:
tk.Label(preview, text="未找到可合并文件,但其他步骤已成功执行", font=("Arial", 12)).pack(pady=0) tk.Label(preview, text="未找到可合并文件,但其他步骤已成功执行", font=("Arial", 12)).pack(pady=0)
result_frame = tk.Frame(preview) result_frame = tk.Frame(preview)
result_frame.pack(pady=10, fill=tk.BOTH, expand=True) result_frame.pack(pady=10, fill=tk.BOTH, expand=True)
@ -758,7 +762,7 @@ def main():
text="处理Excel文件", text="处理Excel文件",
width=button_width, width=button_width,
height=button_height, height=button_height,
command=lambda: process_excel_file(log_text, status_bar) command=lambda: process_excel_file_with_status(log_text, status_bar)
).pack(side=tk.LEFT, padx=button_padx) ).pack(side=tk.LEFT, padx=button_padx)
# OCR批量识别 # OCR批量识别
@ -789,7 +793,7 @@ def main():
text="处理单个图片", text="处理单个图片",
width=button_width, width=button_width,
height=button_height, height=button_height,
command=lambda: process_single_image(log_text, status_bar) command=lambda: process_single_image_with_status(log_text, status_bar)
).pack(side=tk.LEFT, padx=button_padx) ).pack(side=tk.LEFT, padx=button_padx)
# 第三行 # 第三行
@ -818,6 +822,15 @@ def main():
row4 = tk.Frame(button_area) row4 = tk.Frame(button_area)
row4.pack(fill=tk.X, pady=button_pady) row4.pack(fill=tk.X, pady=button_pady)
# 处理烟草订单按钮
tk.Button(
row4,
text="处理烟草订单",
width=button_width,
height=button_height,
command=lambda: run_command_with_logging(["python", "run.py", "tobacco"], log_text, status_bar, on_complete=show_tobacco_result_preview)
).pack(side=tk.LEFT, padx=button_padx)
# 清除处理缓存按钮 # 清除处理缓存按钮
tk.Button( tk.Button(
row4, row4,
@ -827,15 +840,6 @@ def main():
command=lambda: clean_cache(log_text) command=lambda: clean_cache(log_text)
).pack(side=tk.LEFT, padx=button_padx) ).pack(side=tk.LEFT, padx=button_padx)
# 清理文件按钮
tk.Button(
row4,
text="清理文件",
width=button_width,
height=button_height,
command=lambda: clean_data_files(log_text)
).pack(side=tk.LEFT, padx=button_padx)
# 第五行 # 第五行
row5 = tk.Frame(button_area) row5 = tk.Frame(button_area)
row5.pack(fill=tk.X, pady=button_pady) row5.pack(fill=tk.X, pady=button_pady)
@ -858,6 +862,50 @@ def main():
command=lambda: os.startfile(os.path.abspath("data/output")) command=lambda: os.startfile(os.path.abspath("data/output"))
).pack(side=tk.LEFT, padx=button_padx) ).pack(side=tk.LEFT, padx=button_padx)
# 第六行
row6 = tk.Frame(button_area)
row6.pack(fill=tk.X, pady=button_pady)
# 清理文件按钮
tk.Button(
row6,
text="清理文件",
width=button_width,
height=button_height,
command=lambda: clean_data_files(log_text)
).pack(side=tk.LEFT, padx=button_padx)
# 切换主题按钮
tk.Button(
row6,
text="切换主题",
width=button_width,
height=button_height,
command=lambda: toggle_theme(root, log_text, status_bar)
).pack(side=tk.LEFT, padx=button_padx)
# 第七行
row7 = tk.Frame(button_area)
row7.pack(fill=tk.X, pady=button_pady)
# 演示自定义弹窗按钮
tk.Button(
row7,
text="自定义弹窗演示",
width=button_width,
height=button_height,
command=lambda: show_demo_dialog(log_text)
).pack(side=tk.LEFT, padx=button_padx)
# 条码映射编辑按钮
tk.Button(
row7,
text="编辑条码映射",
width=button_width,
height=button_height,
command=lambda: edit_barcode_mappings(log_text)
).pack(side=tk.LEFT, padx=button_padx)
# 底部说明 # 底部说明
tk.Label(left_frame, text="© 2025 益选-OCR订单处理系统 v1.0 by 欢欢欢", font=("Arial", 9)).pack(side=tk.BOTTOM, pady=10) tk.Label(left_frame, text="© 2025 益选-OCR订单处理系统 v1.0 by 欢欢欢", font=("Arial", 9)).pack(side=tk.BOTTOM, pady=10)
@ -1046,5 +1094,178 @@ def center_window(window):
y = (window.winfo_screenheight() // 2) - (height // 2) y = (window.winfo_screenheight() // 2) - (height // 2)
window.geometry('{}x{}+{}+{}'.format(width, height, x, y)) window.geometry('{}x{}+{}+{}'.format(width, height, x, y))
def show_tobacco_result_preview(returncode, output):
"""显示烟草订单处理结果预览"""
# 只在成功时显示结果预览
if returncode != 0:
return
try:
# 查找输出文件路径
result_file = None
order_time = "(未知)"
total_amount = "(未知)"
items_count = 0
# 先使用更可靠的方式查找文件路径
abs_path_match = re.search(r'烟草订单处理完成,绝对路径: (.+)(?:\n|$)', output)
if abs_path_match:
result_file = abs_path_match.group(1).strip()
# 提取处理结果信息
for line in output.split('\n'):
# 提取订单时间和金额
if "烟草公司订单处理成功" in line and "订单时间" in line:
time_match = re.search(r'订单时间: ([^,]+)', line)
amount_match = re.search(r'总金额: ([^,]+)', line)
items_match = re.search(r'处理条目: (\d+)', line)
if time_match:
order_time = time_match.group(1).strip()
if amount_match:
total_amount = amount_match.group(1).strip()
if items_match:
items_count = int(items_match.group(1).strip())
# 如果没有找到文件路径,使用默认路径
if not result_file or not os.path.exists(result_file):
default_path = os.path.abspath("data/output/银豹采购单_烟草公司.xls")
if os.path.exists(default_path):
result_file = default_path
# 创建结果预览对话框
preview = tk.Toplevel()
preview.title("烟草订单处理结果")
preview.geometry("450x320")
preview.resizable(False, False)
# 使弹窗居中显示
center_window(preview)
# 添加内容
tk.Label(preview, text="烟草订单处理完成", font=("Arial", 16, "bold")).pack(pady=10)
result_frame = tk.Frame(preview)
result_frame.pack(pady=10, fill=tk.BOTH, expand=True)
tk.Label(result_frame, text=f"订单时间: {order_time}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
tk.Label(result_frame, text=f"订单总金额: {total_amount}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
tk.Label(result_frame, text=f"处理商品数量: {items_count}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
# 文件信息
if result_file and os.path.exists(result_file):
tk.Label(result_frame, text=f"输出文件: {os.path.basename(result_file)}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
# 处理成功提示
tk.Label(result_frame, text="银豹采购单已成功生成!", font=("Arial", 12, "bold"), fg="#28a745").pack(pady=10)
# 文件信息框
file_frame = tk.Frame(result_frame, relief=tk.GROOVE, borderwidth=1)
file_frame.pack(fill=tk.X, padx=15, pady=5)
tk.Label(file_frame, text="文件信息", font=("Arial", 10, "bold")).pack(anchor=tk.W, padx=10, pady=5)
# 获取文件大小和时间
try:
file_size = os.path.getsize(result_file)
file_time = datetime.datetime.fromtimestamp(os.path.getmtime(result_file))
size_text = f"{file_size / 1024:.1f} KB" if file_size < 1024*1024 else f"{file_size / (1024*1024):.1f} MB"
tk.Label(file_frame, text=f"文件大小: {size_text}", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2)
tk.Label(file_frame, text=f"创建时间: {file_time.strftime('%Y-%m-%d %H:%M:%S')}", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2)
except:
tk.Label(file_frame, text="无法获取文件信息", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2)
# 添加按钮
button_frame = tk.Frame(preview)
button_frame.pack(pady=10)
tk.Button(button_frame, text="打开文件", command=lambda: os.startfile(result_file)).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="打开所在文件夹", command=lambda: os.startfile(os.path.dirname(result_file))).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="关闭", command=preview.destroy).pack(side=tk.LEFT, padx=5)
else:
# 文件不存在或未找到的情况
tk.Label(result_frame, text="未找到输出文件", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5)
tk.Label(result_frame, text="请检查data/output目录", font=("Arial", 12, "bold"), fg="#dc3545").pack(pady=10)
# 添加按钮
button_frame = tk.Frame(preview)
button_frame.pack(pady=10)
tk.Button(button_frame, text="打开输出目录", command=lambda: os.startfile(os.path.abspath("data/output"))).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="关闭", command=preview.destroy).pack(side=tk.LEFT, padx=5)
# 确保窗口显示在最前
preview.lift()
preview.attributes('-topmost', True)
preview.after_idle(lambda: preview.attributes('-topmost', False))
except Exception as e:
# 发生异常,显示错误消息
messagebox.showerror(
"处理异常",
f"显示预览时发生错误: {e}\n请检查日志了解详细信息。"
)
def show_demo_dialog(log_widget):
"""演示自定义弹窗功能"""
try:
add_to_log(log_widget, "显示自定义弹窗演示...\n", "info")
# 创建一个示例结果文件路径
sample_file = os.path.join(os.path.abspath("data/output"), "样例文件.xlsx")
# 获取当前时间
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 创建其他信息
additional_info = {
"客户名称": "示例客户",
"订单编号": "ORD-20250509-001",
"处理类型": "自定义处理"
}
# 显示自定义弹窗
show_custom_dialog(
title="自定义弹窗演示",
message="这是一个自定义弹窗示例",
result_file=sample_file, # 文件可能不存在,会展示文件未找到的情况
time_info=current_time,
count_info="50个商品",
amount_info="¥1,234.56",
additional_info=additional_info
)
add_to_log(log_widget, "自定义弹窗已显示\n", "success")
except Exception as e:
add_to_log(log_widget, f"显示自定义弹窗时出错: {str(e)}\n", "error")
def edit_barcode_mappings(log_widget):
"""编辑条码映射配置"""
try:
add_to_log(log_widget, "正在加载条码映射配置...\n", "info")
# 创建单位转换器实例,用于加载和保存条码映射
unit_converter = UnitConverter()
# 加载现有的映射配置
current_mappings = unit_converter.special_barcodes
# 回调函数,保存更新后的映射
def save_mappings(new_mappings):
success = unit_converter.update_barcode_mappings(new_mappings)
if success:
add_to_log(log_widget, f"成功保存条码映射配置,共{len(new_mappings)}\n", "success")
else:
add_to_log(log_widget, "保存条码映射配置失败\n", "error")
# 显示条码映射编辑对话框
show_barcode_mapping_dialog(None, save_mappings, current_mappings)
except Exception as e:
add_to_log(log_widget, f"编辑条码映射时出错: {str(e)}\n", "error")
messagebox.showerror("错误", f"编辑条码映射时出错: {str(e)}")
if __name__ == "__main__": if __name__ == "__main__":
main() main()