新增条码映射编辑功能图形化界面
This commit is contained in:
parent
7b7d491663
commit
5c0b709528
115
README.md
115
README.md
@ -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,32 +100,55 @@ 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)
|
||||||
|
|
||||||
#### 功能优化
|
#### 功能优化
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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 = [
|
||||||
@ -448,3 +401,97 @@ 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)
|
||||||
@ -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')
|
||||||
|
|
||||||
|
# 确保目录存在
|
||||||
|
os.makedirs(self.output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
# 记录实际路径
|
||||||
|
logger.info(f"使用输出目录: {os.path.abspath(self.output_dir)}")
|
||||||
|
|
||||||
# 获取模板文件路径
|
# 获取模板文件路径
|
||||||
template_folder = self.config.get('Paths', 'template_folder', 'templates')
|
template_folder = config.get('Paths', 'template_folder', fallback='templates')
|
||||||
template_name = self.config.get('Templates', 'purchase_order', '银豹-采购单模板.xls')
|
template_name = config.get('Templates', 'purchase_order', fallback='银豹-采购单模板.xls')
|
||||||
|
|
||||||
self.template_path = os.path.join(template_folder, template_name)
|
self.template_path = os.path.join(template_folder, template_name)
|
||||||
|
|
||||||
# 检查模板文件是否存在
|
# 检查模板文件是否存在
|
||||||
if not os.path.exists(self.template_path):
|
if not os.path.exists(self.template_path):
|
||||||
logger.error(f"模板文件不存在: {self.template_path}")
|
logger.warning(f"模板文件不存在: {self.template_path}")
|
||||||
raise FileNotFoundError(f"模板文件不存在: {self.template_path}")
|
|
||||||
|
|
||||||
# 用于记录已合并的文件
|
# 用于记录已合并的文件
|
||||||
self.cache_file = os.path.join(self.output_dir, "merged_files.json")
|
self.merged_files_json = os.path.join(self.output_dir, "merged_files.json")
|
||||||
self.merged_files = self._load_merged_files()
|
self.merged_files = self._load_merged_files()
|
||||||
|
|
||||||
logger.info(f"初始化完成,模板文件: {self.template_path}")
|
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]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -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')
|
self.template_path = config.get('Paths', 'template_file', fallback='templates/银豹-采购单模板.xls')
|
||||||
template_name = self.config.get('Templates', 'purchase_order', '银豹-采购单模板.xls')
|
|
||||||
|
|
||||||
self.template_path = os.path.join(template_folder, template_name)
|
|
||||||
|
|
||||||
# 检查模板文件是否存在
|
|
||||||
if not os.path.exists(self.template_path):
|
if not os.path.exists(self.template_path):
|
||||||
logger.error(f"模板文件不存在: {self.template_path}")
|
logger.warning(f"模板文件不存在: {self.template_path}")
|
||||||
raise FileNotFoundError(f"模板文件不存在: {self.template_path}")
|
|
||||||
|
|
||||||
# 用于记录已处理的文件
|
# 设置缓存文件路径
|
||||||
self.cache_file = os.path.join(self.output_dir, "processed_files.json")
|
self.cache_file = os.path.join(self.output_dir, "processed_files.json")
|
||||||
self.processed_files = self._load_processed_files()
|
self.processed_files = self._load_processed_files()
|
||||||
|
|
||||||
# 创建单位转换器
|
# 确保目录存在
|
||||||
self.unit_converter = UnitConverter()
|
os.makedirs(self.output_dir, exist_ok=True)
|
||||||
|
os.makedirs(self.temp_dir, exist_ok=True)
|
||||||
|
|
||||||
logger.info(f"初始化完成,模板文件: {self.template_path}")
|
# 记录实际路径
|
||||||
|
logger.info(f"使用输出目录: {os.path.abspath(self.output_dir)}")
|
||||||
|
logger.info(f"使用临时目录: {os.path.abspath(self.temp_dir)}")
|
||||||
|
|
||||||
|
# 加载单位转换器和配置
|
||||||
|
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]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -105,22 +105,39 @@ 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='')
|
||||||
|
|
||||||
|
# 使用fallback而不是位置参数
|
||||||
|
try:
|
||||||
|
self.max_retries = config.getint('API', 'max_retries', fallback=3)
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
# 如果getint不支持fallback,则使用get再转换
|
||||||
|
self.max_retries = int(config.get('API', 'max_retries', fallback='3'))
|
||||||
|
|
||||||
|
try:
|
||||||
|
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.token_manager = TokenManager(
|
||||||
@ -133,6 +150,8 @@ class BaiduOCRClient:
|
|||||||
# 验证API配置
|
# 验证API配置
|
||||||
if not self.api_key or not self.secret_key:
|
if not self.api_key or not self.secret_key:
|
||||||
logger.warning("API密钥未设置,请在配置文件中设置API密钥")
|
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]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -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方法的问题
|
||||||
|
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)
|
self.ocr_client = BaiduOCRClient(self.config)
|
||||||
|
|
||||||
# 获取配置
|
|
||||||
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)
|
|
||||||
|
|
||||||
# 确保目录结构正确
|
|
||||||
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.input_folder)}")
|
||||||
logger.info(f"使用输出目录: {os.path.abspath(self.output_folder)}")
|
logger.info(f"使用输出目录: {os.path.abspath(self.output_folder)}")
|
||||||
logger.info(f"使用临时目录: {os.path.abspath(self.temp_folder)}")
|
logger.info(f"使用临时目录: {os.path.abspath(self.temp_folder)}")
|
||||||
|
logger.info(f"允许的文件类型: {self.file_types}")
|
||||||
|
|
||||||
self.allowed_extensions = self.config.get_list('File', 'allowed_extensions', '.jpg,.jpeg,.png,.bmp')
|
# 初始化processed_files_json和record_manager
|
||||||
self.max_file_size_mb = self.config.getfloat('File', 'max_file_size_mb', 4.0)
|
self.processed_files_json = os.path.join(self.output_folder, 'processed_files.json')
|
||||||
self.excel_extension = self.config.get('File', 'excel_extension', '.xlsx')
|
self.record_manager = ProcessedRecordManager(self.processed_files_json)
|
||||||
|
|
||||||
# 处理性能配置
|
# 加载已处理文件记录
|
||||||
self.max_workers = self.config.getint('Performance', 'max_workers', 4)
|
self.processed_files = self._load_processed_files()
|
||||||
self.batch_size = self.config.getint('Performance', 'batch_size', 5)
|
|
||||||
self.skip_existing = self.config.getboolean('Performance', 'skip_existing', True)
|
|
||||||
|
|
||||||
# 初始化处理记录管理器
|
logger.info(f"初始化OCRProcessor完成:输入目录={self.input_folder}, 输出目录={self.output_folder}")
|
||||||
record_file = self.config.get('Paths', 'processed_record', 'data/processed_files.json')
|
except Exception as e:
|
||||||
self.record_manager = ProcessedRecordManager(record_file)
|
logger.error(f"初始化OCRProcessor失败: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
logger.info(f"OCR处理器初始化完成,输入目录: {self.input_folder}, 输出目录: {self.output_folder}")
|
def _load_processed_files(self) -> Dict[str, str]:
|
||||||
|
"""
|
||||||
|
加载已处理的文件记录
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
已处理的文件记录字典,键为输入文件路径,值为输出文件路径
|
||||||
|
"""
|
||||||
|
return load_json(self.processed_files_json, {})
|
||||||
|
|
||||||
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,8 +344,17 @@ 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()
|
||||||
@ -314,21 +363,19 @@ class OCRProcessor:
|
|||||||
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
|
|
||||||
|
|||||||
BIN
app/core/utils/__pycache__/dialog_utils.cpython-39.pyc
Normal file
BIN
app/core/utils/__pycache__/dialog_utils.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
468
app/core/utils/dialog_utils.py
Normal file
468
app/core/utils/dialog_utils.py
Normal 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)
|
||||||
@ -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:
|
||||||
"""
|
"""
|
||||||
清理日志活跃标记
|
清理日志活跃标记
|
||||||
|
|||||||
Binary file not shown.
BIN
app/services/__pycache__/tobacco_service.cpython-39.pyc
Normal file
BIN
app/services/__pycache__/tobacco_service.cpython-39.pyc
Normal file
Binary file not shown.
@ -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:
|
||||||
"""
|
"""
|
||||||
验证图片是否有效
|
验证图片是否有效
|
||||||
|
|||||||
255
app/services/tobacco_service.py
Normal file
255
app/services/tobacco_service.py
Normal 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}")
|
||||||
35
config/barcode_mappings.json
Normal file
35
config/barcode_mappings.json
Normal 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
1
logs/__main__.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:39
|
||||||
@ -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 - 烟草订单处理失败
|
||||||
|
|||||||
1
logs/app.core.excel.converter.active
Normal file
1
logs/app.core.excel.converter.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-10 11:21:12
|
||||||
@ -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项
|
||||||
|
|||||||
1
logs/app.core.excel.handlers.barcode_mapper.active
Normal file
1
logs/app.core.excel.handlers.barcode_mapper.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-10 11:21:12
|
||||||
@ -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
|
||||||
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-10 11:21:12
|
||||||
@ -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, 单位: 件 -> 瓶
|
||||||
|
|||||||
1
logs/app.core.excel.merger.active
Normal file
1
logs/app.core.excel.merger.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:38
|
||||||
@ -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
|
||||||
|
|||||||
1
logs/app.core.excel.processor.active
Normal file
1
logs/app.core.excel.processor.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:38
|
||||||
@ -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
|
||||||
|
|||||||
1
logs/app.core.excel.validators.active
Normal file
1
logs/app.core.excel.validators.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-10 11:21:12
|
||||||
1
logs/app.core.ocr.baidu_ocr.active
Normal file
1
logs/app.core.ocr.baidu_ocr.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:37
|
||||||
@ -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 - 成功获取访问令牌
|
||||||
|
|||||||
1
logs/app.core.ocr.table_ocr.active
Normal file
1
logs/app.core.ocr.table_ocr.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:37
|
||||||
@ -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
|
||||||
|
|||||||
1
logs/app.core.utils.file_utils.active
Normal file
1
logs/app.core.utils.file_utils.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:36
|
||||||
1
logs/app.services.ocr_service.active
Normal file
1
logs/app.services.ocr_service.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:37
|
||||||
@ -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
|
||||||
|
|||||||
1
logs/app.services.order_service.active
Normal file
1
logs/app.services.order_service.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:38
|
||||||
@ -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
|
||||||
|
|||||||
1
logs/app.services.tobacco_service.active
Normal file
1
logs/app.services.tobacco_service.active
Normal file
@ -0,0 +1 @@
|
|||||||
|
Active since: 2025-05-09 16:01:39
|
||||||
97
logs/app.services.tobacco_service.log
Normal file
97
logs/app.services.tobacco_service.log
Normal 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 - 未找到可处理的烟草订单明细文件
|
||||||
411
run.py
411
run.py
@ -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='输入订单明细文件路径')
|
||||||
|
|
||||||
def run_ocr(ocr_service: OCRService, args) -> bool:
|
# 解析参数
|
||||||
|
parsed_args = parser.parse_args()
|
||||||
|
|
||||||
|
return parsed_args
|
||||||
|
|
||||||
|
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):
|
if not args.command:
|
||||||
logger.error(f"输入文件无效: {args.input}")
|
argparse.ArgumentParser().print_help()
|
||||||
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:
|
|
||||||
order_service: 订单服务
|
|
||||||
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
|
||||||
|
|
||||||
try:
|
# 加载配置
|
||||||
# 创建配置管理器
|
config_path = args.config
|
||||||
config = ConfigManager(parsed_args.config) if parsed_args.config else ConfigManager()
|
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:
|
||||||
|
if args.command == 'ocr':
|
||||||
|
# OCR识别处理
|
||||||
|
ocr_service = OCRService(config)
|
||||||
|
if args.batch:
|
||||||
|
# 批量处理
|
||||||
|
total, success = ocr_service.batch_process(
|
||||||
|
batch_size=args.batch_size,
|
||||||
|
max_workers=args.max_workers
|
||||||
|
)
|
||||||
|
return 0 if success > 0 else 1
|
||||||
|
else:
|
||||||
|
# 处理单个文件
|
||||||
|
result = ocr_service.process_image(args.input)
|
||||||
|
return 0 if result else 1
|
||||||
|
|
||||||
|
elif args.command == 'excel':
|
||||||
|
# Excel处理
|
||||||
|
order_service = OrderService(config)
|
||||||
|
if args.input:
|
||||||
|
# 处理指定文件
|
||||||
|
result = order_service.process_excel(args.input)
|
||||||
|
else:
|
||||||
|
# 处理最新文件
|
||||||
|
result = order_service.process_latest_excel()
|
||||||
|
return 0 if result 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)
|
ocr_service = OCRService(config)
|
||||||
order_service = OrderService(config)
|
order_service = OrderService(config)
|
||||||
|
|
||||||
# 根据命令执行不同功能
|
# 1. OCR处理
|
||||||
if parsed_args.command == 'ocr':
|
if args.input:
|
||||||
success = run_ocr(ocr_service, parsed_args)
|
# 处理单个文件
|
||||||
elif parsed_args.command == 'excel':
|
excel_file = ocr_service.process_image(args.input)
|
||||||
success = run_excel(order_service, parsed_args)
|
|
||||||
elif parsed_args.command == 'merge':
|
|
||||||
success = run_merge(order_service, parsed_args)
|
|
||||||
elif parsed_args.command == 'pipeline':
|
|
||||||
success = run_pipeline(ocr_service, order_service, parsed_args)
|
|
||||||
else:
|
else:
|
||||||
parser.print_help()
|
# 批量处理
|
||||||
|
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
|
return 1
|
||||||
|
|
||||||
return 0 if success else 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())
|
||||||
249
启动器.py
249
启动器.py
@ -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()
|
||||||
Loading…
Reference in New Issue
Block a user