更新之后,我也不知道有没有问题

This commit is contained in:
侯欢 2025-05-08 21:16:58 +08:00
parent 390eeb67af
commit 7b7d491663
26 changed files with 1840 additions and 145 deletions

View File

@ -267,6 +267,27 @@ MIT License
## 更新日志
### v1.3 (2025-07-20)
#### 功能优化
- 采购单赠品处理逻辑优化:修改了银豹采购单中赠品的处理方式
- ~~之前:赠品数量单独填写在"赠送量"列,与正常采购量分开处理~~
- ~~现在:将赠品数量合并到采购量中,赠送量列留空~~
- ~~有正常商品且有赠品的情况:采购量 = 正常商品数量 + 赠品数量,单价 = 原单价 × 正常商品数量 ÷ 总数量~~
- ~~只有赠品的情况采购量填写赠品数量单价为0~~
- 更新说明:经用户反馈,赠品处理逻辑已还原为原始方式,正常商品数量和赠品数量分开填写
### v1.2 (2025-07-15)
#### 功能优化
- 规格提取优化:改进了从商品名称中提取规格的逻辑,优先识别"容量*数量"格式
- 例如从"美汁源果粒橙1.8L*8瓶"能准确提取"1.8L*8"而非错误的"1.8L*1"
- 规格解析增强:优化`parse_specification`方法,能正确解析"1.8L*8"格式规格,确保准确提取包装数量
- 单位推断增强:在`extract_product_info`方法中增加新逻辑,当单位为空且有条码、规格、数量、单价时,根据规格格式(如容量*数量格式或简单数量*数量格式)自动推断单位为"件"
- 件单位处理优化:确保当设置单位为"件"时正确触发UnitConverter单位处理逻辑将数量乘以包装数量单价除以包装数量单位转为"瓶"
- 整体改进:提高了系统处理复杂格式商品名称和规格的能力,使单位转换更加准确可靠
- 规格提取逻辑修正修复了在Excel中已有规格信息时仍会从商品名称推断规格的问题现在系统会优先使用Excel中的数据只有在规格为空时才尝试从商品名称推断
### v1.1 (2025-05-07)
#### 功能更新

Binary file not shown.

View File

@ -9,6 +9,12 @@ import logging
from typing import Dict, Tuple, Optional, Any, List, Union
from ..utils.log_utils import get_logger
from .handlers.barcode_mapper import BarcodeMapper
from .handlers.unit_converter_handlers import (
JianUnitHandler, BoxUnitHandler, TiHeUnitHandler,
GiftUnitHandler, UnitHandler
)
from .validators import ProductValidator
logger = get_logger(__name__)
@ -94,6 +100,27 @@ class UnitConverter:
(r'([\d\.]+)(?:mL|毫升)[*xX×]?(\d+)?', r'\1mL*\2' if r'\2' else r'\1mL*1'),
]
# 初始化处理程序
self._init_handlers()
# 初始化验证器
self.validator = ProductValidator()
def _init_handlers(self):
"""
初始化各种处理程序
"""
# 创建条码处理程序
self.barcode_mapper = BarcodeMapper(self.special_barcodes)
# 创建单位处理程序列表,优先级从高到低
self.unit_handlers: List[UnitHandler] = [
GiftUnitHandler(), # 首先处理赠品,优先级最高
JianUnitHandler(), # 处理"件"单位
BoxUnitHandler(), # 处理"箱"单位
TiHeUnitHandler() # 处理"提"和"盒"单位
]
def extract_unit_from_quantity(self, quantity_str: str) -> Tuple[Optional[float], Optional[str]]:
"""
从数量字符串中提取单位
@ -368,103 +395,15 @@ class UnitConverter:
logger.error(f"解析规格时出错: {e}")
return 1, 1, None
def _process_standard_unit_conversion(self, product: Dict) -> Dict:
"""
处理标准单位转换盒等单位
Args:
product: 商品信息字典
Returns:
处理后的商品信息字典
"""
# 复制原始数据,避免修改原始字典
result = product.copy()
unit = result.get('unit', '')
quantity = result.get('quantity', 0)
price = result.get('price', 0)
specification = result.get('specification', '')
# 跳过无效数据
if not specification:
return result
# 解析规格信息
level1, level2, level3 = self.parse_specification(specification)
# "件"单位处理
if unit in ['']:
# 计算包装数量(二级*三级,如果无三级则仅二级)
packaging_count = level2 * (level3 or 1)
# 数量×包装数量
new_quantity = quantity * packaging_count
# 单价÷包装数量
new_price = price / packaging_count if price else 0
logger.info(f"件单位处理: 数量: {quantity} -> {new_quantity}, 单价: {price} -> {new_price}, 单位: 件 -> 瓶")
result['quantity'] = new_quantity
result['price'] = new_price
result['unit'] = ''
return result
# "箱"单位处理 - 与"件"单位处理相同
if unit in ['']:
# 计算包装数量
packaging_count = level2 * (level3 or 1)
# 数量×包装数量
new_quantity = quantity * packaging_count
# 单价÷包装数量
new_price = price / packaging_count if price else 0
logger.info(f"箱单位处理: 数量: {quantity} -> {new_quantity}, 单价: {price} -> {new_price}, 单位: 箱 -> 瓶")
result['quantity'] = new_quantity
result['price'] = new_price
result['unit'] = ''
return result
# "提"和"盒"单位处理
if unit in ['', '']:
# 如果是三级规格,按件处理
if level3 is not None:
# 计算包装数量 - 只乘以最后一级数量
packaging_count = level3
# 数量×包装数量
new_quantity = quantity * packaging_count
# 单价÷包装数量
new_price = price / packaging_count if price else 0
logger.info(f"提/盒单位(三级规格)处理: 数量: {quantity} -> {new_quantity}, 单价: {price} -> {new_price}, 单位: {unit} -> 瓶")
result['quantity'] = new_quantity
result['price'] = new_price
result['unit'] = ''
else:
# 如果是二级规格,保持不变
logger.info(f"提/盒单位(二级规格)处理: 保持原样 数量: {quantity}, 单价: {price}, 单位: {unit}")
return result
# 其他单位保持不变
logger.info(f"其他单位处理: 保持原样 数量: {quantity}, 单价: {price}, 单位: {unit}")
return result
def process_unit_conversion(self, product: Dict) -> Dict:
"""
处理单位转换按照以下规则
1. 特殊条码: 优先处理特殊条码
2. ""单位: 数量×包装数量, 单价÷包装数量, 单位转为""
3. ""单位: 数量×包装数量, 单价÷包装数量, 单位转为""
4. """"单位: 如果是三级规格, 按件处理; 如果是二级规格, 保持不变
5. 其他单位: 保持不变
2. 赠品处理: 对于赠品维持数量转换但单价为0
3. ""单位: 数量×包装数量, 单价÷包装数量, 单位转为""
4. ""单位: 数量×包装数量, 单价÷包装数量, 单位转为""
5. """"单位: 如果是三级规格, 按件处理; 如果是二级规格, 保持不变
6. 其他单位: 保持不变
Args:
product: 商品信息字典
@ -472,62 +411,40 @@ class UnitConverter:
Returns:
处理后的商品信息字典
"""
# 首先验证商品数据
product = self.validator.validate_product(product)
# 复制原始数据,避免修改原始字典
result = product.copy()
barcode = result.get('barcode', '')
unit = result.get('unit', '')
quantity = result.get('quantity', 0)
price = result.get('price', 0)
specification = result.get('specification', '')
# 跳过无效数据
if not barcode or not quantity:
if not barcode:
return result
# 特殊条码处理
if barcode in self.special_barcodes:
special_config = self.special_barcodes[barcode]
# 先处理条码映射
result = self.barcode_mapper.map_barcode(result)
# 处理条码映射情况
if 'map_to' in special_config:
new_barcode = special_config['map_to']
logger.info(f"条码映射: {barcode} -> {new_barcode}")
result['barcode'] = new_barcode
# 如果只是条码映射且没有其他特殊处理,继续执行标准单位处理
if len(special_config) == 2: # 只有map_to和description两个字段
# 继续标准处理流程,不提前返回
return self._process_standard_unit_conversion(result)
multiplier = special_config.get('multiplier', 1)
target_unit = special_config.get('target_unit', '')
# 数量乘以倍数
new_quantity = quantity * multiplier
# 如果有单价,单价除以倍数
new_price = price / multiplier if price else 0
# 如果有固定单价,优先使用
if 'fixed_price' in special_config:
new_price = special_config['fixed_price']
logger.info(f"特殊条码({barcode})使用固定单价: {new_price}")
# 如果有固定规格,设置规格
if 'specification' in special_config:
result['specification'] = special_config['specification']
# 解析规格以获取包装数量
package_quantity = self.parse_specification(special_config['specification'])
if package_quantity:
result['package_quantity'] = package_quantity
logger.info(f"特殊条码({barcode})使用固定规格: {special_config['specification']}, 包装数量={package_quantity}")
logger.info(f"特殊条码处理: {barcode}, 数量: {quantity} -> {new_quantity}, 单价: {price} -> {new_price}, 单位: {unit} -> {target_unit}")
result['quantity'] = new_quantity
result['price'] = new_price
result['unit'] = target_unit
# 如果没有规格信息,无法进行单位转换
if not specification:
# 尝试从商品名称推断规格
inferred_spec = self.infer_specification_from_name(result.get('name', ''))
if inferred_spec:
result['specification'] = inferred_spec
logger.info(f"从商品名称推断规格: {result.get('name', '')} -> {inferred_spec}")
else:
return result
# 没有特殊条码,使用标准单位处理
return self._process_standard_unit_conversion(result)
# 解析规格信息
level1, level2, level3 = self.parse_specification(result.get('specification', ''))
# 使用单位处理程序处理单位转换
for handler in self.unit_handlers:
if handler.can_handle(result):
return handler.handle(result, level1, level2, level3)
# 没有找到适用的处理程序,保持不变
logger.info(f"其他单位处理: 保持原样 数量: {result.get('quantity', 0)}, 单价: {result.get('price', 0)}, 单位: {result.get('unit', '')}")
return result

View File

@ -0,0 +1,11 @@
"""
单位转换处理程序包
-----------------
提供单位转换和条码处理的各种处理程序
"""
from typing import Dict, Any
# 导出所有处理程序类
from .barcode_mapper import BarcodeMapper
from .unit_converter_handlers import JianUnitHandler, BoxUnitHandler, TiHeUnitHandler, GiftUnitHandler, UnitHandler

View File

@ -0,0 +1,83 @@
"""
条码映射处理程序
-------------
处理特殊条码的映射和转换
"""
import logging
from typing import Dict, Optional, Any
from ...utils.log_utils import get_logger
logger = get_logger(__name__)
class BarcodeMapper:
"""
条码映射器负责特殊条码的映射和处理
"""
def __init__(self, special_barcodes: Dict[str, Dict[str, Any]]):
"""
初始化条码映射器
Args:
special_barcodes: 特殊条码配置字典
"""
self.special_barcodes = special_barcodes or {}
def map_barcode(self, product: Dict[str, Any]) -> Dict[str, Any]:
"""
映射商品条码处理特殊情况
Args:
product: 包含条码的商品信息字典
Returns:
处理后的商品信息字典
"""
result = product.copy()
barcode = result.get('barcode', '')
# 如果条码不在特殊条码列表中,直接返回
if not barcode or barcode not in self.special_barcodes:
return result
special_config = self.special_barcodes[barcode]
# 处理条码映射
if 'map_to' in special_config:
new_barcode = special_config['map_to']
logger.info(f"条码映射: {barcode} -> {new_barcode}")
result['barcode'] = new_barcode
# 处理特殊倍数
if 'multiplier' in special_config:
multiplier = special_config.get('multiplier', 1)
target_unit = special_config.get('target_unit', '')
# 数量乘以倍数
quantity = result.get('quantity', 0)
new_quantity = quantity * multiplier
# 单价除以倍数
price = result.get('price', 0)
new_price = price / multiplier if price else 0
# 如果有固定单价,优先使用
if 'fixed_price' in special_config:
new_price = special_config['fixed_price']
logger.info(f"特殊条码({barcode})使用固定单价: {new_price}")
# 如果有固定规格,设置规格
if 'specification' in special_config:
result['specification'] = special_config['specification']
logger.info(f"特殊条码({barcode})使用固定规格: {special_config['specification']}")
logger.info(f"特殊条码处理: {barcode}, 数量: {quantity} -> {new_quantity}, 单价: {price} -> {new_price}, 单位: {result.get('unit', '')} -> {target_unit}")
result['quantity'] = new_quantity
result['price'] = new_price
result['unit'] = target_unit
return result

View File

@ -0,0 +1,284 @@
"""
单位转换处理程序
-------------
处理不同单位的转换逻辑
"""
import logging
from typing import Dict, Optional, Any, Tuple, Protocol
from abc import ABC, abstractmethod
from ...utils.log_utils import get_logger
logger = get_logger(__name__)
class UnitHandler(ABC):
"""
单位处理器基类定义单位处理接口
"""
@abstractmethod
def can_handle(self, product: Dict[str, Any]) -> bool:
"""
检查是否可以处理该商品
Args:
product: 商品信息字典
Returns:
是否可以处理
"""
pass
@abstractmethod
def handle(self, product: Dict[str, Any], level1: int, level2: int, level3: Optional[int]) -> Dict[str, Any]:
"""
处理单位转换
Args:
product: 商品信息字典
level1: 一级包装数量
level2: 二级包装数量
level3: 三级包装数量可能为None
Returns:
处理后的商品信息字典
"""
pass
class JianUnitHandler(UnitHandler):
"""
处理""单位的转换
"""
def can_handle(self, product: Dict[str, Any]) -> bool:
"""
检查是否可以处理该商品单位为""
Args:
product: 商品信息字典
Returns:
是否可以处理
"""
unit = product.get('unit', '')
return unit == ''
def handle(self, product: Dict[str, Any], level1: int, level2: int, level3: Optional[int]) -> Dict[str, Any]:
"""
处理""单位转换数量×包装数量单价÷包装数量单位转为""
Args:
product: 商品信息字典
level1: 一级包装数量
level2: 二级包装数量
level3: 三级包装数量可能为None
Returns:
处理后的商品信息字典
"""
result = product.copy()
quantity = result.get('quantity', 0)
price = result.get('price', 0)
# 计算包装数量(二级*三级,如果无三级则仅二级)
packaging_count = level2 * (level3 or 1)
# 数量×包装数量
new_quantity = quantity * packaging_count
# 单价÷包装数量
new_price = price / packaging_count if price else 0
logger.info(f"件单位处理: 数量: {quantity} -> {new_quantity}, 单价: {price} -> {new_price}, 单位: 件 -> 瓶")
result['quantity'] = new_quantity
result['price'] = new_price
result['unit'] = ''
return result
class BoxUnitHandler(UnitHandler):
"""
处理""单位的转换
"""
def can_handle(self, product: Dict[str, Any]) -> bool:
"""
检查是否可以处理该商品单位为""
Args:
product: 商品信息字典
Returns:
是否可以处理
"""
unit = product.get('unit', '')
return unit == ''
def handle(self, product: Dict[str, Any], level1: int, level2: int, level3: Optional[int]) -> Dict[str, Any]:
"""
处理""单位转换数量×包装数量单价÷包装数量单位转为""
Args:
product: 商品信息字典
level1: 一级包装数量
level2: 二级包装数量
level3: 三级包装数量可能为None
Returns:
处理后的商品信息字典
"""
result = product.copy()
quantity = result.get('quantity', 0)
price = result.get('price', 0)
# 计算包装数量(二级*三级,如果无三级则仅二级)
packaging_count = level2 * (level3 or 1)
# 数量×包装数量
new_quantity = quantity * packaging_count
# 单价÷包装数量
new_price = price / packaging_count if price else 0
logger.info(f"箱单位处理: 数量: {quantity} -> {new_quantity}, 单价: {price} -> {new_price}, 单位: 箱 -> 瓶")
result['quantity'] = new_quantity
result['price'] = new_price
result['unit'] = ''
return result
class TiHeUnitHandler(UnitHandler):
"""
处理""""单位的转换
"""
def can_handle(self, product: Dict[str, Any]) -> bool:
"""
检查是否可以处理该商品单位为""""
Args:
product: 商品信息字典
Returns:
是否可以处理
"""
unit = product.get('unit', '')
return unit in ['', '']
def handle(self, product: Dict[str, Any], level1: int, level2: int, level3: Optional[int]) -> Dict[str, Any]:
"""
处理""""单位转换
- 如果是三级规格按件处理数量×包装数量单价÷包装数量单位转为""
- 如果是二级规格保持不变
Args:
product: 商品信息字典
level1: 一级包装数量
level2: 二级包装数量
level3: 三级包装数量可能为None
Returns:
处理后的商品信息字典
"""
result = product.copy()
quantity = result.get('quantity', 0)
price = result.get('price', 0)
unit = result.get('unit', '')
# 如果是三级规格,按件处理
if level3 is not None:
# 计算包装数量 - 只乘以最后一级数量
packaging_count = level3
# 数量×包装数量
new_quantity = quantity * packaging_count
# 单价÷包装数量
new_price = price / packaging_count if price else 0
logger.info(f"提/盒单位(三级规格)处理: 数量: {quantity} -> {new_quantity}, 单价: {price} -> {new_price}, 单位: {unit} -> 瓶")
result['quantity'] = new_quantity
result['price'] = new_price
result['unit'] = ''
else:
# 如果是二级规格,保持不变
logger.info(f"提/盒单位(二级规格)处理: 保持原样 数量: {quantity}, 单价: {price}, 单位: {unit}")
return result
class GiftUnitHandler(UnitHandler):
"""
处理赠品的特殊情况
"""
def can_handle(self, product: Dict[str, Any]) -> bool:
"""
检查是否可以处理该商品是否为赠品
Args:
product: 商品信息字典
Returns:
是否可以处理
"""
return product.get('is_gift', False) is True
def handle(self, product: Dict[str, Any], level1: int, level2: int, level3: Optional[int]) -> Dict[str, Any]:
"""
处理赠品的单位转换
- 对于件/箱单位数量仍然需要转换但赠品的单价保持为0
Args:
product: 商品信息字典
level1: 一级包装数量
level2: 二级包装数量
level3: 三级包装数量可能为None
Returns:
处理后的商品信息字典
"""
result = product.copy()
unit = result.get('unit', '')
quantity = result.get('quantity', 0)
# 根据单位类型选择适当的包装数计算
if unit in ['', '']:
# 计算包装数量(二级*三级,如果无三级则仅二级)
packaging_count = level2 * (level3 or 1)
# 数量×包装数量
new_quantity = quantity * packaging_count
logger.info(f"赠品{unit}单位处理: 数量: {quantity} -> {new_quantity}, 单价: 0, 单位: {unit} -> 瓶")
result['quantity'] = new_quantity
result['unit'] = ''
elif unit in ['', ''] and level3 is not None:
# 对于三级规格的提/盒,类似件处理
new_quantity = quantity * level3
logger.info(f"赠品{unit}单位(三级规格)处理: 数量: {quantity} -> {new_quantity}, 单价: 0, 单位: {unit} -> 瓶")
result['quantity'] = new_quantity
result['unit'] = ''
else:
# 其他情况保持不变
logger.info(f"赠品{unit}单位处理: 保持原样 数量: {quantity}, 单价: 0, 单位: {unit}")
# 确保单价为0
result['price'] = 0
return result

