新版本
This commit is contained in:
parent
9f97ac3f21
commit
73d17836d7
@ -1,82 +0,0 @@
|
||||
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
block_cipher = None
|
||||
|
||||
# 需要包含的数据文件
|
||||
added_files = [
|
||||
('config.ini', '.'),
|
||||
('config/barcode_mappings.json', 'config/'),
|
||||
('config/config.ini', 'config/'),
|
||||
('templates/银豹-采购单模板.xls', 'templates/'),
|
||||
('app', 'app'),
|
||||
]
|
||||
|
||||
# 需要隐式导入的模块
|
||||
hidden_imports = [
|
||||
'tkinter',
|
||||
'tkinter.ttk',
|
||||
'tkinter.filedialog',
|
||||
'tkinter.messagebox',
|
||||
'tkinter.scrolledtext',
|
||||
'pandas',
|
||||
'numpy',
|
||||
'openpyxl',
|
||||
'xlrd',
|
||||
'xlwt',
|
||||
'xlutils',
|
||||
'requests',
|
||||
'configparser',
|
||||
'threading',
|
||||
'datetime',
|
||||
'json',
|
||||
're',
|
||||
'subprocess',
|
||||
'shutil',
|
||||
'app.config.settings',
|
||||
'app.services.ocr_service',
|
||||
'app.services.order_service',
|
||||
'app.services.tobacco_service',
|
||||
'app.core.utils.dialog_utils',
|
||||
'app.core.excel.converter',
|
||||
]
|
||||
|
||||
a = Analysis(
|
||||
['启动器.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=added_files,
|
||||
hiddenimports=hidden_imports,
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='OCR订单处理系统',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
@ -285,6 +285,16 @@ class UnitConverter:
|
||||
|
||||
logger.debug(f"解析规格: {spec}")
|
||||
|
||||
# 新增:处理“1件=12桶/袋/盒...”等等式规格,统一为1*12
|
||||
eq_match = re.match(r'(\d+(?:\.\d+)?)\s*(?:件|箱|提|盒)\s*[==]\s*(\d+)\s*(?:瓶|桶|盒|支|个|袋|罐|包|卷)', spec)
|
||||
if eq_match:
|
||||
try:
|
||||
level2 = int(eq_match.group(2))
|
||||
logger.info(f"解析等式规格: {spec} -> 1*{level2}")
|
||||
return 1, level2, None
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# 处理三级包装,如1*5*12
|
||||
three_level_match = re.match(r'(\d+)[*](\d+)[*](\d+)', spec)
|
||||
if three_level_match:
|
||||
@ -522,4 +532,4 @@ class UnitConverter:
|
||||
更新是否成功
|
||||
"""
|
||||
self.special_barcodes = new_mappings
|
||||
return self.save_barcode_mappings(new_mappings)
|
||||
return self.save_barcode_mappings(new_mappings)
|
||||
|
||||
@ -11,7 +11,7 @@ import numpy as np
|
||||
import xlrd
|
||||
import xlwt
|
||||
from xlutils.copy import copy as xlcopy
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
|
||||
from datetime import datetime
|
||||
|
||||
from ...config.settings import ConfigManager
|
||||
@ -414,7 +414,7 @@ class PurchaseOrderMerger:
|
||||
logger.error(f"创建合并采购单时出错: {e}")
|
||||
return None
|
||||
|
||||
def process(self, file_paths: Optional[List[str]] = None) -> Optional[str]:
|
||||
def process(self, file_paths: Optional[List[str]] = None, progress_cb: Optional[Callable[[int], None]] = None) -> Optional[str]:
|
||||
"""
|
||||
处理采购单合并
|
||||
|
||||
@ -427,6 +427,11 @@ class PurchaseOrderMerger:
|
||||
# 如果未指定文件路径,则获取所有采购单文件
|
||||
if file_paths is None:
|
||||
file_paths = self.get_purchase_orders()
|
||||
try:
|
||||
if progress_cb:
|
||||
progress_cb(97)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 检查是否有文件需要合并
|
||||
if not file_paths:
|
||||
@ -438,16 +443,26 @@ class PurchaseOrderMerger:
|
||||
if merged_df is None:
|
||||
logger.error("合并采购单失败")
|
||||
return None
|
||||
try:
|
||||
if progress_cb:
|
||||
progress_cb(98)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 创建合并的采购单文件
|
||||
output_file = self.create_merged_purchase_order(merged_df)
|
||||
if output_file is None:
|
||||
logger.error("创建合并采购单文件失败")
|
||||
return None
|
||||
try:
|
||||
if progress_cb:
|
||||
progress_cb(100)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 记录已合并文件
|
||||
for file_path in file_paths:
|
||||
self.merged_files[file_path] = output_file
|
||||
self._save_merged_files()
|
||||
|
||||
return output_file
|
||||
return output_file
|
||||
|
||||
@ -11,7 +11,7 @@ import numpy as np
|
||||
import xlrd
|
||||
import xlwt
|
||||
from xlutils.copy import copy as xlcopy
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
|
||||
from datetime import datetime
|
||||
|
||||
from ...config.settings import ConfigManager
|
||||
@ -281,6 +281,36 @@ class ExcelProcessor:
|
||||
product['amount'] = row['小计']
|
||||
elif column_mapping.get('amount') and not pd.isna(row[column_mapping['amount']]):
|
||||
product['amount'] = row[column_mapping['amount']]
|
||||
# 根据金额判断赠品:金额为0、为空、或为o/O
|
||||
amt = product.get('amount', None)
|
||||
try:
|
||||
is_amt_gift = False
|
||||
if amt is None:
|
||||
is_amt_gift = True
|
||||
elif isinstance(amt, str):
|
||||
s = amt.strip()
|
||||
if s == '' or s.lower() == 'o' or s == '0' or s == '○':
|
||||
is_amt_gift = True
|
||||
else:
|
||||
amt_clean = re.sub(r'[^\d\.,]', '', s)
|
||||
if ',' in amt_clean and '.' not in amt_clean:
|
||||
amt_clean = amt_clean.replace(',', '.')
|
||||
elif ',' in amt_clean and '.' in amt_clean:
|
||||
amt_clean = amt_clean.replace(',', '')
|
||||
if amt_clean:
|
||||
try:
|
||||
is_amt_gift = float(amt_clean) == 0.0
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
is_amt_gift = float(amt) == 0.0
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if is_amt_gift:
|
||||
product['is_gift'] = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 提取数量
|
||||
if '数量' in df.columns and not pd.isna(row['数量']):
|
||||
@ -472,7 +502,7 @@ class ExcelProcessor:
|
||||
logger.warning(f"通过金额和单价计算数量失败: {e}")
|
||||
|
||||
# 判断是否为赠品(价格为0)
|
||||
is_gift = price == 0
|
||||
is_gift = bool(product.get('is_gift', False)) or (price == 0)
|
||||
|
||||
logger.info(f"处理商品: 条码={barcode}, 数量={quantity}, 单价={price}, 是否赠品={is_gift}")
|
||||
|
||||
@ -631,7 +661,7 @@ class ExcelProcessor:
|
||||
logger.warning("无法识别表头行")
|
||||
return None
|
||||
|
||||
def process_specific_file(self, file_path: str) -> Optional[str]:
|
||||
def process_specific_file(self, file_path: str, progress_cb: Optional[Callable[[int], None]] = None) -> Optional[str]:
|
||||
"""
|
||||
处理指定的Excel文件
|
||||
|
||||
@ -649,6 +679,11 @@ class ExcelProcessor:
|
||||
|
||||
try:
|
||||
# 读取Excel文件时不立即指定表头
|
||||
if progress_cb:
|
||||
try:
|
||||
progress_cb(92)
|
||||
except Exception:
|
||||
pass
|
||||
df = pd.read_excel(file_path, header=None)
|
||||
logger.info(f"成功读取Excel文件: {file_path}, 共 {len(df)} 行")
|
||||
|
||||
@ -661,10 +696,20 @@ class ExcelProcessor:
|
||||
logger.info(f"识别到表头在第 {header_row+1} 行")
|
||||
|
||||
# 重新读取Excel,正确指定表头行
|
||||
if progress_cb:
|
||||
try:
|
||||
progress_cb(94)
|
||||
except Exception:
|
||||
pass
|
||||
df = pd.read_excel(file_path, header=header_row)
|
||||
logger.info(f"使用表头行重新读取数据,共 {len(df)} 行有效数据")
|
||||
|
||||
# 提取商品信息
|
||||
if progress_cb:
|
||||
try:
|
||||
progress_cb(96)
|
||||
except Exception:
|
||||
pass
|
||||
products = self.extract_product_info(df)
|
||||
|
||||
if not products:
|
||||
@ -685,6 +730,11 @@ class ExcelProcessor:
|
||||
|
||||
# 不再自动打开输出目录
|
||||
logger.info(f"采购单已保存到: {output_file}")
|
||||
if progress_cb:
|
||||
try:
|
||||
progress_cb(100)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return output_file
|
||||
|
||||
@ -694,7 +744,7 @@ class ExcelProcessor:
|
||||
logger.error(f"处理Excel文件时出错: {file_path}, 错误: {e}")
|
||||
return None
|
||||
|
||||
def process_latest_file(self) -> Optional[str]:
|
||||
def process_latest_file(self, progress_cb: Optional[Callable[[int], None]] = None) -> Optional[str]:
|
||||
"""
|
||||
处理最新的Excel文件
|
||||
|
||||
@ -708,7 +758,7 @@ class ExcelProcessor:
|
||||
return None
|
||||
|
||||
# 处理文件
|
||||
return self.process_specific_file(latest_file)
|
||||
return self.process_specific_file(latest_file, progress_cb=progress_cb)
|
||||
|
||||
def _detect_column_mapping(self, df: pd.DataFrame) -> Dict[str, str]:
|
||||
"""
|
||||
@ -889,6 +939,11 @@ class ExcelProcessor:
|
||||
|
||||
logger.debug(f"清理后的规格字符串: {spec_str}")
|
||||
|
||||
# 新增:匹配“1件=12桶/袋/盒…”等等式规格,取右侧数量作为包装数量
|
||||
eq_match = re.search(r'(\d+(?:\.\d+)?)\s*(?:件|箱|提|盒)\s*[==]\s*(\d+)\s*(?:瓶|桶|盒|支|个|袋|罐|包|卷)', spec_str)
|
||||
if eq_match:
|
||||
return int(eq_match.group(2))
|
||||
|
||||
# 匹配带单位的格式,如"5kg*6"、"450g*15"、"450ml*15"
|
||||
weight_pattern = r'(\d+(?:\.\d+)?)\s*(?:kg|KG|千克|公斤)[*×](\d+)'
|
||||
match = re.search(weight_pattern, spec_str)
|
||||
@ -946,4 +1001,4 @@ class ExcelProcessor:
|
||||
except Exception as e:
|
||||
logger.warning(f"解析规格'{spec_str}'时出错: {e}")
|
||||
|
||||
return None
|
||||
return None
|
||||
|
||||
@ -1,355 +0,0 @@
|
||||
"""
|
||||
单位转换器测试模块
|
||||
---------------
|
||||
测试单位转换和条码映射逻辑
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from typing import Dict, Any
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../..')))
|
||||
|
||||
from app.core.excel.converter import UnitConverter
|
||||
from app.core.excel.validators import ProductValidator
|
||||
|
||||
|
||||
class TestUnitConverter(unittest.TestCase):
|
||||
"""
|
||||
测试单位转换器功能
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
测试前的准备工作
|
||||
"""
|
||||
self.converter = UnitConverter()
|
||||
|
||||
def test_jian_unit_conversion(self):
|
||||
"""
|
||||
测试"件"单位的转换
|
||||
"""
|
||||
# 准备测试数据
|
||||
product = {
|
||||
'barcode': '6954767400129',
|
||||
'name': '美汁源果粒橙1.8L*8瓶',
|
||||
'specification': '1.8L*8',
|
||||
'quantity': 1.0,
|
||||
'unit': '件',
|
||||
'price': 65.0
|
||||
}
|
||||
|
||||
# 执行转换
|
||||
result = self.converter.process_unit_conversion(product)
|
||||
|
||||
# 验证结果
|
||||
self.assertEqual(result['quantity'], 8.0)
|
||||
self.assertEqual(result['price'], 8.125)
|
||||
self.assertEqual(result['unit'], '瓶')
|
||||
|
||||
def test_box_unit_conversion(self):
|
||||
"""
|
||||
测试"箱"单位的转换
|
||||
"""
|
||||
# 准备测试数据
|
||||
product = {
|
||||
'barcode': '6925303721244',
|
||||
'name': '统一鲜橙多2L*6瓶',
|
||||
'specification': '2L*6',
|
||||
'quantity': 1.0,
|
||||
'unit': '箱',
|
||||
'price': 43.0
|
||||
}
|
||||
|
||||
# 执行转换
|
||||
result = self.converter.process_unit_conversion(product)
|
||||
|
||||
# 验证结果
|
||||
self.assertEqual(result['quantity'], 6.0)
|
||||
self.assertEqual(result['price'], 7.1666666666666667)
|
||||
self.assertEqual(result['unit'], '瓶')
|
||||
|
||||
def test_tihe_unit_conversion_level3(self):
|
||||
"""
|
||||
测试"提"单位的转换(三级规格)
|
||||
"""
|
||||
# 准备测试数据(三级规格:1*6*4,表示1排6提,每提4瓶)
|
||||
product = {
|
||||
'barcode': '6921168509347',
|
||||
'name': '农夫山泉550ml*24瓶',
|
||||
'specification': '1*6*4',
|
||||
'quantity': 2.0,
|
||||
'unit': '提',
|
||||
'price': 16.0
|
||||
}
|
||||
|
||||
# 执行转换
|
||||
result = self.converter.process_unit_conversion(product)
|
||||
|
||||
# 验证结果:三级规格,提单位特殊处理,数量*最后一级
|
||||
self.assertEqual(result['quantity'], 8.0) # 2提 * 4瓶/提
|
||||
self.assertEqual(result['price'], 4.0) # 16元/提 ÷ 4瓶/提
|
||||
self.assertEqual(result['unit'], '瓶')
|
||||
|
||||
def test_tihe_unit_conversion_level2(self):
|
||||
"""
|
||||
测试"提"单位的转换(二级规格)
|
||||
"""
|
||||
# 准备测试数据(二级规格:1*4,表示每件4提)
|
||||
product = {
|
||||
'barcode': '6921168509347',
|
||||
'name': '农夫山泉550ml*4瓶',
|
||||
'specification': '1*4',
|
||||
'quantity': 5.0,
|
||||
'unit': '提',
|
||||
'price': 10.0
|
||||
}
|
||||
|
||||
# 执行转换
|
||||
result = self.converter.process_unit_conversion(product)
|
||||
|
||||
# 验证结果:二级规格,提单位保持不变
|
||||
self.assertEqual(result['quantity'], 5.0)
|
||||
self.assertEqual(result['price'], 10.0)
|
||||
self.assertEqual(result['unit'], '提')
|
||||
|
||||
def test_barcode_mapping(self):
|
||||
"""
|
||||
测试条码映射
|
||||
"""
|
||||
# 准备测试数据(使用需要被映射的条码)
|
||||
product = {
|
||||
'barcode': '6920584471055', # 这个条码应映射到6920584471017
|
||||
'name': '测试映射条码商品',
|
||||
'specification': '1*12',
|
||||
'quantity': 1.0,
|
||||
'unit': '件',
|
||||
'price': 60.0
|
||||
}
|
||||
|
||||
# 执行转换
|
||||
result = self.converter.process_unit_conversion(product)
|
||||
|
||||
# 验证结果:条码应该被映射
|
||||
self.assertEqual(result['barcode'], '6920584471017')
|
||||
self.assertEqual(result['quantity'], 12.0) # 同时处理件单位转换
|
||||
self.assertEqual(result['price'], 5.0) # 60元/件 ÷ 12瓶/件
|
||||
self.assertEqual(result['unit'], '瓶')
|
||||
|
||||
def test_special_barcode_multiplier(self):
|
||||
"""
|
||||
测试特殊条码的倍数处理
|
||||
"""
|
||||
# 准备测试数据(使用特殊条码)
|
||||
product = {
|
||||
'barcode': '6925019900087', # 特殊条码:数量*10,单位转瓶
|
||||
'name': '特殊条码商品',
|
||||
'specification': '1*10',
|
||||
'quantity': 2.0,
|
||||
'unit': '箱',
|
||||
'price': 100.0
|
||||
}
|
||||
|
||||
# 执行转换
|
||||
result = self.converter.process_unit_conversion(product)
|
||||
|
||||
# 验证结果:特殊条码乘数应该生效
|
||||
self.assertEqual(result['quantity'], 20.0) # 2箱 * 10倍数
|
||||
self.assertEqual(result['price'], 5.0) # 100元/箱 ÷ 10倍数/箱
|
||||
self.assertEqual(result['unit'], '瓶')
|
||||
|
||||
|
||||
class TestProductValidator(unittest.TestCase):
|
||||
"""
|
||||
测试商品数据验证器功能
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
测试前的准备工作
|
||||
"""
|
||||
self.validator = ProductValidator()
|
||||
|
||||
def test_validate_barcode(self):
|
||||
"""
|
||||
测试条码验证
|
||||
"""
|
||||
# 测试有效条码
|
||||
is_valid, barcode, error = self.validator.validate_barcode('6925303721244')
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(barcode, '6925303721244')
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试包含非数字字符的条码
|
||||
is_valid, barcode, error = self.validator.validate_barcode('6925303-721244')
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(barcode, '6925303721244')
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试5开头的条码修正
|
||||
is_valid, barcode, error = self.validator.validate_barcode('5925303721244')
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(barcode, '6925303721244')
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试过短的条码
|
||||
is_valid, barcode, error = self.validator.validate_barcode('12345')
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(barcode, '12345')
|
||||
self.assertIn("条码长度异常", error)
|
||||
|
||||
# 测试仓库标识
|
||||
is_valid, barcode, error = self.validator.validate_barcode('仓库')
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(barcode, '仓库')
|
||||
self.assertEqual(error, "条码为仓库标识")
|
||||
|
||||
# 测试空值
|
||||
is_valid, barcode, error = self.validator.validate_barcode(None)
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(barcode, "")
|
||||
self.assertEqual(error, "条码为空")
|
||||
|
||||
def test_validate_quantity(self):
|
||||
"""
|
||||
测试数量验证
|
||||
"""
|
||||
# 测试有效数量
|
||||
is_valid, quantity, error = self.validator.validate_quantity(10)
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(quantity, 10.0)
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试字符串数量
|
||||
is_valid, quantity, error = self.validator.validate_quantity("25.5")
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(quantity, 25.5)
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试带单位的数量
|
||||
is_valid, quantity, error = self.validator.validate_quantity("30瓶")
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(quantity, 30.0)
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试零数量
|
||||
is_valid, quantity, error = self.validator.validate_quantity(0)
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(quantity, 0.0)
|
||||
self.assertIn("数量必须大于0", error)
|
||||
|
||||
# 测试负数量
|
||||
is_valid, quantity, error = self.validator.validate_quantity(-5)
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(quantity, 0.0)
|
||||
self.assertIn("数量必须大于0", error)
|
||||
|
||||
# 测试非数字
|
||||
is_valid, quantity, error = self.validator.validate_quantity("abc")
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(quantity, 0.0)
|
||||
self.assertIn("数量不包含数字", error)
|
||||
|
||||
# 测试空值
|
||||
is_valid, quantity, error = self.validator.validate_quantity(None)
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(quantity, 0.0)
|
||||
self.assertEqual(error, "数量为空")
|
||||
|
||||
def test_validate_price(self):
|
||||
"""
|
||||
测试单价验证
|
||||
"""
|
||||
# 测试有效单价
|
||||
is_valid, price, is_gift, error = self.validator.validate_price(12.5)
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(price, 12.5)
|
||||
self.assertFalse(is_gift)
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试字符串单价
|
||||
is_valid, price, is_gift, error = self.validator.validate_price("8.0")
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(price, 8.0)
|
||||
self.assertFalse(is_gift)
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试零单价(赠品)
|
||||
is_valid, price, is_gift, error = self.validator.validate_price(0)
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(price, 0.0)
|
||||
self.assertTrue(is_gift)
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试"赠品"标记
|
||||
is_valid, price, is_gift, error = self.validator.validate_price("赠品")
|
||||
self.assertTrue(is_valid)
|
||||
self.assertEqual(price, 0.0)
|
||||
self.assertTrue(is_gift)
|
||||
self.assertIsNone(error)
|
||||
|
||||
# 测试负单价
|
||||
is_valid, price, is_gift, error = self.validator.validate_price(-5)
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(price, 0.0)
|
||||
self.assertTrue(is_gift)
|
||||
self.assertIn("单价不能为负数", error)
|
||||
|
||||
# 测试空值
|
||||
is_valid, price, is_gift, error = self.validator.validate_price(None)
|
||||
self.assertFalse(is_valid)
|
||||
self.assertEqual(price, 0.0)
|
||||
self.assertTrue(is_gift)
|
||||
self.assertEqual(error, "单价为空,视为赠品")
|
||||
|
||||
def test_validate_product(self):
|
||||
"""
|
||||
测试商品数据验证
|
||||
"""
|
||||
# 准备测试数据(有效商品)
|
||||
product = {
|
||||
'barcode': '6954767400129',
|
||||
'name': '测试商品',
|
||||
'specification': '1*12',
|
||||
'quantity': 3.0,
|
||||
'price': 36.0,
|
||||
'unit': '件',
|
||||
'is_gift': False
|
||||
}
|
||||
|
||||
# 验证有效商品
|
||||
result = self.validator.validate_product(product)
|
||||
self.assertEqual(result['barcode'], '6954767400129')
|
||||
self.assertEqual(result['quantity'], 3.0)
|
||||
self.assertEqual(result['price'], 36.0)
|
||||
self.assertFalse(result['is_gift'])
|
||||
|
||||
# 验证赠品商品
|
||||
gift_product = product.copy()
|
||||
gift_product['price'] = 0
|
||||
result = self.validator.validate_product(gift_product)
|
||||
self.assertEqual(result['price'], 0.0)
|
||||
self.assertTrue(result['is_gift'])
|
||||
|
||||
# 验证需要修复的商品
|
||||
invalid_product = {
|
||||
'barcode': '5954767-400129', # 需要修复前缀和移除非数字
|
||||
'name': '测试商品',
|
||||
'specification': '1*12',
|
||||
'quantity': '2件', # 需要提取数字
|
||||
'price': '赠品', # 赠品标记
|
||||
'unit': '件',
|
||||
'is_gift': False
|
||||
}
|
||||
|
||||
result = self.validator.validate_product(invalid_product)
|
||||
self.assertEqual(result['barcode'], '6954767400129') # 5->6,移除 '-'
|
||||
self.assertEqual(result['quantity'], 2.0) # 提取数字
|
||||
self.assertEqual(result['price'], 0.0) # 赠品价格为0
|
||||
self.assertTrue(result['is_gift']) # 标记为赠品
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@ -225,6 +225,36 @@ class ProductValidator:
|
||||
validated_product['is_gift'] = True
|
||||
if error_msg:
|
||||
logger.info(error_msg)
|
||||
|
||||
amount = product.get('amount', None)
|
||||
try:
|
||||
is_amount_gift = False
|
||||
if amount is None:
|
||||
is_amount_gift = True
|
||||
elif isinstance(amount, str):
|
||||
s = amount.strip()
|
||||
if s == '' or s.lower() == 'o' or s == '0':
|
||||
is_amount_gift = True
|
||||
else:
|
||||
amt_clean = re.sub(r'[^\d\.,]', '', s)
|
||||
if ',' in amt_clean and '.' not in amt_clean:
|
||||
amt_clean = amt_clean.replace(',', '.')
|
||||
elif ',' in amt_clean and '.' in amt_clean:
|
||||
amt_clean = amt_clean.replace(',', '')
|
||||
if amt_clean:
|
||||
try:
|
||||
is_amount_gift = float(amt_clean) == 0.0
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
is_amount_gift = float(amount) == 0.0
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if is_amount_gift:
|
||||
validated_product['is_gift'] = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 验证数量
|
||||
quantity = product.get('quantity', None)
|
||||
@ -268,4 +298,4 @@ class ProductValidator:
|
||||
logger.warning(f"数量验证失败: {error_msg}")
|
||||
validated_product['quantity'] = 0.0
|
||||
|
||||
return validated_product
|
||||
return validated_product
|
||||
|
||||
9
app/core/handlers/__init__.py
Normal file
9
app/core/handlers/__init__.py
Normal file
@ -0,0 +1,9 @@
|
||||
"""
|
||||
数据处理handlers模块初始化文件
|
||||
"""
|
||||
|
||||
from .data_cleaner import DataCleaner
|
||||
from .column_mapper import ColumnMapper
|
||||
from .calculator import DataCalculator
|
||||
|
||||
__all__ = ['DataCleaner', 'ColumnMapper', 'DataCalculator']
|
||||
378
app/core/handlers/calculator.py
Normal file
378
app/core/handlers/calculator.py
Normal file
@ -0,0 +1,378 @@
|
||||
"""
|
||||
数据计算处理器
|
||||
|
||||
提供各种数据计算功能,如数量计算、价格计算、汇总统计等
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from typing import Dict, Any, Optional, List, Union
|
||||
from ...core.utils.log_utils import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class DataCalculator:
|
||||
"""数据计算处理器
|
||||
|
||||
提供标准化的数据计算功能,支持各种业务计算规则
|
||||
"""
|
||||
|
||||
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
||||
"""初始化数据计算器
|
||||
|
||||
Args:
|
||||
config: 计算配置
|
||||
"""
|
||||
self.config = config or {}
|
||||
self.calculation_rules = []
|
||||
|
||||
def add_rule(self, rule_type: str, **kwargs):
|
||||
"""添加计算规则
|
||||
|
||||
Args:
|
||||
rule_type: 规则类型
|
||||
**kwargs: 规则参数
|
||||
"""
|
||||
rule = {'type': rule_type, **kwargs}
|
||||
self.calculation_rules.append(rule)
|
||||
logger.debug(f"添加计算规则: {rule_type}")
|
||||
|
||||
def calculate(self, df: pd.DataFrame) -> pd.DataFrame:
|
||||
"""执行数据计算
|
||||
|
||||
Args:
|
||||
df: 输入数据
|
||||
|
||||
Returns:
|
||||
计算后的数据
|
||||
"""
|
||||
logger.info(f"开始数据计算,原始数据形状: {df.shape}")
|
||||
|
||||
result_df = df.copy()
|
||||
|
||||
for i, rule in enumerate(self.calculation_rules):
|
||||
try:
|
||||
logger.debug(f"执行计算规则 {i+1}/{len(self.calculation_rules)}: {rule['type']}")
|
||||
result_df = self._apply_rule(result_df, rule)
|
||||
logger.debug(f"规则执行完成,数据形状: {result_df.shape}")
|
||||
except Exception as e:
|
||||
logger.error(f"计算规则执行失败: {rule}, 错误: {e}")
|
||||
# 继续执行下一个规则,而不是中断整个流程
|
||||
continue
|
||||
|
||||
logger.info(f"数据计算完成,最终数据形状: {result_df.shape}")
|
||||
return result_df
|
||||
|
||||
def _apply_rule(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""应用单个计算规则
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
rule_type = rule.get('type')
|
||||
|
||||
if rule_type == 'multiply':
|
||||
return self._multiply(df, rule)
|
||||
elif rule_type == 'divide':
|
||||
return self._divide(df, rule)
|
||||
elif rule_type == 'add':
|
||||
return self._add(df, rule)
|
||||
elif rule_type == 'subtract':
|
||||
return self._subtract(df, rule)
|
||||
elif rule_type == 'formula':
|
||||
return self._formula(df, rule)
|
||||
elif rule_type == 'round':
|
||||
return self._round(df, rule)
|
||||
elif rule_type == 'sum':
|
||||
return self._sum(df, rule)
|
||||
elif rule_type == 'aggregate':
|
||||
return self._aggregate(df, rule)
|
||||
else:
|
||||
logger.warning(f"未知的计算规则类型: {rule_type}")
|
||||
return df
|
||||
|
||||
def _multiply(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""乘法计算
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
source_column = rule.get('source_column')
|
||||
target_column = rule.get('target_column')
|
||||
factor = rule.get('factor', 1)
|
||||
|
||||
if source_column and target_column:
|
||||
if source_column in df.columns:
|
||||
df[target_column] = df[source_column] * factor
|
||||
logger.debug(f"乘法计算: {source_column} * {factor} -> {target_column}")
|
||||
else:
|
||||
logger.warning(f"源列不存在: {source_column}")
|
||||
|
||||
return df
|
||||
|
||||
def _divide(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""除法计算
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
source_column = rule.get('source_column')
|
||||
target_column = rule.get('target_column')
|
||||
divisor = rule.get('divisor', 1)
|
||||
|
||||
if source_column and target_column and divisor != 0:
|
||||
if source_column in df.columns:
|
||||
df[target_column] = df[source_column] / divisor
|
||||
logger.debug(f"除法计算: {source_column} / {divisor} -> {target_column}")
|
||||
else:
|
||||
logger.warning(f"源列不存在: {source_column}")
|
||||
elif divisor == 0:
|
||||
logger.error("除数不能为0")
|
||||
|
||||
return df
|
||||
|
||||
def _add(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""加法计算
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
columns = rule.get('columns', [])
|
||||
target_column = rule.get('target_column')
|
||||
constant = rule.get('constant', 0)
|
||||
|
||||
if target_column:
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
|
||||
if columns:
|
||||
# 列相加
|
||||
valid_columns = [col for col in columns if col in df.columns]
|
||||
if valid_columns:
|
||||
df[target_column] = df[valid_columns].sum(axis=1) + constant
|
||||
logger.debug(f"加法计算: {valid_columns} + {constant} -> {target_column}")
|
||||
else:
|
||||
logger.warning(f"没有有效的列用于加法计算: {columns}")
|
||||
else:
|
||||
# 只加常数
|
||||
if target_column in df.columns:
|
||||
df[target_column] = df[target_column] + constant
|
||||
logger.debug(f"加法计算: {target_column} + {constant}")
|
||||
else:
|
||||
logger.warning(f"目标列不存在: {target_column}")
|
||||
|
||||
return df
|
||||
|
||||
def _subtract(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""减法计算
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
minuend = rule.get('minuend') # 被减数列
|
||||
subtrahend = rule.get('subtrahend') # 减数列
|
||||
target_column = rule.get('target_column')
|
||||
constant = rule.get('constant', 0)
|
||||
|
||||
if target_column and minuend and minuend in df.columns:
|
||||
if subtrahend and subtrahend in df.columns:
|
||||
df[target_column] = df[minuend] - df[subtrahend] - constant
|
||||
logger.debug(f"减法计算: {minuend} - {subtrahend} - {constant} -> {target_column}")
|
||||
else:
|
||||
df[target_column] = df[minuend] - constant
|
||||
logger.debug(f"减法计算: {minuend} - {constant} -> {target_column}")
|
||||
else:
|
||||
logger.warning(f"减法计算参数不完整或列不存在")
|
||||
|
||||
return df
|
||||
|
||||
def _formula(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""公式计算
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
formula = rule.get('formula')
|
||||
target_column = rule.get('target_column')
|
||||
|
||||
if formula and target_column:
|
||||
try:
|
||||
df[target_column] = df.eval(formula)
|
||||
logger.debug(f"公式计算: {formula} -> {target_column}")
|
||||
except Exception as e:
|
||||
logger.error(f"公式计算失败: {formula}, 错误: {e}")
|
||||
else:
|
||||
logger.warning("公式计算缺少公式或目标列")
|
||||
|
||||
return df
|
||||
|
||||
def _round(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""四舍五入
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
columns = rule.get('columns', [])
|
||||
decimals = rule.get('decimals', 0)
|
||||
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
|
||||
target_columns = columns or df.select_dtypes(include=[np.number]).columns
|
||||
|
||||
for col in target_columns:
|
||||
if col in df.columns and pd.api.types.is_numeric_dtype(df[col]):
|
||||
df[col] = df[col].round(decimals)
|
||||
logger.debug(f"四舍五入: {col} 保留 {decimals} 位小数")
|
||||
|
||||
return df
|
||||
|
||||
def _sum(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""求和计算
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
columns = rule.get('columns', [])
|
||||
target_column = rule.get('target_column')
|
||||
group_by = rule.get('group_by')
|
||||
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
|
||||
if group_by and group_by in df.columns:
|
||||
# 分组求和
|
||||
if columns:
|
||||
for col in columns:
|
||||
if col in df.columns:
|
||||
sum_result = df.groupby(group_by)[col].sum()
|
||||
logger.debug(f"分组求和: {col} 按 {group_by} 分组")
|
||||
else:
|
||||
# 所有数值列分组求和
|
||||
numeric_columns = df.select_dtypes(include=[np.number]).columns
|
||||
sum_result = df.groupby(group_by)[numeric_columns].sum()
|
||||
logger.debug(f"分组求和: 所有数值列 按 {group_by} 分组")
|
||||
else:
|
||||
# 总体求和
|
||||
if columns:
|
||||
valid_columns = [col for col in columns if col in df.columns]
|
||||
if valid_columns and target_column:
|
||||
df[target_column] = df[valid_columns].sum(axis=1)
|
||||
logger.debug(f"求和计算: {valid_columns} -> {target_column}")
|
||||
else:
|
||||
# 所有数值列求和
|
||||
numeric_columns = df.select_dtypes(include=[np.number]).columns
|
||||
if target_column and len(numeric_columns) > 0:
|
||||
df[target_column] = df[numeric_columns].sum(axis=1)
|
||||
logger.debug(f"求和计算: {list(numeric_columns)} -> {target_column}")
|
||||
|
||||
return df
|
||||
|
||||
def _aggregate(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""聚合计算
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
group_by = rule.get('group_by')
|
||||
aggregations = rule.get('aggregations', {})
|
||||
|
||||
if group_by and group_by in df.columns:
|
||||
# 构建聚合函数字典
|
||||
agg_dict = {}
|
||||
for column, func in aggregations.items():
|
||||
if column in df.columns:
|
||||
if isinstance(func, str):
|
||||
agg_dict[column] = func
|
||||
elif isinstance(func, list):
|
||||
agg_dict[column] = func
|
||||
|
||||
if agg_dict:
|
||||
result = df.groupby(group_by).agg(agg_dict)
|
||||
logger.debug(f"聚合计算: 按 {group_by} 分组, 聚合: {agg_dict}")
|
||||
return result.reset_index()
|
||||
|
||||
return df
|
||||
|
||||
# 便捷方法
|
||||
def multiply(self, source_column: str, target_column: str, factor: float):
|
||||
"""乘法计算"""
|
||||
self.add_rule('multiply', source_column=source_column,
|
||||
target_column=target_column, factor=factor)
|
||||
return self
|
||||
|
||||
def divide(self, source_column: str, target_column: str, divisor: float):
|
||||
"""除法计算"""
|
||||
self.add_rule('divide', source_column=source_column,
|
||||
target_column=target_column, divisor=divisor)
|
||||
return self
|
||||
|
||||
def add(self, columns: Union[str, List[str]], target_column: str, constant: float = 0):
|
||||
"""加法计算"""
|
||||
self.add_rule('add', columns=columns, target_column=target_column, constant=constant)
|
||||
return self
|
||||
|
||||
def subtract(self, minuend: str, target_column: str,
|
||||
subtrahend: Optional[str] = None, constant: float = 0):
|
||||
"""减法计算"""
|
||||
self.add_rule('subtract', minuend=minuend, target_column=target_column,
|
||||
subtrahend=subtrahend, constant=constant)
|
||||
return self
|
||||
|
||||
def formula(self, formula: str, target_column: str):
|
||||
"""公式计算"""
|
||||
self.add_rule('formula', formula=formula, target_column=target_column)
|
||||
return self
|
||||
|
||||
def round_columns(self, columns: Optional[Union[str, List[str]]] = None, decimals: int = 0):
|
||||
"""四舍五入"""
|
||||
self.add_rule('round', columns=columns, decimals=decimals)
|
||||
return self
|
||||
|
||||
def sum_columns(self, columns: Optional[Union[str, List[str]]] = None,
|
||||
target_column: Optional[str] = None, group_by: Optional[str] = None):
|
||||
"""求和计算"""
|
||||
self.add_rule('sum', columns=columns, target_column=target_column, group_by=group_by)
|
||||
return self
|
||||
|
||||
def aggregate(self, group_by: str, aggregations: Dict[str, Union[str, List[str]]]):
|
||||
"""聚合计算"""
|
||||
self.add_rule('aggregate', group_by=group_by, aggregations=aggregations)
|
||||
return self
|
||||
276
app/core/handlers/column_mapper.py
Normal file
276
app/core/handlers/column_mapper.py
Normal file
@ -0,0 +1,276 @@
|
||||
"""
|
||||
列映射处理器
|
||||
|
||||
提供列名映射和转换功能,支持不同供应商的列名标准化
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from typing import Dict, Any, Optional, List, Union
|
||||
from ...core.utils.log_utils import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class ColumnMapper:
|
||||
"""列映射处理器
|
||||
|
||||
提供列名标准化功能,将不同供应商的列名映射到标准列名
|
||||
"""
|
||||
|
||||
# 标准列名定义
|
||||
STANDARD_COLUMNS = {
|
||||
'barcode': ['条码', '条形码', '商品条码', '产品条码', '条码(必填)', 'barcode', 'code'],
|
||||
'name': ['商品名称', '产品名称', '名称', '商品', '产品', 'name', 'product_name'],
|
||||
'specification': ['规格', '规格型号', '型号', 'specification', 'spec', 'model'],
|
||||
'quantity': ['数量', '采购量', '订货数量', '订单量', '需求量', 'quantity', 'qty', '采购量(必填)'],
|
||||
'unit': ['单位', '计量单位', 'unit', 'units'],
|
||||
'unit_price': ['单价', '价格', '采购单价', '进货价', 'unit_price', 'price', '采购单价(必填)'],
|
||||
'total_price': ['总价', '金额', '小计', 'total_price', 'total', 'amount'],
|
||||
'category': ['类别', '分类', '商品类别', 'category', 'type'],
|
||||
'brand': ['品牌', '商标', 'brand'],
|
||||
'supplier': ['供应商', '供货商', 'supplier', 'vendor']
|
||||
}
|
||||
|
||||
def __init__(self, mapping_config: Optional[Dict[str, Any]] = None):
|
||||
"""初始化列映射器
|
||||
|
||||
Args:
|
||||
mapping_config: 映射配置
|
||||
"""
|
||||
self.mapping_config = mapping_config or {}
|
||||
self.custom_mappings = {}
|
||||
self._build_reverse_mapping()
|
||||
|
||||
def _build_reverse_mapping(self):
|
||||
"""构建反向映射表"""
|
||||
self.reverse_mapping = {}
|
||||
|
||||
# 添加标准列的反向映射
|
||||
for standard_name, variations in self.STANDARD_COLUMNS.items():
|
||||
for variation in variations:
|
||||
self.reverse_mapping[variation.lower()] = standard_name
|
||||
|
||||
# 添加自定义映射
|
||||
for standard_name, custom_names in self.mapping_config.items():
|
||||
if isinstance(custom_names, str):
|
||||
custom_names = [custom_names]
|
||||
|
||||
for custom_name in custom_names:
|
||||
self.reverse_mapping[custom_name.lower()] = standard_name
|
||||
self.custom_mappings[custom_name.lower()] = standard_name
|
||||
|
||||
def map_columns(self, df: pd.DataFrame, target_columns: Optional[List[str]] = None) -> pd.DataFrame:
|
||||
"""映射列名
|
||||
|
||||
Args:
|
||||
df: 输入数据
|
||||
target_columns: 目标列名列表,如果为None则使用所有标准列
|
||||
|
||||
Returns:
|
||||
列名映射后的数据
|
||||
"""
|
||||
if target_columns is None:
|
||||
target_columns = list(self.STANDARD_COLUMNS.keys())
|
||||
|
||||
logger.info(f"开始列名映射,目标列: {target_columns}")
|
||||
logger.info(f"原始列名: {list(df.columns)}")
|
||||
|
||||
# 创建列名映射
|
||||
column_mapping = {}
|
||||
used_columns = set()
|
||||
|
||||
for target_col in target_columns:
|
||||
# 查找匹配的原始列名
|
||||
matched_column = self._find_matching_column(df.columns, target_col)
|
||||
if matched_column:
|
||||
column_mapping[matched_column] = target_col
|
||||
used_columns.add(matched_column)
|
||||
logger.debug(f"列名映射: {matched_column} -> {target_col}")
|
||||
|
||||
# 重命名列
|
||||
if column_mapping:
|
||||
df_mapped = df.rename(columns=column_mapping)
|
||||
|
||||
# 添加缺失的目标列
|
||||
for target_col in target_columns:
|
||||
if target_col not in df_mapped.columns:
|
||||
df_mapped[target_col] = self._get_default_value(target_col)
|
||||
logger.debug(f"添加缺失列: {target_col}")
|
||||
|
||||
# 只保留目标列
|
||||
existing_target_columns = [col for col in target_columns if col in df_mapped.columns]
|
||||
df_result = df_mapped[existing_target_columns]
|
||||
|
||||
logger.info(f"列名映射完成,结果列名: {list(df_result.columns)}")
|
||||
return df_result
|
||||
else:
|
||||
logger.warning("没有找到可映射的列名")
|
||||
return df
|
||||
|
||||
def _find_matching_column(self, columns: List[str], target_column: str) -> Optional[str]:
|
||||
"""查找匹配的列名
|
||||
|
||||
Args:
|
||||
columns: 原始列名列表
|
||||
target_column: 目标标准列名
|
||||
|
||||
Returns:
|
||||
匹配的原始列名或None
|
||||
"""
|
||||
# 获取目标列的所有可能变体
|
||||
possible_names = []
|
||||
|
||||
# 标准列名变体
|
||||
if target_column in self.STANDARD_COLUMNS:
|
||||
possible_names.extend(self.STANDARD_COLUMNS[target_column])
|
||||
|
||||
# 自定义映射
|
||||
for standard_name, custom_names in self.mapping_config.items():
|
||||
if standard_name == target_column:
|
||||
if isinstance(custom_names, str):
|
||||
possible_names.append(custom_names)
|
||||
else:
|
||||
possible_names.extend(custom_names)
|
||||
|
||||
# 查找匹配
|
||||
for possible_name in possible_names:
|
||||
# 精确匹配(忽略大小写)
|
||||
for column in columns:
|
||||
if column.lower() == possible_name.lower():
|
||||
return column
|
||||
|
||||
# 模糊匹配
|
||||
for column in columns:
|
||||
if possible_name.lower() in column.lower() or column.lower() in possible_name.lower():
|
||||
return column
|
||||
|
||||
return None
|
||||
|
||||
def _get_default_value(self, column_name: str) -> Any:
|
||||
"""获取列的默认值
|
||||
|
||||
Args:
|
||||
column_name: 列名
|
||||
|
||||
Returns:
|
||||
默认值
|
||||
"""
|
||||
# 根据列名类型返回合适的默认值
|
||||
if column_name in ['quantity', 'unit_price', 'total_price']:
|
||||
return 0
|
||||
elif column_name in ['barcode', 'name', 'specification', 'unit', 'category', 'brand', 'supplier']:
|
||||
return ''
|
||||
else:
|
||||
return None
|
||||
|
||||
def add_custom_mapping(self, standard_name: str, custom_names: Union[str, List[str]]):
|
||||
"""添加自定义列名映射
|
||||
|
||||
Args:
|
||||
standard_name: 标准列名
|
||||
custom_names: 自定义列名或列名列表
|
||||
"""
|
||||
if isinstance(custom_names, str):
|
||||
custom_names = [custom_names]
|
||||
|
||||
# 更新配置
|
||||
self.mapping_config[standard_name] = custom_names
|
||||
|
||||
# 更新反向映射
|
||||
for custom_name in custom_names:
|
||||
self.reverse_mapping[custom_name.lower()] = standard_name
|
||||
self.custom_mappings[custom_name.lower()] = standard_name
|
||||
|
||||
logger.info(f"添加自定义映射: {standard_name} <- {custom_names}")
|
||||
|
||||
def detect_column_types(self, df: pd.DataFrame) -> Dict[str, str]:
|
||||
"""检测列的数据类型
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
|
||||
Returns:
|
||||
列类型字典
|
||||
"""
|
||||
column_types = {}
|
||||
|
||||
for column in df.columns:
|
||||
if pd.api.types.is_numeric_dtype(df[column]):
|
||||
column_types[column] = 'numeric'
|
||||
elif pd.api.types.is_datetime64_any_dtype(df[column]):
|
||||
column_types[column] = 'datetime'
|
||||
elif pd.api.types.is_bool_dtype(df[column]):
|
||||
column_types[column] = 'boolean'
|
||||
else:
|
||||
column_types[column] = 'text'
|
||||
|
||||
return column_types
|
||||
|
||||
def suggest_column_mapping(self, df: pd.DataFrame) -> Dict[str, List[str]]:
|
||||
"""建议列名映射
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
|
||||
Returns:
|
||||
建议的映射关系
|
||||
"""
|
||||
suggestions = {}
|
||||
|
||||
for column in df.columns:
|
||||
column_lower = column.lower()
|
||||
suggestions[column] = []
|
||||
|
||||
# 检查标准列名
|
||||
for standard_name, variations in self.STANDARD_COLUMNS.items():
|
||||
for variation in variations:
|
||||
if column_lower in variation.lower() or variation.lower() in column_lower:
|
||||
suggestions[column].append(standard_name)
|
||||
|
||||
# 检查自定义映射
|
||||
for custom_name, standard_name in self.custom_mappings.items():
|
||||
if column_lower in custom_name or custom_name in column_lower:
|
||||
suggestions[column].append(standard_name)
|
||||
|
||||
# 去重
|
||||
suggestions[column] = list(set(suggestions[column]))
|
||||
|
||||
# 只返回有建议的列
|
||||
return {k: v for k, v in suggestions.items() if v}
|
||||
|
||||
def validate_mapping(self, df: pd.DataFrame, required_columns: List[str]) -> Dict[str, Any]:
|
||||
"""验证列映射结果
|
||||
|
||||
Args:
|
||||
df: 映射后的数据
|
||||
required_columns: 必需的列名列表
|
||||
|
||||
Returns:
|
||||
验证结果
|
||||
"""
|
||||
result = {
|
||||
'valid': True,
|
||||
'missing_columns': [],
|
||||
'empty_columns': [],
|
||||
'warnings': []
|
||||
}
|
||||
|
||||
# 检查缺失列
|
||||
for col in required_columns:
|
||||
if col not in df.columns:
|
||||
result['missing_columns'].append(col)
|
||||
result['valid'] = False
|
||||
|
||||
# 检查空列
|
||||
for col in df.columns:
|
||||
if df[col].isnull().all():
|
||||
result['empty_columns'].append(col)
|
||||
result['warnings'].append(f"列 '{col}' 全部为空值")
|
||||
|
||||
# 检查数值列
|
||||
numeric_columns = ['quantity', 'unit_price', 'total_price']
|
||||
for col in numeric_columns:
|
||||
if col in df.columns and not pd.api.types.is_numeric_dtype(df[col]):
|
||||
result['warnings'].append(f"列 '{col}' 不是数值类型")
|
||||
|
||||
return result
|
||||
401
app/core/handlers/data_cleaner.py
Normal file
401
app/core/handlers/data_cleaner.py
Normal file
@ -0,0 +1,401 @@
|
||||
"""
|
||||
数据清洗处理器
|
||||
|
||||
提供各种数据清洗功能,如空值处理、重复项处理、数据类型转换等
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
from typing import Dict, Any, Optional, List, Union
|
||||
from ...core.utils.log_utils import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class DataCleaner:
|
||||
"""数据清洗处理器
|
||||
|
||||
提供标准化的数据清洗功能,支持链式调用和规则配置
|
||||
"""
|
||||
|
||||
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
||||
"""初始化数据清洗器
|
||||
|
||||
Args:
|
||||
config: 清洗配置
|
||||
"""
|
||||
self.config = config or {}
|
||||
self.cleaning_rules = []
|
||||
|
||||
def add_rule(self, rule_type: str, **kwargs):
|
||||
"""添加清洗规则
|
||||
|
||||
Args:
|
||||
rule_type: 规则类型
|
||||
**kwargs: 规则参数
|
||||
"""
|
||||
rule = {'type': rule_type, **kwargs}
|
||||
self.cleaning_rules.append(rule)
|
||||
logger.debug(f"添加清洗规则: {rule_type}")
|
||||
|
||||
def clean(self, df: pd.DataFrame) -> pd.DataFrame:
|
||||
"""执行数据清洗
|
||||
|
||||
Args:
|
||||
df: 输入数据
|
||||
|
||||
Returns:
|
||||
清洗后的数据
|
||||
"""
|
||||
logger.info(f"开始数据清洗,原始数据形状: {df.shape}")
|
||||
|
||||
result_df = df.copy()
|
||||
|
||||
for i, rule in enumerate(self.cleaning_rules):
|
||||
try:
|
||||
logger.debug(f"执行清洗规则 {i+1}/{len(self.cleaning_rules)}: {rule['type']}")
|
||||
result_df = self._apply_rule(result_df, rule)
|
||||
logger.debug(f"规则执行完成,数据形状: {result_df.shape}")
|
||||
except Exception as e:
|
||||
logger.error(f"清洗规则执行失败: {rule}, 错误: {e}")
|
||||
# 继续执行下一个规则,而不是中断整个流程
|
||||
continue
|
||||
|
||||
logger.info(f"数据清洗完成,最终数据形状: {result_df.shape}")
|
||||
return result_df
|
||||
|
||||
def _apply_rule(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""应用单个清洗规则
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
rule_type = rule.get('type')
|
||||
|
||||
if rule_type == 'remove_duplicates':
|
||||
return self._remove_duplicates(df, rule)
|
||||
elif rule_type == 'fill_na':
|
||||
return self._fill_na(df, rule)
|
||||
elif rule_type == 'remove_rows':
|
||||
return self._remove_rows(df, rule)
|
||||
elif rule_type == 'convert_type':
|
||||
return self._convert_type(df, rule)
|
||||
elif rule_type == 'strip_whitespace':
|
||||
return self._strip_whitespace(df, rule)
|
||||
elif rule_type == 'normalize_text':
|
||||
return self._normalize_text(df, rule)
|
||||
elif rule_type == 'validate_data':
|
||||
return self._validate_data(df, rule)
|
||||
else:
|
||||
logger.warning(f"未知的清洗规则类型: {rule_type}")
|
||||
return df
|
||||
|
||||
def _remove_duplicates(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""移除重复项
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
subset = rule.get('subset') # 用于判断重复的列
|
||||
keep = rule.get('keep', 'first') # 保留哪个重复项
|
||||
|
||||
before_count = len(df)
|
||||
df_cleaned = df.drop_duplicates(subset=subset, keep=keep)
|
||||
after_count = len(df_cleaned)
|
||||
|
||||
logger.info(f"移除重复项: {before_count - after_count} 行被移除")
|
||||
return df_cleaned
|
||||
|
||||
def _fill_na(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""填充空值
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
columns = rule.get('columns') # 要处理的列
|
||||
value = rule.get('value', 0) # 填充值
|
||||
method = rule.get('method') # 填充方法('ffill', 'bfill', 'mean', 'median')
|
||||
|
||||
if columns:
|
||||
# 处理指定列
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
|
||||
for col in columns:
|
||||
if col in df.columns:
|
||||
if method == 'ffill':
|
||||
df[col] = df[col].fillna(method='ffill')
|
||||
elif method == 'bfill':
|
||||
df[col] = df[col].fillna(method='bfill')
|
||||
elif method == 'mean':
|
||||
df[col] = df[col].fillna(df[col].mean())
|
||||
elif method == 'median':
|
||||
df[col] = df[col].fillna(df[col].median())
|
||||
else:
|
||||
df[col] = df[col].fillna(value)
|
||||
|
||||
logger.debug(f"填充列 {col} 的空值: {method or value}")
|
||||
else:
|
||||
# 处理所有列
|
||||
if method == 'ffill':
|
||||
df = df.fillna(method='ffill')
|
||||
elif method == 'bfill':
|
||||
df = df.fillna(method='bfill')
|
||||
else:
|
||||
df = df.fillna(value)
|
||||
|
||||
logger.debug(f"填充所有列的空值: {method or value}")
|
||||
|
||||
return df
|
||||
|
||||
def _remove_rows(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""移除行
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
condition = rule.get('condition') # 条件表达式
|
||||
columns = rule.get('columns') # 要检查的列
|
||||
values = rule.get('values') # 要移除的值
|
||||
|
||||
if condition:
|
||||
# 使用条件表达式
|
||||
try:
|
||||
before_count = len(df)
|
||||
df_filtered = df.query(condition)
|
||||
after_count = len(df_filtered)
|
||||
logger.info(f"条件过滤: {condition}, 移除了 {before_count - after_count} 行")
|
||||
return df_filtered
|
||||
except Exception as e:
|
||||
logger.error(f"条件表达式执行失败: {condition}, 错误: {e}")
|
||||
return df
|
||||
|
||||
if columns and values:
|
||||
# 基于列值过滤
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
if not isinstance(values, list):
|
||||
values = [values]
|
||||
|
||||
df_filtered = df.copy()
|
||||
for col in columns:
|
||||
if col in df_filtered.columns:
|
||||
mask = ~df_filtered[col].isin(values)
|
||||
df_filtered = df_filtered[mask]
|
||||
logger.debug(f"列 {col} 过滤值 {values}")
|
||||
|
||||
return df_filtered
|
||||
|
||||
logger.warning("移除行规则缺少条件或列配置")
|
||||
return df
|
||||
|
||||
def _convert_type(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""类型转换
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
columns = rule.get('columns')
|
||||
target_type = rule.get('target_type', 'float')
|
||||
errors = rule.get('errors', 'coerce') # 错误处理方式
|
||||
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
|
||||
for col in columns:
|
||||
if col in df.columns:
|
||||
try:
|
||||
if target_type == 'int':
|
||||
df[col] = pd.to_numeric(df[col], errors=errors).astype('Int64')
|
||||
elif target_type == 'float':
|
||||
df[col] = pd.to_numeric(df[col], errors=errors)
|
||||
elif target_type == 'datetime':
|
||||
df[col] = pd.to_datetime(df[col], errors=errors)
|
||||
elif target_type == 'string':
|
||||
df[col] = df[col].astype(str)
|
||||
else:
|
||||
df[col] = df[col].astype(target_type)
|
||||
|
||||
logger.debug(f"列 {col} 类型转换: {target_type}")
|
||||
except Exception as e:
|
||||
logger.error(f"列 {col} 类型转换失败: {e}")
|
||||
|
||||
return df
|
||||
|
||||
def _strip_whitespace(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""去除空白字符
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
columns = rule.get('columns')
|
||||
|
||||
if columns:
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
|
||||
for col in columns:
|
||||
if col in df.columns and df[col].dtype == 'object':
|
||||
df[col] = df[col].str.strip()
|
||||
logger.debug(f"列 {col} 去除空白字符")
|
||||
else:
|
||||
# 处理所有文本列
|
||||
text_columns = df.select_dtypes(include=['object']).columns
|
||||
for col in text_columns:
|
||||
df[col] = df[col].str.strip()
|
||||
|
||||
logger.debug(f"所有文本列去除空白字符: {list(text_columns)}")
|
||||
|
||||
return df
|
||||
|
||||
def _normalize_text(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""文本标准化
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
columns = rule.get('columns')
|
||||
lowercase = rule.get('lowercase', False)
|
||||
uppercase = rule.get('uppercase', False)
|
||||
replace_map = rule.get('replace_map', {}) # 替换映射
|
||||
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
|
||||
target_columns = columns or df.select_dtypes(include=['object']).columns
|
||||
|
||||
for col in target_columns:
|
||||
if col in df.columns and df[col].dtype == 'object':
|
||||
if lowercase:
|
||||
df[col] = df[col].str.lower()
|
||||
elif uppercase:
|
||||
df[col] = df[col].str.upper()
|
||||
|
||||
# 应用替换映射
|
||||
for old, new in replace_map.items():
|
||||
df[col] = df[col].str.replace(old, new)
|
||||
|
||||
logger.debug(f"列 {col} 文本标准化完成")
|
||||
|
||||
return df
|
||||
|
||||
def _validate_data(self, df: pd.DataFrame, rule: Dict[str, Any]) -> pd.DataFrame:
|
||||
"""数据验证
|
||||
|
||||
Args:
|
||||
df: 数据
|
||||
rule: 规则配置
|
||||
|
||||
Returns:
|
||||
处理后的数据
|
||||
"""
|
||||
columns = rule.get('columns')
|
||||
min_value = rule.get('min_value')
|
||||
max_value = rule.get('max_value')
|
||||
required = rule.get('required', False)
|
||||
|
||||
if isinstance(columns, str):
|
||||
columns = [columns]
|
||||
|
||||
validation_results = []
|
||||
|
||||
for col in columns:
|
||||
if col in df.columns:
|
||||
# 检查必需值
|
||||
if required:
|
||||
null_count = df[col].isnull().sum()
|
||||
if null_count > 0:
|
||||
validation_results.append(f"{col}: {null_count} 个空值")
|
||||
|
||||
# 检查数值范围
|
||||
if min_value is not None or max_value is not None:
|
||||
if pd.api.types.is_numeric_dtype(df[col]):
|
||||
invalid_mask = pd.Series(False, index=df.index)
|
||||
if min_value is not None:
|
||||
invalid_mask |= df[col] < min_value
|
||||
if max_value is not None:
|
||||
invalid_mask |= df[col] > max_value
|
||||
|
||||
invalid_count = invalid_mask.sum()
|
||||
if invalid_count > 0:
|
||||
validation_results.append(f"{col}: {invalid_count} 个值超出范围")
|
||||
|
||||
if validation_results:
|
||||
logger.warning(f"数据验证发现问题: {', '.join(validation_results)}")
|
||||
else:
|
||||
logger.debug("数据验证通过")
|
||||
|
||||
return df
|
||||
|
||||
# 便捷方法
|
||||
def remove_duplicates(self, subset: Optional[List[str]] = None, keep: str = 'first'):
|
||||
"""移除重复项"""
|
||||
self.add_rule('remove_duplicates', subset=subset, keep=keep)
|
||||
return self
|
||||
|
||||
def fill_na(self, columns: Optional[Union[str, List[str]]] = None,
|
||||
value: Any = 0, method: Optional[str] = None):
|
||||
"""填充空值"""
|
||||
self.add_rule('fill_na', columns=columns, value=value, method=method)
|
||||
return self
|
||||
|
||||
def remove_rows(self, condition: Optional[str] = None,
|
||||
columns: Optional[Union[str, List[str]]] = None,
|
||||
values: Optional[Any] = None):
|
||||
"""移除行"""
|
||||
self.add_rule('remove_rows', condition=condition, columns=columns, values=values)
|
||||
return self
|
||||
|
||||
def convert_type(self, columns: Union[str, List[str]], target_type: str, errors: str = 'coerce'):
|
||||
"""类型转换"""
|
||||
self.add_rule('convert_type', columns=columns, target_type=target_type, errors=errors)
|
||||
return self
|
||||
|
||||
def strip_whitespace(self, columns: Optional[Union[str, List[str]]] = None):
|
||||
"""去除空白字符"""
|
||||
self.add_rule('strip_whitespace', columns=columns)
|
||||
return self
|
||||
|
||||
def normalize_text(self, columns: Optional[Union[str, List[str]]] = None,
|
||||
lowercase: bool = False, uppercase: bool = False,
|
||||
replace_map: Optional[Dict[str, str]] = None):
|
||||
"""文本标准化"""
|
||||
self.add_rule('normalize_text', columns=columns, lowercase=lowercase,
|
||||
uppercase=uppercase, replace_map=replace_map or {})
|
||||
return self
|
||||
|
||||
def validate_data(self, columns: Union[str, List[str]],
|
||||
min_value: Optional[float] = None,
|
||||
max_value: Optional[float] = None,
|
||||
required: bool = False):
|
||||
"""数据验证"""
|
||||
self.add_rule('validate_data', columns=columns, min_value=min_value,
|
||||
max_value=max_value, required=required)
|
||||
return self
|
||||
@ -11,7 +11,7 @@ import json
|
||||
import base64
|
||||
from datetime import datetime
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
|
||||
|
||||
from ...config.settings import ConfigManager
|
||||
from ..utils.log_utils import get_logger
|
||||
@ -332,7 +332,7 @@ class OCRProcessor:
|
||||
logger.error(f"处理图片时出错: {image_path}, 错误: {e}")
|
||||
return None
|
||||
|
||||
def process_images_batch(self, batch_size: int = None, max_workers: int = None) -> Tuple[int, int]:
|
||||
def process_images_batch(self, batch_size: int = None, max_workers: int = None, progress_cb: Optional[Callable[[int], None]] = None) -> Tuple[int, int]:
|
||||
"""
|
||||
批量处理图片
|
||||
|
||||
@ -369,6 +369,13 @@ class OCRProcessor:
|
||||
for i in range(0, total, batch_size):
|
||||
batch = unprocessed_images[i:i+batch_size]
|
||||
logger.info(f"处理批次 {i//batch_size+1}/{(total+batch_size-1)//batch_size}: {len(batch)} 个文件")
|
||||
try:
|
||||
if progress_cb:
|
||||
# 以批次为单位估算进度(0-90%),保留10%给后续阶段
|
||||
percent = int(10 + (i / max(total, 1)) * 80)
|
||||
progress_cb(min(percent, 90))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 使用多线程处理批次
|
||||
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||
@ -378,4 +385,9 @@ class OCRProcessor:
|
||||
success_count += sum(1 for result in results if result is not None)
|
||||
|
||||
logger.info(f"所有图片处理完成, 总计: {total}, 成功: {success_count}")
|
||||
try:
|
||||
if progress_cb:
|
||||
progress_cb(90)
|
||||
except Exception:
|
||||
pass
|
||||
return total, success_count
|
||||
|
||||
9
app/core/processors/__init__.py
Normal file
9
app/core/processors/__init__.py
Normal file
@ -0,0 +1,9 @@
|
||||
"""
|
||||
处理器模块初始化文件
|
||||
"""
|
||||
|
||||
from .base import BaseProcessor
|
||||
from .ocr_processor import OCRProcessor
|
||||
from .tobacco_processor import TobaccoProcessor
|
||||
|
||||
__all__ = ['BaseProcessor', 'OCRProcessor', 'TobaccoProcessor']
|
||||
139
app/core/processors/base.py
Normal file
139
app/core/processors/base.py
Normal file
@ -0,0 +1,139 @@
|
||||
"""
|
||||
基础处理器接口模块
|
||||
|
||||
定义所有处理器的基类,提供统一的处理接口
|
||||
"""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Dict, Any, Optional, List
|
||||
from pathlib import Path
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BaseProcessor(ABC):
|
||||
"""基础处理器接口 - 所有处理器的基类
|
||||
|
||||
采用策略模式设计,每个处理器负责特定类型的文件处理
|
||||
"""
|
||||
|
||||
def __init__(self, config: Dict[str, Any]):
|
||||
"""初始化处理器
|
||||
|
||||
Args:
|
||||
config: 处理器配置字典
|
||||
"""
|
||||
self.config = config
|
||||
self.name = self.__class__.__name__
|
||||
self.description = ""
|
||||
self._setup_logging()
|
||||
|
||||
def _setup_logging(self):
|
||||
"""设置处理器日志"""
|
||||
self.logger = logging.getLogger(f"{__name__}.{self.name}")
|
||||
|
||||
@abstractmethod
|
||||
def can_process(self, file_path: Path) -> bool:
|
||||
"""判断是否能处理该文件
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
是否能处理该文件
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def process(self, input_file: Path, output_dir: Path) -> Optional[Path]:
|
||||
"""处理文件,返回输出文件路径
|
||||
|
||||
Args:
|
||||
input_file: 输入文件路径
|
||||
output_dir: 输出目录路径
|
||||
|
||||
Returns:
|
||||
输出文件路径,处理失败返回None
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_required_columns(self) -> List[str]:
|
||||
"""返回需要的列名列表
|
||||
|
||||
Returns:
|
||||
列名列表
|
||||
"""
|
||||
pass
|
||||
|
||||
def validate_input(self, file_path: Path) -> bool:
|
||||
"""验证输入文件有效性
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
文件是否有效
|
||||
"""
|
||||
try:
|
||||
if not file_path.exists():
|
||||
self.logger.warning(f"文件不存在: {file_path}")
|
||||
return False
|
||||
|
||||
if not file_path.is_file():
|
||||
self.logger.warning(f"不是文件: {file_path}")
|
||||
return False
|
||||
|
||||
supported_extensions = self.get_supported_extensions()
|
||||
if supported_extensions and file_path.suffix.lower() not in supported_extensions:
|
||||
self.logger.warning(f"不支持的文件类型: {file_path.suffix}, 支持的类型: {supported_extensions}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"验证文件时出错: {e}")
|
||||
return False
|
||||
|
||||
def get_supported_extensions(self) -> List[str]:
|
||||
"""获取支持的文件扩展名
|
||||
|
||||
Returns:
|
||||
支持的扩展名列表,空列表表示支持所有类型
|
||||
"""
|
||||
return []
|
||||
|
||||
def get_output_filename(self, input_file: Path, suffix: str = "_processed") -> str:
|
||||
"""生成输出文件名
|
||||
|
||||
Args:
|
||||
input_file: 输入文件路径
|
||||
suffix: 文件名后缀
|
||||
|
||||
Returns:
|
||||
输出文件名
|
||||
"""
|
||||
return f"{input_file.stem}{suffix}{input_file.suffix}"
|
||||
|
||||
def log_processing_start(self, input_file: Path):
|
||||
"""记录处理开始日志"""
|
||||
self.logger.info(f"开始处理文件: {input_file}")
|
||||
self.logger.info(f"处理器: {self.name} - {self.description}")
|
||||
|
||||
def log_processing_end(self, input_file: Path, output_file: Optional[Path] = None, success: bool = True):
|
||||
"""记录处理结束日志"""
|
||||
if success:
|
||||
self.logger.info(f"处理完成: {input_file}")
|
||||
if output_file:
|
||||
self.logger.info(f"输出文件: {output_file}")
|
||||
else:
|
||||
self.logger.error(f"处理失败: {input_file}")
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""字符串表示"""
|
||||
return f"{self.name}({self.description})"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""详细字符串表示"""
|
||||
return f"{self.__class__.__module__}.{self.__class__.__name__}(name='{self.name}', description='{self.description}')"
|
||||
192
app/core/processors/ocr_processor.py
Normal file
192
app/core/processors/ocr_processor.py
Normal file
@ -0,0 +1,192 @@
|
||||
"""
|
||||
OCR处理器
|
||||
|
||||
处理图片文件的OCR识别完整流程:图片识别 → Excel处理 → 标准采购单生成
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Optional, Dict, Any, List
|
||||
|
||||
from .base import BaseProcessor
|
||||
from ...services.ocr_service import OCRService
|
||||
from ...services.order_service import OrderService
|
||||
from ...core.utils.log_utils import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class OCRProcessor(BaseProcessor):
|
||||
"""OCR处理器
|
||||
|
||||
处理图片文件的完整OCR识别流程:
|
||||
1. OCR识别图片中的表格信息
|
||||
2. 处理识别结果生成Excel文件
|
||||
3. 转换为标准采购单格式
|
||||
"""
|
||||
|
||||
def __init__(self, config: Dict[str, Any]):
|
||||
"""初始化OCR处理器
|
||||
|
||||
Args:
|
||||
config: 配置信息
|
||||
"""
|
||||
super().__init__(config)
|
||||
self.description = "OCR识别完整流程(图片→识别→Excel→采购单)"
|
||||
|
||||
# 初始化服务
|
||||
self.ocr_service = OCRService(config)
|
||||
self.order_service = OrderService(config)
|
||||
|
||||
def can_process(self, file_path: Path) -> bool:
|
||||
"""判断是否为支持的图片文件
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
是否能处理该文件
|
||||
"""
|
||||
if not self.validate_input(file_path):
|
||||
return False
|
||||
|
||||
# 支持的图片格式
|
||||
supported_extensions = ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
|
||||
if file_path.suffix.lower() in supported_extensions:
|
||||
self.logger.info(f"识别为图片文件: {file_path.name}")
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def process(self, input_file: Path, output_dir: Path) -> Optional[Path]:
|
||||
"""处理图片文件的完整OCR流程
|
||||
|
||||
Args:
|
||||
input_file: 输入图片文件路径
|
||||
output_dir: 输出目录路径
|
||||
|
||||
Returns:
|
||||
输出文件路径,处理失败返回None
|
||||
"""
|
||||
self.log_processing_start(input_file)
|
||||
|
||||
try:
|
||||
self.logger.info("开始OCR识别流程...")
|
||||
|
||||
# 步骤1: OCR识别
|
||||
self.logger.info("步骤1/3: OCR识别图片...")
|
||||
ocr_result = self._perform_ocr(input_file, output_dir)
|
||||
if not ocr_result:
|
||||
self.logger.error("OCR识别失败")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
# 步骤2: Excel处理
|
||||
self.logger.info("步骤2/3: 处理Excel文件...")
|
||||
excel_result = self._process_excel(ocr_result, output_dir)
|
||||
if not excel_result:
|
||||
self.logger.error("Excel处理失败")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
# 步骤3: 生成标准采购单
|
||||
self.logger.info("步骤3/3: 生成标准采购单...")
|
||||
final_result = self._generate_purchase_order(excel_result, output_dir)
|
||||
|
||||
if final_result:
|
||||
self.logger.info(f"OCR处理流程完成,输出文件: {final_result}")
|
||||
self.log_processing_end(input_file, final_result, success=True)
|
||||
return final_result
|
||||
else:
|
||||
self.logger.error("生成采购单失败")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"OCR处理流程出错: {e}", exc_info=True)
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
def get_required_columns(self) -> List[str]:
|
||||
"""返回需要的列名列表"""
|
||||
# OCR处理不直接依赖列名,由后续处理步骤决定
|
||||
return []
|
||||
|
||||
def get_supported_extensions(self) -> List[str]:
|
||||
"""支持的文件扩展名"""
|
||||
return ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
|
||||
def _perform_ocr(self, input_file: Path, output_dir: Path) -> Optional[Path]:
|
||||
"""执行OCR识别
|
||||
|
||||
Args:
|
||||
input_file: 输入图片文件
|
||||
output_dir: 输出目录
|
||||
|
||||
Returns:
|
||||
OCR生成的Excel文件路径,失败返回None
|
||||
"""
|
||||
try:
|
||||
self.logger.info(f"开始OCR识别: {input_file}")
|
||||
|
||||
# 使用OCR服务处理图片
|
||||
result_path = self.ocr_service.process_image(str(input_file))
|
||||
|
||||
if result_path:
|
||||
# 确保结果文件在输出目录中
|
||||
result_path = Path(result_path)
|
||||
if result_path.exists():
|
||||
self.logger.info(f"OCR识别成功,输出文件: {result_path}")
|
||||
return result_path
|
||||
else:
|
||||
self.logger.error(f"OCR结果文件不存在: {result_path}")
|
||||
return None
|
||||
else:
|
||||
self.logger.error("OCR服务返回None")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"OCR识别失败: {e}", exc_info=True)
|
||||
return None
|
||||
|
||||
def _process_excel(self, excel_file: Path, output_dir: Path) -> Optional[Path]:
|
||||
"""处理Excel文件
|
||||
|
||||
Args:
|
||||
excel_file: Excel文件路径
|
||||
output_dir: 输出目录
|
||||
|
||||
Returns:
|
||||
处理后的Excel文件路径,失败返回None
|
||||
"""
|
||||
try:
|
||||
self.logger.info(f"开始处理Excel文件: {excel_file}")
|
||||
|
||||
# 使用订单服务处理Excel文件(生成采购单)
|
||||
result_path = self.order_service.process_excel(str(excel_file))
|
||||
|
||||
if result_path:
|
||||
result_path = Path(result_path)
|
||||
if result_path.exists():
|
||||
self.logger.info(f"Excel处理成功,输出文件: {result_path}")
|
||||
return result_path
|
||||
else:
|
||||
self.logger.error(f"Excel处理结果文件不存在: {result_path}")
|
||||
return None
|
||||
else:
|
||||
self.logger.error("Excel处理服务返回None")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Excel处理失败: {e}", exc_info=True)
|
||||
return None
|
||||
|
||||
def _generate_purchase_order(self, processed_file: Path, output_dir: Path) -> Optional[Path]:
|
||||
"""采购单生成由OrderService完成,此处直接返回处理结果"""
|
||||
try:
|
||||
if processed_file and processed_file.exists():
|
||||
return processed_file
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
7
app/core/processors/supplier_processors/__init__.py
Normal file
7
app/core/processors/supplier_processors/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
"""
|
||||
供应商处理器模块初始化文件
|
||||
"""
|
||||
|
||||
from .generic_supplier_processor import GenericSupplierProcessor
|
||||
|
||||
__all__ = ['GenericSupplierProcessor']
|
||||
@ -0,0 +1,430 @@
|
||||
"""
|
||||
通用供应商处理器
|
||||
|
||||
可配置化的供应商处理器,支持通过配置文件定义处理规则
|
||||
"""
|
||||
|
||||
import fnmatch
|
||||
import pandas as pd
|
||||
from typing import Optional, Dict, Any, List
|
||||
from pathlib import Path
|
||||
|
||||
from ..base import BaseProcessor
|
||||
from ...utils.log_utils import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class GenericSupplierProcessor(BaseProcessor):
|
||||
"""通用供应商处理器
|
||||
|
||||
基于配置文件处理不同供应商的Excel文件,支持:
|
||||
- 文件名模式匹配
|
||||
- 内容特征识别
|
||||
- 列映射配置
|
||||
- 数据清洗规则
|
||||
- 计算处理规则
|
||||
"""
|
||||
|
||||
def __init__(self, config: Dict[str, Any], supplier_config: Dict[str, Any]):
|
||||
"""初始化通用供应商处理器
|
||||
|
||||
Args:
|
||||
config: 系统配置
|
||||
supplier_config: 供应商特定配置
|
||||
"""
|
||||
super().__init__(config)
|
||||
self.supplier_config = supplier_config
|
||||
|
||||
# 从配置中提取基本信息
|
||||
self.name = supplier_config.get('name', 'GenericSupplier')
|
||||
self.description = supplier_config.get('description', '通用供应商处理器')
|
||||
|
||||
# 处理规则配置
|
||||
self.filename_patterns = supplier_config.get('filename_patterns', [])
|
||||
self.content_indicators = supplier_config.get('content_indicators', [])
|
||||
self.column_mapping = supplier_config.get('column_mapping', {})
|
||||
self.cleaning_rules = supplier_config.get('cleaning_rules', [])
|
||||
self.calculations = supplier_config.get('calculations', [])
|
||||
|
||||
# 输出配置
|
||||
self.output_template = supplier_config.get('output_template', 'templates/银豹-采购单模板.xls')
|
||||
self.output_suffix = supplier_config.get('output_suffix', '_银豹采购单')
|
||||
|
||||
def can_process(self, file_path: Path) -> bool:
|
||||
"""判断是否能处理该文件
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
是否能处理
|
||||
"""
|
||||
if not self.validate_input(file_path):
|
||||
return False
|
||||
|
||||
# 检查文件名模式
|
||||
if self.filename_patterns:
|
||||
filename_match = self._check_filename_patterns(file_path)
|
||||
if filename_match:
|
||||
return True
|
||||
|
||||
# 检查文件内容特征
|
||||
if self.content_indicators:
|
||||
content_match = self._check_content_indicators(file_path)
|
||||
if content_match:
|
||||
return True
|
||||
|
||||
# 如果都没有配置,则无法判断
|
||||
if not self.filename_patterns and not self.content_indicators:
|
||||
self.logger.warning(f"处理器 {self.name} 没有配置识别规则")
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def process(self, input_file: Path, output_dir: Path) -> Optional[Path]:
|
||||
"""处理文件
|
||||
|
||||
Args:
|
||||
input_file: 输入文件路径
|
||||
output_dir: 输出目录路径
|
||||
|
||||
Returns:
|
||||
输出文件路径,处理失败返回None
|
||||
"""
|
||||
self.log_processing_start(input_file)
|
||||
|
||||
try:
|
||||
# 步骤1: 读取数据
|
||||
self.logger.info("步骤1/4: 读取数据...")
|
||||
df = self._read_supplier_data(input_file)
|
||||
if df is None or df.empty:
|
||||
self.logger.error("读取数据失败或数据为空")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
# 步骤2: 应用列映射
|
||||
self.logger.info("步骤2/4: 应用列映射...")
|
||||
mapped_df = self._apply_column_mapping(df)
|
||||
if mapped_df is None:
|
||||
self.logger.error("列映射失败")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
# 步骤3: 数据清洗
|
||||
self.logger.info("步骤3/4: 数据清洗...")
|
||||
cleaned_df = self._apply_data_cleaning(mapped_df)
|
||||
if cleaned_df is None:
|
||||
self.logger.error("数据清洗失败")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
# 步骤4: 计算处理
|
||||
self.logger.info("步骤4/4: 计算处理...")
|
||||
calculated_df = self._apply_calculations(cleaned_df)
|
||||
if calculated_df is None:
|
||||
self.logger.error("计算处理失败")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
# 生成输出文件
|
||||
output_file = self._generate_output(calculated_df, input_file, output_dir)
|
||||
|
||||
if output_file and output_file.exists():
|
||||
self.logger.info(f"处理完成,输出文件: {output_file}")
|
||||
self.log_processing_end(input_file, output_file, success=True)
|
||||
return output_file
|
||||
else:
|
||||
self.logger.error("输出文件生成失败")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"处理文件时出错: {e}", exc_info=True)
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
def get_required_columns(self) -> List[str]:
|
||||
"""返回需要的列名列表"""
|
||||
# 从列映射配置中提取目标列名
|
||||
return list(self.column_mapping.values()) if self.column_mapping else []
|
||||
|
||||
def _check_filename_patterns(self, file_path: Path) -> bool:
|
||||
"""检查文件名模式
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
是否匹配
|
||||
"""
|
||||
try:
|
||||
filename = file_path.name
|
||||
for pattern in self.filename_patterns:
|
||||
if fnmatch.fnmatch(filename.lower(), pattern.lower()):
|
||||
self.logger.info(f"文件名匹配成功: {filename} -> {pattern}")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
self.logger.error(f"检查文件名模式时出错: {e}")
|
||||
return False
|
||||
|
||||
def _check_content_indicators(self, file_path: Path) -> bool:
|
||||
"""检查文件内容特征
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
是否匹配
|
||||
"""
|
||||
try:
|
||||
df = self._read_excel_safely(file_path, nrows=5)
|
||||
|
||||
# 检查列名中是否包含指定关键词
|
||||
columns_str = str(list(df.columns)).lower()
|
||||
|
||||
for indicator in self.content_indicators:
|
||||
if indicator.lower() in columns_str:
|
||||
self.logger.info(f"内容特征匹配成功: {indicator}")
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"检查内容特征时出错: {e}")
|
||||
return False
|
||||
|
||||
def _read_supplier_data(self, file_path: Path) -> Optional[pd.DataFrame]:
|
||||
"""读取供应商数据
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
数据DataFrame或None
|
||||
"""
|
||||
try:
|
||||
df = self._read_excel_safely(file_path)
|
||||
|
||||
if df.empty:
|
||||
self.logger.warning("数据文件为空")
|
||||
return None
|
||||
|
||||
self.logger.info(f"成功读取数据,形状: {df.shape}")
|
||||
return df
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"读取数据失败: {e}")
|
||||
return None
|
||||
|
||||
def _read_excel_safely(self, file_path: Path, **kwargs) -> pd.DataFrame:
|
||||
"""根据扩展名选择合适的读取引擎并带有回退"""
|
||||
suffix = file_path.suffix.lower()
|
||||
try:
|
||||
if suffix == '.xlsx':
|
||||
return pd.read_excel(file_path, engine='openpyxl', **kwargs)
|
||||
elif suffix == '.xls':
|
||||
try:
|
||||
return pd.read_excel(file_path, engine='xlrd', **kwargs)
|
||||
except Exception as e:
|
||||
self.logger.warning(f"读取xls失败,可能缺少xlrd: {e}")
|
||||
raise
|
||||
else:
|
||||
return pd.read_excel(file_path, **kwargs)
|
||||
except Exception as e:
|
||||
self.logger.error(f"读取Excel失败: {file_path} - {e}")
|
||||
raise
|
||||
|
||||
def _apply_column_mapping(self, df: pd.DataFrame) -> Optional[pd.DataFrame]:
|
||||
"""应用列映射
|
||||
|
||||
Args:
|
||||
df: 原始数据
|
||||
|
||||
Returns:
|
||||
映射后的数据或None
|
||||
"""
|
||||
if not self.column_mapping:
|
||||
self.logger.info("没有列映射配置")
|
||||
return df
|
||||
|
||||
try:
|
||||
# 应用列重命名
|
||||
df_renamed = df.rename(columns=self.column_mapping)
|
||||
|
||||
# 检查必需的列是否存在
|
||||
required_columns = self.get_required_columns()
|
||||
missing_columns = [col for col in required_columns if col not in df_renamed.columns]
|
||||
|
||||
if missing_columns:
|
||||
self.logger.warning(f"缺少必需的列: {missing_columns}")
|
||||
# 创建缺失的列并填充默认值
|
||||
for col in missing_columns:
|
||||
df_renamed[col] = 0 if '量' in col or '价' in col else ''
|
||||
self.logger.info(f"创建缺失列: {col},默认值: {df_renamed[col].iloc[0] if len(df_renamed) > 0 else 'N/A'}")
|
||||
|
||||
self.logger.info(f"列映射完成,列名: {list(df_renamed.columns)}")
|
||||
return df_renamed
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"列映射失败: {e}")
|
||||
return None
|
||||
|
||||
def _apply_data_cleaning(self, df: pd.DataFrame) -> Optional[pd.DataFrame]:
|
||||
"""应用数据清洗规则
|
||||
|
||||
Args:
|
||||
df: 映射后的数据
|
||||
|
||||
Returns:
|
||||
清洗后的数据或None
|
||||
"""
|
||||
if not self.cleaning_rules:
|
||||
self.logger.info("没有数据清洗规则")
|
||||
return df
|
||||
|
||||
try:
|
||||
df_cleaned = df.copy()
|
||||
|
||||
for rule in self.cleaning_rules:
|
||||
rule_type = rule.get('type')
|
||||
|
||||
if rule_type == 'remove_rows':
|
||||
# 删除行
|
||||
condition = rule.get('condition')
|
||||
if condition:
|
||||
before_count = len(df_cleaned)
|
||||
df_cleaned = df_cleaned.query(condition)
|
||||
after_count = len(df_cleaned)
|
||||
self.logger.info(f"删除行规则: {condition}, 删除数量: {before_count - after_count}")
|
||||
|
||||
elif rule_type == 'fill_na':
|
||||
# 填充空值,兼容单列和多列
|
||||
columns = rule.get('columns') or [rule.get('column')] if rule.get('column') else []
|
||||
value = rule.get('value', 0)
|
||||
for col in columns:
|
||||
if col and col in df_cleaned.columns:
|
||||
na_count = df_cleaned[col].isna().sum()
|
||||
df_cleaned[col] = df_cleaned[col].fillna(value)
|
||||
self.logger.info(f"填充空值: {col} -> {value}, 填充数量: {na_count}")
|
||||
|
||||
elif rule_type == 'convert_type':
|
||||
# 类型转换,兼容单列和多列
|
||||
target_type = rule.get('target_type', 'float')
|
||||
columns = rule.get('columns') or [rule.get('column')] if rule.get('column') else []
|
||||
for col in columns:
|
||||
if col and col in df_cleaned.columns:
|
||||
try:
|
||||
if target_type == 'float':
|
||||
df_cleaned[col] = pd.to_numeric(df_cleaned[col], errors='coerce')
|
||||
elif target_type == 'int':
|
||||
df_cleaned[col] = pd.to_numeric(df_cleaned[col], errors='coerce').astype('Int64')
|
||||
self.logger.info(f"类型转换: {col} -> {target_type}")
|
||||
except Exception as e:
|
||||
self.logger.warning(f"类型转换失败: {col} -> {target_type}: {e}")
|
||||
|
||||
else:
|
||||
self.logger.warning(f"未知的清洗规则类型: {rule_type}")
|
||||
|
||||
self.logger.info(f"数据清洗完成,数据形状: {df_cleaned.shape}")
|
||||
return df_cleaned
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"数据清洗失败: {e}")
|
||||
return None
|
||||
|
||||
def _apply_calculations(self, df: pd.DataFrame) -> Optional[pd.DataFrame]:
|
||||
"""应用计算处理
|
||||
|
||||
Args:
|
||||
df: 清洗后的数据
|
||||
|
||||
Returns:
|
||||
计算后的数据或None
|
||||
"""
|
||||
if not self.calculations:
|
||||
self.logger.info("没有计算规则")
|
||||
return df
|
||||
|
||||
try:
|
||||
df_calculated = df.copy()
|
||||
|
||||
for calculation in self.calculations:
|
||||
calc_type = calculation.get('type')
|
||||
|
||||
if calc_type == 'multiply':
|
||||
# 乘法计算
|
||||
source_column = calculation.get('source_column')
|
||||
target_column = calculation.get('target_column')
|
||||
factor = calculation.get('factor', 1)
|
||||
|
||||
if source_column and target_column:
|
||||
if source_column in df_calculated.columns:
|
||||
df_calculated[target_column] = df_calculated[source_column] * factor
|
||||
self.logger.info(f"乘法计算: {source_column} * {factor} -> {target_column}")
|
||||
else:
|
||||
self.logger.warning(f"源列不存在: {source_column}")
|
||||
|
||||
elif calc_type == 'divide':
|
||||
# 除法计算
|
||||
source_column = calculation.get('source_column')
|
||||
target_column = calculation.get('target_column')
|
||||
divisor = calculation.get('divisor', 1)
|
||||
|
||||
if source_column and target_column and divisor != 0:
|
||||
if source_column in df_calculated.columns:
|
||||
df_calculated[target_column] = df_calculated[source_column] / divisor
|
||||
self.logger.info(f"除法计算: {source_column} / {divisor} -> {target_column}")
|
||||
else:
|
||||
self.logger.warning(f"源列不存在: {source_column}")
|
||||
|
||||
elif calc_type == 'formula':
|
||||
# 公式计算
|
||||
formula = calculation.get('formula')
|
||||
target_column = calculation.get('target_column')
|
||||
|
||||
if formula and target_column:
|
||||
try:
|
||||
df_calculated[target_column] = df_calculated.eval(formula)
|
||||
self.logger.info(f"公式计算: {formula} -> {target_column}")
|
||||
except Exception as e:
|
||||
self.logger.error(f"公式计算失败: {formula}: {e}")
|
||||
|
||||
else:
|
||||
self.logger.warning(f"未知的计算类型: {calc_type}")
|
||||
|
||||
self.logger.info(f"计算处理完成,数据形状: {df_calculated.shape}")
|
||||
return df_calculated
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"计算处理失败: {e}")
|
||||
return None
|
||||
|
||||
def _generate_output(self, df: pd.DataFrame, input_file: Path, output_dir: Path) -> Optional[Path]:
|
||||
"""生成输出文件
|
||||
|
||||
Args:
|
||||
df: 最终数据
|
||||
input_file: 输入文件路径
|
||||
output_dir: 输出目录
|
||||
|
||||
Returns:
|
||||
输出文件路径或None
|
||||
"""
|
||||
try:
|
||||
# 生成输出文件名
|
||||
timestamp = pd.Timestamp.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_filename = f"{input_file.stem}{self.output_suffix}_{timestamp}.xls"
|
||||
output_file = output_dir / output_filename
|
||||
|
||||
# 这里应该使用实际的模板生成逻辑
|
||||
# 暂时直接保存为Excel文件
|
||||
df.to_excel(output_file, index=False)
|
||||
|
||||
self.logger.info(f"输出文件生成成功: {output_file}")
|
||||
return output_file
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"生成输出文件失败: {e}")
|
||||
return None
|
||||
362
app/core/processors/tobacco_processor.py
Normal file
362
app/core/processors/tobacco_processor.py
Normal file
@ -0,0 +1,362 @@
|
||||
"""
|
||||
烟草订单处理器
|
||||
|
||||
处理烟草公司特定格式的订单明细文件,生成银豹采购单
|
||||
"""
|
||||
|
||||
import os
|
||||
import datetime
|
||||
import pandas as pd
|
||||
import xlrd
|
||||
import xlwt
|
||||
from xlutils.copy import copy
|
||||
from openpyxl import load_workbook
|
||||
from typing import Optional, Dict, Any, List, Tuple
|
||||
from pathlib import Path
|
||||
|
||||
from .base import BaseProcessor
|
||||
from ...core.utils.log_utils import get_logger
|
||||
from ...core.utils.dialog_utils import show_custom_dialog
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class TobaccoProcessor(BaseProcessor):
|
||||
"""烟草订单处理器
|
||||
|
||||
处理烟草公司订单明细文件,提取商品信息并生成标准银豹采购单格式
|
||||
"""
|
||||
|
||||
def __init__(self, config: Dict[str, Any]):
|
||||
"""初始化烟草订单处理器
|
||||
|
||||
Args:
|
||||
config: 配置信息
|
||||
"""
|
||||
super().__init__(config)
|
||||
self.description = "处理烟草公司订单明细文件"
|
||||
self.template_file = config.get('Paths', 'template_file', fallback='templates/银豹-采购单模板.xls')
|
||||
|
||||
# 输出目录配置
|
||||
self.result_dir = Path("data/result")
|
||||
self.result_dir.mkdir(exist_ok=True)
|
||||
|
||||
# 默认输出文件名
|
||||
self.default_output_name = "银豹采购单_烟草公司.xls"
|
||||
|
||||
def can_process(self, file_path: Path) -> bool:
|
||||
"""判断是否为烟草订单文件
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
是否能处理该文件
|
||||
"""
|
||||
if not self.validate_input(file_path):
|
||||
return False
|
||||
|
||||
# 检查文件名特征
|
||||
filename = file_path.name
|
||||
tobacco_keywords = ['烟草', '卷烟', '订单明细', 'tobacco', '烟']
|
||||
|
||||
# 检查文件内容特征
|
||||
try:
|
||||
df = self._read_excel_safely(file_path, nrows=5)
|
||||
required_columns = ['商品', '盒码', '订单量']
|
||||
|
||||
# 检查文件名或内容特征
|
||||
filename_match = any(keyword in filename for keyword in tobacco_keywords)
|
||||
content_match = all(col in df.columns for col in required_columns)
|
||||
|
||||
if filename_match or content_match:
|
||||
self.logger.info(f"识别为烟草订单文件: {filename}")
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
self.logger.warning(f"检查文件内容时出错: {e}")
|
||||
# 如果无法读取内容,仅基于文件名判断
|
||||
return any(keyword in filename for keyword in tobacco_keywords)
|
||||
|
||||
def process(self, input_file: Path, output_dir: Path) -> Optional[Path]:
|
||||
"""处理烟草订单
|
||||
|
||||
Args:
|
||||
input_file: 输入文件路径
|
||||
output_dir: 输出目录路径
|
||||
|
||||
Returns:
|
||||
输出文件路径,处理失败返回None
|
||||
"""
|
||||
self.log_processing_start(input_file)
|
||||
|
||||
try:
|
||||
# 读取订单信息(时间和总金额)
|
||||
order_info = self._read_order_info(input_file)
|
||||
if not order_info:
|
||||
self.logger.error(f"读取订单信息失败: {input_file}")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
order_time, total_amount = order_info
|
||||
self.logger.info(f"订单信息 - 时间: {order_time}, 总金额: {total_amount}")
|
||||
|
||||
# 读取订单数据
|
||||
order_data = self._read_order_data(input_file)
|
||||
if order_data is None or order_data.empty:
|
||||
self.logger.error(f"读取订单数据失败或数据为空: {input_file}")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
self.logger.info(f"成功读取订单数据,共{len(order_data)}条记录")
|
||||
|
||||
# 生成输出文件路径
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_filename = f"银豹采购单_烟草公司_{timestamp}.xls"
|
||||
output_file = output_dir / output_filename
|
||||
|
||||
# 确保输出目录存在
|
||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 生成银豹采购单
|
||||
result = self._generate_pospal_order(order_data, order_time, output_file)
|
||||
|
||||
if result:
|
||||
self.logger.info(f"采购单生成成功: {output_file}")
|
||||
self.log_processing_end(input_file, output_file, success=True)
|
||||
|
||||
# 显示处理结果
|
||||
self._show_processing_result(output_file, order_time, len(order_data), total_amount)
|
||||
|
||||
return output_file
|
||||
else:
|
||||
self.logger.error("生成银豹采购单失败")
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"处理烟草订单时发生错误: {e}", exc_info=True)
|
||||
self.log_processing_end(input_file, success=False)
|
||||
return None
|
||||
|
||||
def get_required_columns(self) -> List[str]:
|
||||
"""返回需要的列名列表"""
|
||||
return ['商品', '盒码', '条码', '建议零售价', '批发价', '需求量', '订单量', '金额']
|
||||
|
||||
def get_supported_extensions(self) -> List[str]:
|
||||
"""支持的文件扩展名"""
|
||||
return ['.xlsx', '.xls']
|
||||
|
||||
def _read_order_info(self, file_path: Path) -> 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.0
|
||||
|
||||
self.logger.info(f"成功读取订单信息: 时间={order_time}, 总金额={total_amount}")
|
||||
return (order_time, total_amount)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"读取订单信息出错: {e}")
|
||||
return None
|
||||
|
||||
def _read_order_data(self, file_path: Path) -> Optional[pd.DataFrame]:
|
||||
"""读取订单数据
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
订单数据DataFrame或None
|
||||
"""
|
||||
columns = ['商品', '盒码', '条码', '建议零售价', '批发价', '需求量', '订单量', '金额']
|
||||
|
||||
try:
|
||||
df_old = self._read_excel_safely(file_path, header=None, skiprows=3, names=columns)
|
||||
|
||||
# 过滤订单量不为0的数据,并计算采购量和单价
|
||||
df_filtered = df_old[df_old['订单量'] != 0].copy()
|
||||
|
||||
if df_filtered.empty:
|
||||
self.logger.warning("没有订单量不为0的记录")
|
||||
return None
|
||||
|
||||
# 计算采购量和单价
|
||||
df_filtered['采购量'] = df_filtered['订单量'] * 10 # 烟草订单通常需要乘以10
|
||||
df_filtered['采购单价'] = df_filtered['金额'] / df_filtered['采购量']
|
||||
df_filtered = df_filtered.reset_index(drop=True)
|
||||
|
||||
self.logger.info(f"成功处理订单数据,有效记录数: {len(df_filtered)}")
|
||||
return df_filtered
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"读取订单数据失败: {e}")
|
||||
return None
|
||||
|
||||
def _read_excel_safely(self, file_path: Path, **kwargs) -> pd.DataFrame:
|
||||
suffix = file_path.suffix.lower()
|
||||
if suffix == '.xlsx':
|
||||
return pd.read_excel(file_path, engine='openpyxl', **kwargs)
|
||||
elif suffix == '.xls':
|
||||
try:
|
||||
return pd.read_excel(file_path, engine='xlrd', **kwargs)
|
||||
except Exception as e:
|
||||
self.logger.error(f"读取xls失败,可能缺少xlrd: {e}")
|
||||
raise
|
||||
else:
|
||||
return pd.read_excel(file_path, **kwargs)
|
||||
|
||||
def _generate_pospal_order(self, order_data: pd.DataFrame, order_time: str, output_file: Path) -> bool:
|
||||
"""生成银豹采购单
|
||||
|
||||
Args:
|
||||
order_data: 订单数据
|
||||
order_time: 订单时间
|
||||
output_file: 输出文件路径
|
||||
|
||||
Returns:
|
||||
是否生成成功
|
||||
"""
|
||||
try:
|
||||
# 检查模板文件是否存在
|
||||
template_path = Path(self.template_file)
|
||||
if not template_path.exists():
|
||||
self.logger.error(f"采购单模板文件不存在: {template_path}")
|
||||
return False
|
||||
|
||||
self.logger.info(f"使用模板文件: {template_path}")
|
||||
|
||||
# 打开模板,准备写入
|
||||
template_rd = xlrd.open_workbook(str(template_path), 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)
|
||||
|
||||
# 查找需要的列索引
|
||||
try:
|
||||
barcode_col = header_row.index("条码(必填)")
|
||||
amount_col = header_row.index("采购量(必填)")
|
||||
gift_col = header_row.index("赠送量")
|
||||
price_col = header_row.index("采购单价(必填)")
|
||||
except ValueError as e:
|
||||
self.logger.error(f"模板列查找失败: {e}")
|
||||
return False
|
||||
|
||||
self.logger.info(f"模板列索引 - 条码:{barcode_col}, 采购量:{amount_col}, 赠送量:{gift_col}, 单价:{price_col}")
|
||||
|
||||
# 写入数据到模板
|
||||
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)) # 采购单价保留两位小数
|
||||
|
||||
# 确保输出目录存在
|
||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 保存输出文件
|
||||
template_wb.save(str(output_file))
|
||||
|
||||
self.logger.info(f"采购单生成成功: {output_file}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"生成银豹采购单失败: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
def _show_processing_result(self, output_file: Path, order_time: str, total_count: int, total_amount: float):
|
||||
"""显示处理结果
|
||||
|
||||
Args:
|
||||
output_file: 输出文件路径
|
||||
order_time: 订单时间
|
||||
total_count: 处理条目数
|
||||
total_amount: 总金额
|
||||
"""
|
||||
try:
|
||||
# 创建附加信息
|
||||
additional_info = {
|
||||
"订单来源": "烟草公司",
|
||||
"处理时间": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
}
|
||||
|
||||
# 格式化金额显示
|
||||
try:
|
||||
if isinstance(total_amount, str):
|
||||
total_amount = float(total_amount.replace(',', ''))
|
||||
amount_display = f"¥{total_amount:.2f}"
|
||||
except (ValueError, TypeError):
|
||||
amount_display = f"¥{total_amount}"
|
||||
|
||||
# 显示自定义对话框
|
||||
show_custom_dialog(
|
||||
title="烟草订单处理结果",
|
||||
message="烟草订单处理完成",
|
||||
result_file=str(output_file),
|
||||
time_info=order_time,
|
||||
count_info=f"{total_count}个商品",
|
||||
amount_info=amount_display,
|
||||
additional_info=additional_info
|
||||
)
|
||||
|
||||
self.logger.info(f"显示处理结果 - 文件:{output_file}, 时间:{order_time}, 数量:{total_count}, 金额:{total_amount}")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"显示处理结果时出错: {e}")
|
||||
|
||||
def get_latest_tobacco_order(self) -> Optional[Path]:
|
||||
"""获取最新的烟草订单明细文件(兼容旧接口)
|
||||
|
||||
Returns:
|
||||
文件路径或None
|
||||
"""
|
||||
try:
|
||||
# 获取今日开始时间戳
|
||||
today = datetime.date.today()
|
||||
today_start = datetime.datetime.combine(today, datetime.time.min).timestamp()
|
||||
|
||||
# 查找订单明细文件
|
||||
result_dir = Path("data/output")
|
||||
if not result_dir.exists():
|
||||
return None
|
||||
|
||||
# 查找符合条件的文件
|
||||
candidates = []
|
||||
for file_path in result_dir.glob("订单明细*.xlsx"):
|
||||
if file_path.stat().st_ctime >= today_start:
|
||||
candidates.append(file_path)
|
||||
|
||||
if not candidates:
|
||||
self.logger.warning("未找到今天创建的烟草订单明细文件")
|
||||
# 返回最新的文件
|
||||
all_files = list(result_dir.glob("订单明细*.xlsx"))
|
||||
if all_files:
|
||||
all_files.sort(key=lambda x: x.stat().st_ctime, reverse=True)
|
||||
return all_files[0]
|
||||
return None
|
||||
|
||||
# 返回最新的文件
|
||||
candidates.sort(key=lambda x: x.stat().st_ctime, reverse=True)
|
||||
latest_file = candidates[0]
|
||||
|
||||
self.logger.info(f"找到最新烟草订单明细文件: {latest_file}")
|
||||
return latest_file
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取最新烟草订单文件时出错: {e}")
|
||||
return None
|
||||
@ -7,6 +7,7 @@
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Optional, Dict
|
||||
@ -58,7 +59,8 @@ def setup_logger(name: str,
|
||||
|
||||
# 创建文件处理器
|
||||
try:
|
||||
file_handler = logging.FileHandler(log_file, encoding='utf-8')
|
||||
# 使用滚动日志,限制单个日志大小与备份数量
|
||||
file_handler = RotatingFileHandler(log_file, maxBytes=5 * 1024 * 1024, backupCount=3, encoding='utf-8')
|
||||
file_handler.setFormatter(formatter)
|
||||
file_handler.setLevel(level)
|
||||
logger.addHandler(file_handler)
|
||||
@ -175,4 +177,4 @@ def cleanup_active_marker(name: str) -> None:
|
||||
if os.path.exists(active_marker):
|
||||
os.remove(active_marker)
|
||||
except Exception as e:
|
||||
print(f"无法清理日志活跃标记: {e}")
|
||||
print(f"无法清理日志活跃标记: {e}")
|
||||
|
||||
@ -4,7 +4,7 @@ OCR服务模块
|
||||
提供OCR识别服务,协调OCR流程。
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
|
||||
import os
|
||||
|
||||
from ..config.settings import ConfigManager
|
||||
@ -88,7 +88,7 @@ class OCRService:
|
||||
logger.error(f"处理图片时发生错误: {e}", exc_info=True)
|
||||
return None
|
||||
|
||||
def process_images_batch(self, batch_size: int = None, max_workers: int = None) -> Tuple[int, int]:
|
||||
def process_images_batch(self, batch_size: int = None, max_workers: int = None, progress_cb: Optional[Callable[[int], None]] = None) -> Tuple[int, int]:
|
||||
"""
|
||||
批量处理图片
|
||||
|
||||
@ -100,10 +100,10 @@ class OCRService:
|
||||
(总处理数, 成功处理数)元组
|
||||
"""
|
||||
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, progress_cb)
|
||||
|
||||
# 添加batch_process作为process_images_batch的别名,确保兼容性
|
||||
def batch_process(self, batch_size: int = None, max_workers: int = None) -> Tuple[int, int]:
|
||||
def batch_process(self, batch_size: int = None, max_workers: int = None, progress_cb: Optional[Callable[[int], None]] = None) -> Tuple[int, int]:
|
||||
"""
|
||||
批量处理图片(别名方法,与process_images_batch功能相同)
|
||||
|
||||
@ -115,7 +115,7 @@ class OCRService:
|
||||
(总处理数, 成功处理数)元组
|
||||
"""
|
||||
logger.info(f"OCRService.batch_process被调用,转发到process_images_batch")
|
||||
return self.process_images_batch(batch_size, max_workers)
|
||||
return self.process_images_batch(batch_size, max_workers, progress_cb)
|
||||
|
||||
def validate_image(self, image_path: str) -> bool:
|
||||
"""
|
||||
@ -190,4 +190,4 @@ class OCRService:
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"生成Excel文件时发生错误: {e}", exc_info=True)
|
||||
return None
|
||||
return None
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
提供订单处理服务,协调Excel处理和订单合并流程。
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any
|
||||
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
|
||||
|
||||
from ..config.settings import ConfigManager
|
||||
from ..core.utils.log_utils import get_logger
|
||||
@ -43,7 +43,7 @@ class OrderService:
|
||||
"""
|
||||
return self.excel_processor.get_latest_excel()
|
||||
|
||||
def process_excel(self, file_path: Optional[str] = None) -> Optional[str]:
|
||||
def process_excel(self, file_path: Optional[str] = None, progress_cb: Optional[Callable[[int], None]] = None) -> Optional[str]:
|
||||
"""
|
||||
处理Excel文件,生成采购单
|
||||
|
||||
@ -55,10 +55,10 @@ class OrderService:
|
||||
"""
|
||||
if file_path:
|
||||
logger.info(f"OrderService开始处理指定Excel文件: {file_path}")
|
||||
return self.excel_processor.process_specific_file(file_path)
|
||||
return self.excel_processor.process_specific_file(file_path, progress_cb=progress_cb)
|
||||
else:
|
||||
logger.info("OrderService开始处理最新Excel文件")
|
||||
return self.excel_processor.process_latest_file()
|
||||
return self.excel_processor.process_latest_file(progress_cb=progress_cb)
|
||||
|
||||
def get_purchase_orders(self) -> List[str]:
|
||||
"""
|
||||
@ -69,7 +69,7 @@ class OrderService:
|
||||
"""
|
||||
return self.order_merger.get_purchase_orders()
|
||||
|
||||
def merge_purchase_orders(self, file_paths: List[str]) -> Optional[str]:
|
||||
def merge_purchase_orders(self, file_paths: List[str], progress_cb: Optional[Callable[[int], None]] = None) -> Optional[str]:
|
||||
"""
|
||||
合并指定的采购单文件
|
||||
|
||||
@ -80,9 +80,9 @@ class OrderService:
|
||||
合并后的采购单文件路径,如果合并失败则返回None
|
||||
"""
|
||||
logger.info(f"OrderService开始合并指定采购单: {file_paths}")
|
||||
return self.merge_orders(file_paths)
|
||||
return self.merge_orders(file_paths, progress_cb)
|
||||
|
||||
def merge_all_purchase_orders(self) -> Optional[str]:
|
||||
def merge_all_purchase_orders(self, progress_cb: Optional[Callable[[int], None]] = None) -> Optional[str]:
|
||||
"""
|
||||
合并所有可用的采购单文件
|
||||
|
||||
@ -90,9 +90,9 @@ class OrderService:
|
||||
合并后的采购单文件路径,如果合并失败则返回None
|
||||
"""
|
||||
logger.info("OrderService开始合并所有采购单")
|
||||
return self.merge_orders(None)
|
||||
return self.merge_orders(None, progress_cb)
|
||||
|
||||
def merge_orders(self, file_paths: Optional[List[str]] = None) -> Optional[str]:
|
||||
def merge_orders(self, file_paths: Optional[List[str]] = None, progress_cb: Optional[Callable[[int], None]] = None) -> Optional[str]:
|
||||
"""
|
||||
合并采购单
|
||||
|
||||
@ -107,4 +107,4 @@ class OrderService:
|
||||
else:
|
||||
logger.info("OrderService开始合并所有采购单")
|
||||
|
||||
return self.order_merger.process(file_paths)
|
||||
return self.order_merger.process(file_paths, progress_cb)
|
||||
|
||||
297
app/services/processor_service.py
Normal file
297
app/services/processor_service.py
Normal file
@ -0,0 +1,297 @@
|
||||
"""
|
||||
处理器调度服务
|
||||
|
||||
负责管理和调度各种文件处理器,实现智能文件类型检测和处理器选择
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict, Any, Optional, List
|
||||
from pathlib import Path
|
||||
|
||||
from ..core.processors.base import BaseProcessor
|
||||
from ..core.processors.tobacco_processor import TobaccoProcessor
|
||||
from ..core.processors.ocr_processor import OCRProcessor
|
||||
from ..core.utils.log_utils import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class ProcessorService:
|
||||
"""处理器调度服务
|
||||
|
||||
负责管理所有处理器实例,提供统一的文件处理接口
|
||||
"""
|
||||
|
||||
def __init__(self, config: Dict[str, Any]):
|
||||
"""初始化处理器服务
|
||||
|
||||
Args:
|
||||
config: 系统配置字典
|
||||
"""
|
||||
self.config = config
|
||||
self.processors: List[BaseProcessor] = []
|
||||
self._load_processors()
|
||||
logger.info(f"处理器服务初始化完成,加载了{len(self.processors)}个处理器")
|
||||
|
||||
def _load_processors(self):
|
||||
"""加载所有处理器"""
|
||||
try:
|
||||
self.processors = [
|
||||
TobaccoProcessor(self.config),
|
||||
OCRProcessor(self.config),
|
||||
]
|
||||
|
||||
supplier_configs = []
|
||||
try:
|
||||
import json
|
||||
from pathlib import Path
|
||||
# 优先从`config/suppliers_config.json`加载
|
||||
config_path = Path("config/suppliers_config.json")
|
||||
if not config_path.exists():
|
||||
# 兼容其它路径
|
||||
config_path = Path("./suppliers_config.json")
|
||||
if config_path.exists():
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
ok, errs, supplier_configs = self._validate_suppliers_config(data)
|
||||
if not ok:
|
||||
logger.error("供应商配置校验失败:\n" + "\n".join([f"- {e}" for e in errs]))
|
||||
else:
|
||||
logger.info(f"从 {config_path} 加载供应商配置,共 {len(supplier_configs)} 项")
|
||||
else:
|
||||
logger.info("未找到供应商配置文件,跳过供应商处理器加载")
|
||||
except Exception as e:
|
||||
logger.error(f"读取供应商配置失败: {e}")
|
||||
|
||||
for supplier_config in supplier_configs:
|
||||
try:
|
||||
from ..core.processors.supplier_processors.generic_supplier_processor import GenericSupplierProcessor
|
||||
processor = GenericSupplierProcessor(self.config, supplier_config)
|
||||
self.processors.append(processor)
|
||||
logger.info(f"加载供应商处理器: {processor.name}")
|
||||
except Exception as e:
|
||||
logger.error(f"加载供应商处理器失败: {e}")
|
||||
|
||||
logger.info(f"成功加载{len(self.processors)}个处理器")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"加载处理器时出错: {e}", exc_info=True)
|
||||
self.processors = [
|
||||
TobaccoProcessor(self.config),
|
||||
OCRProcessor(self.config),
|
||||
]
|
||||
|
||||
def _validate_suppliers_config(self, data):
|
||||
try:
|
||||
suppliers = data.get('suppliers')
|
||||
errors = []
|
||||
valid = []
|
||||
if not isinstance(suppliers, list) or not suppliers:
|
||||
errors.append('suppliers必须是非空数组')
|
||||
return False, errors, []
|
||||
for idx, s in enumerate(suppliers):
|
||||
e = self._validate_single_supplier(s, idx)
|
||||
if e:
|
||||
errors.extend(e)
|
||||
else:
|
||||
valid.append(s)
|
||||
return len(errors) == 0, errors, valid
|
||||
except Exception as e:
|
||||
return False, [f'配置解析异常: {e}'], []
|
||||
|
||||
def _validate_single_supplier(self, s, idx):
|
||||
errs = []
|
||||
prefix = f'suppliers[{idx}]'
|
||||
name = s.get('name')
|
||||
if not name or not isinstance(name, str):
|
||||
errs.append(f'{prefix}.name 必须为字符串')
|
||||
fp = s.get('filename_patterns', [])
|
||||
ci = s.get('content_indicators', [])
|
||||
if not fp and not ci:
|
||||
errs.append(f'{prefix} 必须至少提供 filename_patterns 或 content_indicators 之一')
|
||||
cm = s.get('column_mapping', {})
|
||||
if cm and not isinstance(cm, dict):
|
||||
errs.append(f'{prefix}.column_mapping 必须为对象')
|
||||
cr = s.get('cleaning_rules', [])
|
||||
if cr and not isinstance(cr, list):
|
||||
errs.append(f'{prefix}.cleaning_rules 必须为数组')
|
||||
else:
|
||||
for i, rule in enumerate(cr):
|
||||
rtype = rule.get('type')
|
||||
if rtype not in ('remove_rows','fill_na','convert_type'):
|
||||
errs.append(f'{prefix}.cleaning_rules[{i}].type 非法: {rtype}')
|
||||
if rtype == 'remove_rows' and not rule.get('condition'):
|
||||
errs.append(f'{prefix}.cleaning_rules[{i}].condition 必填')
|
||||
if rtype in ('fill_na','convert_type'):
|
||||
if not rule.get('columns') and not rule.get('column'):
|
||||
errs.append(f'{prefix}.cleaning_rules[{i}] 需提供 columns 或 column')
|
||||
calc = s.get('calculations', [])
|
||||
if calc and not isinstance(calc, list):
|
||||
errs.append(f'{prefix}.calculations 必须为数组')
|
||||
else:
|
||||
for i, c in enumerate(calc):
|
||||
ctype = c.get('type')
|
||||
if ctype not in ('multiply','divide','formula'):
|
||||
errs.append(f'{prefix}.calculations[{i}].type 非法: {ctype}')
|
||||
if ctype in ('multiply','divide'):
|
||||
if not c.get('source_column') or not c.get('target_column'):
|
||||
errs.append(f'{prefix}.calculations[{i}] 需提供 source_column 与 target_column')
|
||||
if ctype == 'formula' and (not c.get('formula') or not c.get('target_column')):
|
||||
errs.append(f'{prefix}.calculations[{i}] 需提供 formula 与 target_column')
|
||||
return errs
|
||||
|
||||
def process_file(self, input_file: Path, output_dir: Path,
|
||||
preferred_processor: Optional[str] = None) -> Optional[Path]:
|
||||
"""处理文件 - 自动选择合适的处理器
|
||||
|
||||
Args:
|
||||
input_file: 输入文件路径
|
||||
output_dir: 输出目录路径
|
||||
preferred_processor: 优先使用的处理器名称(可选)
|
||||
|
||||
Returns:
|
||||
输出文件路径,处理失败返回None
|
||||
"""
|
||||
if not input_file.exists():
|
||||
logger.error(f"输入文件不存在: {input_file}")
|
||||
return None
|
||||
|
||||
if not output_dir.exists():
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
# 如果指定了优先处理器,先尝试使用它
|
||||
if preferred_processor:
|
||||
processor = self._get_processor_by_name(preferred_processor)
|
||||
if processor and processor.can_process(input_file):
|
||||
logger.info(f"使用指定的处理器: {processor.name}")
|
||||
return processor.process(input_file, output_dir)
|
||||
else:
|
||||
logger.warning(f"指定的处理器不可用或无法处理该文件: {preferred_processor}")
|
||||
|
||||
# 自动选择合适的处理器
|
||||
suitable_processors = [p for p in self.processors if p.can_process(input_file)]
|
||||
|
||||
if not suitable_processors:
|
||||
logger.warning(f"未找到适合处理文件的处理器: {input_file}")
|
||||
logger.info(f"支持的文件类型: {self.get_supported_types()}")
|
||||
return None
|
||||
|
||||
# 使用第一个合适的处理器
|
||||
processor = suitable_processors[0]
|
||||
logger.info(f"使用处理器 {processor.name} 处理文件: {input_file}")
|
||||
|
||||
return processor.process(input_file, output_dir)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"处理文件时出错: {e}", exc_info=True)
|
||||
return None
|
||||
|
||||
def _get_processor_by_name(self, name: str) -> Optional[BaseProcessor]:
|
||||
"""根据名称获取处理器
|
||||
|
||||
Args:
|
||||
name: 处理器名称
|
||||
|
||||
Returns:
|
||||
处理器实例或None
|
||||
"""
|
||||
for processor in self.processors:
|
||||
if processor.name == name or processor.__class__.__name__ == name:
|
||||
return processor
|
||||
return None
|
||||
|
||||
def get_supported_types(self) -> List[Dict[str, Any]]:
|
||||
"""获取支持的文件类型信息
|
||||
|
||||
Returns:
|
||||
处理器类型信息列表
|
||||
"""
|
||||
return [
|
||||
{
|
||||
'name': processor.name,
|
||||
'description': processor.description,
|
||||
'extensions': processor.get_supported_extensions(),
|
||||
'class_name': processor.__class__.__name__
|
||||
}
|
||||
for processor in self.processors
|
||||
]
|
||||
|
||||
def get_processor_info(self) -> List[Dict[str, Any]]:
|
||||
"""获取处理器详细信息
|
||||
|
||||
Returns:
|
||||
处理器详细信息列表
|
||||
"""
|
||||
return [
|
||||
{
|
||||
'name': processor.name,
|
||||
'description': processor.description,
|
||||
'extensions': processor.get_supported_extensions(),
|
||||
'required_columns': processor.get_required_columns(),
|
||||
'class_name': processor.__class__.__name__,
|
||||
'module': processor.__class__.__module__
|
||||
}
|
||||
for processor in self.processors
|
||||
]
|
||||
|
||||
def can_process_file(self, file_path: Path) -> bool:
|
||||
"""检查是否有处理器能处理该文件
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
是否有处理器能处理
|
||||
"""
|
||||
if not file_path.exists():
|
||||
return False
|
||||
|
||||
return any(processor.can_process(file_path) for processor in self.processors)
|
||||
|
||||
def get_suitable_processors(self, file_path: Path) -> List[BaseProcessor]:
|
||||
"""获取能处理该文件的所有处理器
|
||||
|
||||
Args:
|
||||
file_path: 文件路径
|
||||
|
||||
Returns:
|
||||
合适的处理器列表
|
||||
"""
|
||||
if not file_path.exists():
|
||||
return []
|
||||
|
||||
return [p for p in self.processors if p.can_process(file_path)]
|
||||
|
||||
def reload_processors(self):
|
||||
"""重新加载处理器"""
|
||||
logger.info("重新加载处理器...")
|
||||
self.processors.clear()
|
||||
self._load_processors()
|
||||
logger.info(f"重新加载完成,共{len(self.processors)}个处理器")
|
||||
|
||||
def add_processor(self, processor: BaseProcessor):
|
||||
"""添加处理器
|
||||
|
||||
Args:
|
||||
processor: 处理器实例
|
||||
"""
|
||||
self.processors.append(processor)
|
||||
logger.info(f"添加处理器: {processor.name}")
|
||||
|
||||
def remove_processor(self, processor_name: str) -> bool:
|
||||
"""移除处理器
|
||||
|
||||
Args:
|
||||
processor_name: 处理器名称
|
||||
|
||||
Returns:
|
||||
是否成功移除
|
||||
"""
|
||||
for i, processor in enumerate(self.processors):
|
||||
if processor.name == processor_name or processor.__class__.__name__ == processor_name:
|
||||
del self.processors[i]
|
||||
logger.info(f"移除处理器: {processor_name}")
|
||||
return True
|
||||
logger.warning(f"未找到要移除的处理器: {processor_name}")
|
||||
return False
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,316 +0,0 @@
|
||||
|
||||
This file lists modules PyInstaller was not able to find. This does not
|
||||
necessarily mean this module is required for running your program. Python and
|
||||
Python 3rd-party packages include a lot of conditional or optional modules. For
|
||||
example the module 'ntpath' only exists on Windows, whereas the module
|
||||
'posixpath' only exists on Posix systems.
|
||||
|
||||
Types if import:
|
||||
* top-level: imported at the top-level - look at these first
|
||||
* conditional: imported within an if-statement
|
||||
* delayed: imported within a function
|
||||
* optional: imported within a try-except-statement
|
||||
|
||||
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
|
||||
tracking down the missing module yourself. Thanks!
|
||||
|
||||
missing module named _posixshmem - imported by multiprocessing.resource_tracker (conditional), multiprocessing.shared_memory (conditional)
|
||||
missing module named 'org.python' - imported by copy (optional), xml.sax (delayed, conditional)
|
||||
missing module named _scproxy - imported by urllib.request (conditional)
|
||||
missing module named termios - imported by getpass (optional), tty (top-level)
|
||||
missing module named pwd - imported by posixpath (delayed, conditional), shutil (optional), tarfile (optional), pathlib (delayed, conditional, optional), subprocess (optional), netrc (delayed, conditional), getpass (delayed), http.server (delayed, optional), webbrowser (delayed)
|
||||
missing module named 'java.lang' - imported by platform (delayed, optional), xml.sax._exceptions (conditional)
|
||||
missing module named multiprocessing.BufferTooShort - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
|
||||
missing module named multiprocessing.AuthenticationError - imported by multiprocessing (top-level), multiprocessing.connection (top-level)
|
||||
missing module named _posixsubprocess - imported by subprocess (optional), multiprocessing.util (delayed)
|
||||
missing module named multiprocessing.get_context - imported by multiprocessing (top-level), multiprocessing.pool (top-level), multiprocessing.managers (top-level), multiprocessing.sharedctypes (top-level)
|
||||
missing module named multiprocessing.TimeoutError - imported by multiprocessing (top-level), multiprocessing.pool (top-level)
|
||||
missing module named org - imported by pickle (optional)
|
||||
missing module named multiprocessing.set_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
|
||||
missing module named multiprocessing.get_start_method - imported by multiprocessing (top-level), multiprocessing.spawn (top-level)
|
||||
missing module named grp - imported by shutil (optional), tarfile (optional), pathlib (delayed, optional), subprocess (optional)
|
||||
missing module named pep517 - imported by importlib.metadata (delayed)
|
||||
missing module named posix - imported by os (conditional, optional), shutil (conditional), importlib._bootstrap_external (conditional)
|
||||
missing module named resource - imported by posix (top-level)
|
||||
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level)
|
||||
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level)
|
||||
missing module named pyimod02_importers - imported by C:\Program Files\Python39\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed)
|
||||
missing module named simplejson - imported by requests.compat (conditional, optional)
|
||||
missing module named dummy_threading - imported by requests.cookies (optional)
|
||||
missing module named typing_extensions - imported by urllib3.util.retry (conditional), urllib3._collections (conditional), urllib3.util.ssltransport (conditional), urllib3.connectionpool (conditional), urllib3.poolmanager (conditional), urllib3.contrib.emscripten.fetch (conditional), charset_normalizer.legacy (conditional), pandas._typing (conditional)
|
||||
missing module named zstandard - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named compression - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named 'h2.events' - imported by urllib3.http2.connection (top-level)
|
||||
missing module named 'h2.connection' - imported by urllib3.http2.connection (top-level)
|
||||
missing module named h2 - imported by urllib3.http2.connection (top-level)
|
||||
missing module named brotli - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
|
||||
missing module named socks - imported by urllib3.contrib.socks (optional)
|
||||
missing module named 'typing.io' - imported by importlib.resources (top-level)
|
||||
missing module named cryptography - imported by urllib3.contrib.pyopenssl (top-level), requests (conditional, optional)
|
||||
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl (delayed, conditional)
|
||||
missing module named 'cryptography.x509' - imported by urllib3.contrib.pyopenssl (delayed, optional)
|
||||
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl (top-level)
|
||||
missing module named chardet - imported by requests (optional)
|
||||
missing module named 'pyodide.ffi' - imported by urllib3.contrib.emscripten.fetch (delayed, optional)
|
||||
missing module named pyodide - imported by urllib3.contrib.emscripten.fetch (top-level)
|
||||
missing module named js - imported by urllib3.contrib.emscripten.fetch (top-level)
|
||||
missing module named cStringIO - imported by xlrd.timemachine (conditional)
|
||||
missing module named PIL - imported by openpyxl.drawing.image (optional)
|
||||
missing module named 'defusedxml.ElementTree' - imported by openpyxl.xml.functions (conditional)
|
||||
missing module named 'lxml.etree' - imported by openpyxl.xml.functions (conditional), pandas.io.xml (delayed), pandas.io.formats.xml (delayed), pandas.io.html (delayed)
|
||||
missing module named openpyxl.tests - imported by openpyxl.reader.excel (optional)
|
||||
missing module named defusedxml - imported by openpyxl.xml (delayed, optional)
|
||||
missing module named lxml - imported by openpyxl.xml (delayed, optional), pandas.io.xml (conditional)
|
||||
missing module named _dummy_thread - imported by numpy._core.arrayprint (optional)
|
||||
missing module named numpy._typing._ufunc - imported by numpy._typing (conditional)
|
||||
missing module named 'numpy_distutils.cpuinfo' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
|
||||
missing module named 'numpy_distutils.fcompiler' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
|
||||
missing module named 'numpy_distutils.command' - imported by numpy.f2py.diagnose (delayed, conditional, optional)
|
||||
missing module named numpy_distutils - imported by numpy.f2py.diagnose (delayed, optional)
|
||||
missing module named psutil - imported by numpy.testing._private.utils (delayed, optional)
|
||||
missing module named readline - imported by cmd (delayed, conditional, optional), code (delayed, conditional, optional), pdb (delayed, optional)
|
||||
missing module named win32pdh - imported by numpy.testing._private.utils (delayed, conditional)
|
||||
missing module named asyncio.DefaultEventLoopPolicy - imported by asyncio (delayed, conditional), asyncio.events (delayed, conditional)
|
||||
missing module named threadpoolctl - imported by numpy.lib._utils_impl (delayed, optional)
|
||||
missing module named numpy._core.zeros - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.vstack - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.void - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.vecdot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.ushort - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.unsignedinteger - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ulonglong - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ulong - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uintp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uintc - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uint64 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uint32 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uint16 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.uint - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ubyte - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.trunc - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.true_divide - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.transpose - imported by numpy._core (top-level), numpy.lib._function_base_impl (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.trace - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.timedelta64 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.tensordot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.tanh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.tan - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.swapaxes - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.sum - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.subtract - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.str_ - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.square - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.sqrt - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.spacing - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.sort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.sinh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.single - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.signedinteger - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.signbit - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.sign - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.short - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.rint - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.right_shift - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.result_type - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.remainder - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.reciprocal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.radians - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.rad2deg - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.prod - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.power - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.positive - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.pi - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.outer - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.ones - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.object_ - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.number - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.not_equal - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.newaxis - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.negative - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ndarray - imported by numpy._core (top-level), numpy.lib._utils_impl (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
|
||||
missing module named numpy._core.multiply - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.moveaxis - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.modf - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.mod - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.minimum - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.maximum - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.max - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.matrix_transpose - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.matmul - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.longdouble - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.long - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logical_xor - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logical_or - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logical_not - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logical_and - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logaddexp2 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.logaddexp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.log2 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.log1p - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.log - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.linspace - imported by numpy._core (top-level), numpy.lib._index_tricks_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.less_equal - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.less - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.left_shift - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ldexp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.lcm - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.isscalar - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.isnat - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
|
||||
missing module named numpy._core.isnan - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.isfinite - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.intp - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
|
||||
missing module named numpy._core.integer - imported by numpy._core (conditional), numpy (conditional), numpy.fft._helper (top-level)
|
||||
missing module named numpy._core.intc - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.int8 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.int64 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.int32 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.int16 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.inf - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.inexact - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.iinfo - imported by numpy._core (top-level), numpy.lib._twodim_base_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.hypot - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.hstack - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.heaviside - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.half - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.greater_equal - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.greater - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.gcd - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.frompyfunc - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.frexp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.fmod - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.fmin - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.fmax - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.floor_divide - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.floor - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.floating - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.float_power - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.float32 - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
|
||||
missing module named numpy._core.float16 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.finfo - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.fabs - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.expm1 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.exp - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.euler_gamma - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.errstate - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.equal - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.empty_like - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.empty - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy.fft._helper (top-level)
|
||||
missing module named numpy._core.e - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.double - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.dot - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.divmod - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.divide - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.diagonal - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.degrees - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.deg2rad - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.datetime64 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.csingle - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.cross - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.count_nonzero - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.cosh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.cos - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.copysign - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.conjugate - imported by numpy._core (conditional), numpy (conditional), numpy.fft._pocketfft (top-level)
|
||||
missing module named numpy._core.conj - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.complexfloating - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.complex64 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.clongdouble - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.character - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.ceil - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.cdouble - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.cbrt - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bytes_ - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.byte - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bool_ - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bitwise_xor - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bitwise_or - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bitwise_count - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.bitwise_and - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.atleast_3d - imported by numpy._core (top-level), numpy.lib._shape_base_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.atleast_2d - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.atleast_1d - imported by numpy._core (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.asarray - imported by numpy._core (top-level), numpy.lib._array_utils_impl (top-level), numpy.linalg._linalg (top-level), numpy (conditional), numpy.fft._pocketfft (top-level), numpy.fft._helper (top-level)
|
||||
missing module named numpy._core.asanyarray - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.array_repr - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional)
|
||||
missing module named numpy._core.array2string - imported by numpy._core (delayed), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.array - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (top-level), numpy.lib._polynomial_impl (top-level), numpy (conditional)
|
||||
missing module named numpy._core.argsort - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.arctanh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arctan2 - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arctan - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arcsinh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arcsin - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arccosh - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arccos - imported by numpy._core (conditional), numpy (conditional)
|
||||
missing module named numpy._core.arange - imported by numpy._core (top-level), numpy.testing._private.utils (top-level), numpy (conditional), numpy.fft._helper (top-level)
|
||||
missing module named numpy._core.amin - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.amax - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named numpy._core.all - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy.testing._private.utils (delayed), numpy (conditional)
|
||||
missing module named numpy._core.add - imported by numpy._core (top-level), numpy.linalg._linalg (top-level), numpy (conditional)
|
||||
missing module named yaml - imported by numpy.__config__ (delayed)
|
||||
missing module named numpy._distributor_init_local - imported by numpy (optional), numpy._distributor_init (optional)
|
||||
missing module named vms_lib - imported by platform (delayed, optional)
|
||||
missing module named java - imported by platform (delayed)
|
||||
missing module named _winreg - imported by platform (delayed, optional)
|
||||
missing module named six.moves.range - imported by six.moves (top-level), dateutil.rrule (top-level)
|
||||
runtime module named six.moves - imported by dateutil.tz.tz (top-level), dateutil.tz._factories (top-level), dateutil.tz.win (top-level), dateutil.rrule (top-level)
|
||||
missing module named dateutil.tz.tzfile - imported by dateutil.tz (top-level), dateutil.zoneinfo (top-level)
|
||||
missing module named StringIO - imported by six (conditional), xlutils.compat (conditional)
|
||||
missing module named numexpr - imported by pandas.core.computation.expressions (conditional), pandas.core.computation.engines (delayed)
|
||||
missing module named numba - imported by pandas.core._numba.executor (delayed, conditional), pandas.core.util.numba_ (delayed, conditional), pandas.core.window.numba_ (delayed, conditional), pandas.core.window.online (delayed, conditional), pandas.core._numba.kernels.mean_ (top-level), pandas.core._numba.kernels.shared (top-level), pandas.core._numba.kernels.sum_ (top-level), pandas.core._numba.kernels.min_max_ (top-level), pandas.core._numba.kernels.var_ (top-level), pandas.core.groupby.numba_ (delayed, conditional), pandas.core._numba.extensions (top-level)
|
||||
missing module named 'numba.extending' - imported by pandas.core._numba.kernels.sum_ (top-level)
|
||||
missing module named 'pyarrow.compute' - imported by pandas.core.arrays._arrow_string_mixins (conditional), pandas.core.arrays.string_arrow (conditional), pandas.core.reshape.merge (delayed, conditional), pandas.core.arrays.arrow.array (conditional), pandas.core.arrays.arrow.accessors (conditional)
|
||||
missing module named 'numba.typed' - imported by pandas.core._numba.extensions (delayed)
|
||||
missing module named 'numba.core' - imported by pandas.core._numba.extensions (top-level)
|
||||
missing module named pyarrow - imported by pandas.core.arrays._arrow_string_mixins (conditional), pandas.core.arrays.masked (delayed), pandas.core.arrays.boolean (delayed, conditional), pandas.core.arrays.numeric (delayed, conditional), pandas.core.arrays.arrow._arrow_utils (top-level), pandas.core.interchange.utils (delayed, conditional), pandas.core.strings.accessor (delayed, conditional), pandas.io._util (conditional), pandas.io.parsers.base_parser (delayed, conditional), pandas.core.arrays.interval (delayed), pandas.core.arrays.arrow.extension_types (top-level), pandas.core.arrays.period (delayed), pandas.core.methods.describe (delayed, conditional), pandas.io.sql (delayed, conditional), pandas.core.arrays.string_arrow (conditional), pandas.core.reshape.merge (delayed, conditional), pandas.core.arrays.arrow.array (conditional), pandas.core.interchange.buffer (conditional), pandas.io.feather_format (delayed), pandas.core.indexes.base (delayed, conditional), pandas.core.dtypes.cast (delayed, conditional), pandas.core.arrays.string_ (delayed, conditional), pandas.core.arrays.arrow.accessors (conditional), pandas.core.dtypes.dtypes (delayed, conditional), pandas.compat.pyarrow (optional), pandas.core.reshape.encoding (delayed, conditional), pandas._testing (conditional)
|
||||
missing module named 'scipy.stats' - imported by pandas.core.nanops (delayed, conditional)
|
||||
missing module named scipy - imported by pandas.core.dtypes.common (delayed, conditional, optional), pandas.core.missing (delayed)
|
||||
missing module named traitlets - imported by pandas.io.formats.printing (delayed, conditional)
|
||||
missing module named 'IPython.core' - imported by pandas.io.formats.printing (delayed, conditional)
|
||||
missing module named IPython - imported by pandas.io.formats.printing (delayed)
|
||||
missing module named xlsxwriter - imported by pandas.io.excel._xlsxwriter (delayed)
|
||||
missing module named 'odf.config' - imported by pandas.io.excel._odswriter (delayed)
|
||||
missing module named 'odf.style' - imported by pandas.io.excel._odswriter (delayed)
|
||||
missing module named 'odf.text' - imported by pandas.io.excel._odfreader (delayed), pandas.io.excel._odswriter (delayed)
|
||||
missing module named 'odf.table' - imported by pandas.io.excel._odfreader (delayed), pandas.io.excel._odswriter (delayed)
|
||||
missing module named 'odf.opendocument' - imported by pandas.io.excel._odfreader (delayed), pandas.io.excel._odswriter (delayed)
|
||||
missing module named pyxlsb - imported by pandas.io.excel._pyxlsb (delayed, conditional)
|
||||
missing module named 'odf.office' - imported by pandas.io.excel._odfreader (delayed)
|
||||
missing module named 'odf.element' - imported by pandas.io.excel._odfreader (delayed)
|
||||
missing module named 'odf.namespaces' - imported by pandas.io.excel._odfreader (delayed)
|
||||
missing module named odf - imported by pandas.io.excel._odfreader (conditional)
|
||||
missing module named python_calamine - imported by pandas.io.excel._calamine (delayed, conditional)
|
||||
missing module named 'matplotlib.pyplot' - imported by pandas.io.formats.style (optional)
|
||||
missing module named matplotlib - imported by pandas.plotting._core (conditional), pandas.io.formats.style (optional)
|
||||
missing module named 'matplotlib.colors' - imported by pandas.plotting._misc (conditional), pandas.io.formats.style (conditional)
|
||||
missing module named markupsafe - imported by pandas.io.formats.style_render (top-level)
|
||||
missing module named botocore - imported by pandas.io.common (delayed, conditional, optional)
|
||||
missing module named sets - imported by pytz.tzinfo (optional)
|
||||
missing module named collections.Mapping - imported by collections (optional), pytz.lazy (optional)
|
||||
missing module named UserDict - imported by pytz.lazy (optional)
|
||||
missing module named 'scipy.sparse' - imported by pandas.core.arrays.sparse.array (conditional), pandas.core.arrays.sparse.scipy_sparse (delayed, conditional), pandas.core.arrays.sparse.accessor (delayed)
|
||||
missing module named pandas.core.internals.Block - imported by pandas.core.internals (conditional), pandas.io.pytables (conditional)
|
||||
missing module named Foundation - imported by pandas.io.clipboard (delayed, conditional, optional)
|
||||
missing module named AppKit - imported by pandas.io.clipboard (delayed, conditional, optional)
|
||||
missing module named PyQt4 - imported by pandas.io.clipboard (delayed, conditional, optional)
|
||||
missing module named qtpy - imported by pandas.io.clipboard (delayed, conditional, optional)
|
||||
missing module named 'sqlalchemy.engine' - imported by pandas.io.sql (delayed)
|
||||
missing module named 'sqlalchemy.types' - imported by pandas.io.sql (delayed, conditional)
|
||||
missing module named 'sqlalchemy.schema' - imported by pandas.io.sql (delayed)
|
||||
missing module named 'sqlalchemy.sql' - imported by pandas.io.sql (conditional)
|
||||
missing module named sqlalchemy - imported by pandas.io.sql (delayed, conditional)
|
||||
missing module named tables - imported by pandas.io.pytables (delayed, conditional)
|
||||
missing module named 'pyarrow.fs' - imported by pandas.io.orc (conditional)
|
||||
missing module named fsspec - imported by pandas.io.orc (conditional)
|
||||
missing module named 'pyarrow.parquet' - imported by pandas.io.parquet (delayed)
|
||||
missing module named google - imported by pandas.io.gbq (conditional)
|
||||
missing module named 'lxml.html' - imported by pandas.io.html (delayed)
|
||||
missing module named bs4 - imported by pandas.io.html (delayed)
|
||||
missing module named pytest - imported by pandas._testing._io (delayed), pandas._testing (delayed)
|
||||
missing module named 'matplotlib.axes' - imported by pandas.plotting._misc (conditional), pandas._testing.asserters (delayed)
|
||||
missing module named 'matplotlib.artist' - imported by pandas._testing.asserters (delayed)
|
||||
missing module named 'matplotlib.table' - imported by pandas.plotting._misc (conditional)
|
||||
missing module named 'matplotlib.figure' - imported by pandas.plotting._misc (conditional)
|
||||
missing module named errorhandler - imported by xlutils.filter (delayed)
|
||||
missing module named guppy - imported by xlutils.filter (optional)
|
||||
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@ api_url = https://aip.baidubce.com/rest/2.0/ocr/v1/table
|
||||
input_folder = data/input
|
||||
output_folder = data/output
|
||||
temp_folder = data/temp
|
||||
template_folder = templates
|
||||
template_folder = E:\2025Code\python\orc-order-v2\templates
|
||||
processed_record = data/processed_files.json
|
||||
|
||||
[Performance]
|
||||
|
||||
61
config/suppliers_config.json
Normal file
61
config/suppliers_config.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"suppliers": [
|
||||
{
|
||||
"name": "蓉城易购",
|
||||
"description": "蓉城易购供应商订单处理",
|
||||
"filename_patterns": ["*蓉城*", "*rongcheng*", "*易*"],
|
||||
"content_indicators": ["蓉城易购", "商品编码", "订货数量"],
|
||||
"column_mapping": {
|
||||
"商品编码": "barcode",
|
||||
"商品名称": "name",
|
||||
"订货数量": "quantity",
|
||||
"单价": "unit_price"
|
||||
},
|
||||
"cleaning_rules": [
|
||||
{
|
||||
"type": "remove_rows",
|
||||
"condition": "订货数量 == 0 or 订货数量.isna()"
|
||||
},
|
||||
{
|
||||
"type": "fill_na",
|
||||
"columns": ["unit_price"],
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"calculations": [
|
||||
{
|
||||
"type": "multiply",
|
||||
"source_column": "quantity",
|
||||
"target_column": "quantity",
|
||||
"factor": 1
|
||||
}
|
||||
],
|
||||
"output_suffix": "_蓉城易购_银豹采购单"
|
||||
},
|
||||
{
|
||||
"name": "通用食品供应商",
|
||||
"description": "通用食品类供应商订单",
|
||||
"filename_patterns": ["*食品*", "*配送*", "*供货*"],
|
||||
"content_indicators": ["产品条码", "订购量", "进货价"],
|
||||
"column_mapping": {
|
||||
"产品条码": "barcode",
|
||||
"产品名称": "name",
|
||||
"订购量": "quantity",
|
||||
"进货价": "unit_price"
|
||||
},
|
||||
"cleaning_rules": [
|
||||
{
|
||||
"type": "convert_type",
|
||||
"columns": ["unit_price"],
|
||||
"target_type": "float"
|
||||
},
|
||||
{
|
||||
"type": "fill_na",
|
||||
"columns": ["barcode", "name", "quantity"],
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"output_suffix": "_食品供应商_银豹采购单"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 173 KiB |
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
{
|
||||
"data/output\\7a3a78a02fcf6ccef5daad31bd50bdf2.xlsx": "data/result\\采购单_7a3a78a02fcf6ccef5daad31bd50bdf2.xls"
|
||||
}
|
||||
Binary file not shown.
@ -1 +0,0 @@
|
||||
{"theme": "light"}
|
||||
BIN
dist/OCR订单处理系统.exe
vendored
BIN
dist/OCR订单处理系统.exe
vendored
Binary file not shown.
28
dist/config.ini
vendored
28
dist/config.ini
vendored
@ -1,28 +0,0 @@
|
||||
[API]
|
||||
api_key = O0Fgk3o69RWJ86eAX8BTHRaB
|
||||
secret_key = VyZD5lzcIMgsup1uuD6Cw0pfzS20IGPZ
|
||||
timeout = 30
|
||||
max_retries = 3
|
||||
retry_delay = 2
|
||||
api_url = https://aip.baidubce.com/rest/2.0/ocr/v1/table
|
||||
|
||||
[Paths]
|
||||
input_folder = data/input
|
||||
output_folder = data/output
|
||||
temp_folder = data/temp
|
||||
template_folder = templates
|
||||
processed_record = data/processed_files.json
|
||||
|
||||
[Performance]
|
||||
max_workers = 4
|
||||
batch_size = 5
|
||||
skip_existing = true
|
||||
|
||||
[File]
|
||||
allowed_extensions = .jpg,.jpeg,.png,.bmp
|
||||
excel_extension = .xlsx
|
||||
max_file_size_mb = 4
|
||||
|
||||
[Templates]
|
||||
purchase_order = 银豹-采购单模板.xls
|
||||
|
||||
205
dist/config/barcode_mappings.json
vendored
205
dist/config/barcode_mappings.json
vendored
@ -1,205 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
"6907992508344": {
|
||||
"map_to": "6907992508191",
|
||||
"description": "条码映射:6907992508344 -> 6907992508191"
|
||||
},
|
||||
"6903979000979": {
|
||||
"map_to": "6903979000962",
|
||||
"description": "条码映射:6903979000979 -> 6903979000962"
|
||||
},
|
||||
"6923644283582": {
|
||||
"map_to": "6923644283575",
|
||||
"description": "条码映射:6923644283582 -> 6923644283575"
|
||||
},
|
||||
"6923644268930": {
|
||||
"map_to": "6923644268497",
|
||||
"description": "条码映射:6923644268930 -> 6923644268497"
|
||||
},
|
||||
"6923644268916": {
|
||||
"map_to": "6923644268503",
|
||||
"description": "条码映射:6923644268916 -> 6923644268503"
|
||||
},
|
||||
"6923644268909": {
|
||||
"map_to": "6923644268510",
|
||||
"description": "条码映射:6923644268909 -> 6923644268510"
|
||||
},
|
||||
"6923644299804": {
|
||||
"map_to": "6923644299774",
|
||||
"description": "条码映射:6923644299804 -> 6923644299774"
|
||||
},
|
||||
"6923644266318": {
|
||||
"map_to": "6923644266066",
|
||||
"description": "条码映射:6923644266318 -> 6923644266066"
|
||||
},
|
||||
"6923644210151": {
|
||||
"map_to": "6923644223458",
|
||||
"description": "条码映射:6923644210151 -> 6923644223458"
|
||||
},
|
||||
"6907992501819": {
|
||||
"map_to": "6907992500133",
|
||||
"description": "条码映射:6907992501819 -> 6907992500133"
|
||||
},
|
||||
"6907992502052": {
|
||||
"map_to": "6907992100272",
|
||||
"description": "条码映射:6907992502052 -> 6907992100272"
|
||||
},
|
||||
"6907992507385": {
|
||||
"map_to": "6907992507095",
|
||||
"description": "条码映射:6907992507385 -> 6907992507095"
|
||||
},
|
||||
"6973726149671": {
|
||||
"map_to": "6973726149657",
|
||||
"description": "条码映射:6973726149671 -> 6973726149657"
|
||||
},
|
||||
"6977426410574": {
|
||||
"map_to": "6977426410567",
|
||||
"description": "条码映射:6977426410574 -> 6977426410567"
|
||||
},
|
||||
"6973726149688": {
|
||||
"map_to": "6973726149664",
|
||||
"description": "条码映射:6973726149688 -> 6973726149664"
|
||||
},
|
||||
"6935205322012": {
|
||||
"map_to": "6935205320018",
|
||||
"description": "条码映射:6935205322012 -> 6935205320018"
|
||||
},
|
||||
"6943497411024": {
|
||||
"map_to": "6943497411017",
|
||||
"description": "条码映射:6943497411024 -> 6943497411017"
|
||||
},
|
||||
"6921734968821": {
|
||||
"map_to": "6921734968814",
|
||||
"description": "条码映射:6921734968821 -> 6921734968814"
|
||||
},
|
||||
"6921734968258": {
|
||||
"map_to": "6921734968241",
|
||||
"description": "条码映射:6921734968258 -> 6921734968241"
|
||||
},
|
||||
"6921734968180": {
|
||||
"map_to": "6921734968173",
|
||||
"description": "条码映射:6921734968180 -> 6921734968173"
|
||||
},
|
||||
"6921734908735": {
|
||||
"map_to": "6935205372772",
|
||||
"description": "条码映射:6921734908735 -> 6935205372772"
|
||||
},
|
||||
"6923644248222": {
|
||||
"map_to": "6923644248208",
|
||||
"description": "条码映射:6923644248222 -> 6923644248208"
|
||||
},
|
||||
"6902083881122": {
|
||||
"map_to": "6902083881085",
|
||||
"description": "条码映射:6902083881122 -> 6902083881085"
|
||||
},
|
||||
"6907992501857": {
|
||||
"map_to": "6907992500010",
|
||||
"description": "条码映射:6907992501857 -> 6907992500010"
|
||||
},
|
||||
"6902083891015": {
|
||||
"map_to": "6902083890636",
|
||||
"description": "条码映射:6902083891015 -> 6902083890636"
|
||||
},
|
||||
"6923450605240": {
|
||||
"map_to": "6923450605226",
|
||||
"description": "条码映射:6923450605240 -> 6923450605226"
|
||||
},
|
||||
"6923450605196": {
|
||||
"map_to": "6923450614624",
|
||||
"description": "条码映射:6923450605196 -> 6923450614624"
|
||||
},
|
||||
"6923450665213": {
|
||||
"map_to": "6923450665206",
|
||||
"description": "条码映射:6923450665213 -> 6923450665206"
|
||||
},
|
||||
"6923450666821": {
|
||||
"map_to": "6923450666838",
|
||||
"description": "条码映射:6923450666821 -> 6923450666838"
|
||||
},
|
||||
"6923450661505": {
|
||||
"map_to": "6923450661499",
|
||||
"description": "条码映射:6923450661505 -> 6923450661499"
|
||||
},
|
||||
"6923450676103": {
|
||||
"map_to": "6923450676097",
|
||||
"description": "条码映射:6923450676103 -> 6923450676097"
|
||||
},
|
||||
"6923450614631": {
|
||||
"map_to": "6923450614624",
|
||||
"description": "条码映射:6923450614631 -> 6923450614624"
|
||||
},
|
||||
"6901424334174": {
|
||||
"map_to": "6973730760015",
|
||||
"description": "条码映射:6901424334174 -> 6973730760015"
|
||||
},
|
||||
"6958620703716": {
|
||||
"map_to": "6958620703907",
|
||||
"description": "条码映射:6958620703716 -> 6958620703907"
|
||||
},
|
||||
"6937003706322": {
|
||||
"map_to": "6937003703833",
|
||||
"description": "条码映射:6937003706322 -> 6937003703833"
|
||||
},
|
||||
"6950783203494": {
|
||||
"map_to": "6950873203494",
|
||||
"description": "条码映射:6950783203494 -> 6950873203494"
|
||||
},
|
||||
"6907992501871": {
|
||||
"map_to": "6907992500010",
|
||||
"description": "条码映射:6907992501871 -> 6907992500010"
|
||||
},
|
||||
"6907992501864": {
|
||||
"map_to": "6907992100012",
|
||||
"description": "条码映射:6907992501864 -> 6907992100012"
|
||||
},
|
||||
"6923644264192": {
|
||||
"map_to": "6923644264116",
|
||||
"description": "条码映射:6923644264192 -> 6923644264116"
|
||||
},
|
||||
"6923450667316": {
|
||||
"map_to": "69042386",
|
||||
"description": "条码映射:6923450667316 -> 69042386"
|
||||
},
|
||||
"6923450653012": {
|
||||
"map_to": "69021343",
|
||||
"description": "条码映射:6923450653012 -> 69021343"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"6958620703907": {
|
||||
"multiplier": 14,
|
||||
"target_unit": "个",
|
||||
"specification": "1*14",
|
||||
"description": "友臣肉松,1盒14个"
|
||||
}
|
||||
}
|
||||
28
dist/config/config.ini
vendored
28
dist/config/config.ini
vendored
@ -1,28 +0,0 @@
|
||||
[API]
|
||||
api_key = O0Fgk3o69RWJ86eAX8BTHRaB
|
||||
secret_key = VyZD5lzcIMgsup1uuD6Cw0pfzS20IGPZ
|
||||
timeout = 30
|
||||
max_retries = 3
|
||||
retry_delay = 2
|
||||
api_url = https://aip.baidubce.com/rest/2.0/ocr/v1/table
|
||||
|
||||
[Paths]
|
||||
input_folder = data/input
|
||||
output_folder = data/output
|
||||
temp_folder = data/temp
|
||||
template_folder = templates
|
||||
processed_record = data/processed_files.json
|
||||
|
||||
[Performance]
|
||||
max_workers = 4
|
||||
batch_size = 5
|
||||
skip_existing = true
|
||||
|
||||
[File]
|
||||
allowed_extensions = .jpg,.jpeg,.png,.bmp
|
||||
excel_extension = .xlsx
|
||||
max_file_size_mb = 4
|
||||
|
||||
[Templates]
|
||||
purchase_order = 银豹-采购单模板.xls
|
||||
|
||||
@ -27,4 +27,4 @@
|
||||
- Excel处理功能
|
||||
- 采购单合并功能
|
||||
- 烟草订单处理功能
|
||||
- 图形用户界面
|
||||
- 图形用户界面
|
||||
309
doc/PROJECT_DOCUMENTATION.md
Normal file
309
doc/PROJECT_DOCUMENTATION.md
Normal file
@ -0,0 +1,309 @@
|
||||
# 益选-OCR订单处理系统 - 项目概述文档
|
||||
|
||||
## 项目介绍和目标
|
||||
|
||||
益选-OCR订单处理系统是一个基于Python开发的智能化采购单处理解决方案。该项目旨在通过OCR(光学字符识别)技术自动识别采购单图片中的商品信息,并将其转换为结构化的Excel数据,实现采购流程的数字化和自动化。
|
||||
|
||||
### 项目愿景
|
||||
- **自动化处理**:减少人工录入工作,提高数据处理效率
|
||||
- **智能化识别**:准确识别商品条码、名称、规格、数量、单价等关键信息
|
||||
- **标准化输出**:生成统一格式的采购单,便于后续处理和管理
|
||||
- **批量处理能力**:支持大批量图片的并发处理
|
||||
|
||||
### 核心价值
|
||||
- 将传统的手工录入模式转变为自动化处理
|
||||
- 提高采购单处理准确率,减少人为错误
|
||||
- 大幅缩短采购单处理时间,提升工作效率
|
||||
- 提供友好的图形界面,降低使用门槛
|
||||
|
||||
## 系统功能特性
|
||||
|
||||
### 核心功能模块
|
||||
|
||||
#### 1. OCR识别模块
|
||||
- **图片识别**:支持JPG、JPEG、PNG、BMP等多种图片格式
|
||||
- **表格识别**:专门优化表格结构识别,准确提取行列信息
|
||||
- **文字识别**:高精度中文数字混合识别
|
||||
- **智能纠错**:自动纠正识别过程中的常见错误
|
||||
|
||||
#### 2. Excel处理模块
|
||||
- **数据提取**:从OCR结果中提取商品信息
|
||||
- **格式转换**:将识别结果转换为标准采购单格式
|
||||
- **数据清洗**:自动清理和标准化不规范数据
|
||||
- **模板应用**:支持自定义采购单模板
|
||||
|
||||
#### 3. 采购单合并模块
|
||||
- **多文件合并**:支持合并多个采购单文件
|
||||
- **商品汇总**:自动汇总相同商品,计算总数量
|
||||
- **格式统一**:确保合并后的采购单格式一致性
|
||||
- **冲突处理**:智能处理合并过程中的数据冲突
|
||||
|
||||
#### 4. 条码映射模块
|
||||
- **条码转换**:支持将特定条码映射为其他条码
|
||||
- **系统适配**:适应不同供应商系统的条码要求
|
||||
- **映射配置**:提供灵活的条码映射规则配置
|
||||
|
||||
#### 5. 规格处理模块
|
||||
- **单位识别**:智能识别商品计量单位
|
||||
- **单位转换**:自动进行单位换算(如箱转个)
|
||||
- **规格解析**:解析复杂的商品规格描述
|
||||
|
||||
#### 6. 烟草订单处理模块
|
||||
- **专用优化**:针对烟草行业订单的特殊格式优化
|
||||
- **规则适配**:适配烟草公司的特殊要求和格式
|
||||
|
||||
### 辅助功能
|
||||
|
||||
#### 图形用户界面
|
||||
- **直观操作**:提供简洁明了的操作界面
|
||||
- **进度显示**:实时显示处理进度和状态
|
||||
- **结果预览**:处理完成后显示结果摘要
|
||||
- **日志查看**:提供详细的处理日志查看功能
|
||||
|
||||
#### 配置管理
|
||||
- **灵活配置**:支持多种处理参数的配置
|
||||
- **配置文件**:使用INI格式配置文件,易于修改
|
||||
- **运行时调整**:支持运行时的参数调整
|
||||
|
||||
#### 性能优化
|
||||
- **批量处理**:支持大批量图片的并发处理
|
||||
- **断点续传**:支持处理中断后的继续处理
|
||||
- **内存优化**:优化内存使用,支持大文件处理
|
||||
|
||||
## 技术栈和架构
|
||||
|
||||
### 核心技术栈
|
||||
|
||||
#### 后端技术
|
||||
- **Python 3.8+**:主要开发语言
|
||||
- **百度OCR API**:提供高精度的OCR识别服务
|
||||
- **Pandas**:数据处理和分析
|
||||
- **OpenPyXL**:Excel文件读写
|
||||
- **ConfigParser**:配置文件管理
|
||||
|
||||
#### 前端技术
|
||||
- **Tkinter**:Python标准GUI库
|
||||
- **Threading**:多线程处理,避免界面卡顿
|
||||
- **ttk**:现代风格的界面组件
|
||||
|
||||
#### 工具库
|
||||
- **Requests**:HTTP请求处理
|
||||
- **Logging**:日志记录和管理
|
||||
- **JSON**:数据序列化和配置存储
|
||||
- **Pathlib**:文件路径处理
|
||||
- **Datetime**:日期时间处理
|
||||
|
||||
### 系统架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 用户界面层 (UI Layer) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 业务逻辑层 (Service Layer) │
|
||||
│ ┌─────────────┬──────────────┬─────────────┬──────────┐ │
|
||||
│ │ OCR服务 │ Excel服务 │ 合并服务 │ 配置管理 │ │
|
||||
│ │ (OCRService)│ (OrderService)│ (MergeService)│ (Config) │ │
|
||||
│ └─────────────┴──────────────┴─────────────┴──────────┘ │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 核心处理层 (Core Layer) │
|
||||
│ ┌─────────────┬──────────────┬─────────────┬──────────┐ │
|
||||
│ │ OCR处理器 │ Excel处理器 │ 数据清洗 │ 工具函数 │ │
|
||||
│ │ (OCRProc) │ (ExcelProc) │ (Cleaner) │ (Utils) │ │
|
||||
│ └─────────────┴──────────────┴─────────────┴──────────┘ │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 数据访问层 (Data Access Layer) │
|
||||
│ ┌─────────────┬──────────────┬─────────────┬──────────┐ │
|
||||
│ │ 文件系统 │ 配置文件 │ 日志文件 │ 模板文件 │ │
|
||||
│ │ (FileSystem)│ (Config) │ (Logs) │ (Templates)│ │
|
||||
│ └─────────────┴──────────────┴─────────────┴──────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 模块划分
|
||||
|
||||
#### 应用层 (app/)
|
||||
- **cli/**:命令行接口模块
|
||||
- **config/**:配置管理模块
|
||||
- **core/**:核心业务逻辑模块
|
||||
- **services/**:服务层模块
|
||||
|
||||
#### 核心层 (app/core/)
|
||||
- **ocr/**:OCR识别相关功能
|
||||
- **excel/**:Excel处理相关功能
|
||||
- **utils/**:工具函数和辅助功能
|
||||
|
||||
#### 数据层
|
||||
- **data/**:数据文件存储目录
|
||||
- **templates/**:模板文件存储目录
|
||||
- **logs/**:日志文件存储目录
|
||||
|
||||
## 安装配置说明
|
||||
|
||||
### 系统要求
|
||||
|
||||
#### 软件要求
|
||||
- **操作系统**:Windows 7/8/10/11,Linux,macOS
|
||||
- **Python版本**:Python 3.8 或更高版本
|
||||
- **依赖库**:详见requirements.txt文件
|
||||
|
||||
#### 硬件要求
|
||||
- **CPU**:双核处理器或以上
|
||||
- **内存**:4GB RAM或以上
|
||||
- **存储**:至少1GB可用磁盘空间
|
||||
- **网络**:需要网络连接(用于OCR API调用)
|
||||
|
||||
### 安装步骤
|
||||
|
||||
#### 1. 环境准备
|
||||
```bash
|
||||
# 确保已安装Python 3.8+
|
||||
python --version
|
||||
|
||||
# 安装项目依赖
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
#### 2. 配置百度OCR API
|
||||
1. 注册百度智能云账号
|
||||
2. 创建OCR应用,获取API Key和Secret Key
|
||||
3. 在config.ini文件中配置API密钥:
|
||||
```ini
|
||||
[API]
|
||||
api_key = 你的API密钥
|
||||
secret_key = 你的密钥
|
||||
```
|
||||
|
||||
#### 3. 配置文件设置
|
||||
编辑config.ini文件,设置相关路径和参数:
|
||||
```ini
|
||||
[Paths]
|
||||
input_folder = data/input
|
||||
output_folder = data/output
|
||||
temp_folder = data/temp
|
||||
|
||||
[Performance]
|
||||
max_workers = 4
|
||||
batch_size = 5
|
||||
skip_existing = true
|
||||
```
|
||||
|
||||
### 运行配置
|
||||
|
||||
#### 启动方式
|
||||
```bash
|
||||
# 方式1:直接运行启动器
|
||||
python 启动器.py
|
||||
|
||||
# 方式2:运行主程序
|
||||
python run.py
|
||||
```
|
||||
|
||||
#### 可执行文件
|
||||
项目提供编译好的可执行文件:
|
||||
- **OCR订单处理系统.exe**:主程序可执行文件
|
||||
- **release/**目录:完整的发布版本
|
||||
|
||||
## 使用指南
|
||||
|
||||
### 基本操作流程
|
||||
|
||||
#### 1. 准备图片文件
|
||||
- 将需要识别的采购单图片放入`data/input`目录
|
||||
- 支持的图片格式:JPG、JPEG、PNG、BMP
|
||||
- 建议图片清晰度在300DPI以上
|
||||
|
||||
#### 2. 启动系统
|
||||
- 运行`启动器.py`或`OCR订单处理系统.exe`
|
||||
- 系统会自动加载配置并初始化
|
||||
|
||||
#### 3. 选择功能
|
||||
主界面提供以下功能选项:
|
||||
- **OCR识别**:识别图片中的商品信息
|
||||
- **Excel处理**:将OCR结果处理成标准采购单
|
||||
- **采购单合并**:合并多个采购单文件
|
||||
- **完整流程**:执行OCR识别+Excel处理+合并的完整流程
|
||||
|
||||
#### 4. 执行处理
|
||||
- 点击相应功能按钮
|
||||
- 系统会显示处理进度和状态
|
||||
- 处理完成后显示结果预览
|
||||
|
||||
#### 5. 查看结果
|
||||
- 处理结果保存在`data/output`目录
|
||||
- 可以查看生成的Excel采购单文件
|
||||
- 通过日志查看详细处理过程
|
||||
|
||||
### 高级功能使用
|
||||
|
||||
#### 批量处理配置
|
||||
在config.ini中设置批量处理参数:
|
||||
```ini
|
||||
[Performance]
|
||||
batch_size = 5 # 每批处理的文件数量
|
||||
max_workers = 4 # 最大并发线程数
|
||||
skip_existing = true # 跳过已处理的文件
|
||||
```
|
||||
|
||||
#### 条码映射配置
|
||||
编辑`config/barcode_mappings.json`文件,设置条码映射规则:
|
||||
```json
|
||||
{
|
||||
"原条码1": "目标条码1",
|
||||
"原条码2": "目标条码2"
|
||||
}
|
||||
```
|
||||
|
||||
#### 模板配置
|
||||
在`templates`目录中放置自定义的采购单模板文件,系统会自动识别并使用。
|
||||
|
||||
### 故障排除
|
||||
|
||||
#### 常见问题
|
||||
1. **OCR识别失败**:检查图片清晰度和格式
|
||||
2. **网络连接失败**:检查API密钥和网络设置
|
||||
3. **文件权限错误**:确保有读写权限
|
||||
4. **内存不足**:减少批量处理的大小
|
||||
|
||||
#### 日志查看
|
||||
查看`logs`目录下的日志文件,获取详细的错误信息和处理过程。
|
||||
|
||||
### 最佳实践
|
||||
|
||||
#### 图片质量
|
||||
- 使用高分辨率扫描或拍照
|
||||
- 确保图片清晰,无反光和阴影
|
||||
- 保持采购单平整,避免折叠
|
||||
|
||||
#### 处理效率
|
||||
- 合理设置批量处理大小
|
||||
- 使用多线程处理提高效率
|
||||
- 定期清理临时文件
|
||||
|
||||
#### 数据管理
|
||||
- 定期备份重要的采购单数据
|
||||
- 建立规范的文件命名规则
|
||||
- 及时清理已处理的文件
|
||||
|
||||
## 项目维护
|
||||
|
||||
### 版本管理
|
||||
- 使用Git进行版本控制
|
||||
- 定期更新CHANGELOG.md文件
|
||||
- 维护版本发布记录
|
||||
|
||||
### 依赖管理
|
||||
- 定期更新依赖库版本
|
||||
- 测试新版本的兼容性
|
||||
- 维护requirements.txt文件
|
||||
|
||||
### 文档维护
|
||||
- 保持文档的及时更新
|
||||
- 根据用户反馈完善文档
|
||||
- 提供多语言支持
|
||||
|
||||
## 版权信息
|
||||
|
||||
© 2025 益选-OCR订单处理系统
|
||||
作者:欢欢欢
|
||||
|
||||
本项目采用模块化设计,遵循最佳实践,致力于为用户提供高效、准确的采购单自动化处理解决方案。
|
||||
@ -40,4 +40,4 @@
|
||||
|
||||
## 版权
|
||||
|
||||
© 2025 益选-OCR订单处理系统
|
||||
© 2025 益选-OCR订单处理系统
|
||||
634
doc/TECHNICAL_ARCHITECTURE.md
Normal file
634
doc/TECHNICAL_ARCHITECTURE.md
Normal file
@ -0,0 +1,634 @@
|
||||
# 益选-OCR订单处理系统 - 技术架构文档
|
||||
|
||||
## 系统架构设计
|
||||
|
||||
### 整体架构概述
|
||||
|
||||
益选-OCR订单处理系统采用分层架构设计,遵循单一职责原则和开闭原则,确保系统的可维护性、可扩展性和可测试性。系统架构分为四个主要层次:用户界面层、业务逻辑层、核心处理层和数据访问层。
|
||||
|
||||
### 架构设计原则
|
||||
|
||||
#### 1. 分层解耦
|
||||
- 各层之间通过明确定义的接口进行通信
|
||||
- 上层依赖下层,下层不依赖上层
|
||||
- 层与层之间保持松耦合关系
|
||||
|
||||
#### 2. 模块化设计
|
||||
- 每个模块具有明确的职责边界
|
||||
- 模块内部高内聚,模块之间低耦合
|
||||
- 支持模块的独立开发和测试
|
||||
|
||||
#### 3. 配置驱动
|
||||
- 系统行为通过配置文件控制
|
||||
- 支持运行时参数调整
|
||||
- 提供灵活的配置管理机制
|
||||
|
||||
#### 4. 错误处理
|
||||
- 统一的异常处理机制
|
||||
- 详细的日志记录和错误追踪
|
||||
- 优雅的错误恢复机制
|
||||
|
||||
## 模块划分和职责
|
||||
|
||||
### 用户界面层 (UI Layer)
|
||||
|
||||
#### 启动器模块 (启动器.py)
|
||||
**职责**:
|
||||
- 提供图形用户界面
|
||||
- 协调各个功能模块的调用
|
||||
- 显示处理进度和结果
|
||||
- 管理用户交互流程
|
||||
|
||||
**主要组件**:
|
||||
- `OCR订单处理系统`类:主应用程序类
|
||||
- `StatusBar`类:状态栏组件
|
||||
- `LogRedirector`类:日志重定向器
|
||||
- 各种对话框和预览窗口
|
||||
|
||||
#### 命令行接口 (app/cli/)
|
||||
**职责**:
|
||||
- 提供命令行操作方式
|
||||
- 支持脚本化操作
|
||||
- 实现批量处理功能
|
||||
|
||||
**子模块**:
|
||||
- `ocr_cli.py`:OCR识别命令行接口
|
||||
- `excel_cli.py`:Excel处理命令行接口
|
||||
- `merge_cli.py`:合并功能命令行接口
|
||||
|
||||
### 业务逻辑层 (Service Layer)
|
||||
|
||||
#### OCR服务 (app/services/ocr_service.py)
|
||||
**职责**:
|
||||
- 协调OCR识别流程
|
||||
- 管理OCR处理器的生命周期
|
||||
- 提供OCR相关的业务逻辑
|
||||
- 处理OCR结果的验证和转换
|
||||
|
||||
**核心方法**:
|
||||
- `process_image()`:处理单个图片
|
||||
- `process_images_batch()`:批量处理图片
|
||||
- `get_unprocessed_images()`:获取待处理图片列表
|
||||
- `validate_image()`:验证图片有效性
|
||||
|
||||
#### 订单服务 (app/services/order_service.py)
|
||||
**职责**:
|
||||
- 处理Excel订单文件
|
||||
- 提取和标准化商品信息
|
||||
- 应用条码映射规则
|
||||
- 执行规格单位转换
|
||||
|
||||
**核心功能**:
|
||||
- Excel文件读取和解析
|
||||
- 商品信息提取和清洗
|
||||
- 条码映射和转换
|
||||
- 规格单位智能识别
|
||||
|
||||
#### 烟草服务 (app/services/tobacco_service.py)
|
||||
**职责**:
|
||||
- 专门处理烟草行业订单
|
||||
- 适配烟草公司的特殊格式
|
||||
- 处理烟草订单的特定规则
|
||||
|
||||
#### 合并服务
|
||||
**职责**:
|
||||
- 合并多个采购单文件
|
||||
- 汇总相同商品信息
|
||||
- 处理合并冲突和重复项
|
||||
|
||||
### 核心处理层 (Core Layer)
|
||||
|
||||
#### OCR处理核心 (app/core/ocr/)
|
||||
|
||||
##### 表格OCR处理器 (table_ocr.py)
|
||||
**职责**:
|
||||
- 协调OCR识别流程
|
||||
- 管理处理记录
|
||||
- 控制批量处理逻辑
|
||||
- 处理文件I/O操作
|
||||
|
||||
**核心组件**:
|
||||
- `OCRProcessor`类:主要的OCR处理器
|
||||
- `ProcessedRecordManager`类:处理记录管理器
|
||||
|
||||
**处理流程**:
|
||||
1. 图片验证和预处理
|
||||
2. 调用百度OCR API进行识别
|
||||
3. 解析OCR返回结果
|
||||
4. 生成Excel文件
|
||||
5. 更新处理记录
|
||||
|
||||
##### 百度OCR客户端 (baidu_ocr.py)
|
||||
**职责**:
|
||||
- 封装百度OCR API调用
|
||||
- 处理API认证和授权
|
||||
- 管理API请求和响应
|
||||
- 实现重试和错误处理机制
|
||||
|
||||
**核心功能**:
|
||||
- API密钥管理
|
||||
- 请求签名生成
|
||||
- 表格识别API调用
|
||||
- 结果获取和解析
|
||||
|
||||
#### Excel处理核心 (app/core/excel/)
|
||||
|
||||
##### Excel处理器
|
||||
**职责**:
|
||||
- 读取和解析Excel文件
|
||||
- 提取商品信息
|
||||
- 数据清洗和标准化
|
||||
- 生成标准采购单格式
|
||||
|
||||
**处理逻辑**:
|
||||
1. 读取Excel文件
|
||||
2. 识别商品数据区域
|
||||
3. 提取商品属性(条码、名称、规格、数量、单价)
|
||||
4. 应用数据清洗规则
|
||||
5. 生成标准化输出
|
||||
|
||||
##### 单位转换器 (converter.py)
|
||||
**职责**:
|
||||
- 智能识别商品规格单位
|
||||
- 执行单位换算
|
||||
- 处理复杂的规格描述
|
||||
|
||||
**支持的单位**:
|
||||
- 数量单位:个、只、条、包、箱、件等
|
||||
- 重量单位:克、千克、斤、公斤等
|
||||
- 体积单位:毫升、升、立方米等
|
||||
|
||||
#### 工具模块 (app/core/utils/)
|
||||
|
||||
##### 文件工具 (file_utils.py)
|
||||
**职责**:
|
||||
- 文件系统操作封装
|
||||
- 路径处理和验证
|
||||
- 文件类型检查
|
||||
- 批量文件操作
|
||||
|
||||
##### 日志工具 (log_utils.py)
|
||||
**职责**:
|
||||
- 日志配置和管理
|
||||
- 日志级别控制
|
||||
- 日志文件轮转
|
||||
- 错误追踪和记录
|
||||
|
||||
##### 对话框工具 (dialog_utils.py)
|
||||
**职责**:
|
||||
- 自定义对话框实现
|
||||
- 用户交互界面组件
|
||||
- 配置界面管理
|
||||
|
||||
### 数据访问层 (Data Access Layer)
|
||||
|
||||
#### 配置管理 (app/config/)
|
||||
|
||||
##### 配置管理器 (settings.py)
|
||||
**职责**:
|
||||
- 配置文件加载和解析
|
||||
- 配置项访问和修改
|
||||
- 配置验证和默认值处理
|
||||
- 配置持久化
|
||||
|
||||
##### 默认配置 (defaults.py)
|
||||
**职责**:
|
||||
- 定义系统默认配置
|
||||
- 提供配置模板
|
||||
- 确保配置完整性
|
||||
|
||||
#### 数据存储
|
||||
|
||||
##### 文件系统接口
|
||||
- **输入目录**:`data/input/` - 存放待处理的图片文件
|
||||
- **输出目录**:`data/output/` - 存放处理结果和生成的Excel文件
|
||||
- **临时目录**:`data/temp/` - 存放临时文件
|
||||
- **模板目录**:`templates/` - 存放Excel模板文件
|
||||
- **配置目录**:`config/` - 存放配置文件和映射规则
|
||||
|
||||
##### 处理记录管理
|
||||
- **JSON记录文件**:`data/output/processed_files.json`
|
||||
- **记录内容**:已处理文件的映射关系
|
||||
- **更新机制**:处理完成后自动更新记录
|
||||
|
||||
## 核心算法和流程
|
||||
|
||||
### OCR识别算法流程
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[开始] --> B[图片验证]
|
||||
B --> C{图片有效?}
|
||||
C -->|是| D[检查是否已处理]
|
||||
C -->|否| E[返回错误]
|
||||
D --> F{已处理?}
|
||||
F -->|是| G[返回现有结果]
|
||||
F -->|否| H[调用百度OCR API]
|
||||
H --> I[解析OCR结果]
|
||||
I --> J[生成Excel文件]
|
||||
J --> K[更新处理记录]
|
||||
K --> L[返回成功]
|
||||
E --> M[结束]
|
||||
G --> M
|
||||
L --> M
|
||||
```
|
||||
|
||||
#### 图片验证算法
|
||||
```python
|
||||
def validate_image(image_path: str) -> bool:
|
||||
# 1. 文件存在性检查
|
||||
if not os.path.exists(image_path):
|
||||
return False
|
||||
|
||||
# 2. 文件扩展名验证
|
||||
ext = get_file_extension(image_path)
|
||||
if ext not in ALLOWED_EXTENSIONS:
|
||||
return False
|
||||
|
||||
# 3. 文件大小检查
|
||||
if not is_file_size_valid(image_path, MAX_SIZE_MB):
|
||||
return False
|
||||
|
||||
# 4. 图片格式验证(可选)
|
||||
try:
|
||||
with Image.open(image_path) as img:
|
||||
img.verify()
|
||||
except:
|
||||
return False
|
||||
|
||||
return True
|
||||
```
|
||||
|
||||
#### OCR结果解析算法
|
||||
```python
|
||||
def parse_ocr_result(ocr_response: dict) -> dict:
|
||||
result = {
|
||||
'tables': [],
|
||||
'text': '',
|
||||
'excel_data': None
|
||||
}
|
||||
|
||||
# 1. 提取表格数据
|
||||
if 'tables_result' in ocr_response:
|
||||
for table in ocr_response['tables_result']:
|
||||
table_data = extract_table_data(table)
|
||||
result['tables'].append(table_data)
|
||||
|
||||
# 2. 提取文本内容
|
||||
if 'words_result' in ocr_response:
|
||||
result['text'] = extract_text_content(ocr_response['words_result'])
|
||||
|
||||
# 3. 提取Excel数据
|
||||
excel_base64 = find_excel_data(ocr_response)
|
||||
if excel_base64:
|
||||
result['excel_data'] = base64.b64decode(excel_base64)
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
### Excel处理算法流程
|
||||
|
||||
#### 商品信息提取算法
|
||||
```python
|
||||
def extract_product_info(excel_data: pd.DataFrame) -> List[Dict]:
|
||||
products = []
|
||||
|
||||
# 1. 识别表头行
|
||||
header_row = identify_header_row(excel_data)
|
||||
|
||||
# 2. 确定列映射
|
||||
column_mapping = map_columns(excel_data.iloc[header_row])
|
||||
|
||||
# 3. 提取商品数据
|
||||
for row_idx in range(header_row + 1, len(excel_data)):
|
||||
row_data = excel_data.iloc[row_idx]
|
||||
|
||||
product = {
|
||||
'barcode': extract_barcode(row_data, column_mapping),
|
||||
'name': extract_product_name(row_data, column_mapping),
|
||||
'specification': extract_specification(row_data, column_mapping),
|
||||
'quantity': extract_quantity(row_data, column_mapping),
|
||||
'unit_price': extract_unit_price(row_data, column_mapping),
|
||||
'total_price': extract_total_price(row_data, column_mapping)
|
||||
}
|
||||
|
||||
# 4. 数据验证和清洗
|
||||
if validate_product(product):
|
||||
cleaned_product = clean_product_data(product)
|
||||
products.append(cleaned_product)
|
||||
|
||||
return products
|
||||
```
|
||||
|
||||
#### 规格单位识别算法
|
||||
```python
|
||||
def parse_specification(spec_text: str) -> Dict:
|
||||
result = {
|
||||
'original': spec_text,
|
||||
'quantity': 1,
|
||||
'unit': '个',
|
||||
'parsed': False
|
||||
}
|
||||
|
||||
# 1. 预定义单位模式
|
||||
unit_patterns = {
|
||||
r'(\d+)\s*个': ('个', 1),
|
||||
r'(\d+)\s*只': ('只', 1),
|
||||
r'(\d+)\s*条': ('条', 1),
|
||||
r'(\d+)\s*包': ('包', 1),
|
||||
r'(\d+)\s*箱': ('箱', 1),
|
||||
r'(\d+)\s*件': ('件', 1),
|
||||
r'(\d+)\s*克': ('克', 1),
|
||||
r'(\d+)\s*千克': ('千克', 1),
|
||||
r'(\d+)\s*斤': ('斤', 1),
|
||||
r'(\d+)\s*公斤': ('公斤', 1)
|
||||
}
|
||||
|
||||
# 2. 模式匹配
|
||||
for pattern, (unit, multiplier) in unit_patterns.items():
|
||||
match = re.search(pattern, spec_text, re.IGNORECASE)
|
||||
if match:
|
||||
result['quantity'] = int(match.group(1))
|
||||
result['unit'] = unit
|
||||
result['parsed'] = True
|
||||
break
|
||||
|
||||
# 3. 复杂规格处理
|
||||
if not result['parsed']:
|
||||
result = parse_complex_specification(spec_text)
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
### 采购单合并算法
|
||||
|
||||
#### 商品汇总算法
|
||||
```python
|
||||
def merge_products(products_list: List[List[Dict]]) -> List[Dict]:
|
||||
merged_products = {}
|
||||
|
||||
# 1. 收集所有商品
|
||||
for products in products_list:
|
||||
for product in products:
|
||||
key = generate_product_key(product)
|
||||
|
||||
if key in merged_products:
|
||||
# 2. 合并相同商品
|
||||
merged_products[key]['quantity'] += product['quantity']
|
||||
merged_products[key]['total_price'] += product['total_price']
|
||||
merged_products[key]['source_files'].append(product.get('source_file', ''))
|
||||
else:
|
||||
# 3. 添加新商品
|
||||
merged_products[key] = product.copy()
|
||||
merged_products[key]['source_files'] = [product.get('source_file', '')]
|
||||
|
||||
# 4. 转换回列表格式
|
||||
result = list(merged_products.values())
|
||||
|
||||
# 5. 排序(按条码或名称)
|
||||
result.sort(key=lambda x: x.get('barcode', x.get('name', '')))
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
## 数据流设计
|
||||
|
||||
### 主要数据流
|
||||
|
||||
#### 1. OCR识别数据流
|
||||
```
|
||||
输入图片 → 图片验证 → OCR API调用 → 结果解析 → Excel生成 → 输出文件
|
||||
```
|
||||
|
||||
#### 2. Excel处理数据流
|
||||
```
|
||||
Excel文件 → 数据读取 → 商品提取 → 数据清洗 → 格式转换 → 标准采购单
|
||||
```
|
||||
|
||||
#### 3. 合并处理数据流
|
||||
```
|
||||
多个采购单 → 商品提取 → 去重汇总 → 冲突处理 → 合并结果 → 输出文件
|
||||
```
|
||||
|
||||
### 数据结构设计
|
||||
|
||||
#### 商品数据结构
|
||||
```python
|
||||
{
|
||||
'barcode': str, # 商品条码
|
||||
'name': str, # 商品名称
|
||||
'specification': str, # 商品规格
|
||||
'quantity': int, # 数量
|
||||
'unit': str, # 单位
|
||||
'unit_price': float, # 单价
|
||||
'total_price': float, # 总价
|
||||
'source_file': str, # 来源文件
|
||||
'category': str, # 商品类别
|
||||
'brand': str # 品牌
|
||||
}
|
||||
```
|
||||
|
||||
#### 处理记录数据结构
|
||||
```python
|
||||
{
|
||||
'image_file': str, # 输入图片路径
|
||||
'output_file': str, # 输出文件路径
|
||||
'processing_time': str, # 处理时间
|
||||
'status': str, # 处理状态
|
||||
'error_message': str # 错误信息(如果有)
|
||||
}
|
||||
```
|
||||
|
||||
#### OCR结果数据结构
|
||||
```python
|
||||
{
|
||||
'tables': List[Dict], # 表格数据
|
||||
'text': str, # 文本内容
|
||||
'excel_data': bytes, # Excel文件数据
|
||||
'confidence': float, # 识别置信度
|
||||
'processing_time': float # 处理耗时
|
||||
}
|
||||
```
|
||||
|
||||
## 关键技术实现
|
||||
|
||||
### 并发处理机制
|
||||
|
||||
#### 多线程批量处理
|
||||
```python
|
||||
class BatchProcessor:
|
||||
def __init__(self, max_workers: int = 4):
|
||||
self.max_workers = max_workers
|
||||
self.executor = ThreadPoolExecutor(max_workers=max_workers)
|
||||
|
||||
def process_batch(self, items: List[Any], processor_func) -> List[Any]:
|
||||
# 使用线程池并发处理
|
||||
futures = [self.executor.submit(processor_func, item) for item in items]
|
||||
|
||||
# 收集处理结果
|
||||
results = []
|
||||
for future in as_completed(futures):
|
||||
try:
|
||||
result = future.result()
|
||||
results.append(result)
|
||||
except Exception as e:
|
||||
logger.error(f"处理失败: {e}")
|
||||
results.append(None)
|
||||
|
||||
return results
|
||||
```
|
||||
|
||||
### 错误处理和重试机制
|
||||
|
||||
#### API调用重试机制
|
||||
```python
|
||||
def call_with_retry(func, max_retries=3, retry_delay=2):
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
result = func()
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.warning(f"第{attempt + 1}次尝试失败: {e}")
|
||||
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(retry_delay)
|
||||
else:
|
||||
logger.error(f"所有重试尝试都失败")
|
||||
raise
|
||||
```
|
||||
|
||||
### 内存优化策略
|
||||
|
||||
#### 大文件处理
|
||||
```python
|
||||
def process_large_file(file_path: str, chunk_size: int = 1000):
|
||||
# 使用生成器避免一次性加载大文件
|
||||
def read_in_chunks():
|
||||
with pd.read_excel(file_path, chunksize=chunk_size) as reader:
|
||||
for chunk in reader:
|
||||
yield chunk
|
||||
|
||||
# 逐块处理
|
||||
for chunk in read_in_chunks():
|
||||
process_chunk(chunk)
|
||||
# 及时清理内存
|
||||
del chunk
|
||||
gc.collect()
|
||||
```
|
||||
|
||||
### 配置管理实现
|
||||
|
||||
#### 动态配置加载
|
||||
```python
|
||||
class ConfigManager:
|
||||
def __init__(self, config_file: str):
|
||||
self.config_file = config_file
|
||||
self.config = configparser.ConfigParser()
|
||||
self.load_config()
|
||||
|
||||
def load_config(self):
|
||||
if os.path.exists(self.config_file):
|
||||
self.config.read(self.config_file, encoding='utf-8')
|
||||
else:
|
||||
self.create_default_config()
|
||||
|
||||
def get(self, section: str, option: str, fallback: Any = None) -> Any:
|
||||
return self.config.get(section, option, fallback=fallback)
|
||||
|
||||
def getint(self, section: str, option: str, fallback: int = 0) -> int:
|
||||
return self.config.getint(section, option, fallback=fallback)
|
||||
|
||||
def getboolean(self, section: str, option: str, fallback: bool = False) -> bool:
|
||||
return self.config.getboolean(section, option, fallback=fallback)
|
||||
```
|
||||
|
||||
### 日志系统设计
|
||||
|
||||
#### 结构化日志记录
|
||||
```python
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
def setup_logging(log_file: str = 'logs/app.log'):
|
||||
# 创建logger
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
# 创建文件处理器(带轮转)
|
||||
file_handler = RotatingFileHandler(
|
||||
log_file, maxBytes=10*1024*1024, backupCount=5
|
||||
)
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
|
||||
# 创建控制台处理器
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
|
||||
# 创建格式化器
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
|
||||
# 添加格式化器到处理器
|
||||
file_handler.setFormatter(formatter)
|
||||
console_handler.setFormatter(formatter)
|
||||
|
||||
# 添加处理器到logger
|
||||
logger.addHandler(file_handler)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
return logger
|
||||
```
|
||||
|
||||
### 性能监控和优化
|
||||
|
||||
#### 处理时间统计
|
||||
```python
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
def timing_decorator(func):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
start_time = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
end_time = time.time()
|
||||
|
||||
processing_time = end_time - start_time
|
||||
logger.info(f"{func.__name__} 执行耗时: {processing_time:.2f}秒")
|
||||
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
```
|
||||
|
||||
### 安全性考虑
|
||||
|
||||
#### API密钥管理
|
||||
```python
|
||||
import os
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
class SecureConfig:
|
||||
def __init__(self, encryption_key: str = None):
|
||||
self.cipher = Fernet(encryption_key or self._get_or_create_key())
|
||||
|
||||
def _get_or_create_key(self) -> str:
|
||||
key_file = 'config/.key'
|
||||
if os.path.exists(key_file):
|
||||
with open(key_file, 'rb') as f:
|
||||
return f.read()
|
||||
else:
|
||||
key = Fernet.generate_key()
|
||||
with open(key_file, 'wb') as f:
|
||||
f.write(key)
|
||||
return key
|
||||
|
||||
def encrypt(self, data: str) -> str:
|
||||
return self.cipher.encrypt(data.encode()).decode()
|
||||
|
||||
def decrypt(self, encrypted_data: str) -> str:
|
||||
return self.cipher.decrypt(encrypted_data.encode()).decode()
|
||||
```
|
||||
|
||||
这个技术架构文档详细描述了益选-OCR订单处理系统的技术实现细节,包括系统架构设计、模块职责划分、核心算法流程、数据流设计以及关键技术实现。系统设计遵循软件工程最佳实践,确保系统的可靠性、可维护性和可扩展性。
|
||||
476
doc/USER_MANUAL.md
Normal file
476
doc/USER_MANUAL.md
Normal file
@ -0,0 +1,476 @@
|
||||
# 益选-OCR订单处理系统 - 用户操作手册
|
||||
|
||||
## 界面功能介绍
|
||||
|
||||
### 主界面布局
|
||||
|
||||
#### 启动界面
|
||||
系统启动时会显示一个简洁的启动界面,包含:
|
||||
- **系统标题**:益选-OCR订单处理系统
|
||||
- **版本信息**:显示当前系统版本
|
||||
- **加载进度**:显示系统初始化进度
|
||||
|
||||
#### 主操作界面
|
||||
主界面采用现代化设计风格,包含以下主要区域:
|
||||
|
||||
##### 顶部工具栏
|
||||
- **系统标题**:显示在界面顶部中央
|
||||
- **主题切换**:支持浅色/深色主题切换
|
||||
- **帮助按钮**:访问用户手册和系统信息
|
||||
|
||||
##### 功能按钮区域
|
||||
- **OCR识别按钮**:启动图片识别功能
|
||||
- **Excel处理按钮**:处理OCR识别结果
|
||||
- **采购单合并按钮**:合并多个采购单
|
||||
- **完整流程按钮**:执行完整的处理流程
|
||||
- **配置管理按钮**:打开系统配置界面
|
||||
|
||||
##### 状态栏
|
||||
- **状态显示**:显示当前系统状态(就绪/处理中/完成)
|
||||
- **进度条**:显示处理进度百分比
|
||||
- **时间信息**:显示处理开始时间和耗时
|
||||
|
||||
##### 日志显示区域
|
||||
- **实时日志**:显示处理过程的详细日志
|
||||
- **颜色标识**:不同级别的日志使用不同颜色
|
||||
- **滚动支持**:支持日志内容的滚动查看
|
||||
- **清空功能**:可以清空当前日志内容
|
||||
|
||||
### 功能界面详解
|
||||
|
||||
#### OCR识别界面
|
||||
当点击OCR识别按钮时,系统会:
|
||||
1. 自动扫描`data/input`目录中的图片文件
|
||||
2. 显示找到的图片文件数量
|
||||
3. 开始批量OCR识别处理
|
||||
4. 实时显示处理进度和结果
|
||||
|
||||
#### Excel处理界面
|
||||
处理OCR结果时,系统会:
|
||||
1. 读取OCR生成的Excel文件
|
||||
2. 提取商品信息(条码、名称、规格、数量、单价)
|
||||
3. 应用数据清洗和标准化规则
|
||||
4. 生成标准格式的采购单
|
||||
|
||||
#### 采购单合并界面
|
||||
合并功能界面提供:
|
||||
1. 选择要合并的采购单文件
|
||||
2. 显示合并进度和状态
|
||||
3. 展示合并结果摘要
|
||||
4. 提供合并后文件的快速访问
|
||||
|
||||
#### 配置管理界面
|
||||
配置界面包含:
|
||||
1. **基本设置**:输入输出目录配置
|
||||
2. **API配置**:百度OCR API密钥设置
|
||||
3. **性能设置**:批量处理参数配置
|
||||
4. **高级设置**:其他高级参数配置
|
||||
|
||||
## 详细操作步骤
|
||||
|
||||
### 首次使用设置
|
||||
|
||||
#### 1. 系统安装和配置
|
||||
**步骤1.1**:确保系统环境满足要求
|
||||
- 操作系统:Windows 7/8/10/11,Linux,macOS
|
||||
- Python版本:3.8或更高版本(如使用源码)
|
||||
|
||||
**步骤1.2**:获取百度OCR API密钥
|
||||
1. 访问百度智能云官网(https://cloud.baidu.com/)
|
||||
2. 注册并登录账号
|
||||
3. 进入"文字识别"服务
|
||||
4. 创建应用,获取API Key和Secret Key
|
||||
5. 记录这两个密钥,后续配置需要使用
|
||||
|
||||
**步骤1.3**:配置系统参数
|
||||
1. 打开`config.ini`文件
|
||||
2. 在`[API]`部分填入获取的密钥:
|
||||
```ini
|
||||
[API]
|
||||
api_key = 你的API密钥
|
||||
secret_key = 你的Secret密钥
|
||||
timeout = 30
|
||||
max_retries = 3
|
||||
retry_delay = 2
|
||||
```
|
||||
|
||||
3. 配置输入输出路径:
|
||||
```ini
|
||||
[Paths]
|
||||
input_folder = data/input
|
||||
output_folder = data/output
|
||||
temp_folder = data/temp
|
||||
```
|
||||
|
||||
#### 2. 准备图片文件
|
||||
**步骤2.1**:创建图片文件夹
|
||||
在系统目录下确保存在以下文件夹:
|
||||
- `data/input/` - 存放待处理的采购单图片
|
||||
- `data/output/` - 存放处理结果
|
||||
|
||||
**步骤2.2**:图片质量要求
|
||||
- **分辨率**:建议300DPI或更高
|
||||
- **格式**:支持JPG、JPEG、PNG、BMP格式
|
||||
- **大小**:单张图片不超过4MB
|
||||
- **清晰度**:文字清晰,无模糊、反光
|
||||
|
||||
**步骤2.3**:图片命名规范
|
||||
- 使用有意义的文件名,如"采购单_20250101.jpg"
|
||||
- 避免使用特殊字符和空格
|
||||
- 建议使用日期和序号进行命名
|
||||
|
||||
### 基本操作流程
|
||||
|
||||
#### 单张图片处理流程
|
||||
|
||||
**步骤1**:启动系统
|
||||
1. 双击`OCR订单处理系统.exe`或在命令行运行`python 启动器.py`
|
||||
2. 等待系统初始化完成(状态栏显示"就绪")
|
||||
|
||||
**步骤2**:放置图片文件
|
||||
1. 将采购单图片文件复制到`data/input/`目录
|
||||
2. 确保图片格式正确,质量良好
|
||||
|
||||
**步骤3**:执行OCR识别
|
||||
1. 点击"OCR识别"按钮
|
||||
2. 系统会自动扫描输入目录
|
||||
3. 在日志区域查看处理进度
|
||||
4. 等待识别完成
|
||||
|
||||
**步骤4**:处理Excel结果
|
||||
1. 点击"Excel处理"按钮
|
||||
2. 系统会读取OCR生成的Excel文件
|
||||
3. 提取商品信息并标准化
|
||||
4. 生成标准采购单格式
|
||||
|
||||
**步骤5**:查看处理结果
|
||||
1. 处理完成后,点击"打开输出目录"
|
||||
2. 查看生成的Excel采购单文件
|
||||
3. 核对商品信息是否正确
|
||||
|
||||
#### 批量处理流程
|
||||
|
||||
**步骤1**:准备多张图片
|
||||
1. 将多个采购单图片放入`data/input/`目录
|
||||
2. 确保所有图片都符合质量要求
|
||||
|
||||
**步骤2**:执行完整流程
|
||||
1. 点击"完整流程"按钮
|
||||
2. 系统会依次执行:
|
||||
- OCR识别所有图片
|
||||
- 处理所有Excel文件
|
||||
- 合并相同商品
|
||||
3. 查看批量处理结果
|
||||
|
||||
**步骤3**:监控处理进度
|
||||
1. 观察状态栏的进度条
|
||||
2. 查看日志区域的详细信息
|
||||
3. 如有错误,查看错误信息并处理
|
||||
|
||||
### 高级功能使用
|
||||
|
||||
#### 条码映射配置
|
||||
|
||||
**步骤1**:打开条码映射文件
|
||||
1. 编辑`config/barcode_mappings.json`文件
|
||||
2. 按照JSON格式添加映射规则
|
||||
|
||||
**步骤2**:配置映射规则
|
||||
```json
|
||||
{
|
||||
"原条码1": "目标条码1",
|
||||
"原条码2": "目标条码2",
|
||||
"6901234567890": "新条码123456"
|
||||
}
|
||||
```
|
||||
|
||||
**步骤3**:应用映射规则
|
||||
1. 系统在处理时会自动应用映射
|
||||
2. 原条码会被替换为目标条码
|
||||
3. 适用于不同系统的条码适配
|
||||
|
||||
#### 自定义模板使用
|
||||
|
||||
**步骤1**:准备模板文件
|
||||
1. 在`templates/`目录放置Excel模板
|
||||
2. 模板应包含标准的采购单格式
|
||||
|
||||
**步骤2**:配置模板
|
||||
1. 在`config.ini`中配置模板:
|
||||
```ini
|
||||
[Templates]
|
||||
purchase_order = 银豹-采购单模板.xls
|
||||
```
|
||||
|
||||
**步骤3**:使用模板
|
||||
1. 系统生成采购单时会使用指定模板
|
||||
2. 确保模板格式与系统要求匹配
|
||||
|
||||
#### 性能调优
|
||||
|
||||
**步骤1**:调整批量处理参数
|
||||
在`config.ini`中配置:
|
||||
```ini
|
||||
[Performance]
|
||||
max_workers = 4 # 最大工作线程数
|
||||
batch_size = 5 # 每批处理文件数
|
||||
skip_existing = true # 跳过已处理文件
|
||||
```
|
||||
|
||||
**步骤2**:优化处理策略
|
||||
- 根据电脑性能调整线程数
|
||||
- 大批量处理时适当增加批大小
|
||||
- 启用跳过已处理文件以提高效率
|
||||
|
||||
**步骤3**:监控资源使用
|
||||
- 观察CPU和内存使用情况
|
||||
- 根据系统资源调整参数
|
||||
- 避免设置过高的并发数
|
||||
|
||||
## 常见问题解答
|
||||
|
||||
### Q1: 系统无法启动怎么办?
|
||||
**A1**:
|
||||
1. 检查Python环境是否正确安装(源码版本)
|
||||
2. 确认所有依赖库已安装:`pip install -r requirements.txt`
|
||||
3. 检查是否有足够的系统权限
|
||||
4. 查看错误日志获取详细信息
|
||||
|
||||
### Q2: OCR识别失败如何处理?
|
||||
**A2**:
|
||||
1. 检查图片质量是否满足要求
|
||||
2. 确认图片格式是否支持
|
||||
3. 验证百度OCR API密钥是否正确
|
||||
4. 检查网络连接是否正常
|
||||
5. 尝试降低图片分辨率或压缩图片大小
|
||||
|
||||
### Q3: 识别结果不准确怎么办?
|
||||
**A3**:
|
||||
1. 提高图片扫描分辨率
|
||||
2. 确保图片光线充足,无反光
|
||||
3. 检查采购单格式是否规范
|
||||
4. 手动校正重要的商品信息
|
||||
5. 考虑使用更高质量的扫描设备
|
||||
|
||||
### Q4: 批量处理时系统卡顿?
|
||||
**A4**:
|
||||
1. 降低批量处理的并发线程数
|
||||
2. 减小每批处理的文件数量
|
||||
3. 关闭其他占用资源的程序
|
||||
4. 增加系统内存或使用更高配置的电脑
|
||||
|
||||
### Q5: 生成的Excel文件打不开?
|
||||
**A5**:
|
||||
1. 确认已安装Excel或兼容软件
|
||||
2. 检查文件是否完整生成
|
||||
3. 验证文件路径是否正确
|
||||
4. 尝试使用不同版本的Excel打开
|
||||
5. 检查是否有足够的磁盘空间
|
||||
|
||||
### Q6: 条码映射不生效?
|
||||
**A6**:
|
||||
1. 检查JSON文件格式是否正确
|
||||
2. 确认条码映射文件路径正确
|
||||
3. 验证原条码和目标条码格式
|
||||
4. 重启系统使配置生效
|
||||
5. 检查日志中是否有映射相关的错误信息
|
||||
|
||||
### Q7: 处理速度很慢怎么办?
|
||||
**A7**:
|
||||
1. 优化网络连接,使用稳定的网络
|
||||
2. 调整批量处理参数
|
||||
3. 使用本地缓存减少API调用
|
||||
4. 考虑使用更高性能的硬件
|
||||
5. 分批处理大量文件,避免一次性处理过多
|
||||
|
||||
### Q8: 系统显示"未找到可合并的文件"?
|
||||
**A8**:
|
||||
1. 确认输出目录中有Excel文件
|
||||
2. 检查文件格式是否符合要求
|
||||
3. 验证文件是否包含有效的商品数据
|
||||
4. 确保文件没有被其他程序锁定
|
||||
|
||||
## 故障排除指南
|
||||
|
||||
### 系统启动问题
|
||||
|
||||
#### 症状:双击程序无反应
|
||||
**可能原因**:
|
||||
1. 系统缺少运行库
|
||||
2. 防病毒软件阻止运行
|
||||
3. 程序文件损坏
|
||||
|
||||
**解决方案**:
|
||||
1. 以管理员身份运行程序
|
||||
2. 临时关闭防病毒软件
|
||||
3. 重新下载或编译程序
|
||||
4. 检查系统事件查看器中的错误日志
|
||||
|
||||
#### 症状:显示缺少DLL文件
|
||||
**可能原因**:
|
||||
1. 系统缺少Visual C++运行库
|
||||
2. .NET Framework版本过低
|
||||
|
||||
**解决方案**:
|
||||
1. 安装Visual C++ 2015-2022运行库
|
||||
2. 更新.NET Framework到最新版本
|
||||
3. 安装所有Windows更新
|
||||
|
||||
### OCR识别问题
|
||||
|
||||
#### 症状:所有图片都识别失败
|
||||
**排查步骤**:
|
||||
1. **检查API密钥**:
|
||||
- 确认config.ini中的API密钥正确
|
||||
- 验证密钥是否过期或被禁用
|
||||
- 检查百度智能云账户余额
|
||||
|
||||
2. **检查网络连接**:
|
||||
- 测试能否访问百度智能云服务
|
||||
- 检查防火墙设置
|
||||
- 验证代理设置(如使用代理)
|
||||
|
||||
3. **检查图片文件**:
|
||||
- 确认图片格式正确
|
||||
- 验证图片文件未损坏
|
||||
- 检查文件大小是否超限
|
||||
|
||||
#### 症状:部分图片识别失败
|
||||
**可能原因**:
|
||||
1. 图片质量问题
|
||||
2. 图片格式不支持
|
||||
3. 文件大小超过限制
|
||||
|
||||
**解决方案**:
|
||||
1. 重新扫描或拍摄图片
|
||||
2. 转换图片格式为支持的格式
|
||||
3. 压缩或调整图片大小
|
||||
4. 手动处理失败的图片
|
||||
|
||||
### Excel处理问题
|
||||
|
||||
#### 症状:Excel文件生成失败
|
||||
**排查方法**:
|
||||
1. **检查磁盘空间**:确保有足够的可用空间
|
||||
2. **验证文件权限**:确认有写入权限
|
||||
3. **检查Excel格式**:确认模板文件格式正确
|
||||
4. **查看错误日志**:获取详细的错误信息
|
||||
|
||||
#### 症状:商品信息提取错误
|
||||
**常见原因**:
|
||||
1. Excel格式不规范
|
||||
2. 表头识别错误
|
||||
3. 数据格式不统一
|
||||
|
||||
**解决方法**:
|
||||
1. 标准化Excel格式
|
||||
2. 手动指定表头行
|
||||
3. 使用数据清洗功能
|
||||
4. 调整提取规则
|
||||
|
||||
### 合并功能问题
|
||||
|
||||
#### 症状:合并后商品信息丢失
|
||||
**可能原因**:
|
||||
1. 商品关键信息缺失
|
||||
2. 合并规则设置不当
|
||||
3. 文件格式不兼容
|
||||
|
||||
**解决方案**:
|
||||
1. 确保所有商品都有条码或名称
|
||||
2. 调整合并规则配置
|
||||
3. 统一文件格式和结构
|
||||
|
||||
### 性能问题
|
||||
|
||||
#### 症状:系统响应缓慢
|
||||
**优化建议**:
|
||||
1. **减少并发数**:降低max_workers值
|
||||
2. **减小批大小**:减少batch_size值
|
||||
3. **清理临时文件**:定期清理temp目录
|
||||
4. **增加内存**:关闭其他占用内存的程序
|
||||
|
||||
#### 症状:处理过程中崩溃
|
||||
**排查步骤**:
|
||||
1. 检查系统内存使用情况
|
||||
2. 查看Windows事件日志
|
||||
3. 分析错误日志文件
|
||||
4. 逐步减少处理量测试
|
||||
|
||||
## 最佳实践建议
|
||||
|
||||
### 日常使用建议
|
||||
|
||||
#### 1. 文件管理最佳实践
|
||||
- **分类存储**:按日期或供应商分类存储图片文件
|
||||
- **规范命名**:使用统一的文件命名规则
|
||||
- **定期清理**:定期清理已处理的文件和临时文件
|
||||
- **备份重要数据**:定期备份重要的采购单数据
|
||||
|
||||
#### 2. 图片质量优化
|
||||
- **扫描设置**:使用300DPI或更高分辨率扫描
|
||||
- **光线控制**:确保充足均匀的光线
|
||||
- **避免反光**:使用防反光材料或调整角度
|
||||
- **保持平整**:确保采购单平整无折叠
|
||||
|
||||
#### 3. 处理效率提升
|
||||
- **批量操作**:尽量使用批量处理功能
|
||||
- **合理分批**:将大量文件分成小批次处理
|
||||
- **预处理检查**:处理前检查图片质量
|
||||
- **参数调优**:根据硬件配置调整处理参数
|
||||
|
||||
### 系统维护建议
|
||||
|
||||
#### 1. 定期维护任务
|
||||
- **日志清理**:定期清理旧的日志文件
|
||||
- **临时文件清理**:清理temp目录中的临时文件
|
||||
- **配置备份**:定期备份配置文件
|
||||
- **更新检查**:关注系统更新和补丁
|
||||
|
||||
#### 2. 性能优化
|
||||
- **硬件升级**:根据需要升级内存和CPU
|
||||
- **存储优化**:使用SSD提高文件读写速度
|
||||
- **网络优化**:确保稳定的网络连接
|
||||
- **系统优化**:关闭不必要的服务和程序
|
||||
|
||||
#### 3. 安全建议
|
||||
- **API密钥保护**:妥善保管API密钥,不要泄露
|
||||
- **文件权限**:设置适当的文件访问权限
|
||||
- **数据加密**:对敏感数据进行加密存储
|
||||
- **定期备份**:建立定期备份机制
|
||||
|
||||
### 业务流程优化
|
||||
|
||||
#### 1. 采购流程整合
|
||||
- **标准化格式**:统一采购单格式和标准
|
||||
- **自动化集成**:与其他业务系统集成
|
||||
- **数据验证**:建立数据质量检查机制
|
||||
- **异常处理**:制定异常情况处理流程
|
||||
|
||||
#### 2. 质量控制
|
||||
- **准确性检查**:定期抽查处理结果的准确性
|
||||
- **性能监控**:监控系统处理性能指标
|
||||
- **错误分析**:分析常见错误类型和原因
|
||||
- **持续改进**:根据使用情况优化流程
|
||||
|
||||
#### 3. 团队协作
|
||||
- **权限管理**:根据角色设置不同的操作权限
|
||||
- **操作规范**:制定标准化的操作流程
|
||||
- **培训体系**:建立用户培训和技能提升机制
|
||||
- **经验分享**:定期分享使用经验和技巧
|
||||
|
||||
### 故障预防
|
||||
|
||||
#### 1. 预防措施
|
||||
- **定期测试**:定期测试系统各项功能
|
||||
- **监控告警**:建立系统监控和告警机制
|
||||
- **容量规划**:根据业务量规划系统容量
|
||||
- **应急预案**:制定系统故障应急预案
|
||||
|
||||
#### 2. 问题响应
|
||||
- **快速定位**:建立问题快速定位和诊断机制
|
||||
- **分级处理**:根据问题严重程度分级处理
|
||||
- **升级机制**:建立问题升级和汇报机制
|
||||
- **恢复流程**:制定系统恢复和重启流程
|
||||
|
||||
通过遵循这些最佳实践建议,用户可以更高效、更稳定地使用益选-OCR订单处理系统,获得更好的使用体验和业务价值。
|
||||
79
doc/优化实施计划.md
Normal file
79
doc/优化实施计划.md
Normal file
@ -0,0 +1,79 @@
|
||||
# OCR订单处理系统优化实施建议与周计划
|
||||
|
||||
## 目标
|
||||
- 提升稳定性与可维护性:统一日志、进度回调、错误提示与配置持久化
|
||||
- 优化用户体验:一致的弹窗与目录打开、清晰进度与结果摘要
|
||||
- 控制成本与性能:合理并发、避免重复处理、日志滚动归档
|
||||
|
||||
## 范围
|
||||
- 应用层(GUI、设置、交互)
|
||||
- 服务层(OCR、Excel、合并)
|
||||
- 工具层(日志、配置、校验)
|
||||
|
||||
## 已完成优化
|
||||
- 日志滚动归档:单文件5MB,保留3个备份(RotatingFileHandler)
|
||||
- 统一GUI日志挂载:`init_gui_logger`/`dispose_gui_logger`
|
||||
- 统一进度显示:`ProgressReporter` 接入主要流程
|
||||
- 结果目录一致化:Excel/合并/完整流程优先打开 `data/result`
|
||||
- Excel引擎错误提示:统一弹窗附带安装建议(openpyxl/xlrd)
|
||||
- 用户设置持久化:窗口尺寸与主题记忆(`data/user_settings.json`)
|
||||
|
||||
## 待实施优化(按周迭代)
|
||||
|
||||
### 第1周:基础能力统一与设置面板扩展
|
||||
- 任务1:系统设置面板扩展
|
||||
- 新增设置项:日志级别、并发参数(`max_workers`/`batch_size`)、模板路径、输入/输出/结果目录
|
||||
- 写入 `user_settings.json` 并同步到 `config.ini`(通过 `ConfigManager.update/save_config`)
|
||||
- 验收:设置变更后重启仍生效;操作流程读取最新参数
|
||||
- 任务2:进度回调全链路接入(服务层)
|
||||
- 为合并流程(`PurchaseOrderMerger`)添加 `progress_cb`(97%→100%),UI显示阶段进度
|
||||
- 完整流程串联 OCR→Excel→合并 三段进度
|
||||
- 验收:状态栏进度从0→100%,阶段文案一致、无跳变
|
||||
- 任务3:错误提示模板统一
|
||||
- 抽象错误弹窗生成:标题/描述/建议操作(缺依赖、模板列缺失、文件格式异常)
|
||||
- 在服务层捕获常见错误并附带建议(不用泄露敏感信息)
|
||||
- 验收:触发典型错误时弹窗一致、日志有详细堆栈
|
||||
|
||||
### 第2周:兼容性与可维护性增强
|
||||
- 任务4:供应商配置校验(schema)
|
||||
- 对 `suppliers_config.json` 加载前校验:字段完整、列映射存在、清洗/计算规则可执行
|
||||
- 失败时聚合错误列表并弹窗提示
|
||||
- 验收:错误配置阻止加载且提示清晰;正确配置即时生效
|
||||
- 任务5:拖拽与最近文件
|
||||
- 日志面板上方增加拖拽区域(图片/Excel),拖入即处理
|
||||
- 最近处理文件列表(持久化、可清空)
|
||||
- 验收:拖拽成功处理;最近列表记忆与操作正常
|
||||
- 任务6:线程池复用与批次自适应
|
||||
- OCR批量识别的线程池复用;根据 CPU 核心数与文件量自适应 `max_workers`、`batch_size`
|
||||
- 验收:大批量处理性能平稳,无过载或明显阻塞
|
||||
|
||||
### 第3周:数据处理与模板管理
|
||||
- 任务7:列映射向导
|
||||
- 弹窗展示识别到的列与标准列,支持手动修正并保存到供应商配置
|
||||
- 验收:手动修正列映射后处理成功;配置热重载生效
|
||||
- 任务8:多模板管理与校验
|
||||
- 支持按供应商选择模板;校验模板表头与系统标准列,给出差异提示
|
||||
- 验收:不同模板无错填;差异提示友好
|
||||
|
||||
### 第4周:测试与交付质量
|
||||
- 任务9:单元测试与烟雾测试
|
||||
- 核心逻辑单元测试(规格解析、数量反推、列映射、模板填充)
|
||||
- 端到端小样本烟雾测试(OCR→Excel→采购单)
|
||||
- 验收:测试通过率达标;烟雾测试稳定
|
||||
- 任务10:打包与版本信息
|
||||
- 打包资源校验(模板与配置存在性);显示版本号与更新日志入口
|
||||
- 验收:打包可用;启动显示版本信息;更新日志可查看
|
||||
|
||||
## 验收标准与度量
|
||||
- 功能验收:设置变更生效、进度准确、错误提示一致
|
||||
- 稳定性:长时间运行日志不会膨胀;批量处理无明显卡顿
|
||||
- 可维护性:配置驱动、模块职责清晰、代码重复显著减少
|
||||
|
||||
## 风险与回滚
|
||||
- 配置同步风险:提供回滚策略(保留最近一次有效 `config.ini` 与 `user_settings.json` 备份)
|
||||
- 依赖安装风险:提供一键安装与离线安装说明
|
||||
- 模板差异风险:在校验失败时阻断流程并提示修复路径
|
||||
|
||||
## 实施说明
|
||||
- 每周开始前将与您确认要启动的任务;每个任务完成后提交变更摘要与验证结果
|
||||
- 如发现新需求或变化,计划将滚动更新,并在执行前与您确认
|
||||
@ -158,4 +158,4 @@
|
||||
- 添加了文件存在性检查
|
||||
- 添加了文件类型验证
|
||||
- 添加了已处理文件检查
|
||||
- 优化了错误处理和日志记录
|
||||
- 优化了错误处理和日志记录
|
||||
File diff suppressed because it is too large
Load Diff
@ -1 +1,2 @@
|
||||
2025-08-16 00:52:17,210 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6937003706322 -> 6937003703833
|
||||
2025-11-15 16:34:22,181 - app.core.excel.handlers.barcode_mapper - INFO - 条码映射: 6923450653012 -> 69021343
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,2 +1,163 @@
|
||||
2025-08-16 00:52:16,853 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-08-16 00:52:16,861 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 20:52:59,975 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:52:59,975 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 20:52:59,980 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:52:59,980 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 20:52:59,985 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:52:59,985 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 20:52:59,999 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:52:59,999 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 20:53:00,004 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:53:00,004 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 21:55:05,648 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 21:55:05,656 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 21:55:14,957 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 21:55:14,960 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 21:56:00,538 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 21:56:00,562 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 22:00:56,344 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 22:00:56,344 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 22:00:56,357 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 22:00:56,357 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 22:00:56,364 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 22:00:56,365 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 23:22:38,475 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 23:22:38,475 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 23:53:32,028 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 23:53:32,028 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-14 23:56:57,447 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 23:56:57,447 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-15 00:18:49,537 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 00:18:49,537 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-15 00:44:36,719 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 00:44:36,720 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-15 01:58:02,054 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 01:58:02,054 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-15 09:48:24,108 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 09:48:24,126 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:06:56,596 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:06:56,620 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:10:31,639 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:10:31,653 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:39:24,612 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:39:24,612 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:39:48,326 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:39:48,337 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:39:52,727 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 10:39:52,728 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 10:49:13,775 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:49:13,775 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:51:44,473 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:51:44,475 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:51:49,960 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:51:49,960 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:54:02,883 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:54:02,886 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:54:06,684 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 10:54:06,705 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 10:58:26,607 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:58:26,621 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 10:58:36,067 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:58:36,082 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 14:17:23,600 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 14:17:23,608 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 14:17:23,670 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 14:17:23,682 - app.core.excel.merger - WARNING - 未在 data/result 目录下找到采购单Excel文件
|
||||
2025-11-15 14:17:23,718 - app.core.excel.merger - WARNING - 没有找到可合并的采购单文件
|
||||
2025-11-15 14:22:16,926 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 14:22:16,935 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:11:57,981 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:11:57,984 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:11:59,649 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 15:11:59,650 - app.core.excel.merger - INFO - 找到 2 个采购单Excel文件
|
||||
2025-11-15 15:12:52,674 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:12:52,692 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:12:54,195 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 15:12:54,206 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 15:21:05,667 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:21:05,673 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:22:01,186 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:22:01,202 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:25:41,372 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:25:41,379 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:25:42,598 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 15:25:42,601 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 15:34:06,486 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:34:06,497 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:34:08,030 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 15:34:08,041 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 15:37:42,584 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:37:42,592 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:39:11,314 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:39:11,314 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:43:33,538 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:43:33,548 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:43:37,053 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 15:43:37,054 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 15:54:35,546 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:54:35,559 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 15:54:38,702 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 15:54:38,713 - app.core.excel.merger - INFO - 找到 2 个采购单Excel文件
|
||||
2025-11-15 16:19:42,388 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:19:42,388 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:34:22,131 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:34:22,132 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:46:22,429 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:46:22,440 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:46:28,876 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:46:28,896 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:46:37,767 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:46:37,782 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:46:39,219 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 16:46:39,230 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 16:48:30,476 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:48:30,488 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:48:42,047 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:48:42,063 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:48:43,633 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 16:48:43,644 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 16:52:35,959 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:52:35,969 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:52:37,531 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 16:52:37,541 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 16:57:42,442 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:57:42,451 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:59:07,007 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:59:07,016 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:59:14,595 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:59:14,604 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 16:59:16,171 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 16:59:16,180 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 17:01:30,240 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:01:30,245 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 17:01:31,385 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 17:01:31,395 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 17:04:33,243 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:04:33,255 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 17:04:45,041 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:04:45,048 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 17:04:46,493 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 17:04:46,505 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 17:09:39,846 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:09:39,851 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 17:12:37,471 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:12:37,476 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 17:12:39,165 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 17:12:39,173 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2025-11-15 17:28:46,834 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:28:46,847 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 17:28:49,875 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 17:28:49,876 - app.core.excel.merger - INFO - 找到 2 个采购单Excel文件
|
||||
2025-11-15 17:59:22,818 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:59:22,823 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 17:59:33,491 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:59:33,506 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 17:59:39,835 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:59:39,849 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 18:00:04,153 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 18:00:04,165 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2025-11-15 18:00:07,581 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2025-11-15 18:00:07,582 - app.core.excel.merger - INFO - 找到 3 个采购单Excel文件
|
||||
2025-11-15 18:01:51,698 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 18:01:51,710 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,16 @@
|
||||
2025-11-14 21:55:30,948 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-14 23:53:34,369 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 00:20:01,697 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 09:53:49,682 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 10:06:38,107 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 10:39:49,255 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 10:54:03,264 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 14:16:12,391 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 14:41:42,507 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 15:12:40,831 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 15:25:05,333 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 15:33:48,514 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 15:43:34,042 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 16:39:06,073 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 17:28:47,324 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
2025-11-15 18:00:04,623 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
|
||||
@ -0,0 +1,270 @@
|
||||
2025-11-14 20:52:59,972 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 20:52:59,973 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:52:59,973 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 20:52:59,973 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 20:52:59,974 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 20:52:59,976 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 20:52:59,978 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:52:59,978 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 20:52:59,978 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 20:52:59,978 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 20:52:59,982 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 20:52:59,982 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:52:59,982 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 20:52:59,984 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 20:52:59,984 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 20:52:59,996 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 20:52:59,996 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:52:59,996 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 20:52:59,997 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 20:52:59,997 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 20:53:00,001 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 20:53:00,001 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 20:53:00,001 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 20:53:00,001 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 20:53:00,002 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 21:55:14,932 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 21:55:14,933 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 21:55:14,935 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 21:55:14,936 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 21:55:14,937 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 21:55:15,025 - app.core.ocr.table_ocr - INFO - 找到 0 个图片文件,其中 0 个未处理
|
||||
2025-11-14 21:55:15,031 - app.core.ocr.table_ocr - WARNING - 没有需要处理的图片
|
||||
2025-11-14 21:55:30,512 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 21:55:30,522 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 21:55:30,535 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 21:55:30,547 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 21:55:30,563 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 21:55:30,612 - app.core.ocr.table_ocr - INFO - 开始处理图片: E:/2025Code/python/orc-order-v2/data/input/微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 21:55:32,256 - app.core.ocr.table_ocr - INFO - 图片处理成功: E:/2025Code/python/orc-order-v2/data/input/微信图片_20250909184135_44_108.jpg, 输出文件: data/output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 22:00:56,334 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 22:00:56,335 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 22:00:56,336 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 22:00:56,336 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 22:00:56,338 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 22:00:56,354 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 22:00:56,354 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 22:00:56,354 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 22:00:56,355 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 22:00:56,355 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 22:00:56,361 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 22:00:56,361 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 22:00:56,361 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 22:00:56,361 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 22:00:56,362 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 23:22:38,471 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 23:22:38,471 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 23:22:38,472 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 23:22:38,472 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 23:22:38,472 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 23:53:32,026 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 23:53:32,026 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 23:53:32,026 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 23:53:32,026 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 23:53:32,026 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-14 23:53:34,048 - app.core.ocr.table_ocr - INFO - 开始处理图片: data\input\微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 23:53:35,690 - app.core.ocr.table_ocr - INFO - 图片处理成功: data\input\微信图片_20250909184135_44_108.jpg, 输出文件: data/output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:54:00,127 - app.core.ocr.table_ocr - INFO - 开始处理图片: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:01,441 - app.core.ocr.table_ocr - INFO - 图片处理成功: data\input\微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:50,647 - app.core.ocr.table_ocr - INFO - 开始处理图片: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:54:51,981 - app.core.ocr.table_ocr - INFO - 图片处理成功: data\input\微信图片_20251019141843_92_108.jpg, 输出文件: data/output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:56:57,443 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-14 23:56:57,443 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-14 23:56:57,443 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-14 23:56:57,443 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-14 23:56:57,443 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 00:18:49,534 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 00:18:49,534 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 00:18:49,534 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 00:18:49,534 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 00:18:49,535 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 00:20:01,395 - app.core.ocr.table_ocr - INFO - 开始处理图片: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:03,253 - app.core.ocr.table_ocr - INFO - 图片处理成功: data\input\微信图片_20251019141843_92_108.jpg, 输出文件: data/output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:44:36,717 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 00:44:36,717 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 00:44:36,717 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 00:44:36,717 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 00:44:36,718 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 01:58:02,050 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 01:58:02,051 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 01:58:02,051 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 01:58:02,051 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 01:58:02,051 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 09:48:24,086 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 09:48:24,087 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 09:48:24,087 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 09:48:24,087 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 09:48:24,088 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 09:49:24,553 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 09:49:24,553 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 09:49:24,557 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 09:49:24,560 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 09:49:24,563 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 09:53:49,094 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 09:53:49,107 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 09:53:49,118 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 09:53:49,132 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 09:53:49,147 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 09:53:49,215 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 1 个未处理
|
||||
2025-11-15 09:53:49,231 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 1 个文件
|
||||
2025-11-15 09:53:49,248 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 09:53:51,046 - app.core.ocr.table_ocr - INFO - 图片处理成功: data/input\微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 09:53:51,047 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
|
||||
2025-11-15 10:06:37,789 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 10:06:37,795 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:06:37,803 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 10:06:37,811 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 10:06:37,818 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 10:06:37,843 - app.core.ocr.table_ocr - INFO - 开始处理图片: E:/2025Code/python/orc-order-v2/data/input/微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 10:06:39,473 - app.core.ocr.table_ocr - INFO - 图片处理成功: E:/2025Code/python/orc-order-v2/data/input/微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 10:39:24,607 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 10:39:24,607 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:39:24,608 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 10:39:24,608 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 10:39:24,609 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 10:39:48,299 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 10:39:48,301 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:39:48,303 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 10:39:48,305 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 10:39:48,308 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 10:39:48,365 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 1 个未处理
|
||||
2025-11-15 10:39:48,368 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 1 个文件
|
||||
2025-11-15 10:39:48,392 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 10:39:50,666 - app.core.ocr.table_ocr - INFO - 图片处理成功: data/input\微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 10:39:50,667 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
|
||||
2025-11-15 10:49:13,768 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 10:49:13,769 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:49:13,769 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 10:49:13,769 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 10:49:13,770 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 10:51:44,469 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 10:51:44,469 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:51:44,469 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 10:51:44,470 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 10:51:44,470 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 10:51:49,953 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 10:51:49,954 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:51:49,954 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 10:51:49,955 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 10:51:49,955 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 10:54:02,833 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 10:54:02,834 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 10:54:02,837 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 10:54:02,841 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 10:54:02,846 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 10:54:02,940 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 1 个未处理
|
||||
2025-11-15 10:54:02,943 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 1 个文件
|
||||
2025-11-15 10:54:02,973 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 10:54:04,733 - app.core.ocr.table_ocr - INFO - 图片处理成功: data/input\微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 10:54:04,738 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
|
||||
2025-11-15 14:16:11,980 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 14:16:11,982 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 14:16:11,985 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 14:16:11,997 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 14:16:11,999 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 14:16:12,028 - app.core.ocr.table_ocr - INFO - 开始处理图片: E:/2025Code/python/orc-order-v2/data/input/微信图片_20251113183218_594_278.jpg
|
||||
2025-11-15 14:16:14,042 - app.core.ocr.table_ocr - INFO - 图片处理成功: E:/2025Code/python/orc-order-v2/data/input/微信图片_20251113183218_594_278.jpg, 输出文件: data/output\微信图片_20251113183218_594_278.xlsx
|
||||
2025-11-15 14:41:42,172 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 14:41:42,173 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 14:41:42,175 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 14:41:42,176 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 14:41:42,179 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 14:41:42,198 - app.core.ocr.table_ocr - INFO - 开始处理图片: F:/下载/微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 14:41:44,478 - app.core.ocr.table_ocr - INFO - 图片处理成功: F:/下载/微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:11:57,934 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 15:11:57,937 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:11:57,939 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 15:11:57,945 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 15:11:57,946 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 15:11:58,040 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 1 个未处理
|
||||
2025-11-15 15:11:58,053 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 1 个文件
|
||||
2025-11-15 15:11:58,081 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20251113183218_594_278.jpg
|
||||
2025-11-15 15:11:58,091 - app.core.ocr.table_ocr - INFO - 已存在对应的Excel文件,跳过处理: 微信图片_20251113183218_594_278.jpg -> 微信图片_20251113183218_594_278.xlsx
|
||||
2025-11-15 15:11:58,132 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
|
||||
2025-11-15 15:12:40,318 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 15:12:40,333 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:12:40,345 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 15:12:40,358 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 15:12:40,370 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 15:12:40,403 - app.core.ocr.table_ocr - INFO - 开始处理图片: F:/下载/微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 15:12:42,172 - app.core.ocr.table_ocr - INFO - 图片处理成功: F:/下载/微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:25:05,003 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 15:25:05,004 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:25:05,006 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 15:25:05,009 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 15:25:05,019 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 15:25:05,052 - app.core.ocr.table_ocr - INFO - 开始处理图片: F:/下载/微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 15:25:06,786 - app.core.ocr.table_ocr - INFO - 图片处理成功: F:/下载/微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:33:47,219 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 15:33:47,225 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:33:47,228 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 15:33:47,229 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 15:33:47,234 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 15:33:47,269 - app.core.ocr.table_ocr - INFO - 开始处理图片: F:/下载/微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 15:33:50,403 - app.core.ocr.table_ocr - INFO - 图片处理成功: F:/下载/微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:39:11,309 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 15:39:11,310 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:39:11,310 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 15:39:11,310 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 15:39:11,311 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 15:43:33,473 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 15:43:33,474 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 15:43:33,478 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 15:43:33,481 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 15:43:33,485 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 15:43:33,617 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 1 个未处理
|
||||
2025-11-15 15:43:33,637 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 1 个文件
|
||||
2025-11-15 15:43:33,670 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20251113183218_594_278.jpg
|
||||
2025-11-15 15:43:35,235 - app.core.ocr.table_ocr - INFO - 图片处理成功: data/input\微信图片_20251113183218_594_278.jpg, 输出文件: data/output\微信图片_20251113183218_594_278.xlsx
|
||||
2025-11-15 15:43:35,236 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
|
||||
2025-11-15 16:39:05,575 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 16:39:05,581 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:39:05,587 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 16:39:05,594 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 16:39:05,597 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 16:39:05,641 - app.core.ocr.table_ocr - INFO - 开始处理图片: F:/下载/微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 16:39:07,420 - app.core.ocr.table_ocr - INFO - 图片处理成功: F:/下载/微信图片_20251027125604_98_108.jpg, 输出文件: data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 16:46:22,388 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 16:46:22,388 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 16:46:22,390 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 16:46:22,390 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 16:46:22,392 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 16:46:22,501 - app.core.ocr.table_ocr - INFO - 找到 0 个图片文件,其中 0 个未处理
|
||||
2025-11-15 16:46:22,522 - app.core.ocr.table_ocr - WARNING - 没有需要处理的图片
|
||||
2025-11-15 17:28:46,777 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 17:28:46,778 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:28:46,781 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 17:28:46,784 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 17:28:46,789 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 17:28:46,913 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 1 个未处理
|
||||
2025-11-15 17:28:46,930 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 1 个文件
|
||||
2025-11-15 17:28:46,975 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20251115145536_614_278.jpg
|
||||
2025-11-15 17:28:48,564 - app.core.ocr.table_ocr - INFO - 图片处理成功: data/input\微信图片_20251115145536_614_278.jpg, 输出文件: data/output\微信图片_20251115145536_614_278.xlsx
|
||||
2025-11-15 17:28:48,566 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
|
||||
2025-11-15 17:29:22,057 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 17:29:22,070 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:29:22,076 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 17:29:22,084 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 17:29:22,098 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 17:29:22,147 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 1 个未处理
|
||||
2025-11-15 17:29:22,159 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 1 个文件
|
||||
2025-11-15 17:29:22,180 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20251115145536_614_278.jpg
|
||||
2025-11-15 17:29:22,198 - app.core.ocr.table_ocr - INFO - 已存在对应的Excel文件,跳过处理: 微信图片_20251115145536_614_278.jpg -> 微信图片_20251115145536_614_278.xlsx
|
||||
2025-11-15 17:29:22,217 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
|
||||
2025-11-15 17:59:39,798 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 17:59:39,799 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 17:59:39,800 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 17:59:39,800 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 17:59:39,801 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 17:59:39,913 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 0 个未处理
|
||||
2025-11-15 17:59:39,930 - app.core.ocr.table_ocr - WARNING - 没有需要处理的图片
|
||||
2025-11-15 18:00:04,112 - app.core.ocr.table_ocr - INFO - 使用输入目录: E:\2025Code\python\orc-order-v2\data\input
|
||||
2025-11-15 18:00:04,114 - app.core.ocr.table_ocr - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2025-11-15 18:00:04,116 - app.core.ocr.table_ocr - INFO - 使用临时目录: E:\2025Code\python\orc-order-v2\data\temp
|
||||
2025-11-15 18:00:04,117 - app.core.ocr.table_ocr - INFO - 允许的文件类型: ['.jpg', '.jpeg', '.png', '.bmp']
|
||||
2025-11-15 18:00:04,119 - app.core.ocr.table_ocr - INFO - 初始化OCRProcessor完成:输入目录=data/input, 输出目录=data/output
|
||||
2025-11-15 18:00:04,224 - app.core.ocr.table_ocr - INFO - 找到 2 个图片文件,其中 1 个未处理
|
||||
2025-11-15 18:00:04,247 - app.core.ocr.table_ocr - INFO - 处理批次 1/1: 1 个文件
|
||||
2025-11-15 18:00:04,278 - app.core.ocr.table_ocr - INFO - 开始处理图片: data/input\微信图片_20251114131924_600_278.jpg
|
||||
2025-11-15 18:00:05,870 - app.core.ocr.table_ocr - INFO - 图片处理成功: data/input\微信图片_20251114131924_600_278.jpg, 输出文件: data/output\微信图片_20251114131924_600_278.xlsx
|
||||
2025-11-15 18:00:05,872 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
|
||||
@ -0,0 +1 @@
|
||||
2025-11-14 21:55:05,688 - app.core.utils.file_utils - WARNING - 未在目录 data/output 中找到符合条件的文件
|
||||
@ -0,0 +1,537 @@
|
||||
2025-11-14 20:52:59,971 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 20:52:59,974 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 20:52:59,976 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 20:52:59,978 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 20:52:59,982 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 20:52:59,984 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 20:52:59,995 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 20:52:59,997 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 20:53:00,000 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 20:53:00,002 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 21:55:14,931 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 21:55:14,939 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 21:55:14,988 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-14 21:55:15,019 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-14 21:55:30,504 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 21:55:30,576 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 21:55:32,258 - app.services.ocr_service - INFO - 处理完成: E:/2025Code/python/orc-order-v2/data/input/微信图片_20250909184135_44_108.jpg -> data/output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 22:00:56,331 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 22:00:56,339 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 22:00:56,354 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 22:00:56,355 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 22:00:56,360 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 22:00:56,362 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 23:22:38,470 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 23:22:38,472 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 23:53:32,025 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 23:53:32,027 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 23:53:35,691 - app.services.ocr_service - INFO - 处理完成: data\input\微信图片_20250909184135_44_108.jpg -> data/output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:53:37,742 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 23:53:39,788 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 23:53:41,832 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 23:53:43,881 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 23:53:45,934 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 23:53:48,001 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 23:53:50,039 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20250909184135_44_108.jpg
|
||||
2025-11-14 23:54:01,442 - app.services.ocr_service - INFO - 处理完成: data\input\微信图片_20251027125604_98_108.jpg -> data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:03,487 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:05,528 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:07,576 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:09,616 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:13,773 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:15,821 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:17,867 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:19,919 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:21,962 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:24,008 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:26,046 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:28,097 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:30,151 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:32,204 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:34,250 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:36,296 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:38,351 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:40,404 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:42,458 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:44,502 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:46,556 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:48,600 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:51,982 - app.services.ocr_service - INFO - 处理完成: data\input\微信图片_20251019141843_92_108.jpg -> data/output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:54:52,021 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:54,069 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:54:54,107 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:56,148 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:54:56,189 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:54:58,238 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:54:58,275 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:00,326 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:00,364 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:02,419 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:02,462 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:04,521 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:04,558 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:06,605 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:06,642 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:08,703 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:08,740 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:10,786 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:10,827 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:12,879 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:12,916 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:14,960 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:14,996 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:17,036 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:17,073 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:19,125 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:19,162 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:21,204 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:21,242 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:23,294 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:23,335 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:25,382 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:25,421 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:27,467 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:27,505 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:29,547 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:29,582 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:31,622 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:31,669 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:33,737 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:33,774 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:35,817 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:35,853 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:37,920 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:37,961 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:40,013 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:40,051 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:42,108 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:42,146 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:44,193 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:44,229 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:46,275 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:46,315 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:48,365 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:48,404 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:50,443 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:50,482 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:52,535 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:52,573 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:54,614 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:54,653 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:56,710 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:56,748 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:55:58,800 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:55:58,838 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:56:00,891 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:56:00,933 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:56:02,979 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:56:03,018 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:56:05,062 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:56:05,105 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:56:07,162 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:56:07,210 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:56:57,442 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-14 23:56:57,445 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-14 23:56:59,616 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:01,537 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:05,227 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:06,470 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:09,653 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:11,576 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:15,136 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:16,887 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:20,234 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:21,430 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:24,780 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:26,265 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:29,872 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:31,572 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:35,123 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:36,918 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:40,537 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:42,112 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:45,416 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:46,720 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:49,990 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:51,501 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:54,894 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:57:56,395 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:57:59,834 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:01,639 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:05,077 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:06,547 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:09,915 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:11,351 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:14,705 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:16,392 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:19,888 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:21,532 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:24,978 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:26,500 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:29,831 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:31,416 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:34,852 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:36,575 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:39,921 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:41,452 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:44,946 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:46,443 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:50,034 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:51,597 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:58:55,053 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:58:56,555 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:00,070 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:01,844 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:05,320 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:06,825 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:10,473 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:12,139 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:15,603 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:17,192 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:20,612 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:22,114 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:25,589 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:27,211 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:30,767 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:32,326 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:36,011 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:37,686 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:41,201 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:42,778 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:46,304 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:47,761 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:51,191 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:52,841 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-14 23:59:56,216 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-14 23:59:57,611 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:01,219 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:02,758 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:06,052 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:07,434 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:10,840 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:12,561 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:16,097 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:17,522 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:20,868 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:22,464 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:26,088 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:27,515 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:31,017 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:32,515 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:36,053 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:37,624 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:41,060 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:42,493 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:45,839 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:47,275 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:50,609 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:52,109 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:00:55,459 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:00:57,222 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:00,688 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:02,298 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:05,719 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:07,317 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:10,858 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:12,551 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:16,041 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:17,743 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:21,145 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:22,630 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:26,026 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:27,349 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:30,913 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:32,597 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:35,986 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:37,481 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:40,840 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:42,630 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:46,085 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:47,711 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:51,307 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:53,097 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:01:56,452 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:01:57,944 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:01,308 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:02,944 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:06,570 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:08,356 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:12,004 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:13,757 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:17,556 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:19,476 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:22,928 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:24,545 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:27,890 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:29,443 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:32,790 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:34,247 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:37,750 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:39,242 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:42,620 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:44,196 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:47,546 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:49,236 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:52,656 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:54,352 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:02:57,747 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:02:59,241 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:02,582 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:03,966 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:07,396 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:09,150 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:12,454 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:14,078 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:17,563 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:18,931 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:22,254 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:23,958 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:27,433 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:28,875 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:32,492 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:33,730 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:37,280 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:38,745 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:42,378 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:44,064 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:47,518 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:49,323 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:52,839 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:54,315 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:03:57,762 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:03:59,377 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:02,912 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:04,333 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:07,634 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:09,217 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:12,781 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:14,391 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:17,952 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:19,426 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:22,773 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:24,437 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:27,786 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:29,491 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:33,208 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:34,834 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:38,270 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:39,870 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:43,227 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:44,671 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:48,011 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:49,544 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:52,898 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:54,514 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:04:58,133 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:04:59,637 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:03,203 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:04,439 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:07,802 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:09,420 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:13,002 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:14,449 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:17,865 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:19,351 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:22,585 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:24,115 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:27,622 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:29,332 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:32,669 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:34,242 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:37,801 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:39,407 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:42,969 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:44,554 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:48,144 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:49,714 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:53,196 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:54,908 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:05:58,328 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:05:59,736 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:18:49,533 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 00:18:49,535 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 00:18:51,772 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:18:53,982 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:18:57,742 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:18:59,499 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:19:02,811 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:19:04,852 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:19:08,780 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:19:10,559 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:19:14,369 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:19:16,366 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251027125604_98_108.jpg
|
||||
2025-11-15 00:20:03,254 - app.services.ocr_service - INFO - 处理完成: data\input\微信图片_20251019141843_92_108.jpg -> data/output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:06,966 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:10,786 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:14,177 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:17,835 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:21,070 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:24,531 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:28,407 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:31,774 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:35,631 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:39,543 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:20:43,297 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:44:36,716 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 00:44:36,718 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 00:44:39,002 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:44:43,224 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 00:44:47,343 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:02,050 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 01:58:02,051 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 01:58:04,310 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:08,536 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:12,817 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:17,274 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:21,129 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:39,915 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:43,786 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:47,743 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:52,055 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:58:56,257 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:59:38,855 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:59:42,879 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:59:46,931 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:59:51,017 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 01:59:55,157 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:00:39,353 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:00:43,387 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:00:47,550 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:00:52,036 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:00:56,180 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:01:40,371 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:01:44,582 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:01:48,847 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:01:53,093 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:01:57,105 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:02:41,519 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:02:45,567 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:02:49,844 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:02:53,881 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:02:57,870 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:03:42,078 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:03:46,476 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:03:50,820 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:03:54,976 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:03:59,499 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:04:44,020 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:04:48,141 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:04:52,372 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:04:56,700 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:05:00,874 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:05:45,362 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:05:49,450 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:05:53,666 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:05:57,703 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:06:01,736 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:06:46,004 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:06:50,334 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:06:54,620 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:06:59,012 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:07:03,137 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:07:47,221 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:07:51,451 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:07:55,498 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:07:59,518 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:08:03,656 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:08:47,835 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:08:52,031 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:08:56,234 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:09:00,502 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:09:04,593 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:09:48,844 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:09:52,817 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:09:56,979 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:10:01,030 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:10:05,248 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:10:49,756 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:10:53,930 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:10:57,881 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:11:01,994 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:11:05,986 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:11:50,114 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:11:54,250 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:11:58,403 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:12:02,467 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:12:06,514 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:12:50,982 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:12:55,311 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:12:59,508 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:13:03,771 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 02:13:08,205 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: data\input\微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 09:48:24,085 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 09:48:24,088 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 09:49:24,549 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 09:49:24,565 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 09:49:24,572 - app.services.ocr_service - INFO - 文件已处理过,跳过OCR识别: E:/2025Code/python/orc-order-v2/data/input/微信图片_20251019141843_92_108.jpg
|
||||
2025-11-15 09:53:49,066 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 09:53:49,162 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 09:53:49,180 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 09:53:49,195 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 10:06:37,768 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 10:06:37,827 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 10:06:39,474 - app.services.ocr_service - INFO - 处理完成: E:/2025Code/python/orc-order-v2/data/input/微信图片_20251027125604_98_108.jpg -> data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 10:39:24,605 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 10:39:24,609 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 10:39:48,296 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 10:39:48,310 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 10:39:48,360 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 10:39:48,361 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 10:49:13,767 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 10:49:13,771 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 10:51:44,468 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 10:51:44,471 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 10:51:49,953 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 10:51:49,956 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 10:54:02,829 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 10:54:02,847 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 10:54:02,925 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 10:54:02,926 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 14:16:11,975 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 14:16:12,005 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 14:16:14,043 - app.services.ocr_service - INFO - 处理完成: E:/2025Code/python/orc-order-v2/data/input/微信图片_20251113183218_594_278.jpg -> data/output\微信图片_20251113183218_594_278.xlsx
|
||||
2025-11-15 14:41:42,157 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 14:41:42,185 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 14:41:44,498 - app.services.ocr_service - INFO - 处理完成: F:/下载/微信图片_20251027125604_98_108.jpg -> data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:11:57,934 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 15:11:57,950 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 15:11:58,027 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 15:11:58,027 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 15:12:40,317 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 15:12:40,382 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 15:12:42,173 - app.services.ocr_service - INFO - 处理完成: F:/下载/微信图片_20251027125604_98_108.jpg -> data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:25:04,977 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 15:25:05,031 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 15:25:06,788 - app.services.ocr_service - INFO - 处理完成: F:/下载/微信图片_20251027125604_98_108.jpg -> data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:33:47,199 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 15:33:47,245 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 15:33:50,404 - app.services.ocr_service - INFO - 处理完成: F:/下载/微信图片_20251027125604_98_108.jpg -> data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:39:11,308 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 15:39:11,311 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 15:43:33,472 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 15:43:33,492 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 15:43:33,597 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 15:43:33,597 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 16:39:05,552 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 16:39:05,605 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 16:39:07,421 - app.services.ocr_service - INFO - 处理完成: F:/下载/微信图片_20251027125604_98_108.jpg -> data/output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 16:46:22,384 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 16:46:22,392 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 16:46:22,491 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 16:46:22,491 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 17:28:46,775 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 17:28:46,794 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 17:28:46,901 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 17:28:46,901 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 17:29:22,045 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 17:29:22,113 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 17:29:22,124 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 17:29:22,138 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 17:59:39,797 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 17:59:39,802 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 17:59:39,891 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 17:59:39,892 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
2025-11-15 18:00:04,109 - app.services.ocr_service - INFO - 初始化OCRService
|
||||
2025-11-15 18:00:04,120 - app.services.ocr_service - INFO - OCRService初始化完成
|
||||
2025-11-15 18:00:04,212 - app.services.ocr_service - INFO - OCRService.batch_process被调用,转发到process_images_batch
|
||||
2025-11-15 18:00:04,213 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
|
||||
@ -1,3 +1,593 @@
|
||||
2025-08-16 00:52:16,815 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-08-16 00:52:16,863 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-08-16 00:52:16,867 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-14 20:52:59,974 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 20:52:59,976 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 20:52:59,979 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 20:52:59,980 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 20:52:59,984 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 20:52:59,985 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 20:52:59,997 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 20:52:59,999 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 20:53:00,002 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 20:53:00,005 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 21:55:05,594 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 21:55:05,663 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 21:55:05,672 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-14 21:55:14,941 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 21:55:14,963 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 21:56:00,461 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 21:56:00,575 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 21:56:00,599 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 22:00:56,339 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 22:00:56,344 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 22:00:56,355 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 22:00:56,357 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 22:00:56,362 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 22:00:56,365 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 23:22:38,472 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 23:22:38,475 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 23:53:32,027 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 23:53:32,028 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 23:53:35,691 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:53:37,742 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:53:39,788 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:53:41,832 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:53:43,882 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:53:45,934 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:53:48,001 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:53:50,039 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20250909184135_44_108.xlsx
|
||||
2025-11-14 23:54:01,442 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:03,487 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:05,529 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:07,577 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:09,616 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:13,773 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:15,821 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:17,867 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:19,919 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:21,962 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:24,008 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:26,047 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:28,098 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:30,151 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:32,204 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:34,250 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:36,296 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:38,351 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:40,404 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:42,458 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:44,502 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:46,556 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:48,600 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:51,983 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:54:52,021 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:54,069 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:54:54,107 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:56,148 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:54:56,189 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:54:58,238 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:54:58,275 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:00,326 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:00,365 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:02,420 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:02,462 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:04,521 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:04,558 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:06,605 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:06,643 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:08,703 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:08,740 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:10,788 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:10,828 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:12,879 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:12,916 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:14,960 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:14,996 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:17,036 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:17,073 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:19,125 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:19,162 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:21,205 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:21,243 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:23,295 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:23,335 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:25,382 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:25,421 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:27,467 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:27,505 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:29,547 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:29,582 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:31,622 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:31,669 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:33,737 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:33,774 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:35,817 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:35,853 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:37,921 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:37,961 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:40,014 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:40,051 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:42,108 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:42,147 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:44,193 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:44,229 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:46,275 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:46,315 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:48,365 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:48,404 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:50,443 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:50,482 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:52,535 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:52,573 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:54,614 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:54,653 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:56,710 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:56,748 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:55:58,800 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:55:58,838 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:56:00,891 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:56:00,935 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:56:02,980 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:56:03,018 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:56:05,062 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:56:05,106 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:56:07,162 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:56:07,210 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:56:57,445 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-14 23:56:57,448 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-14 23:56:59,671 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:01,610 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:05,270 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:06,524 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:09,725 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:11,648 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:15,205 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:16,956 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:20,272 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:21,477 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:24,830 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:26,314 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:29,933 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:31,639 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:35,183 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:36,999 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:40,585 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:42,149 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:45,471 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:46,771 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:50,045 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:51,537 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:54,947 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:57:56,455 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:57:59,886 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:01,675 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:05,116 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:06,597 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:09,988 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:11,402 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:14,762 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:16,456 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:19,926 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:21,593 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:25,017 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:26,549 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:29,869 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:31,480 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:34,917 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:36,626 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:39,970 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:41,505 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:45,014 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:46,495 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:50,070 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:51,660 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:58:55,105 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:58:56,605 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:00,139 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:01,892 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:05,383 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:06,901 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:10,551 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:12,206 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:15,639 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:17,241 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:20,663 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:22,160 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:25,634 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:27,248 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:30,819 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:32,365 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:36,079 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:37,734 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:41,258 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:42,824 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:46,370 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:47,834 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:51,254 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:52,905 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-14 23:59:56,269 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-14 23:59:57,672 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:01,256 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:02,807 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:06,104 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:07,485 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:10,893 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:12,610 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:16,149 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:17,562 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:20,946 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:22,538 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:26,131 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:27,583 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:31,069 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:32,567 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:36,102 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:37,675 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:41,096 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:42,559 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:45,876 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:47,314 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:50,657 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:52,159 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:00:55,531 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:00:57,287 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:00,725 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:02,358 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:05,756 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:07,382 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:10,909 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:12,635 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:16,124 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:17,810 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:21,182 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:22,681 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:26,069 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:27,398 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:30,983 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:32,654 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:36,036 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:37,546 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:40,916 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:42,666 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:46,135 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:47,771 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:51,376 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:53,154 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:01:56,488 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:01:58,006 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:01,361 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:03,000 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:06,651 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:08,438 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:12,057 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:13,824 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:17,635 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:19,526 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:23,005 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:24,594 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:27,928 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:29,505 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:32,852 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:34,299 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:37,813 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:39,281 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:42,672 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:44,232 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:47,595 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:49,284 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:52,743 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:54,437 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:02:57,797 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:02:59,304 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:02,645 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:04,003 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:07,447 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:09,204 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:12,509 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:14,146 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:17,611 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:18,970 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:22,320 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:23,995 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:27,472 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:28,938 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:32,546 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:33,779 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:37,358 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:38,810 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:42,430 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:44,137 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:47,587 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:49,403 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:52,901 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:54,388 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:03:57,810 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:03:59,455 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:02,984 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:04,394 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:07,710 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:09,289 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:12,859 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:14,474 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:17,989 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:19,500 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:22,822 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:24,473 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:27,848 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:29,568 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:33,270 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:34,897 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:38,318 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:39,934 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:43,278 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:44,722 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:48,052 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:49,619 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:52,975 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:54,572 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:04:58,173 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:04:59,694 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:03,261 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:04,491 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:07,887 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:09,478 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:13,079 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:14,500 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:17,918 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:19,387 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:22,622 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:24,193 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:27,664 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:29,394 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:32,717 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:34,328 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:37,870 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:39,473 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:43,044 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:44,606 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:48,195 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:49,765 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:53,268 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:54,963 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:05:58,364 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:05:59,802 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:18:49,535 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 00:18:49,538 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 00:18:51,832 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:18:54,057 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:18:57,817 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:18:59,547 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:19:02,881 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:19:04,937 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:19:08,852 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:19:10,644 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:19:14,425 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:19:16,439 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 00:20:03,324 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:07,029 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:10,864 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:14,215 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:17,878 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:21,109 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:24,592 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:28,474 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:31,856 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:35,700 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:39,605 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:20:43,355 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:44:36,718 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 00:44:36,720 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 00:44:39,085 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:44:43,294 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 00:44:47,418 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:02,052 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 01:58:02,054 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 01:58:04,404 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:08,613 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:12,905 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:17,338 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:21,192 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:39,977 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:43,852 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:47,831 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:52,175 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:58:56,355 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:59:38,962 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:59:42,963 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:59:47,041 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:59:51,100 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 01:59:55,247 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:00:39,437 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:00:43,455 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:00:47,653 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:00:52,105 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:00:56,245 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:01:40,456 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:01:44,653 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:01:48,950 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:01:53,159 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:01:57,193 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:02:41,611 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:02:45,668 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:02:49,948 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:02:53,952 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:02:57,956 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:03:42,179 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:03:46,610 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:03:50,918 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:03:55,072 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:03:59,598 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:04:44,111 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:04:48,235 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:04:52,463 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:04:56,788 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:05:01,024 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:05:45,464 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:05:49,519 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:05:53,734 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:05:57,788 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:06:01,836 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:06:46,074 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:06:50,451 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:06:54,716 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:06:59,148 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:07:03,221 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:07:47,305 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:07:51,518 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:07:55,599 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:07:59,603 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:08:03,773 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:08:47,930 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:08:52,146 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:08:56,363 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:09:00,604 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:09:04,679 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:09:48,912 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:09:52,927 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:09:57,080 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:10:01,136 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:10:05,339 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:10:49,825 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:10:53,995 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:10:57,962 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:11:02,097 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:11:06,075 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:11:50,181 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:11:54,337 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:11:58,472 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:12:02,549 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:12:06,611 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:12:51,091 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:12:55,402 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:12:59,595 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:13:03,883 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 02:13:08,305 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data\output\微信图片_20251019141843_92_108.xlsx
|
||||
2025-11-15 09:48:24,088 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 09:48:24,126 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:06:56,495 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:06:56,644 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:06:56,677 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 10:10:31,568 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:10:31,669 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:10:31,686 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 10:39:24,610 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:39:24,613 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:39:48,312 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:39:48,340 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:39:50,736 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 10:49:13,771 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:49:13,775 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:51:44,471 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:51:44,475 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:51:49,956 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:51:49,960 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:54:02,853 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:54:02,897 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:54:04,837 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 10:58:26,517 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:58:26,634 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:58:26,651 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 10:58:36,001 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 10:58:36,098 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 10:58:36,133 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 14:17:23,548 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 14:17:23,617 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 14:17:23,630 - app.services.order_service - INFO - OrderService开始合并所有采购单
|
||||
2025-11-15 14:17:23,648 - app.services.order_service - INFO - OrderService开始合并所有采购单
|
||||
2025-11-15 14:22:16,889 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 14:22:16,949 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 14:22:16,977 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: F:/下载/订单1762933924814.xlsx
|
||||
2025-11-15 15:11:57,955 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:11:57,991 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:11:58,198 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 15:12:52,608 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:12:52,708 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:12:52,745 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 15:21:05,637 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:21:05,678 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:21:05,686 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:22:01,116 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:22:01,217 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:22:01,232 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/微信图片_20251027125604_98_108.xlsx
|
||||
2025-11-15 15:25:41,328 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:25:41,393 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:25:41,435 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 15:34:06,437 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:34:06,514 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:34:06,543 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 15:37:42,545 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:37:42,599 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:37:42,606 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 15:39:11,311 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:39:11,314 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:43:33,496 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:43:33,561 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:43:35,318 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 15:54:35,478 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 15:54:35,573 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 15:54:35,609 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 16:19:42,366 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:19:42,388 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:19:42,389 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:\2025Code\python\orc-order-v2\data\output\蓉城易购-订单明细20251115154455.xlsx
|
||||
2025-11-15 16:34:22,100 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:34:22,132 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:34:22,132 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:\2025Code\python\orc-order-v2\data\output\蓉城易购-订单1762933924814.xlsx
|
||||
2025-11-15 16:46:22,393 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:46:22,453 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:46:28,800 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:46:28,913 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:46:29,004 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 16:46:37,684 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:46:37,798 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:46:37,873 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 16:48:30,424 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:48:30,499 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:48:30,574 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 16:48:41,962 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:48:42,077 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:48:42,154 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 16:52:35,911 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:52:35,973 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:52:36,050 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 16:57:42,391 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:57:42,459 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:57:42,542 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 16:59:06,951 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:59:07,027 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:59:07,102 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 16:59:14,530 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 16:59:14,619 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 16:59:14,678 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:01:30,192 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:01:30,257 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 17:01:30,308 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:04:33,184 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:04:33,258 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 17:04:33,323 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:04:44,983 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:04:45,063 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 17:04:45,134 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:09:39,792 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:09:39,862 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 17:09:39,929 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:12:37,423 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:12:37,485 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 17:12:37,545 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:28:46,799 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:28:46,861 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 17:28:48,645 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:59:22,782 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:59:22,828 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 17:59:22,867 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:59:33,421 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:59:33,523 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 17:59:33,585 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 17:59:39,804 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 17:59:39,862 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 18:00:04,123 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 18:00:04,180 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 18:00:05,990 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2025-11-15 18:01:51,643 - app.services.order_service - INFO - 初始化OrderService
|
||||
2025-11-15 18:01:51,715 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2025-11-15 18:01:51,763 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
2025-11-15 15:44:36,108 - app.services.tobacco_service - WARNING - 未找到烟草公司订单明细文件
|
||||
2025-11-15 15:44:36,116 - app.services.tobacco_service - WARNING - 未找到烟草公司订单明细文件
|
||||
2025-11-15 15:44:36,125 - app.services.tobacco_service - ERROR - 未找到可处理的烟草订单明细文件
|
||||
2025-11-15 15:45:17,682 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:45:17,689 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:45:17,724 - app.services.tobacco_service - INFO - 采购单生成成功: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:45:17,726 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:45:17,738 - app.services.tobacco_service - INFO - 采购单已生成: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:45:17,850 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:46:55,566 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:46:55,572 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:46:55,599 - app.services.tobacco_service - INFO - 采购单生成成功: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:46:55,600 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:46:55,607 - app.services.tobacco_service - INFO - 采购单已生成: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:46:55,667 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:47:59,480 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:47:59,485 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:47:59,512 - app.services.tobacco_service - INFO - 采购单生成成功: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:47:59,513 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:47:59,520 - app.services.tobacco_service - INFO - 采购单已生成: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:47:59,582 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:50:32,432 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:50:32,432 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:50:32,455 - app.services.tobacco_service - INFO - 采购单生成成功: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:50:32,456 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:50:32,463 - app.services.tobacco_service - INFO - 采购单已生成: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:50:32,519 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:51:02,790 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:51:02,791 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:51:02,814 - app.services.tobacco_service - INFO - 采购单生成成功: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:51:02,815 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:51:02,827 - app.services.tobacco_service - INFO - 采购单已生成: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:51:02,885 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:53:51,294 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:53:51,298 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:53:51,328 - app.services.tobacco_service - INFO - 采购单生成成功: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:53:51,329 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:53:51,337 - app.services.tobacco_service - INFO - 采购单已生成: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:53:51,391 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:54:07,757 - app.services.tobacco_service - INFO - 找到最新烟草订单明细文件: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:54:07,758 - app.services.tobacco_service - INFO - 开始处理烟草公司订单: data/output\订单明细20251115154455.xlsx
|
||||
2025-11-15 15:54:07,783 - app.services.tobacco_service - INFO - 采购单生成成功: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:54:07,783 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
2025-11-15 15:54:07,796 - app.services.tobacco_service - INFO - 采购单已生成: data/result\银豹采购单_烟草公司.xls
|
||||
2025-11-15 15:54:07,930 - app.services.tobacco_service - INFO - 烟草公司订单处理成功,订单时间: 2025-11-10, 总金额: 12226.22, 处理条目: 34
|
||||
Binary file not shown.
@ -1,19 +0,0 @@
|
||||
|
||||
# OCR订单处理系统 - 便携版
|
||||
|
||||
## 使用说明
|
||||
1. 双击 "OCR订单处理系统.exe" 启动程序
|
||||
2. 将需要处理的图片文件放入 data/input 目录
|
||||
3. 处理结果将保存在 data/output 目录
|
||||
4. 日志文件保存在 logs 目录
|
||||
|
||||
## 注意事项
|
||||
- 首次运行时需要配置百度OCR API密钥
|
||||
- 支持的图片格式:jpg, jpeg, png, bmp
|
||||
- 单个文件大小不超过4MB
|
||||
|
||||
## 目录结构
|
||||
- OCR订单处理系统.exe - 主程序
|
||||
- data/input/ - 输入图片目录
|
||||
- data/output/ - 输出结果目录
|
||||
- logs/ - 日志目录
|
||||
@ -1,28 +0,0 @@
|
||||
[API]
|
||||
api_key = O0Fgk3o69RWJ86eAX8BTHRaB
|
||||
secret_key = VyZD5lzcIMgsup1uuD6Cw0pfzS20IGPZ
|
||||
timeout = 30
|
||||
max_retries = 3
|
||||
retry_delay = 2
|
||||
api_url = https://aip.baidubce.com/rest/2.0/ocr/v1/table
|
||||
|
||||
[Paths]
|
||||
input_folder = data/input
|
||||
output_folder = data/output
|
||||
temp_folder = data/temp
|
||||
template_folder = templates
|
||||
processed_record = data/processed_files.json
|
||||
|
||||
[Performance]
|
||||
max_workers = 4
|
||||
batch_size = 5
|
||||
skip_existing = true
|
||||
|
||||
[File]
|
||||
allowed_extensions = .jpg,.jpeg,.png,.bmp
|
||||
excel_extension = .xlsx
|
||||
max_file_size_mb = 4
|
||||
|
||||
[Templates]
|
||||
purchase_order = 银豹-采购单模板.xls
|
||||
|
||||
@ -1,205 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
"6907992508344": {
|
||||
"map_to": "6907992508191",
|
||||
"description": "条码映射:6907992508344 -> 6907992508191"
|
||||
},
|
||||
"6903979000979": {
|
||||
"map_to": "6903979000962",
|
||||
"description": "条码映射:6903979000979 -> 6903979000962"
|
||||
},
|
||||
"6923644283582": {
|
||||
"map_to": "6923644283575",
|
||||
"description": "条码映射:6923644283582 -> 6923644283575"
|
||||
},
|
||||
"6923644268930": {
|
||||
"map_to": "6923644268497",
|
||||
"description": "条码映射:6923644268930 -> 6923644268497"
|
||||
},
|
||||
"6923644268916": {
|
||||
"map_to": "6923644268503",
|
||||
"description": "条码映射:6923644268916 -> 6923644268503"
|
||||
},
|
||||
"6923644268909": {
|
||||
"map_to": "6923644268510",
|
||||
"description": "条码映射:6923644268909 -> 6923644268510"
|
||||
},
|
||||
"6923644299804": {
|
||||
"map_to": "6923644299774",
|
||||
"description": "条码映射:6923644299804 -> 6923644299774"
|
||||
},
|
||||
"6923644266318": {
|
||||
"map_to": "6923644266066",
|
||||
"description": "条码映射:6923644266318 -> 6923644266066"
|
||||
},
|
||||
"6923644210151": {
|
||||
"map_to": "6923644223458",
|
||||
"description": "条码映射:6923644210151 -> 6923644223458"
|
||||
},
|
||||
"6907992501819": {
|
||||
"map_to": "6907992500133",
|
||||
"description": "条码映射:6907992501819 -> 6907992500133"
|
||||
},
|
||||
"6907992502052": {
|
||||
"map_to": "6907992100272",
|
||||
"description": "条码映射:6907992502052 -> 6907992100272"
|
||||
},
|
||||
"6907992507385": {
|
||||
"map_to": "6907992507095",
|
||||
"description": "条码映射:6907992507385 -> 6907992507095"
|
||||
},
|
||||
"6973726149671": {
|
||||
"map_to": "6973726149657",
|
||||
"description": "条码映射:6973726149671 -> 6973726149657"
|
||||
},
|
||||
"6977426410574": {
|
||||
"map_to": "6977426410567",
|
||||
"description": "条码映射:6977426410574 -> 6977426410567"
|
||||
},
|
||||
"6973726149688": {
|
||||
"map_to": "6973726149664",
|
||||
"description": "条码映射:6973726149688 -> 6973726149664"
|
||||
},
|
||||
"6935205322012": {
|
||||
"map_to": "6935205320018",
|
||||
"description": "条码映射:6935205322012 -> 6935205320018"
|
||||
},
|
||||
"6943497411024": {
|
||||
"map_to": "6943497411017",
|
||||
"description": "条码映射:6943497411024 -> 6943497411017"
|
||||
},
|
||||
"6921734968821": {
|
||||
"map_to": "6921734968814",
|
||||
"description": "条码映射:6921734968821 -> 6921734968814"
|
||||
},
|
||||
"6921734968258": {
|
||||
"map_to": "6921734968241",
|
||||
"description": "条码映射:6921734968258 -> 6921734968241"
|
||||
},
|
||||
"6921734968180": {
|
||||
"map_to": "6921734968173",
|
||||
"description": "条码映射:6921734968180 -> 6921734968173"
|
||||
},
|
||||
"6921734908735": {
|
||||
"map_to": "6935205372772",
|
||||
"description": "条码映射:6921734908735 -> 6935205372772"
|
||||
},
|
||||
"6923644248222": {
|
||||
"map_to": "6923644248208",
|
||||
"description": "条码映射:6923644248222 -> 6923644248208"
|
||||
},
|
||||
"6902083881122": {
|
||||
"map_to": "6902083881085",
|
||||
"description": "条码映射:6902083881122 -> 6902083881085"
|
||||
},
|
||||
"6907992501857": {
|
||||
"map_to": "6907992500010",
|
||||
"description": "条码映射:6907992501857 -> 6907992500010"
|
||||
},
|
||||
"6902083891015": {
|
||||
"map_to": "6902083890636",
|
||||
"description": "条码映射:6902083891015 -> 6902083890636"
|
||||
},
|
||||
"6923450605240": {
|
||||
"map_to": "6923450605226",
|
||||
"description": "条码映射:6923450605240 -> 6923450605226"
|
||||
},
|
||||
"6923450605196": {
|
||||
"map_to": "6923450614624",
|
||||
"description": "条码映射:6923450605196 -> 6923450614624"
|
||||
},
|
||||
"6923450665213": {
|
||||
"map_to": "6923450665206",
|
||||
"description": "条码映射:6923450665213 -> 6923450665206"
|
||||
},
|
||||
"6923450666821": {
|
||||
"map_to": "6923450666838",
|
||||
"description": "条码映射:6923450666821 -> 6923450666838"
|
||||
},
|
||||
"6923450661505": {
|
||||
"map_to": "6923450661499",
|
||||
"description": "条码映射:6923450661505 -> 6923450661499"
|
||||
},
|
||||
"6923450676103": {
|
||||
"map_to": "6923450676097",
|
||||
"description": "条码映射:6923450676103 -> 6923450676097"
|
||||
},
|
||||
"6923450614631": {
|
||||
"map_to": "6923450614624",
|
||||
"description": "条码映射:6923450614631 -> 6923450614624"
|
||||
},
|
||||
"6901424334174": {
|
||||
"map_to": "6973730760015",
|
||||
"description": "条码映射:6901424334174 -> 6973730760015"
|
||||
},
|
||||
"6958620703716": {
|
||||
"map_to": "6958620703907",
|
||||
"description": "条码映射:6958620703716 -> 6958620703907"
|
||||
},
|
||||
"6937003706322": {
|
||||
"map_to": "6937003703833",
|
||||
"description": "条码映射:6937003706322 -> 6937003703833"
|
||||
},
|
||||
"6950783203494": {
|
||||
"map_to": "6950873203494",
|
||||
"description": "条码映射:6950783203494 -> 6950873203494"
|
||||
},
|
||||
"6907992501871": {
|
||||
"map_to": "6907992500010",
|
||||
"description": "条码映射:6907992501871 -> 6907992500010"
|
||||
},
|
||||
"6907992501864": {
|
||||
"map_to": "6907992100012",
|
||||
"description": "条码映射:6907992501864 -> 6907992100012"
|
||||
},
|
||||
"6923644264192": {
|
||||
"map_to": "6923644264116",
|
||||
"description": "条码映射:6923644264192 -> 6923644264116"
|
||||
},
|
||||
"6923450667316": {
|
||||
"map_to": "69042386",
|
||||
"description": "条码映射:6923450667316 -> 69042386"
|
||||
},
|
||||
"6923450653012": {
|
||||
"map_to": "69021343",
|
||||
"description": "条码映射:6923450653012 -> 69021343"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"6958620703907": {
|
||||
"multiplier": 14,
|
||||
"target_unit": "个",
|
||||
"specification": "1*14",
|
||||
"description": "友臣肉松,1盒14个"
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
[API]
|
||||
api_key = O0Fgk3o69RWJ86eAX8BTHRaB
|
||||
secret_key = VyZD5lzcIMgsup1uuD6Cw0pfzS20IGPZ
|
||||
timeout = 30
|
||||
max_retries = 3
|
||||
retry_delay = 2
|
||||
api_url = https://aip.baidubce.com/rest/2.0/ocr/v1/table
|
||||
|
||||
[Paths]
|
||||
input_folder = data/input
|
||||
output_folder = data/output
|
||||
temp_folder = data/temp
|
||||
template_folder = templates
|
||||
processed_record = data/processed_files.json
|
||||
|
||||
[Performance]
|
||||
max_workers = 4
|
||||
batch_size = 5
|
||||
skip_existing = true
|
||||
|
||||
[File]
|
||||
allowed_extensions = .jpg,.jpeg,.png,.bmp
|
||||
excel_extension = .xlsx
|
||||
max_file_size_mb = 4
|
||||
|
||||
[Templates]
|
||||
purchase_order = 银豹-采购单模板.xls
|
||||
|
||||
Binary file not shown.
@ -1,89 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
测试数量计算逻辑
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
import pandas as pd
|
||||
from decimal import Decimal
|
||||
|
||||
# 添加项目根目录到路径
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from app.core.excel.validators import ProductValidator
|
||||
|
||||
|
||||
class TestQuantityCalculation(unittest.TestCase):
|
||||
"""测试数量计算逻辑"""
|
||||
|
||||
def setUp(self):
|
||||
"""设置测试环境"""
|
||||
self.validator = ProductValidator()
|
||||
|
||||
def test_quantity_calculation_from_amount(self):
|
||||
"""测试通过单价和金额计算数量"""
|
||||
# 测试数量为空,但单价和金额存在的情况
|
||||
product = {
|
||||
'barcode': '6901028075862',
|
||||
'name': '可口可乐',
|
||||
'quantity': None,
|
||||
'price': 5.0,
|
||||
'amount': 60.0,
|
||||
'unit': '瓶'
|
||||
}
|
||||
|
||||
# 验证产品
|
||||
validated = self.validator.validate_product(product)
|
||||
|
||||
# 断言:数量应该被计算为金额/单价 = 60/5 = 12
|
||||
self.assertAlmostEqual(validated['quantity'], 12.0, places=2)
|
||||
|
||||
def test_quantity_calculation_with_string_values(self):
|
||||
"""测试字符串形式的单价和金额"""
|
||||
# 测试数量为空,单价和金额为字符串的情况
|
||||
product = {
|
||||
'barcode': '6901028075862',
|
||||
'name': '可口可乐',
|
||||
'quantity': None,
|
||||
'price': '5.0',
|
||||
'amount': '60.0',
|
||||
'unit': '瓶'
|
||||
}
|
||||
|
||||
# 验证产品
|
||||
validated = self.validator.validate_product(product)
|
||||
|
||||
# 断言:数量应该被计算为金额/单价 = 60/5 = 12
|
||||
self.assertAlmostEqual(validated['quantity'], 12.0, places=2)
|
||||
|
||||
def test_quantity_calculation_with_format_issues(self):
|
||||
"""测试格式问题的情况"""
|
||||
# 测试数量为空,单价和金额有格式问题的情况
|
||||
product = {
|
||||
'barcode': '6901028075862',
|
||||
'name': '可口可乐',
|
||||
'quantity': None,
|
||||
'price': '5,0', # 使用逗号作为小数点
|
||||
'amount': '¥60.0', # 带货币符号
|
||||
'unit': '瓶'
|
||||
}
|
||||
|
||||
# 验证产品
|
||||
validated = self.validator.validate_product(product)
|
||||
|
||||
# 断言:数量应该被计算为金额/单价 = 60/5 = 12
|
||||
self.assertAlmostEqual(validated['quantity'], 12.0, places=2)
|
||||
|
||||
def test_specification_parsing(self):
|
||||
"""测试规格解析逻辑"""
|
||||
# 这部分测试需要导入规格解析器
|
||||
# 由于需要引入额外的代码,此处仅作为示例
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Reference in New Issue
Block a user