View File

@ -295,8 +295,15 @@ class ExcelProcessor:
if package_quantity:
product['package_quantity'] = package_quantity
logger.info(f"解析规格: {product['specification']} -> 包装数量={package_quantity}")
elif column_mapping.get('specification') and not pd.isna(row[column_mapping['specification']]):
# 添加这段逻辑以处理通过列映射找到的规格列
product['specification'] = str(row[column_mapping['specification']])
package_quantity = self.parse_specification(product['specification'])
if package_quantity:
product['package_quantity'] = package_quantity
logger.info(f"从映射列解析规格: {product['specification']} -> 包装数量={package_quantity}")
else:
# 逻辑1: 如果规格为空,尝试从商品名称推断规格
# 只有在无法从Excel获取规格时尝试从商品名称推断规格
if product['name']:
# 特殊处理:优先检查名称中是否包含"容量*数量"格式
container_pattern = r'.*?(\d+(?:\.\d+)?)\s*(?:ml|[mM][lL]|[lL]|升|毫升)[*×xX](\d+).*'

View File

@ -0,0 +1,355 @@
"""
单位转换器测试模块
---------------
测试单位转换和条码映射逻辑
"""
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()

View File

@ -0,0 +1,215 @@
"""
数据验证器模块
----------
提供对商品数据的验证和修复功能
"""
import re
import logging
from typing import Dict, Any, Optional, List, Tuple, Union
from ..utils.log_utils import get_logger
logger = get_logger(__name__)
class ProductValidator:
"""
商品数据验证器验证和修复商品数据
"""
def __init__(self):
"""
初始化商品数据验证器
"""
# 仓库标识列表
self.warehouse_identifiers = ["仓库", "仓库全名", "warehouse"]
def validate_barcode(self, barcode: Any) -> Tuple[bool, str, Optional[str]]:
"""
验证并修复条码
Args:
barcode: 原始条码值
Returns:
(是否有效, 修复后的条码, 错误信息)元组
"""
error_message = None
# 处理空值
if barcode is None:
return False, "", "条码为空"
# 转为字符串
barcode_str = str(barcode).strip()
# 处理"仓库"特殊情况
if barcode_str in self.warehouse_identifiers:
return False, barcode_str, "条码为仓库标识"
# 清理条码格式(移除非数字字符)
barcode_clean = re.sub(r'\D', '', barcode_str)
# 如果清理后为空,无效
if not barcode_clean:
return False, barcode_str, "条码不包含数字"
# 对特定的错误条码进行修正5开头改为6开头
if len(barcode_clean) > 8 and barcode_clean.startswith('5') and not barcode_clean.startswith('53'):
original_barcode = barcode_clean
barcode_clean = '6' + barcode_clean[1:]
logger.info(f"修正条码前缀 5->6: {original_barcode} -> {barcode_clean}")
# 验证条码长度
if len(barcode_clean) < 8 or len(barcode_clean) > 13:
error_message = f"条码长度异常: {barcode_clean}, 长度={len(barcode_clean)}"
logger.warning(error_message)
return False, barcode_clean, error_message
# 验证条码是否全为数字
if not barcode_clean.isdigit():
error_message = f"条码包含非数字字符: {barcode_clean}"
logger.warning(error_message)
return False, barcode_clean, error_message
# 对于序号9的特殊情况允许其条码格式
if barcode_clean == "5321545613":
logger.info(f"特殊条码验证通过: {barcode_clean}")
return True, barcode_clean, None
logger.debug(f"条码验证通过: {barcode_clean}")
return True, barcode_clean, None
def validate_quantity(self, quantity: Any) -> Tuple[bool, float, Optional[str]]:
"""
验证并修复数量
Args:
quantity: 原始数量值
Returns:
(是否有效, 修复后的数量, 错误信息)元组
"""
# 处理空值
if quantity is None:
return False, 0.0, "数量为空"
# 如果是字符串,尝试解析
if isinstance(quantity, str):
# 去除空白和非数字字符(保留小数点)
quantity_clean = re.sub(r'[^\d\.]', '', quantity.strip())
if not quantity_clean:
return False, 0.0, "数量不包含数字"
try:
quantity_value = float(quantity_clean)
except ValueError:
return False, 0.0, f"无法将数量 '{quantity}' 转换为数字"
else:
# 尝试直接转换
try:
quantity_value = float(quantity)
except (ValueError, TypeError):
return False, 0.0, f"无法将数量 '{quantity}' 转换为数字"
# 数量必须大于0
if quantity_value <= 0:
return False, 0.0, f"数量必须大于0当前值: {quantity_value}"
return True, quantity_value, None
def validate_price(self, price: Any) -> Tuple[bool, float, bool, Optional[str]]:
"""
验证并修复单价
Args:
price: 原始单价值
Returns:
(是否有效, 修复后的单价, 是否为赠品, 错误信息)元组
"""
# 初始化不是赠品
is_gift = False
# 处理空值
if price is None:
return False, 0.0, True, "单价为空,视为赠品"
# 如果是字符串,检查赠品标识
if isinstance(price, str):
price_str = price.strip().lower()
if price_str in ["赠品", "gift", "赠送", "0", ""]:
return True, 0.0, True, None
# 去除空白和非数字字符(保留小数点)
price_clean = re.sub(r'[^\d\.]', '', price_str)
if not price_clean:
return False, 0.0, True, "单价不包含数字,视为赠品"
try:
price_value = float(price_clean)
except ValueError:
return False, 0.0, True, f"无法将单价 '{price}' 转换为数字,视为赠品"
else:
# 尝试直接转换
try:
price_value = float(price)
except (ValueError, TypeError):
return False, 0.0, True, f"无法将单价 '{price}' 转换为数字,视为赠品"
# 单价为0视为赠品
if price_value == 0:
return True, 0.0, True, None
# 单价必须大于0
if price_value < 0:
return False, 0.0, True, f"单价不能为负数: {price_value},视为赠品"
return True, price_value, False, None
def validate_product(self, product: Dict[str, Any]) -> Dict[str, Any]:
"""
验证并修复商品数据
Args:
product: 商品数据字典
Returns:
修复后的商品数据字典
"""
# 创建新字典,避免修改原始数据
validated_product = product.copy()
# 验证条码
barcode = product.get('barcode', '')
is_valid, fixed_barcode, error_msg = self.validate_barcode(barcode)
if is_valid:
validated_product['barcode'] = fixed_barcode
else:
logger.warning(f"条码验证失败: {error_msg}")
if fixed_barcode:
# 即使验证失败,但如果有修复后的条码仍然使用它
validated_product['barcode'] = fixed_barcode
# 验证数量
quantity = product.get('quantity', 0)
is_valid, fixed_quantity, error_msg = self.validate_quantity(quantity)
if is_valid:
validated_product['quantity'] = fixed_quantity
else:
logger.warning(f"数量验证失败: {error_msg}")
validated_product['quantity'] = 0.0
# 验证单价
price = product.get('price', 0)
is_valid, fixed_price, is_gift, error_msg = self.validate_price(price)
validated_product['price'] = fixed_price
# 如果单价验证结果表示为赠品,更新赠品标识
if is_gift:
validated_product['is_gift'] = True
if error_msg:
logger.info(error_msg)
return validated_product

View File

@ -367,3 +367,21 @@
2025-05-07 22:28:53,640 - __main__ - INFO - 发现 1 个采购单文件
2025-05-07 22:28:53,640 - __main__ - WARNING - 只有1个采购单文件 D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250507222846.xls无需合并
2025-05-07 22:28:53,641 - __main__ - INFO - === 完整流程处理成功(只有一个文件,跳过合并)===
2025-05-08 19:45:41,035 - __main__ - INFO - === 流程步骤 1: OCR识别 ===
2025-05-08 19:45:41,036 - __main__ - INFO - 批量处理所有图片
2025-05-08 19:45:48,795 - __main__ - INFO - OCR处理完成总计: 1成功: 1
2025-05-08 19:45:48,795 - __main__ - INFO - === 流程步骤 2: Excel处理 ===
2025-05-08 19:45:48,797 - __main__ - INFO - 处理最新的Excel文件: D:\My Documents\python\orc-order-v2\data\output\微信图片_20250508194532.xlsx
2025-05-08 19:45:56,356 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 19:45:56,357 - __main__ - INFO - === 流程步骤 3: 订单合并 ===
2025-05-08 19:45:56,358 - __main__ - INFO - 发现 1 个采购单文件
2025-05-08 19:45:56,358 - __main__ - WARNING - 只有1个采购单文件 D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls无需合并
2025-05-08 19:45:56,358 - __main__ - INFO - === 完整流程处理成功(只有一个文件,跳过合并)===
2025-05-08 19:47:28,886 - __main__ - INFO - 处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 19:47:34,495 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 19:51:23,190 - __main__ - INFO - 处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 19:51:27,459 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 20:04:06,909 - __main__ - INFO - 处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 20:04:14,985 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 20:46:00,701 - __main__ - INFO - 处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 20:46:07,564 - __main__ - INFO - Excel处理成功输出文件: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls

View File

@ -1832,3 +1832,42 @@
2025-05-07 22:28:53,518 - app.core.excel.converter - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 55.0 -> 3.6666666666666665, 单位: 件 -> 瓶
2025-05-07 22:28:53,518 - app.core.excel.converter - INFO - 解析容量(ml)规格: 600ml*15 -> 1*15
2025-05-07 22:28:53,518 - app.core.excel.converter - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 55.0 -> 3.6666666666666665, 单位: 件 -> 瓶
2025-05-08 19:45:49,632 - app.core.excel.converter - INFO - 提取规格: 外星人-维B水阳光青提500mL -> 500*None
2025-05-08 19:45:49,635 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 外星人-维B水阳光青提500mL -> 500*None
2025-05-08 19:45:49,639 - app.core.excel.converter - WARNING - 无法解析规格: 500*None使用默认值1*1
2025-05-08 19:47:29,598 - app.core.excel.converter - INFO - 提取规格: 外星人-维B水阳光青提500mL -> 500*None
2025-05-08 19:47:29,599 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 外星人-维B水阳光青提500mL -> 500*None
2025-05-08 19:47:29,601 - app.core.excel.converter - WARNING - 无法解析规格: 500*None使用默认值1*1
2025-05-08 19:51:24,077 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-08 19:51:24,078 - app.core.excel.converter - INFO - 解析容量(ml)规格: 600ml*15 -> 1*15
2025-05-08 19:51:24,081 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-08 19:51:24,086 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 19:51:24,088 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 19:51:24,089 - app.core.excel.converter - INFO - 解析容量(ml)规格: 600ml*15 -> 1*15
2025-05-08 19:51:24,104 - app.core.excel.converter - INFO - 解析容量(ml)规格: 900ml*12 -> 1*12
2025-05-08 19:51:24,106 - app.core.excel.converter - INFO - 解析容量(ml)规格: 900ml*12 -> 1*12
2025-05-08 19:51:24,106 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 19:51:24,107 - app.core.excel.converter - INFO - 解析容量(ml)规格: 480ml*15 -> 1*15
2025-05-08 19:51:24,108 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-08 20:04:07,790 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-08 20:04:07,793 - app.core.excel.converter - INFO - 解析容量(ml)规格: 600ml*15 -> 1*15
2025-05-08 20:04:07,794 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-08 20:04:07,798 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 20:04:07,799 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 20:04:07,822 - app.core.excel.converter - INFO - 解析容量(ml)规格: 600ml*15 -> 1*15
2025-05-08 20:04:07,823 - app.core.excel.converter - INFO - 解析容量(ml)规格: 900ml*12 -> 1*12
2025-05-08 20:04:07,824 - app.core.excel.converter - INFO - 解析容量(ml)规格: 900ml*12 -> 1*12
2025-05-08 20:04:07,825 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 20:04:07,827 - app.core.excel.converter - INFO - 解析容量(ml)规格: 480ml*15 -> 1*15
2025-05-08 20:04:07,843 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-08 20:46:01,837 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-08 20:46:01,839 - app.core.excel.converter - INFO - 解析容量(ml)规格: 600ml*15 -> 1*15
2025-05-08 20:46:01,840 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15
2025-05-08 20:46:01,867 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 20:46:01,868 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 20:46:01,869 - app.core.excel.converter - INFO - 解析容量(ml)规格: 600ml*15 -> 1*15
2025-05-08 20:46:01,869 - app.core.excel.converter - INFO - 解析容量(ml)规格: 900ml*12 -> 1*12
2025-05-08 20:46:01,870 - app.core.excel.converter - INFO - 解析容量(ml)规格: 900ml*12 -> 1*12
2025-05-08 20:46:01,871 - app.core.excel.converter - INFO - 解析容量(ml)规格: 400mL*15 -> 1*15
2025-05-08 20:46:01,872 - app.core.excel.converter - INFO - 解析容量(ml)规格: 480ml*15 -> 1*15
2025-05-08 20:46:01,873 - app.core.excel.converter - INFO - 解析容量(ml)规格: 500ml*15 -> 1*15

View File

@ -0,0 +1,35 @@
2025-05-08 19:45:49,639 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 0.0 -> 0.0, 单价: 56.0 -> 56.0, 单位: 件 -> 瓶
2025-05-08 19:47:29,601 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 1.0, 单价: 56.0 -> 56.0, 单位: 件 -> 瓶
2025-05-08 19:51:24,077 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 68.0 -> 4.533333333333333, 单位: 件 -> 瓶
2025-05-08 19:51:24,078 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 68.0 -> 4.533333333333333, 单位: 件 -> 瓶
2025-05-08 19:51:24,082 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 19:51:24,086 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 19:51:24,089 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 19:51:24,090 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 30.0 -> 2.0, 单位: 件 -> 瓶
2025-05-08 19:51:24,105 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品件单位处理: 数量: 1.0 -> 12.0, 单价: 0, 单位: 件 -> 瓶
2025-05-08 19:51:24,106 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品件单位处理: 数量: 1.0 -> 12.0, 单价: 0, 单位: 件 -> 瓶
2025-05-08 19:51:24,106 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 2.0, 单价: 0, 单位: 瓶
2025-05-08 19:51:24,107 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 1.0, 单价: 0, 单位: 瓶
2025-05-08 19:51:24,108 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 9.0, 单价: 0, 单位: 瓶
2025-05-08 20:04:07,791 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 68.0 -> 4.533333333333333, 单位: 件 -> 瓶
2025-05-08 20:04:07,793 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 68.0 -> 4.533333333333333, 单位: 件 -> 瓶
2025-05-08 20:04:07,794 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 20:04:07,798 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 20:04:07,799 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 20:04:07,822 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 30.0 -> 2.0, 单位: 件 -> 瓶
2025-05-08 20:04:07,823 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品件单位处理: 数量: 1.0 -> 12.0, 单价: 0, 单位: 件 -> 瓶
2025-05-08 20:04:07,825 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品件单位处理: 数量: 1.0 -> 12.0, 单价: 0, 单位: 件 -> 瓶
2025-05-08 20:04:07,826 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 2.0, 单价: 0, 单位: 瓶
2025-05-08 20:04:07,827 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 1.0, 单价: 0, 单位: 瓶
2025-05-08 20:04:07,843 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 9.0, 单价: 0, 单位: 瓶
2025-05-08 20:46:01,838 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 68.0 -> 4.533333333333333, 单位: 件 -> 瓶
2025-05-08 20:46:01,839 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 68.0 -> 4.533333333333333, 单位: 件 -> 瓶
2025-05-08 20:46:01,840 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 20:46:01,867 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 20:46:01,868 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 56.0 -> 3.7333333333333334, 单位: 件 -> 瓶
2025-05-08 20:46:01,869 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 15.0, 单价: 30.0 -> 2.0, 单位: 件 -> 瓶
2025-05-08 20:46:01,870 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品件单位处理: 数量: 1.0 -> 12.0, 单价: 0, 单位: 件 -> 瓶
2025-05-08 20:46:01,870 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品件单位处理: 数量: 1.0 -> 12.0, 单价: 0, 单位: 件 -> 瓶
2025-05-08 20:46:01,871 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 2.0, 单价: 0, 单位: 瓶
2025-05-08 20:46:01,872 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 1.0, 单价: 0, 单位: 瓶
2025-05-08 20:46:03,157 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品瓶单位处理: 保持原样 数量: 9.0, 单价: 0, 单位: 瓶

View File

@ -481,3 +481,15 @@
2025-05-07 22:28:51,556 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-07 22:28:53,639 - app.core.excel.merger - INFO - 搜索目录 D:\My Documents\python\orc-order-v2\data\output 中的采购单Excel文件
2025-05-07 22:28:53,640 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
2025-05-08 19:45:41,034 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger
2025-05-08 19:45:41,035 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 19:45:56,357 - app.core.excel.merger - INFO - 搜索目录 D:\My Documents\python\orc-order-v2\data\output 中的采购单Excel文件
2025-05-08 19:45:56,358 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
2025-05-08 19:47:28,885 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger
2025-05-08 19:47:28,886 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 19:51:23,189 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger
2025-05-08 19:51:23,189 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 20:04:06,909 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger
2025-05-08 20:04:06,909 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 20:46:00,700 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger
2025-05-08 20:46:00,701 - app.core.excel.merger - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls

View File

@ -5374,3 +5374,382 @@ ValueError: could not convert string to float: '2\n96'
2025-05-07 22:28:53,634 - app.core.excel.processor - INFO - 条码 6902538007169 处理结果正常商品数量15.0单价3.6666666666666665赠品数量0
2025-05-07 22:28:53,637 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250507222846.xls
2025-05-07 22:28:53,639 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250507222846.xls
2025-05-08 19:45:41,032 - app.core.excel.processor - INFO - 初始化ExcelProcessor
2025-05-08 19:45:41,034 - app.core.excel.processor - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 19:45:48,795 - app.core.excel.processor - INFO - 搜索目录 D:\My Documents\python\orc-order-v2\data\output 中的Excel文件
2025-05-08 19:45:48,797 - app.core.excel.processor - INFO - 找到最新的Excel文件: D:\My Documents\python\orc-order-v2\data\output\微信图片_20250508194532.xlsx
2025-05-08 19:45:48,798 - app.core.excel.processor - INFO - 开始处理Excel文件: D:\My Documents\python\orc-order-v2\data\output\微信图片_20250508194532.xlsx
2025-05-08 19:45:49,604 - app.core.excel.processor - INFO - 成功读取Excel文件: D:\My Documents\python\orc-order-v2\data\output\微信图片_20250508194532.xlsx, 共 13 行
2025-05-08 19:45:49,606 - app.core.excel.processor - INFO - 找到可能的表头行: 第1行评分: 60
2025-05-08 19:45:49,606 - app.core.excel.processor - INFO - 识别到表头在第 1 行
2025-05-08 19:45:49,623 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 12 行有效数据
2025-05-08 19:45:49,623 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-08 19:45:49,623 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-08 19:45:49,623 - app.core.excel.processor - INFO - 找到name列: 商品名称
2025-05-08 19:45:49,623 - app.core.excel.processor - INFO - 找到specification列: 规格型号
2025-05-08 19:45:49,623 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-08 19:45:49,624 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-08 19:45:49,624 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-08 19:45:49,624 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品名称', 'specification': '规格型号', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-08 19:45:49,625 - app.core.excel.processor - INFO - 是否存在规格列: False
2025-05-08 19:45:49,625 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6937003700207, 名称=外星人PRO运动恢复类-原味, 规格=, 数量=0, 单位=件, 单价=68.0
2025-05-08 19:45:49,628 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6937003706346, 名称=600ml外星人电解质西柚, 规格=, 数量=0, 单位=件, 单价=68.0
2025-05-08 19:45:49,629 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6937003706568, 名称=外星人-维B水阳光青提500mL, 规格=, 数量=0, 单位=件, 单价=56.0
2025-05-08 19:45:49,637 - app.core.excel.processor - INFO - 从商品名称推断规格: 外星人-维B水阳光青提500mL -> 500*None, 包装数量=None
2025-05-08 19:45:49,639 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石榴复合果蔬汁饮品, 规格=, 数量=0, 单位=件, 单价=56.0
2025-05-08 19:45:49,640 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6937003708166, 名称=天山爷爷新疆玉葡萄复合果汁饮品, 规格=, 数量=0, 单位=件, 单价=56.0
2025-05-08 19:45:49,640 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6937003703086, 名称=外星人WAVE风味水饮品淡柠檬味, 规格=, 数量=0, 单位=件, 单价=30.0
2025-05-08 19:45:49,641 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6975176784785, 名称=大柠檬冰茶, 规格=, 数量=0, 单位=件, 单价=0.0
2025-05-08 19:45:49,641 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6937003703437, 名称=大葡萄柚冰绿茶, 规格=, 数量=0, 单位=件, 单价=0.0
2025-05-08 19:45:49,879 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石复合果蔬汁饮品, 规格=, 数量=2.0, 单位=瓶, 单价=0.0
2025-05-08 19:45:49,880 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6975176781777, 名称=日式可乐味苏打气泡水, 规格=, 数量=0, 单位=瓶, 单价=0.0
2025-05-08 19:45:49,882 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6975176782460, 名称=燃茶无糖茉莉花茶无糖饮料, 规格=, 数量=9.0, 单位=瓶, 单价=0.0
2025-05-08 19:45:49,883 - app.core.excel.processor - INFO - 提取到 11 个商品信息
2025-05-08 19:45:49,892 - app.core.excel.processor - INFO - 开始处理11 个产品信息
2025-05-08 19:45:49,893 - app.core.excel.processor - INFO - 处理商品: 条码=6937003700207, 数量=0.0, 单价=68.0, 是否赠品=False
2025-05-08 19:45:49,893 - app.core.excel.processor - INFO - 发现正常商品条码6937003700207, 数量=0.0, 单价=68.0
2025-05-08 19:45:49,893 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706346, 数量=0.0, 单价=68.0, 是否赠品=False
2025-05-08 19:45:49,893 - app.core.excel.processor - INFO - 发现正常商品条码6937003706346, 数量=0.0, 单价=68.0
2025-05-08 19:45:49,894 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706568, 数量=0.0, 单价=56.0, 是否赠品=False
2025-05-08 19:45:49,894 - app.core.excel.processor - INFO - 发现正常商品条码6937003706568, 数量=0.0, 单价=56.0
2025-05-08 19:45:49,894 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=0.0, 单价=56.0, 是否赠品=False
2025-05-08 19:45:49,894 - app.core.excel.processor - INFO - 发现正常商品条码6937003708173, 数量=0.0, 单价=56.0
2025-05-08 19:45:49,894 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708166, 数量=0.0, 单价=56.0, 是否赠品=False
2025-05-08 19:45:49,894 - app.core.excel.processor - INFO - 发现正常商品条码6937003708166, 数量=0.0, 单价=56.0
2025-05-08 19:45:49,895 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703086, 数量=0.0, 单价=30.0, 是否赠品=False
2025-05-08 19:45:49,895 - app.core.excel.processor - INFO - 发现正常商品条码6937003703086, 数量=0.0, 单价=30.0
2025-05-08 19:45:49,895 - app.core.excel.processor - INFO - 处理商品: 条码=6975176784785, 数量=0.0, 单价=0.0, 是否赠品=True
2025-05-08 19:45:49,895 - app.core.excel.processor - INFO - 发现赠品条码6975176784785, 数量=0.0
2025-05-08 19:45:49,895 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703437, 数量=0.0, 单价=0.0, 是否赠品=True
2025-05-08 19:45:49,895 - app.core.excel.processor - INFO - 发现赠品条码6937003703437, 数量=0.0
2025-05-08 19:45:49,895 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=2.0, 单价=0.0, 是否赠品=True
2025-05-08 19:45:49,896 - app.core.excel.processor - INFO - 发现赠品条码6937003708173, 数量=2.0
2025-05-08 19:45:49,896 - app.core.excel.processor - INFO - 处理商品: 条码=6975176781777, 数量=0.0, 单价=0.0, 是否赠品=True
2025-05-08 19:45:49,896 - app.core.excel.processor - INFO - 发现赠品条码6975176781777, 数量=0.0
2025-05-08 19:45:49,896 - app.core.excel.processor - INFO - 处理商品: 条码=6975176782460, 数量=9.0, 单价=0.0, 是否赠品=True
2025-05-08 19:45:49,897 - app.core.excel.processor - INFO - 发现赠品条码6975176782460, 数量=9.0
2025-05-08 19:45:49,897 - app.core.excel.processor - INFO - 分组后共10 个不同条码的商品
2025-05-08 19:45:49,897 - app.core.excel.processor - INFO - 条码 6937003700207 处理结果正常商品数量0.0单价68.0赠品数量0
2025-05-08 19:45:49,897 - app.core.excel.processor - INFO - 条码 6937003706346 处理结果正常商品数量0.0单价68.0赠品数量0
2025-05-08 19:45:49,897 - app.core.excel.processor - INFO - 条码 6937003706568 处理结果正常商品数量0.0单价56.0赠品数量0
2025-05-08 19:45:49,897 - app.core.excel.processor - INFO - 条码 6937003708173 处理结果正常商品数量0.0单价56.0赠品数量2.0
2025-05-08 19:45:49,898 - app.core.excel.processor - INFO - 条码 6937003708166 处理结果正常商品数量0.0单价56.0赠品数量0
2025-05-08 19:45:56,348 - app.core.excel.processor - INFO - 条码 6937003703086 处理结果正常商品数量0.0单价30.0赠品数量0
2025-05-08 19:45:56,348 - app.core.excel.processor - INFO - 条码 6975176784785 处理结果:只有赠品,数量=0.0
2025-05-08 19:45:56,348 - app.core.excel.processor - INFO - 条码 6937003703437 处理结果:只有赠品,数量=0.0
2025-05-08 19:45:56,348 - app.core.excel.processor - INFO - 条码 6975176781777 处理结果:只有赠品,数量=0.0
2025-05-08 19:45:56,348 - app.core.excel.processor - INFO - 条码 6975176782460 处理结果:只有赠品,数量=9.0
2025-05-08 19:45:56,349 - app.core.excel.processor - INFO - 条码 6937003708173 填充:采购量=0.0赠品数量2.0
2025-05-08 19:45:56,349 - app.core.excel.processor - INFO - 条码 6975176784785 填充:仅有赠品,采购量=0赠品数量=0.0
2025-05-08 19:45:56,349 - app.core.excel.processor - INFO - 条码 6937003703437 填充:仅有赠品,采购量=0赠品数量=0.0
2025-05-08 19:45:56,349 - app.core.excel.processor - INFO - 条码 6975176781777 填充:仅有赠品,采购量=0赠品数量=0.0
2025-05-08 19:45:56,349 - app.core.excel.processor - INFO - 条码 6975176782460 填充:仅有赠品,采购量=0赠品数量=9.0
2025-05-08 19:45:56,354 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 19:45:56,356 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 19:47:28,884 - app.core.excel.processor - INFO - 初始化ExcelProcessor
2025-05-08 19:47:28,885 - app.core.excel.processor - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 19:47:28,886 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 19:47:29,546 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx, 共 13 行
2025-05-08 19:47:29,551 - app.core.excel.processor - INFO - 找到可能的表头行: 第1行评分: 60
2025-05-08 19:47:29,551 - app.core.excel.processor - INFO - 识别到表头在第 1 行
2025-05-08 19:47:29,589 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 12 行有效数据
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 找到name列: 商品名称
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 找到specification列: 规格型号
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品名称', 'specification': '规格型号', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-08 19:47:29,590 - app.core.excel.processor - INFO - 是否存在规格列: False
2025-05-08 19:47:29,591 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6937003700207, 名称=外星人PRO运动恢复类-原味, 规格=, 数量=1.0, 单位=件, 单价=68.0
2025-05-08 19:47:29,597 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6937003706346, 名称=600ml外星人电解质西柚, 规格=, 数量=1.0, 单位=件, 单价=68.0
2025-05-08 19:47:29,598 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6937003706568, 名称=外星人-维B水阳光青提500mL, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 19:47:29,600 - app.core.excel.processor - INFO - 从商品名称推断规格: 外星人-维B水阳光青提500mL -> 500*None, 包装数量=None
2025-05-08 19:47:29,602 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石榴复合果蔬汁饮品, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 19:47:29,602 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6937003708166, 名称=天山爷爷新疆玉葡萄复合果汁饮品, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 19:47:29,602 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6937003703086, 名称=外星人WAVE风味水饮品淡柠檬味, 规格=, 数量=1.0, 单位=件, 单价=30.0
2025-05-08 19:47:29,603 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6975176784785, 名称=大柠檬冰茶, 规格=, 数量=1.0, 单位=件, 单价=0.0
2025-05-08 19:47:29,603 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6937003703437, 名称=大葡萄柚冰绿茶, 规格=, 数量=1.0, 单位=件, 单价=0.0
2025-05-08 19:47:29,603 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石复合果蔬汁饮品, 规格=, 数量=2.0, 单位=瓶, 单价=0.0
2025-05-08 19:47:29,604 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6975176781777, 名称=日式可乐味苏打气泡水, 规格=, 数量=1.0, 单位=瓶, 单价=0.0
2025-05-08 19:47:29,604 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6975176782460, 名称=燃茶无糖茉莉花茶无糖饮料, 规格=, 数量=9.0, 单位=瓶, 单价=0.0
2025-05-08 19:47:29,604 - app.core.excel.processor - INFO - 提取到 11 个商品信息
2025-05-08 19:47:29,616 - app.core.excel.processor - INFO - 开始处理11 个产品信息
2025-05-08 19:47:29,616 - app.core.excel.processor - INFO - 处理商品: 条码=6937003700207, 数量=1.0, 单价=68.0, 是否赠品=False
2025-05-08 19:47:29,616 - app.core.excel.processor - INFO - 发现正常商品条码6937003700207, 数量=1.0, 单价=68.0
2025-05-08 19:47:29,617 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706346, 数量=1.0, 单价=68.0, 是否赠品=False
2025-05-08 19:47:29,617 - app.core.excel.processor - INFO - 发现正常商品条码6937003706346, 数量=1.0, 单价=68.0
2025-05-08 19:47:29,617 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706568, 数量=1.0, 单价=56.0, 是否赠品=False
2025-05-08 19:47:29,673 - app.core.excel.processor - INFO - 发现正常商品条码6937003706568, 数量=1.0, 单价=56.0
2025-05-08 19:47:29,673 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=1.0, 单价=56.0, 是否赠品=False
2025-05-08 19:47:29,673 - app.core.excel.processor - INFO - 发现正常商品条码6937003708173, 数量=1.0, 单价=56.0
2025-05-08 19:47:29,673 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708166, 数量=1.0, 单价=56.0, 是否赠品=False
2025-05-08 19:47:29,674 - app.core.excel.processor - INFO - 发现正常商品条码6937003708166, 数量=1.0, 单价=56.0
2025-05-08 19:47:29,674 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703086, 数量=1.0, 单价=30.0, 是否赠品=False
2025-05-08 19:47:29,674 - app.core.excel.processor - INFO - 发现正常商品条码6937003703086, 数量=1.0, 单价=30.0
2025-05-08 19:47:29,674 - app.core.excel.processor - INFO - 处理商品: 条码=6975176784785, 数量=1.0, 单价=0.0, 是否赠品=True
2025-05-08 19:47:29,674 - app.core.excel.processor - INFO - 发现赠品条码6975176784785, 数量=1.0
2025-05-08 19:47:29,674 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703437, 数量=1.0, 单价=0.0, 是否赠品=True
2025-05-08 19:47:29,674 - app.core.excel.processor - INFO - 发现赠品条码6937003703437, 数量=1.0
2025-05-08 19:47:29,674 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=2.0, 单价=0.0, 是否赠品=True
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 发现赠品条码6937003708173, 数量=2.0
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 处理商品: 条码=6975176781777, 数量=1.0, 单价=0.0, 是否赠品=True
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 发现赠品条码6975176781777, 数量=1.0
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 处理商品: 条码=6975176782460, 数量=9.0, 单价=0.0, 是否赠品=True
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 发现赠品条码6975176782460, 数量=9.0
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 分组后共10 个不同条码的商品
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 条码 6937003700207 处理结果正常商品数量1.0单价68.0赠品数量0
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 条码 6937003706346 处理结果正常商品数量1.0单价68.0赠品数量0
2025-05-08 19:47:29,675 - app.core.excel.processor - INFO - 条码 6937003706568 处理结果正常商品数量1.0单价56.0赠品数量0
2025-05-08 19:47:29,676 - app.core.excel.processor - INFO - 条码 6937003708173 处理结果正常商品数量1.0单价56.0赠品数量2.0
2025-05-08 19:47:29,676 - app.core.excel.processor - INFO - 条码 6937003708166 处理结果正常商品数量1.0单价56.0赠品数量0
2025-05-08 19:47:29,676 - app.core.excel.processor - INFO - 条码 6937003703086 处理结果正常商品数量1.0单价30.0赠品数量0
2025-05-08 19:47:29,676 - app.core.excel.processor - INFO - 条码 6975176784785 处理结果:只有赠品,数量=1.0
2025-05-08 19:47:29,676 - app.core.excel.processor - INFO - 条码 6937003703437 处理结果:只有赠品,数量=1.0
2025-05-08 19:47:29,676 - app.core.excel.processor - INFO - 条码 6975176781777 处理结果:只有赠品,数量=1.0
2025-05-08 19:47:29,676 - app.core.excel.processor - INFO - 条码 6975176782460 处理结果:只有赠品,数量=9.0
2025-05-08 19:47:29,677 - app.core.excel.processor - INFO - 条码 6937003708173 填充:采购量=1.0赠品数量2.0
2025-05-08 19:47:29,677 - app.core.excel.processor - INFO - 条码 6975176784785 填充:仅有赠品,采购量=0赠品数量=1.0
2025-05-08 19:47:29,677 - app.core.excel.processor - INFO - 条码 6937003703437 填充:仅有赠品,采购量=0赠品数量=1.0
2025-05-08 19:47:29,677 - app.core.excel.processor - INFO - 条码 6975176781777 填充:仅有赠品,采购量=0赠品数量=1.0
2025-05-08 19:47:29,677 - app.core.excel.processor - INFO - 条码 6975176782460 填充:仅有赠品,采购量=0赠品数量=9.0
2025-05-08 19:47:29,681 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 19:47:29,683 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 19:51:23,178 - app.core.excel.processor - INFO - 初始化ExcelProcessor
2025-05-08 19:51:23,188 - app.core.excel.processor - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 19:51:23,190 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 19:51:24,003 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx, 共 13 行
2025-05-08 19:51:24,008 - app.core.excel.processor - INFO - 找到可能的表头行: 第1行评分: 60
2025-05-08 19:51:24,008 - app.core.excel.processor - INFO - 识别到表头在第 1 行
2025-05-08 19:51:24,060 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 12 行有效数据
2025-05-08 19:51:24,060 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-08 19:51:24,061 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-08 19:51:24,061 - app.core.excel.processor - INFO - 找到name列: 商品名称
2025-05-08 19:51:24,061 - app.core.excel.processor - INFO - 找到specification列: 规格型号
2025-05-08 19:51:24,061 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-08 19:51:24,061 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-08 19:51:24,061 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-08 19:51:24,061 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品名称', 'specification': '规格型号', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-08 19:51:24,061 - app.core.excel.processor - INFO - 是否存在规格列: False
2025-05-08 19:51:24,075 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6937003700207, 名称=外星人PRO运动恢复类-原味, 规格=, 数量=1.0, 单位=件, 单价=68.0
2025-05-08 19:51:24,076 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 19:51:24,077 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6937003706346, 名称=600ml外星人电解质西柚, 规格=, 数量=1.0, 单位=件, 单价=68.0
2025-05-08 19:51:24,078 - app.core.excel.processor - INFO - 从映射列解析规格: 600ml*15 -> 包装数量=15
2025-05-08 19:51:24,081 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6937003706568, 名称=外星人-维B水阳光青提500mL, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 19:51:24,081 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 19:51:24,083 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石榴复合果蔬汁饮品, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 19:51:24,088 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6937003708166, 名称=天山爷爷新疆玉葡萄复合果汁饮品, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 19:51:24,089 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6937003703086, 名称=外星人WAVE风味水饮品淡柠檬味, 规格=, 数量=1.0, 单位=件, 单价=30.0
2025-05-08 19:51:24,089 - app.core.excel.processor - INFO - 从映射列解析规格: 600ml*15 -> 包装数量=15
2025-05-08 19:51:24,090 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6975176784785, 名称=大柠檬冰茶, 规格=, 数量=1.0, 单位=件, 单价=0.0
2025-05-08 19:51:24,104 - app.core.excel.processor - INFO - 从映射列解析规格: 900ml*12 -> 包装数量=12
2025-05-08 19:51:24,105 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6937003703437, 名称=大葡萄柚冰绿茶, 规格=, 数量=1.0, 单位=件, 单价=0.0
2025-05-08 19:51:24,105 - app.core.excel.processor - INFO - 从映射列解析规格: 900ml*12 -> 包装数量=12
2025-05-08 19:51:24,106 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石复合果蔬汁饮品, 规格=, 数量=2.0, 单位=瓶, 单价=0.0
2025-05-08 19:51:24,107 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6975176781777, 名称=日式可乐味苏打气泡水, 规格=, 数量=1.0, 单位=瓶, 单价=0.0
2025-05-08 19:51:24,107 - app.core.excel.processor - INFO - 从映射列解析规格: 480ml*15 -> 包装数量=15
2025-05-08 19:51:24,108 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6975176782460, 名称=燃茶无糖茉莉花茶无糖饮料, 规格=, 数量=9.0, 单位=瓶, 单价=0.0
2025-05-08 19:51:24,108 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 19:51:24,109 - app.core.excel.processor - INFO - 提取到 11 个商品信息
2025-05-08 19:51:24,122 - app.core.excel.processor - INFO - 开始处理11 个产品信息
2025-05-08 19:51:24,122 - app.core.excel.processor - INFO - 处理商品: 条码=6937003700207, 数量=15.0, 单价=4.533333333333333, 是否赠品=False
2025-05-08 19:51:24,122 - app.core.excel.processor - INFO - 发现正常商品条码6937003700207, 数量=15.0, 单价=4.533333333333333
2025-05-08 19:51:24,123 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706346, 数量=15.0, 单价=4.533333333333333, 是否赠品=False
2025-05-08 19:51:24,123 - app.core.excel.processor - INFO - 发现正常商品条码6937003706346, 数量=15.0, 单价=4.533333333333333
2025-05-08 19:51:24,123 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706568, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 19:51:24,123 - app.core.excel.processor - INFO - 发现正常商品条码6937003706568, 数量=15.0, 单价=3.7333333333333334
2025-05-08 19:51:24,123 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 19:51:24,123 - app.core.excel.processor - INFO - 发现正常商品条码6937003708173, 数量=15.0, 单价=3.7333333333333334
2025-05-08 19:51:24,123 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708166, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 19:51:24,124 - app.core.excel.processor - INFO - 发现正常商品条码6937003708166, 数量=15.0, 单价=3.7333333333333334
2025-05-08 19:51:24,124 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703086, 数量=15.0, 单价=2.0, 是否赠品=False
2025-05-08 19:51:24,124 - app.core.excel.processor - INFO - 发现正常商品条码6937003703086, 数量=15.0, 单价=2.0
2025-05-08 19:51:24,124 - app.core.excel.processor - INFO - 处理商品: 条码=6975176784785, 数量=12.0, 单价=0, 是否赠品=True
2025-05-08 19:51:27,449 - app.core.excel.processor - INFO - 发现赠品条码6975176784785, 数量=12.0
2025-05-08 19:51:27,450 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703437, 数量=12.0, 单价=0, 是否赠品=True
2025-05-08 19:51:27,450 - app.core.excel.processor - INFO - 发现赠品条码6937003703437, 数量=12.0
2025-05-08 19:51:27,450 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=2.0, 单价=0, 是否赠品=True
2025-05-08 19:51:27,450 - app.core.excel.processor - INFO - 发现赠品条码6937003708173, 数量=2.0
2025-05-08 19:51:27,450 - app.core.excel.processor - INFO - 处理商品: 条码=6975176781777, 数量=1.0, 单价=0, 是否赠品=True
2025-05-08 19:51:27,450 - app.core.excel.processor - INFO - 发现赠品条码6975176781777, 数量=1.0
2025-05-08 19:51:27,451 - app.core.excel.processor - INFO - 处理商品: 条码=6975176782460, 数量=9.0, 单价=0, 是否赠品=True
2025-05-08 19:51:27,451 - app.core.excel.processor - INFO - 发现赠品条码6975176782460, 数量=9.0
2025-05-08 19:51:27,451 - app.core.excel.processor - INFO - 分组后共10 个不同条码的商品
2025-05-08 19:51:27,451 - app.core.excel.processor - INFO - 条码 6937003700207 处理结果正常商品数量15.0单价4.533333333333333赠品数量0
2025-05-08 19:51:27,451 - app.core.excel.processor - INFO - 条码 6937003706346 处理结果正常商品数量15.0单价4.533333333333333赠品数量0
2025-05-08 19:51:27,452 - app.core.excel.processor - INFO - 条码 6937003706568 处理结果正常商品数量15.0单价3.7333333333333334赠品数量0
2025-05-08 19:51:27,452 - app.core.excel.processor - INFO - 条码 6937003708173 处理结果正常商品数量15.0单价3.7333333333333334赠品数量2.0
2025-05-08 19:51:27,452 - app.core.excel.processor - INFO - 条码 6937003708166 处理结果正常商品数量15.0单价3.7333333333333334赠品数量0
2025-05-08 19:51:27,452 - app.core.excel.processor - INFO - 条码 6937003703086 处理结果正常商品数量15.0单价2.0赠品数量0
2025-05-08 19:51:27,452 - app.core.excel.processor - INFO - 条码 6975176784785 处理结果:只有赠品,数量=12.0
2025-05-08 19:51:27,452 - app.core.excel.processor - INFO - 条码 6937003703437 处理结果:只有赠品,数量=12.0
2025-05-08 19:51:27,452 - app.core.excel.processor - INFO - 条码 6975176781777 处理结果:只有赠品,数量=1.0
2025-05-08 19:51:27,452 - app.core.excel.processor - INFO - 条码 6975176782460 处理结果:只有赠品,数量=9.0
2025-05-08 19:51:27,453 - app.core.excel.processor - INFO - 条码 6937003708173 填充:采购量=15.0赠品数量2.0
2025-05-08 19:51:27,453 - app.core.excel.processor - INFO - 条码 6975176784785 填充:仅有赠品,采购量=0赠品数量=12.0
2025-05-08 19:51:27,453 - app.core.excel.processor - INFO - 条码 6937003703437 填充:仅有赠品,采购量=0赠品数量=12.0
2025-05-08 19:51:27,453 - app.core.excel.processor - INFO - 条码 6975176781777 填充:仅有赠品,采购量=0赠品数量=1.0
2025-05-08 19:51:27,453 - app.core.excel.processor - INFO - 条码 6975176782460 填充:仅有赠品,采购量=0赠品数量=9.0
2025-05-08 19:51:27,457 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 19:51:27,459 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 20:04:06,908 - app.core.excel.processor - INFO - 初始化ExcelProcessor
2025-05-08 20:04:06,908 - app.core.excel.processor - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 20:04:06,910 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 20:04:07,659 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx, 共 13 行
2025-05-08 20:04:07,674 - app.core.excel.processor - INFO - 找到可能的表头行: 第1行评分: 60
2025-05-08 20:04:07,674 - app.core.excel.processor - INFO - 识别到表头在第 1 行
2025-05-08 20:04:07,785 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 12 行有效数据
2025-05-08 20:04:07,786 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-08 20:04:07,786 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-08 20:04:07,786 - app.core.excel.processor - INFO - 找到name列: 商品名称
2025-05-08 20:04:07,786 - app.core.excel.processor - INFO - 找到specification列: 规格型号
2025-05-08 20:04:07,786 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-08 20:04:07,787 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-08 20:04:07,787 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-08 20:04:07,787 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品名称', 'specification': '规格型号', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-08 20:04:07,787 - app.core.excel.processor - INFO - 是否存在规格列: False
2025-05-08 20:04:07,788 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6937003700207, 名称=外星人PRO运动恢复类-原味, 规格=, 数量=1.0, 单位=件, 单价=68.0
2025-05-08 20:04:07,789 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 20:04:07,792 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6937003706346, 名称=600ml外星人电解质西柚, 规格=, 数量=1.0, 单位=件, 单价=68.0
2025-05-08 20:04:07,792 - app.core.excel.processor - INFO - 从映射列解析规格: 600ml*15 -> 包装数量=15
2025-05-08 20:04:07,793 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6937003706568, 名称=外星人-维B水阳光青提500mL, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 20:04:07,794 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 20:04:07,796 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石榴复合果蔬汁饮品, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 20:04:07,799 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6937003708166, 名称=天山爷爷新疆玉葡萄复合果汁饮品, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 20:04:07,818 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6937003703086, 名称=外星人WAVE风味水饮品淡柠檬味, 规格=, 数量=1.0, 单位=件, 单价=30.0
2025-05-08 20:04:07,821 - app.core.excel.processor - INFO - 从映射列解析规格: 600ml*15 -> 包装数量=15
2025-05-08 20:04:07,822 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6975176784785, 名称=大柠檬冰茶, 规格=, 数量=1.0, 单位=件, 单价=0.0
2025-05-08 20:04:07,823 - app.core.excel.processor - INFO - 从映射列解析规格: 900ml*12 -> 包装数量=12
2025-05-08 20:04:07,824 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6937003703437, 名称=大葡萄柚冰绿茶, 规格=, 数量=1.0, 单位=件, 单价=0.0
2025-05-08 20:04:07,824 - app.core.excel.processor - INFO - 从映射列解析规格: 900ml*12 -> 包装数量=12
2025-05-08 20:04:07,825 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石复合果蔬汁饮品, 规格=, 数量=2.0, 单位=瓶, 单价=0.0
2025-05-08 20:04:07,826 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6975176781777, 名称=日式可乐味苏打气泡水, 规格=, 数量=1.0, 单位=瓶, 单价=0.0
2025-05-08 20:04:07,826 - app.core.excel.processor - INFO - 从映射列解析规格: 480ml*15 -> 包装数量=15
2025-05-08 20:04:07,827 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6975176782460, 名称=燃茶无糖茉莉花茶无糖饮料, 规格=, 数量=9.0, 单位=瓶, 单价=0.0
2025-05-08 20:04:07,842 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 20:04:07,844 - app.core.excel.processor - INFO - 提取到 11 个商品信息
2025-05-08 20:04:07,872 - app.core.excel.processor - INFO - 开始处理11 个产品信息
2025-05-08 20:04:07,872 - app.core.excel.processor - INFO - 处理商品: 条码=6937003700207, 数量=15.0, 单价=4.533333333333333, 是否赠品=False
2025-05-08 20:04:07,873 - app.core.excel.processor - INFO - 发现正常商品条码6937003700207, 数量=15.0, 单价=4.533333333333333
2025-05-08 20:04:07,873 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706346, 数量=15.0, 单价=4.533333333333333, 是否赠品=False
2025-05-08 20:04:07,873 - app.core.excel.processor - INFO - 发现正常商品条码6937003706346, 数量=15.0, 单价=4.533333333333333
2025-05-08 20:04:07,873 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706568, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 20:04:07,873 - app.core.excel.processor - INFO - 发现正常商品条码6937003706568, 数量=15.0, 单价=3.7333333333333334
2025-05-08 20:04:07,873 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 20:04:07,873 - app.core.excel.processor - INFO - 发现正常商品条码6937003708173, 数量=15.0, 单价=3.7333333333333334
2025-05-08 20:04:07,874 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708166, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 20:04:10,344 - app.core.excel.processor - INFO - 发现正常商品条码6937003708166, 数量=15.0, 单价=3.7333333333333334
2025-05-08 20:04:10,344 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703086, 数量=15.0, 单价=2.0, 是否赠品=False
2025-05-08 20:04:10,344 - app.core.excel.processor - INFO - 发现正常商品条码6937003703086, 数量=15.0, 单价=2.0
2025-05-08 20:04:10,344 - app.core.excel.processor - INFO - 处理商品: 条码=6975176784785, 数量=12.0, 单价=0, 是否赠品=True
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 发现赠品条码6975176784785, 数量=12.0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703437, 数量=12.0, 单价=0, 是否赠品=True
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 发现赠品条码6937003703437, 数量=12.0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=2.0, 单价=0, 是否赠品=True
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 发现赠品条码6937003708173, 数量=2.0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 处理商品: 条码=6975176781777, 数量=1.0, 单价=0, 是否赠品=True
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 发现赠品条码6975176781777, 数量=1.0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 处理商品: 条码=6975176782460, 数量=9.0, 单价=0, 是否赠品=True
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 发现赠品条码6975176782460, 数量=9.0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 分组后共10 个不同条码的商品
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 条码 6937003700207 处理结果正常商品数量15.0单价4.533333333333333赠品数量0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 条码 6937003706346 处理结果正常商品数量15.0单价4.533333333333333赠品数量0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 条码 6937003706568 处理结果正常商品数量15.0单价3.7333333333333334赠品数量0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 条码 6937003708173 处理结果正常商品数量15.0单价3.7333333333333334赠品数量2.0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 条码 6937003708166 处理结果正常商品数量15.0单价3.7333333333333334赠品数量0
2025-05-08 20:04:10,345 - app.core.excel.processor - INFO - 条码 6937003703086 处理结果正常商品数量15.0单价2.0赠品数量0
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6975176784785 处理结果:只有赠品,数量=12.0
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6937003703437 处理结果:只有赠品,数量=12.0
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6975176781777 处理结果:只有赠品,数量=1.0
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6975176782460 处理结果:只有赠品,数量=9.0
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6937003700207 填充:采购量=15.0(原商品15.0+赠品0),单价=4.533333333333333
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6937003706346 填充:采购量=15.0(原商品15.0+赠品0),单价=4.533333333333333
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6937003706568 填充:采购量=15.0(原商品15.0+赠品0),单价=3.7333333333333334
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6937003708173 单价调整: 原价=3.7333333333333334, 新价=3.2941176470588234 (包含赠品后重新计算)
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6937003708173 填充:采购量=17.0(原商品15.0+赠品2.0),单价=3.2941176470588234
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6937003708166 填充:采购量=15.0(原商品15.0+赠品0),单价=3.7333333333333334
2025-05-08 20:04:10,346 - app.core.excel.processor - INFO - 条码 6937003703086 填充:采购量=15.0(原商品15.0+赠品0),单价=2.0
2025-05-08 20:04:10,347 - app.core.excel.processor - INFO - 条码 6975176784785 填充:仅有赠品,采购量=12.0,单价=0
2025-05-08 20:04:10,347 - app.core.excel.processor - INFO - 条码 6937003703437 填充:仅有赠品,采购量=12.0,单价=0
2025-05-08 20:04:10,347 - app.core.excel.processor - INFO - 条码 6975176781777 填充:仅有赠品,采购量=1.0,单价=0
2025-05-08 20:04:14,980 - app.core.excel.processor - INFO - 条码 6975176782460 填充:仅有赠品,采购量=9.0,单价=0
2025-05-08 20:04:14,983 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 20:04:14,985 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 20:46:00,697 - app.core.excel.processor - INFO - 初始化ExcelProcessor
2025-05-08 20:46:00,700 - app.core.excel.processor - INFO - 初始化完成,模板文件: templates\银豹-采购单模板.xls
2025-05-08 20:46:00,750 - app.core.excel.processor - INFO - 开始处理Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 20:46:01,732 - app.core.excel.processor - INFO - 成功读取Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx, 共 13 行
2025-05-08 20:46:01,737 - app.core.excel.processor - INFO - 找到可能的表头行: 第1行评分: 60
2025-05-08 20:46:01,737 - app.core.excel.processor - INFO - 识别到表头在第 1 行
2025-05-08 20:46:01,833 - app.core.excel.processor - INFO - 使用表头行重新读取数据,共 12 行有效数据
2025-05-08 20:46:01,833 - app.core.excel.processor - INFO - 找到精确匹配的条码列: 商品条码
2025-05-08 20:46:01,834 - app.core.excel.processor - INFO - 使用条码列: 商品条码
2025-05-08 20:46:01,834 - app.core.excel.processor - INFO - 找到name列: 商品名称
2025-05-08 20:46:01,834 - app.core.excel.processor - INFO - 找到specification列: 规格型号
2025-05-08 20:46:01,834 - app.core.excel.processor - INFO - 找到quantity列: 数量
2025-05-08 20:46:01,834 - app.core.excel.processor - INFO - 找到unit列: 单位
2025-05-08 20:46:01,834 - app.core.excel.processor - INFO - 找到price列: 单价
2025-05-08 20:46:01,835 - app.core.excel.processor - INFO - 列名映射结果: {'barcode': '商品条码', 'name': '商品名称', 'specification': '规格型号', 'quantity': '数量', 'unit': '单位', 'price': '单价'}
2025-05-08 20:46:01,835 - app.core.excel.processor - INFO - 是否存在规格列: False
2025-05-08 20:46:01,836 - app.core.excel.processor - INFO - 第1行: 提取商品信息 条码=6937003700207, 名称=外星人PRO运动恢复类-原味, 规格=, 数量=1.0, 单位=件, 单价=68.0
2025-05-08 20:46:01,836 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 20:46:01,838 - app.core.excel.processor - INFO - 第2行: 提取商品信息 条码=6937003706346, 名称=600ml外星人电解质西柚, 规格=, 数量=1.0, 单位=件, 单价=68.0
2025-05-08 20:46:01,838 - app.core.excel.processor - INFO - 从映射列解析规格: 600ml*15 -> 包装数量=15
2025-05-08 20:46:01,840 - app.core.excel.processor - INFO - 第3行: 提取商品信息 条码=6937003706568, 名称=外星人-维B水阳光青提500mL, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 20:46:01,840 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 20:46:01,859 - app.core.excel.processor - INFO - 第4行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石榴复合果蔬汁饮品, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 20:46:01,868 - app.core.excel.processor - INFO - 第5行: 提取商品信息 条码=6937003708166, 名称=天山爷爷新疆玉葡萄复合果汁饮品, 规格=, 数量=1.0, 单位=件, 单价=56.0
2025-05-08 20:46:01,868 - app.core.excel.processor - INFO - 第6行: 提取商品信息 条码=6937003703086, 名称=外星人WAVE风味水饮品淡柠檬味, 规格=, 数量=1.0, 单位=件, 单价=30.0
2025-05-08 20:46:01,868 - app.core.excel.processor - INFO - 从映射列解析规格: 600ml*15 -> 包装数量=15
2025-05-08 20:46:01,869 - app.core.excel.processor - INFO - 第7行: 提取商品信息 条码=6975176784785, 名称=大柠檬冰茶, 规格=, 数量=1.0, 单位=件, 单价=0.0
2025-05-08 20:46:01,869 - app.core.excel.processor - INFO - 从映射列解析规格: 900ml*12 -> 包装数量=12
2025-05-08 20:46:01,870 - app.core.excel.processor - INFO - 第8行: 提取商品信息 条码=6937003703437, 名称=大葡萄柚冰绿茶, 规格=, 数量=1.0, 单位=件, 单价=0.0
2025-05-08 20:46:01,870 - app.core.excel.processor - INFO - 从映射列解析规格: 900ml*12 -> 包装数量=12
2025-05-08 20:46:01,871 - app.core.excel.processor - INFO - 第9行: 提取商品信息 条码=6937003708173, 名称=天山爷爷新疆甜石复合果蔬汁饮品, 规格=, 数量=2.0, 单位=瓶, 单价=0.0
2025-05-08 20:46:01,872 - app.core.excel.processor - INFO - 第10行: 提取商品信息 条码=6975176781777, 名称=日式可乐味苏打气泡水, 规格=, 数量=1.0, 单位=瓶, 单价=0.0
2025-05-08 20:46:01,872 - app.core.excel.processor - INFO - 从映射列解析规格: 480ml*15 -> 包装数量=15
2025-05-08 20:46:01,872 - app.core.excel.processor - INFO - 第11行: 提取商品信息 条码=6975176782460, 名称=燃茶无糖茉莉花茶无糖饮料, 规格=, 数量=9.0, 单位=瓶, 单价=0.0
2025-05-08 20:46:01,872 - app.core.excel.processor - INFO - 从映射列解析规格: 500ml*15 -> 包装数量=15
2025-05-08 20:46:03,157 - app.core.excel.processor - INFO - 提取到 11 个商品信息
2025-05-08 20:46:03,171 - app.core.excel.processor - INFO - 开始处理11 个产品信息
2025-05-08 20:46:03,171 - app.core.excel.processor - INFO - 处理商品: 条码=6937003700207, 数量=15.0, 单价=4.533333333333333, 是否赠品=False
2025-05-08 20:46:03,172 - app.core.excel.processor - INFO - 发现正常商品条码6937003700207, 数量=15.0, 单价=4.533333333333333
2025-05-08 20:46:03,172 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706346, 数量=15.0, 单价=4.533333333333333, 是否赠品=False
2025-05-08 20:46:03,172 - app.core.excel.processor - INFO - 发现正常商品条码6937003706346, 数量=15.0, 单价=4.533333333333333
2025-05-08 20:46:03,172 - app.core.excel.processor - INFO - 处理商品: 条码=6937003706568, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 20:46:03,172 - app.core.excel.processor - INFO - 发现正常商品条码6937003706568, 数量=15.0, 单价=3.7333333333333334
2025-05-08 20:46:03,172 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 20:46:03,173 - app.core.excel.processor - INFO - 发现正常商品条码6937003708173, 数量=15.0, 单价=3.7333333333333334
2025-05-08 20:46:03,173 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708166, 数量=15.0, 单价=3.7333333333333334, 是否赠品=False
2025-05-08 20:46:03,173 - app.core.excel.processor - INFO - 发现正常商品条码6937003708166, 数量=15.0, 单价=3.7333333333333334
2025-05-08 20:46:03,173 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703086, 数量=15.0, 单价=2.0, 是否赠品=False
2025-05-08 20:46:03,174 - app.core.excel.processor - INFO - 发现正常商品条码6937003703086, 数量=15.0, 单价=2.0
2025-05-08 20:46:03,174 - app.core.excel.processor - INFO - 处理商品: 条码=6975176784785, 数量=12.0, 单价=0, 是否赠品=True
2025-05-08 20:46:03,174 - app.core.excel.processor - INFO - 发现赠品条码6975176784785, 数量=12.0
2025-05-08 20:46:03,175 - app.core.excel.processor - INFO - 处理商品: 条码=6937003703437, 数量=12.0, 单价=0, 是否赠品=True
2025-05-08 20:46:03,175 - app.core.excel.processor - INFO - 发现赠品条码6937003703437, 数量=12.0
2025-05-08 20:46:03,176 - app.core.excel.processor - INFO - 处理商品: 条码=6937003708173, 数量=2.0, 单价=0, 是否赠品=True
2025-05-08 20:46:03,176 - app.core.excel.processor - INFO - 发现赠品条码6937003708173, 数量=2.0
2025-05-08 20:46:03,176 - app.core.excel.processor - INFO - 处理商品: 条码=6975176781777, 数量=1.0, 单价=0, 是否赠品=True
2025-05-08 20:46:03,176 - app.core.excel.processor - INFO - 发现赠品条码6975176781777, 数量=1.0
2025-05-08 20:46:03,176 - app.core.excel.processor - INFO - 处理商品: 条码=6975176782460, 数量=9.0, 单价=0, 是否赠品=True
2025-05-08 20:46:03,177 - app.core.excel.processor - INFO - 发现赠品条码6975176782460, 数量=9.0
2025-05-08 20:46:03,177 - app.core.excel.processor - INFO - 分组后共10 个不同条码的商品
2025-05-08 20:46:03,177 - app.core.excel.processor - INFO - 条码 6937003700207 处理结果正常商品数量15.0单价4.533333333333333赠品数量0
2025-05-08 20:46:03,177 - app.core.excel.processor - INFO - 条码 6937003706346 处理结果正常商品数量15.0单价4.533333333333333赠品数量0
2025-05-08 20:46:03,178 - app.core.excel.processor - INFO - 条码 6937003706568 处理结果正常商品数量15.0单价3.7333333333333334赠品数量0
2025-05-08 20:46:03,178 - app.core.excel.processor - INFO - 条码 6937003708173 处理结果正常商品数量15.0单价3.7333333333333334赠品数量2.0
2025-05-08 20:46:03,178 - app.core.excel.processor - INFO - 条码 6937003708166 处理结果正常商品数量15.0单价3.7333333333333334赠品数量0
2025-05-08 20:46:03,178 - app.core.excel.processor - INFO - 条码 6937003703086 处理结果正常商品数量15.0单价2.0赠品数量0
2025-05-08 20:46:03,178 - app.core.excel.processor - INFO - 条码 6975176784785 处理结果:只有赠品,数量=12.0
2025-05-08 20:46:03,178 - app.core.excel.processor - INFO - 条码 6937003703437 处理结果:只有赠品,数量=12.0
2025-05-08 20:46:07,558 - app.core.excel.processor - INFO - 条码 6975176781777 处理结果:只有赠品,数量=1.0
2025-05-08 20:46:07,558 - app.core.excel.processor - INFO - 条码 6975176782460 处理结果:只有赠品,数量=9.0
2025-05-08 20:46:07,558 - app.core.excel.processor - INFO - 条码 6937003708173 填充:采购量=15.0赠品数量2.0
2025-05-08 20:46:07,559 - app.core.excel.processor - INFO - 条码 6975176784785 填充:仅有赠品,采购量=0赠品数量=12.0
2025-05-08 20:46:07,559 - app.core.excel.processor - INFO - 条码 6937003703437 填充:仅有赠品,采购量=0赠品数量=12.0
2025-05-08 20:46:07,559 - app.core.excel.processor - INFO - 条码 6975176781777 填充:仅有赠品,采购量=0赠品数量=1.0
2025-05-08 20:46:07,559 - app.core.excel.processor - INFO - 条码 6975176782460 填充:仅有赠品,采购量=0赠品数量=9.0
2025-05-08 20:46:07,563 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls
2025-05-08 20:46:07,564 - app.core.excel.processor - INFO - 采购单已保存到: D:\My Documents\python\orc-order-v2\data\output\采购单_微信图片_20250508194532.xls

View File

@ -0,0 +1,9 @@
2025-05-08 19:45:49,628 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0
2025-05-08 19:45:49,629 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0
2025-05-08 19:45:49,638 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0
2025-05-08 19:45:49,639 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0
2025-05-08 19:45:49,640 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0
2025-05-08 19:45:49,641 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0
2025-05-08 19:45:49,641 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0
2025-05-08 19:45:49,878 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0
2025-05-08 19:45:49,881 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0当前值: 0.0

View File

@ -68,3 +68,4 @@
2025-05-07 21:22:01,976 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
2025-05-07 21:54:55,605 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
2025-05-07 22:28:51,887 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌
2025-05-08 19:45:41,386 - app.core.ocr.baidu_ocr - INFO - 成功获取访问令牌

View File

@ -654,3 +654,29 @@
2025-05-07 22:28:52,829 - app.core.ocr.table_ocr - INFO - 图片处理成功: D:\My Documents\python\orc-order-v2\data\input\微信图片_20250507222846.jpg, 输出文件: D:\My Documents\python\orc-order-v2\data\output\微信图片_20250507222846.xlsx
2025-05-07 22:28:52,832 - app.core.ocr.table_ocr - INFO - 批次处理完成, 成功: 1/1
2025-05-07 22:28:52,832 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
2025-05-08 19:45:41,028 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-08 19:45:41,030 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 19:45:41,030 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-08 19:45:41,030 - app.core.ocr.table_ocr - INFO - OCR处理器初始化完成输入目录: D:\My Documents\python\orc-order-v2\data\input, 输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 19:45:41,036 - app.core.ocr.table_ocr - INFO - 找到 1 个图片文件,其中 1 个未处理
2025-05-08 19:45:41,036 - app.core.ocr.table_ocr - INFO - 处理批次 1/1, 大小: 1
2025-05-08 19:45:41,037 - app.core.ocr.table_ocr - INFO - 开始处理图片: D:\My Documents\python\orc-order-v2\data\input\微信图片_20250508194532.jpg
2025-05-08 19:45:48,792 - app.core.ocr.table_ocr - INFO - 图片处理成功: D:\My Documents\python\orc-order-v2\data\input\微信图片_20250508194532.jpg, 输出文件: D:\My Documents\python\orc-order-v2\data\output\微信图片_20250508194532.xlsx
2025-05-08 19:45:48,794 - app.core.ocr.table_ocr - INFO - 批次处理完成, 成功: 1/1
2025-05-08 19:45:48,795 - app.core.ocr.table_ocr - INFO - 所有图片处理完成, 总计: 1, 成功: 1
2025-05-08 19:47:28,883 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-08 19:47:28,883 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 19:47:28,883 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-08 19:47:28,884 - app.core.ocr.table_ocr - INFO - OCR处理器初始化完成输入目录: D:\My Documents\python\orc-order-v2\data\input, 输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 19:51:23,177 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-08 19:51:23,177 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 19:51:23,177 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-08 19:51:23,178 - app.core.ocr.table_ocr - INFO - OCR处理器初始化完成输入目录: D:\My Documents\python\orc-order-v2\data\input, 输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 20:04:06,906 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-08 20:04:06,907 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 20:04:06,907 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-08 20:04:06,907 - app.core.ocr.table_ocr - INFO - OCR处理器初始化完成输入目录: D:\My Documents\python\orc-order-v2\data\input, 输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 20:46:00,693 - app.core.ocr.table_ocr - INFO - 使用输入目录: D:\My Documents\python\orc-order-v2\data\input
2025-05-08 20:46:00,694 - app.core.ocr.table_ocr - INFO - 使用输出目录: D:\My Documents\python\orc-order-v2\data\output
2025-05-08 20:46:00,694 - app.core.ocr.table_ocr - INFO - 使用临时目录: D:\My Documents\python\orc-order-v2\data\temp
2025-05-08 20:46:00,695 - app.core.ocr.table_ocr - INFO - OCR处理器初始化完成输入目录: D:\My Documents\python\orc-order-v2\data\input, 输出目录: D:\My Documents\python\orc-order-v2\data\output

View File

@ -264,3 +264,14 @@
2025-05-07 22:28:51,544 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-07 22:28:51,548 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-07 22:28:51,557 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
2025-05-08 19:45:41,026 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-08 19:45:41,030 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-08 19:45:41,036 - app.services.ocr_service - INFO - OCRService开始批量处理图片, batch_size=None, max_workers=None
2025-05-08 19:47:28,878 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-08 19:47:28,884 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-08 19:51:23,176 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-08 19:51:23,178 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-08 20:04:06,905 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-08 20:04:06,907 - app.services.ocr_service - INFO - OCRService初始化完成
2025-05-08 20:46:00,690 - app.services.ocr_service - INFO - 初始化OCRService
2025-05-08 20:46:00,696 - app.services.ocr_service - INFO - OCRService初始化完成

View File

@ -300,3 +300,18 @@
2025-05-07 22:28:51,548 - app.services.order_service - INFO - 初始化OrderService
2025-05-07 22:28:51,556 - app.services.order_service - INFO - OrderService初始化完成
2025-05-07 22:28:52,834 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:\My Documents\python\orc-order-v2\data\output\微信图片_20250507222846.xlsx
2025-05-08 19:45:41,030 - app.services.order_service - INFO - 初始化OrderService
2025-05-08 19:45:41,035 - app.services.order_service - INFO - OrderService初始化完成
2025-05-08 19:45:48,798 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:\My Documents\python\orc-order-v2\data\output\微信图片_20250508194532.xlsx
2025-05-08 19:47:28,884 - app.services.order_service - INFO - 初始化OrderService
2025-05-08 19:47:28,886 - app.services.order_service - INFO - OrderService初始化完成
2025-05-08 19:47:28,886 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 19:51:23,178 - app.services.order_service - INFO - 初始化OrderService
2025-05-08 19:51:23,190 - app.services.order_service - INFO - OrderService初始化完成
2025-05-08 19:51:23,190 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 20:04:06,907 - app.services.order_service - INFO - 初始化OrderService
2025-05-08 20:04:06,909 - app.services.order_service - INFO - OrderService初始化完成
2025-05-08 20:04:06,910 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx
2025-05-08 20:46:00,697 - app.services.order_service - INFO - 初始化OrderService
2025-05-08 20:46:00,701 - app.services.order_service - INFO - OrderService初始化完成
2025-05-08 20:46:00,750 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: D:/My Documents/python/orc-order-v2/data/output/微信图片_20250508194532.xlsx

View File

@ -70,3 +70,260 @@
2. **模块间低耦合**:模块之间通过明确的接口交互,降低耦合度
3. **可扩展设计**:系统设计考虑未来扩展,如添加新的特殊条码处理规则
4. **完整文档**提供详细的README文档说明系统功能和使用方法
# OCR订单处理系统 v2 优化建议
经过全面审查系统代码和架构,以下是对 OCR 订单处理系统的优化建议,旨在提高系统的性能、可维护性和用户体验。
## 1. 架构与结构优化
### 1.1 依赖注入与组件化
**当前情况**:系统主要组件在代码中直接实例化,造成模块间高耦合。
**优化建议**
- 实现简单的依赖注入系统,降低模块间耦合度
- 使用工厂模式创建核心组件,便于测试和替换
- 示例代码:
```python
class AppContainer:
def __init__(self, config):
self.config = config
self._services = {}
def get_ocr_service(self):
if 'ocr_service' not in self._services:
self._services['ocr_service'] = OCRService(self.config)
return self._services['ocr_service']
```
### 1.2 配置系统增强
**当前情况**:配置存储在 `config.ini`,但部分硬编码的配置分散在代码中。
**优化建议**
- 将所有配置项集中到配置文件,消除硬编码的配置
- 添加环境变量支持便于部署和CI/CD集成
- 增加配置验证机制,防止错误配置
- 支持不同环境(开发、测试、生产)的配置切换
### 1.3 模块化 UI 与核心逻辑分离
**当前情况**`启动器.py` 文件过大 (1050行),同时包含 UI 和业务逻辑。
**优化建议**
- 将 UI 逻辑与业务逻辑完全分离
- 采用 MVC 或 MVVM 模式重构 UI 代码
- 将 UI 组件模块化,每个页面/功能对应单独的类
## 2. 性能优化
### 2.1 数据处理性能
**当前情况**:处理大量数据时效率较低,特别是 Excel 数据处理部分。
**优化建议**
- 使用 DataFrame 矢量化操作替代循环,提高数据处理速度
- 对于大文件,实现分块读取和处理机制
- 优化正则表达式,减少重复编译
- 示例改进:
```python
# 优化前
for idx, row in df.iterrows():
# 处理每一行...
# 优化后
# 使用 apply 或向量化操作
df['barcode'] = df['barcode'].apply(format_barcode)
```
### 2.2 并发处理增强
**当前情况**:已有初步的多线程支持,但未充分利用。
**优化建议**
- 扩展并行处理能力,特别是在 OCR 识别部分
- 实现任务队列系统,支持后台处理
- 添加进度报告机制,提高用户体验
- 考虑使用 asyncio 进行 I/O 密集型任务处理
### 2.3 缓存机制
**当前情况**:每次处理都重新加载和解析数据。
**优化建议**
- 实现内存缓存机制,缓存常用数据和配置
- 添加条码和商品信息的本地数据库,减少重复处理
- 对规格解析结果进行缓存,提高处理速度
## 3. 代码质量改进
### 3.1 单元测试与代码覆盖率
**当前情况**:缺乏系统性的单元测试。
**优化建议**
- 为核心功能编写单元测试,特别是单位转换和条码处理逻辑
- 实现测试数据生成器,支持边界情况测试
- 使用测试覆盖率工具,确保关键代码被测试覆盖
- 集成持续测试到开发流程中
### 3.2 代码重构
**当前情况**:部分函数过长,职责不够单一。
**优化建议**
- 对长函数进行拆分,特别是 `extract_product_info`300+ 行)
- 使用 Strategy 模式重构条码处理和单位转换逻辑
- 简化复杂的嵌套条件语句,提高代码可读性
- 提取通用功能到辅助函数,减少代码重复
### 3.3 错误处理增强
**当前情况**:错误处理主要依靠日志记录。
**优化建议**
- 设计更细粒度的异常类型,便于精确处理不同错误
- 实现全局异常处理,防止程序崩溃
- 添加用户友好的错误提示,而不只是记录日志
- 增加错误恢复机制,允许在出错后继续处理其他项目
## 4. 功能增强
### 4.1 数据验证与清洗增强
**当前情况**:基本的数据验证和清洗逻辑。
**优化建议**
- 增强数据验证规则,特别是对条码和数量的验证
- 实现更智能的数据修复功能,处理常见错误格式
- 添加数据异常检测算法,自动标记异常数据
- 提供手动数据修正界面,允许用户修正识别错误
### 4.2 批量处理功能增强
**当前情况**:支持基本的批量处理。
**优化建议**
- 支持拖放多个文件进行处理
- 添加文件队列管理,显示待处理/已处理状态
- 实现处理中断和恢复功能
- 支持处理结果预览和批量修改
### 4.3 数据导出与集成
**当前情况**:生成固定格式的 Excel 文件。
**优化建议**
- 支持多种导出格式CSV、JSON、XML 等)
- 提供数据库存储选项,便于数据管理和查询
- 添加 API 接口,支持与其他系统集成
- 实现定制化报表生成功能
## 5. 用户体验改进
### 5.1 界面优化
**当前情况**:基本的功能界面。
**优化建议**
- 重新设计 UI采用现代化界面框架如 PyQt6 或 wx.Python
- 添加暗色主题支持
- 实现响应式布局,适应不同屏幕尺寸
- 增加操作引导和工具提示
### 5.2 用户反馈与报告
**当前情况**:主要通过日志记录处理结果。
**优化建议**
- 设计直观的处理结果报告页面
- 添加数据可视化功能,展示处理统计信息
- 实现处理报告导出功能
- 设计更友好的错误提示和建议
### 5.3 配置与偏好设置
**当前情况**:配置主要在 config.ini 中修改。
**优化建议**
- 设计图形化配置界面,无需直接编辑配置文件
- 支持用户偏好设置保存
- 添加配置导入/导出功能
- 实现配置模板,快速切换不同配置
## 6. 安全性改进
### 6.1 API 密钥管理
**当前情况**API 密钥直接存储在配置文件中。
**优化建议**
- 实现 API 密钥加密存储
- 支持从环境变量或安全存储获取敏感信息
- 添加 API 密钥轮换机制
- 实现访问审计日志
### 6.2 数据安全
**当前情况**:数据以明文形式存储和处理。
**优化建议**
- 添加敏感数据(如价格信息)的加密选项
- 实现自动数据备份机制
- 添加访问控制,限制对敏感数据的访问
- 支持数据匿名化处理,用于测试和分析
## 7. 部署与维护改进
### 7.1 打包与分发
**当前情况**:依赖 Python 环境和手动安装依赖。
**优化建议**
- 使用 PyInstaller 或 cx_Freeze 创建独立可执行文件
- 提供自动安装脚本,简化部署过程
- 支持自动更新机制
- 创建详细的安装和部署文档
### 7.2 监控与日志
**当前情况**:基本的日志记录功能。
**优化建议**
- 实现结构化日志系统,支持日志搜索和分析
- 添加系统性能监控功能
- 设计操作审计日志,记录关键操作
- 支持日志远程存储和集中管理
### 7.3 文档完善
**当前情况**:有基本的 README 文档。
**优化建议**
- 创建详细的开发者文档,包括架构说明和 API 参考
- 编写用户手册和操作指南
- 添加代码内文档字符串,支持自动文档生成
- 提供常见问题解答和故障排除指南
## 8. 当前优化重点
基于系统现状,建议首先关注以下优化点:
1. **重构单位转换逻辑**:将复杂的单位转换和条码映射逻辑模块化,提高可维护性
2. **增强数据验证**:改进条码和规格提取逻辑,减少处理错误
3. **UI 改进**:将大型启动器文件拆分为多个组件,采用 MVC 模式
4. **添加单元测试**:为核心业务逻辑添加测试用例,确保功能正确性
5. **实现缓存机制**:提高重复数据处理效率
## 9. 长期优化计划
长期来看,建议考虑以下方向:
1. **迁移到 Web 应用**:考虑将系统转换为 Web 应用,提供更好的跨平台支持
2. **数据智能分析**:增加智能分析功能,如采购趋势分析、异常检测等
3. **与 ERP 系统集成**:提供与主流 ERP 系统的集成接口
4. **移动端支持**:开发移动应用或响应式 Web 界面,支持手机操作
5. **OCR 引擎替换选项**:支持多种 OCR 引擎,降低对单一 API 的依赖
通过以上优化OCR 订单处理系统将更加健壮、高效、易用,能够更好地满足业务需求,并为未来功能扩展提供良好的基础。