feat(ui): simplify interface by removing dedicated tobacco/rongcheng buttons and optimizing auto-routing
This commit is contained in:
parent
c06e3e55f9
commit
76859fd774
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,5 +1,19 @@
|
||||
# Changelog
|
||||
|
||||
## [v2.2.0] - 2026-03-31
|
||||
### Added
|
||||
- **UI Simplification**: Removed dedicated buttons for Rongcheng and Tobacco; all Excel orders now use the intelligent auto-routing.
|
||||
- **Enhanced Yang Biyue Support**: Fixed column mapping for Yang Biyue orders, ensuring standard fields (Barcode, Quantity, Price) are correctly extracted.
|
||||
- **Headless API Auto-Detect**: `headless_api.py` now automatically distinguishes between Image (OCR) and Excel (Direct) inputs based on file extension.
|
||||
|
||||
### Fixed
|
||||
- **Yang Biyue Preprocessing**: Resolved issue where data was empty due to incorrect column renaming.
|
||||
- **Interference Filtering**: Added logic to exclude distractor columns like "Settlement Unit" or "Base Quantity" during preprocessing.
|
||||
|
||||
### Removed
|
||||
- **Redundant Files**: Cleaned up `run.py`, `clean.py`, and unused CLI modules.
|
||||
- **Legacy UI Elements**: Removed tobacco-specific keyboard shortcuts and help entries.
|
||||
|
||||
## [v2.1.0] - 2026-03-30
|
||||
### Added
|
||||
- **Intelligent Recognition**: Automated fingerprinting for Rongcheng Yigou, Tobacco, and Yang Biyue orders.
|
||||
|
||||
@ -1,45 +1,30 @@
|
||||
# OCR 订单处理系统 - v2.1 更新报告
|
||||
# OCR 订单处理系统 - v2.2 更新报告
|
||||
|
||||
## 1. 业务逻辑变更 (Business Logic Updates)
|
||||
## 1. 业务逻辑与 UI 变更 (v2.2 Updates)
|
||||
|
||||
### 1.1 智能识别与自动路由
|
||||
- **功能描述**:系统现在能自动扫描 Excel 前 50 行的特征码。
|
||||
- **蓉城易购**:检测到 `RCDH` 关键字时自动启用专用清洗。
|
||||
- **烟草公司**:检测到 `专卖证号` 或 `510109104938` 时自动启用专用清洗。
|
||||
- **杨碧月**:检测到经手人为 `杨碧月` 时自动执行列对齐预处理。
|
||||
### 1.1 UI 极简优化
|
||||
- **移除专用按钮**:从主界面彻底移除了“蓉城易购”和“烟草处理”两个特定按钮。
|
||||
- **统一入口**:所有供应商 Excel 订单现在均通过“处理 Excel 文件”或直接拖拽至主界面进行处理。系统会自动识别并路由。
|
||||
- **快捷键更新**:移除了 `Ctrl+T` (烟草处理) 快捷键,简化了键盘操作逻辑。
|
||||
|
||||
### 1.2 供应商清洗规则校准
|
||||
### 1.2 杨碧月预处理修复
|
||||
- **列名校准**:修正了预处理输出列名,确保与银豹处理器期望的中文列名(商品条码、数量、单价等)完全一致。
|
||||
- **干扰过滤**:在提取列时,自动排除了 `结算单位`、`基本单位数量` 等名称相似的非业务列,提高了匹配精度。
|
||||
|
||||
### 1.3 Headless API 智能增强
|
||||
- **后缀感知**:`headless_api.py` 能够根据文件后缀自动区分图片与 Excel,不再需要显式指定 `--excel` 或 `--tobacco`。
|
||||
- **零配置接入**:OpenClaw 仅需运行 `python headless_api.py [文件路径]` 即可完成全流程。
|
||||
|
||||
## 2. 供应商清洗规则 (保持最新)
|
||||
| 供应商 | 条码列 | 数量逻辑 | 单价逻辑 | 金额逻辑 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| **蓉城易购** | E列 (Index 4) | N列 (Index 13),不换算 | Q列 (Index 16) | S列 (Index 18) |
|
||||
| **烟草公司** | B列 (Index 1) | G列 (Index 6) **x 10** | E列 (Index 4) **/ 10** | H列 (Index 7) |
|
||||
|
||||
## 2. 系统接口与集成 (API & Integration)
|
||||
|
||||
### 2.1 Headless API (headless_api.py)
|
||||
- **更新内容**:`--excel` 参数现在支持全自动识别模式,OpenClaw 无需再手动区分供应商。
|
||||
- **日志增强**:所有详细日志通过 `stderr` 输出,`stdout` 仅保留最终结果路径,确保自动化脚本精准捕获。
|
||||
|
||||
### 2.2 OpenClaw 对接文档
|
||||
- **文档更新**:[OPENCLAW_GUIDE.md](OPENCLAW_GUIDE.md) 已同步至 v2.1,包含最新的列映射说明和调用示例。
|
||||
|
||||
## 3. 测试与质量保证 (QA & Testing)
|
||||
|
||||
### 3.1 自动化测试
|
||||
- **回归测试**:已通过 `订单1774849009841.xlsx` (蓉城) 和 `订单明细20260330133908.xlsx` (烟草) 的实测验证。
|
||||
- **单价校验**:集成了银豹标准进货价对比功能,差异超过 1.0 元时自动触发警告。
|
||||
|
||||
### 3.2 风险清单与回滚方案
|
||||
- **风险**:若供应商 Excel 格式发生重大列位移(非上述索引),自动处理可能失效。
|
||||
- **回滚方案**:可通过 `git checkout v2.0` 回退至上一稳定版本。
|
||||
- **监控**:建议 OpenClaw 监控 `stderr` 中的 `ERROR` 关键字并实时预警。
|
||||
|
||||
## 4. 变更日志 (Changelog)
|
||||
- `[FIX]` 修复了蓉城易购条码分裂导致的数量计算错误(30 变 5)。
|
||||
- `[FIX]` 修复了烟草订单单价计算未除以 10 的问题。
|
||||
- `[NEW]` 实现了基于 `header=None` 的全局智能指纹识别。
|
||||
- `[OPT]` 移除了 UI 界面中冗余的验证匹配按钮,精简流程。
|
||||
## 3. 代码与环境清理
|
||||
- **移除无用文件**:清理了 `run.py` (冗余)、`clean.py` (旧脚本) 以及 `doc/` (旧文档)。
|
||||
- **模块重构**:删除了 `app/cli/` 模块,所有命令行逻辑已合并至根目录的 `headless_api.py`。
|
||||
|
||||
---
|
||||
*报告生成日期:2026-03-30*
|
||||
*报告生成日期:2026-03-31*
|
||||
*负责人:Trae Code Assistant*
|
||||
|
||||
@ -1,61 +1,45 @@
|
||||
# OCR 订单处理系统 - OpenClaw 对接指南 (增强版)
|
||||
|
||||
本指南旨在帮助 OpenClaw 实现对采购单处理系统的全功能自动化控制,涵盖图片识别、Excel 清洗、特殊供应商处理及条码映射管理。
|
||||
# OCR 订单处理系统 - OpenClaw 对接指南 (v2.2)
|
||||
|
||||
## 1. 核心接口说明 (headless_api.py)
|
||||
|
||||
`headless_api.py` 是系统的统一命令行入口。它现在支持**智能文件类型识别**,大多数情况下 OpenClaw **无需携带任何参数**。
|
||||
`headless_api.py` 是系统的统一命令行入口。它支持**智能文件类型与供应商识别**,OpenClaw 通常**无需携带任何功能参数**。
|
||||
|
||||
### 1.1 全自动智能模式 (推荐方式)
|
||||
无论是收到**图片**还是 **Excel**,都可以直接调用。系统会自动判断文件类型,如果是 Excel 则自动识别供应商指纹并处理;如果是图片则先 OCR 后再智能处理。
|
||||
无论是收到**图片**还是 **Excel**,都可以直接调用。系统会自动判断文件类型:如果是 Excel 则自动识别供应商指纹(蓉城、烟草、杨碧月等)并处理;如果是图片则先 OCR 后再智能处理。
|
||||
|
||||
```bash
|
||||
# 场景 1: 自动处理 data/input 中最新的文件 (图片或 Excel)
|
||||
# 自动处理 data/input 中最新的文件 (图片或 Excel)
|
||||
python headless_api.py
|
||||
|
||||
# 场景 2: 处理指定的任意文件 (图片或 Excel)
|
||||
# 处理指定的任意文件 (图片或 Excel)
|
||||
python headless_api.py "data/input/my_file.jpg"
|
||||
python headless_api.py "data/input/my_file.xlsx"
|
||||
```
|
||||
|
||||
### 1.2 显式特殊指令
|
||||
仅在需要强制指定特定流程时使用。
|
||||
### 1.2 显式特殊指令 (备用)
|
||||
仅在自动识别失效或需要特殊操作时使用。
|
||||
```bash
|
||||
# 强制指定为 Excel 处理模式 (即便文件没有正确后缀)
|
||||
# 强制指定为 Excel 处理模式
|
||||
python headless_api.py --excel
|
||||
|
||||
# 强制映射条码
|
||||
# 强制更新条码映射关系
|
||||
python headless_api.py --update-mapping --barcode "123" --target "456"
|
||||
```
|
||||
|
||||
## 2. 字段与逻辑变更 (v2.1)
|
||||
## 2. 字段与逻辑变更
|
||||
|
||||
### 2.1 蓉城易购 (Rongcheng)
|
||||
- **条码位置**:固定映射到 **E列** (Index 4)。
|
||||
- **数量逻辑**:固定映射到 **N列** (Index 13)。直接提取数值,**不进行任何单位或规格换算**。
|
||||
- **单价与金额**:Q列 (单价) 和 S列 (金额)。
|
||||
- **条码分裂**:若条码包含 `/`, `,`, `,`, `、` 等分隔符,系统将自动均分数量。
|
||||
- **条码映射**:E列 (Index 4)。
|
||||
- **数量逻辑**:N列 (Index 13)。直接提取,不进行单位换算。
|
||||
- **条码分裂**:支持 `/` `,` `,` `、` 分隔符自动均分。
|
||||
|
||||
### 2.2 烟草公司 (Tobacco)
|
||||
- **条码位置**:固定映射到 **B列** (Index 1)。
|
||||
- **数量换算**:映射 **G列** (订单量),最终数量 = 订单量 **x 10**。
|
||||
- **单价换算**:映射 **E列** (批发价),最终单价 = 批发价 **/ 10**。
|
||||
- **金额逻辑**:H列 (金额)。不看规格,直接按数量*单价逻辑填充。
|
||||
- **条码映射**:B列 (Index 1)。
|
||||
- **数量逻辑**:G列 (订单量) **x 10**。
|
||||
- **单价逻辑**:E列 (批发价) **/ 10**。
|
||||
|
||||
## 3. OpenClaw 集成策略
|
||||
|
||||
### 3.1 任务分发逻辑
|
||||
OpenClaw 应根据用户输入判断调用的参数:
|
||||
- **收到图片** -> 调用默认模式。
|
||||
- **收到 Excel** -> 调用 `--excel` 模式(推荐,支持全自动识别)。
|
||||
- **用户明确要求“强制蓉城”** -> 调用 `--rongcheng`。
|
||||
- **用户明确要求“强制烟草”** -> 调用 `--tobacco`。
|
||||
- **用户纠正条码错误** -> 调用 `--update-mapping`。
|
||||
|
||||
### 3.2 错误码与返回值
|
||||
- **0**:处理成功,输出结果文件绝对路径。
|
||||
- **1**:处理失败,详细错误信息在 `stderr`。
|
||||
- **WARNING**: stderr 中包含 `Price validation found...` 表示价格差异过大。
|
||||
### 2.3 杨碧月 (Yang Biyue)
|
||||
- **自动对齐**:自动识别经手人并对齐“商品条码”、“数量”、“单价”等标准列。
|
||||
|
||||
---
|
||||
*版本:2.1 | 更新日期:2026-03-30*
|
||||
*版本:2.2 | 更新日期:2026-03-31*
|
||||
|
||||
13
README.md
13
README.md
@ -7,22 +7,23 @@
|
||||
|
||||
## 核心功能
|
||||
- **全自动智能识别**:系统现在能自动识别 Excel 内容特征(如:蓉城易购 RCDH、烟草公司专卖证号、杨碧月经手人),并自动路由至专用预处理流程,无需手动干预。
|
||||
- **图片/Excel处理**:拖拽或选择文件,生成标准银豹采购单。
|
||||
- **无界面自动化接口 (headless_api.py)**:专为 OpenClaw 等平台设计,支持 `--excel` 模式下的全自动识别。
|
||||
- **图片/Excel处理**:支持拖拽或选择文件,一键生成标准银豹采购单。
|
||||
- **极简 UI 体验**:移除了冗余的供应商特定按钮,所有 Excel 统一走智能路由处理。
|
||||
- **无界面自动化接口 (headless_api.py)**:专为 OpenClaw 等平台设计,支持全自动文件类型与供应商识别。
|
||||
- **单价预警机制**:自动比对 `templates/商品资料.xlsx`,若价差超过 1.0 元则触发警告。
|
||||
|
||||
## 供应商专用逻辑 (v2.1)
|
||||
## 供应商专用逻辑 (v2.2)
|
||||
### 蓉城易购 (Rongcheng)
|
||||
- **精准映射**:条码(E列)、数量(N列)、单价(Q列)、金额(S列)。
|
||||
- **精准映射**:商品条码(E列)、数量(N列)、单价(Q列)、金额(S列)。
|
||||
- **条码分裂**:支持多条码行(如 `条码1/条码2`)自动均分数量。
|
||||
- **纯净数据**:直接提取原始数量,不进行多余的单位换算。
|
||||
- **逻辑简化**:直接提取原始数量,不进行多余的单位或包装换算。
|
||||
|
||||
### 烟草公司 (Tobacco)
|
||||
- **换算逻辑**:条码(B列)、数量(G列 x 10)、单价(E列 / 10)、总额(H列)。
|
||||
- **智能跳行**:自动识别并跳过合计行及非数据行。
|
||||
|
||||
### 杨碧月订单
|
||||
- **自动对齐**:识别到经手人“杨碧月”后,自动将非标 Excel 转换为标准列格式。
|
||||
- **自动对齐**:识别到经手人“杨碧月”后,自动将非标 Excel 转换为标准列格式,支持单位换算(件 -> 瓶)。
|
||||
|
||||
## 关键适配(蓉城易购)
|
||||
- 新模板(如“订单1765440157955.xlsx”):
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
"""
|
||||
OCR订单处理系统 - 命令行接口
|
||||
-------------------------
|
||||
提供命令行工具,便于用户使用系统功能。
|
||||
"""
|
||||
@ -1,138 +0,0 @@
|
||||
"""
|
||||
Excel处理命令行工具
|
||||
---------------
|
||||
提供Excel处理相关的命令行接口。
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from typing import List, Optional
|
||||
|
||||
from ..config.settings import ConfigManager
|
||||
from ..core.utils.log_utils import get_logger, close_logger
|
||||
from ..services.order_service import OrderService
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
def create_parser() -> argparse.ArgumentParser:
|
||||
"""
|
||||
创建命令行参数解析器
|
||||
|
||||
Returns:
|
||||
参数解析器
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description='Excel处理工具')
|
||||
|
||||
# 通用选项
|
||||
parser.add_argument('--config', type=str, help='配置文件路径')
|
||||
|
||||
# 子命令
|
||||
subparsers = parser.add_subparsers(dest='command', help='子命令')
|
||||
|
||||
# 处理Excel命令
|
||||
process_parser = subparsers.add_parser('process', help='处理Excel文件')
|
||||
process_parser.add_argument('--input', type=str, help='输入Excel文件路径,如果不指定则处理最新的文件')
|
||||
|
||||
# 查看命令
|
||||
list_parser = subparsers.add_parser('list', help='获取最新的Excel文件')
|
||||
|
||||
return parser
|
||||
|
||||
def process_excel(order_service: OrderService, input_file: Optional[str] = None) -> bool:
|
||||
"""
|
||||
处理Excel文件
|
||||
|
||||
Args:
|
||||
order_service: 订单服务
|
||||
input_file: 输入文件路径,如果为None则处理最新的文件
|
||||
|
||||
Returns:
|
||||
处理是否成功
|
||||
"""
|
||||
if input_file:
|
||||
if not os.path.exists(input_file):
|
||||
logger.error(f"输入文件不存在: {input_file}")
|
||||
return False
|
||||
|
||||
result = order_service.process_excel(input_file)
|
||||
else:
|
||||
latest_file = order_service.get_latest_excel()
|
||||
if not latest_file:
|
||||
logger.warning("未找到可处理的Excel文件")
|
||||
return False
|
||||
|
||||
logger.info(f"处理最新的Excel文件: {latest_file}")
|
||||
result = order_service.process_excel(latest_file)
|
||||
|
||||
if result:
|
||||
logger.info(f"处理成功,输出文件: {result}")
|
||||
return True
|
||||
else:
|
||||
logger.error("处理失败")
|
||||
return False
|
||||
|
||||
def list_latest_excel(order_service: OrderService) -> bool:
|
||||
"""
|
||||
获取最新的Excel文件
|
||||
|
||||
Args:
|
||||
order_service: 订单服务
|
||||
|
||||
Returns:
|
||||
是否找到Excel文件
|
||||
"""
|
||||
latest_file = order_service.get_latest_excel()
|
||||
|
||||
if latest_file:
|
||||
logger.info(f"最新的Excel文件: {latest_file}")
|
||||
return True
|
||||
else:
|
||||
logger.info("未找到Excel文件")
|
||||
return False
|
||||
|
||||
def main(args: Optional[List[str]] = None) -> int:
|
||||
"""
|
||||
Excel处理命令行主函数
|
||||
|
||||
Args:
|
||||
args: 命令行参数,如果为None则使用sys.argv
|
||||
|
||||
Returns:
|
||||
退出状态码
|
||||
"""
|
||||
parser = create_parser()
|
||||
parsed_args = parser.parse_args(args)
|
||||
|
||||
if parsed_args.command is None:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
try:
|
||||
# 创建配置管理器
|
||||
config = ConfigManager(parsed_args.config) if parsed_args.config else ConfigManager()
|
||||
|
||||
# 创建订单服务
|
||||
order_service = OrderService(config)
|
||||
|
||||
# 根据命令执行不同功能
|
||||
if parsed_args.command == 'process':
|
||||
success = process_excel(order_service, parsed_args.input)
|
||||
elif parsed_args.command == 'list':
|
||||
success = list_latest_excel(order_service)
|
||||
else:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
return 0 if success else 1
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"执行过程中发生错误: {e}")
|
||||
return 1
|
||||
|
||||
finally:
|
||||
# 关闭日志
|
||||
close_logger(__name__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@ -1,147 +0,0 @@
|
||||
"""
|
||||
订单合并命令行工具
|
||||
--------------
|
||||
提供订单合并相关的命令行接口。
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from typing import List, Optional
|
||||
|
||||
from ..config.settings import ConfigManager
|
||||
from ..core.utils.log_utils import get_logger, close_logger
|
||||
from ..services.order_service import OrderService
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
def create_parser() -> argparse.ArgumentParser:
|
||||
"""
|
||||
创建命令行参数解析器
|
||||
|
||||
Returns:
|
||||
参数解析器
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description='订单合并工具')
|
||||
|
||||
# 通用选项
|
||||
parser.add_argument('--config', type=str, help='配置文件路径')
|
||||
|
||||
# 子命令
|
||||
subparsers = parser.add_subparsers(dest='command', help='子命令')
|
||||
|
||||
# 合并命令
|
||||
merge_parser = subparsers.add_parser('merge', help='合并采购单')
|
||||
merge_parser.add_argument('--input', type=str, help='输入采购单文件路径列表,以逗号分隔,如果不指定则合并所有采购单')
|
||||
|
||||
# 列出采购单命令
|
||||
list_parser = subparsers.add_parser('list', help='列出采购单文件')
|
||||
|
||||
return parser
|
||||
|
||||
def merge_orders(order_service: OrderService, input_files: Optional[str] = None) -> bool:
|
||||
"""
|
||||
合并采购单
|
||||
|
||||
Args:
|
||||
order_service: 订单服务
|
||||
input_files: 输入文件路径列表,以逗号分隔,如果为None则合并所有采购单
|
||||
|
||||
Returns:
|
||||
合并是否成功
|
||||
"""
|
||||
if input_files:
|
||||
# 分割输入文件列表
|
||||
file_paths = [path.strip() for path in input_files.split(',')]
|
||||
|
||||
# 检查文件是否存在
|
||||
for path in file_paths:
|
||||
if not os.path.exists(path):
|
||||
logger.error(f"输入文件不存在: {path}")
|
||||
return False
|
||||
|
||||
result = order_service.merge_orders(file_paths)
|
||||
else:
|
||||
# 获取所有采购单文件
|
||||
file_paths = order_service.get_purchase_orders()
|
||||
if not file_paths:
|
||||
logger.warning("未找到采购单文件")
|
||||
return False
|
||||
|
||||
logger.info(f"合并 {len(file_paths)} 个采购单文件")
|
||||
result = order_service.merge_orders()
|
||||
|
||||
if result:
|
||||
logger.info(f"合并成功,输出文件: {result}")
|
||||
return True
|
||||
else:
|
||||
logger.error("合并失败")
|
||||
return False
|
||||
|
||||
def list_purchase_orders(order_service: OrderService) -> bool:
|
||||
"""
|
||||
列出采购单文件
|
||||
|
||||
Args:
|
||||
order_service: 订单服务
|
||||
|
||||
Returns:
|
||||
是否有采购单文件
|
||||
"""
|
||||
files = order_service.get_purchase_orders()
|
||||
|
||||
if not files:
|
||||
logger.info("未找到采购单文件")
|
||||
return False
|
||||
|
||||
logger.info(f"采购单文件 ({len(files)}):")
|
||||
for file in files:
|
||||
logger.info(f" {file}")
|
||||
|
||||
return True
|
||||
|
||||
def main(args: Optional[List[str]] = None) -> int:
|
||||
"""
|
||||
订单合并命令行主函数
|
||||
|
||||
Args:
|
||||
args: 命令行参数,如果为None则使用sys.argv
|
||||
|
||||
Returns:
|
||||
退出状态码
|
||||
"""
|
||||
parser = create_parser()
|
||||
parsed_args = parser.parse_args(args)
|
||||
|
||||
if parsed_args.command is None:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
try:
|
||||
# 创建配置管理器
|
||||
config = ConfigManager(parsed_args.config) if parsed_args.config else ConfigManager()
|
||||
|
||||
# 创建订单服务
|
||||
order_service = OrderService(config)
|
||||
|
||||
# 根据命令执行不同功能
|
||||
if parsed_args.command == 'merge':
|
||||
success = merge_orders(order_service, parsed_args.input)
|
||||
elif parsed_args.command == 'list':
|
||||
success = list_purchase_orders(order_service)
|
||||
else:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
return 0 if success else 1
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"执行过程中发生错误: {e}")
|
||||
return 1
|
||||
|
||||
finally:
|
||||
# 关闭日志
|
||||
close_logger(__name__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@ -1,164 +0,0 @@
|
||||
"""
|
||||
OCR命令行工具
|
||||
----------
|
||||
提供OCR识别相关的命令行接口。
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from typing import List, Optional
|
||||
|
||||
from ..config.settings import ConfigManager
|
||||
from ..core.utils.log_utils import get_logger, close_logger
|
||||
from ..services.ocr_service import OCRService
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
def create_parser() -> argparse.ArgumentParser:
|
||||
"""
|
||||
创建命令行参数解析器
|
||||
|
||||
Returns:
|
||||
参数解析器
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description='OCR识别工具')
|
||||
|
||||
# 通用选项
|
||||
parser.add_argument('--config', type=str, help='配置文件路径')
|
||||
|
||||
# 子命令
|
||||
subparsers = parser.add_subparsers(dest='command', help='子命令')
|
||||
|
||||
# 单文件处理命令
|
||||
process_parser = subparsers.add_parser('process', help='处理单个文件')
|
||||
process_parser.add_argument('--input', type=str, required=True, help='输入图片文件路径')
|
||||
|
||||
# 批量处理命令
|
||||
batch_parser = subparsers.add_parser('batch', help='批量处理文件')
|
||||
batch_parser.add_argument('--batch-size', type=int, help='批处理大小')
|
||||
batch_parser.add_argument('--max-workers', type=int, help='最大线程数')
|
||||
|
||||
# 查看未处理文件命令
|
||||
list_parser = subparsers.add_parser('list', help='列出未处理的文件')
|
||||
|
||||
return parser
|
||||
|
||||
def process_file(ocr_service: OCRService, input_file: str) -> bool:
|
||||
"""
|
||||
处理单个文件
|
||||
|
||||
Args:
|
||||
ocr_service: OCR服务
|
||||
input_file: 输入文件路径
|
||||
|
||||
Returns:
|
||||
处理是否成功
|
||||
"""
|
||||
if not os.path.exists(input_file):
|
||||
logger.error(f"输入文件不存在: {input_file}")
|
||||
return False
|
||||
|
||||
if not ocr_service.validate_image(input_file):
|
||||
logger.error(f"输入文件无效: {input_file}")
|
||||
return False
|
||||
|
||||
result = ocr_service.process_image(input_file)
|
||||
|
||||
if result:
|
||||
logger.info(f"处理成功,输出文件: {result}")
|
||||
return True
|
||||
else:
|
||||
logger.error("处理失败")
|
||||
return False
|
||||
|
||||
def process_batch(ocr_service: OCRService, batch_size: Optional[int] = None, max_workers: Optional[int] = None) -> bool:
|
||||
"""
|
||||
批量处理文件
|
||||
|
||||
Args:
|
||||
ocr_service: OCR服务
|
||||
batch_size: 批处理大小
|
||||
max_workers: 最大线程数
|
||||
|
||||
Returns:
|
||||
处理是否成功
|
||||
"""
|
||||
total, success = ocr_service.process_images_batch(batch_size, max_workers)
|
||||
|
||||
if total == 0:
|
||||
logger.warning("没有找到需要处理的文件")
|
||||
return False
|
||||
|
||||
logger.info(f"批量处理完成,总计: {total},成功: {success}")
|
||||
return success > 0
|
||||
|
||||
def list_unprocessed(ocr_service: OCRService) -> bool:
|
||||
"""
|
||||
列出未处理的文件
|
||||
|
||||
Args:
|
||||
ocr_service: OCR服务
|
||||
|
||||
Returns:
|
||||
是否有未处理的文件
|
||||
"""
|
||||
files = ocr_service.get_unprocessed_images()
|
||||
|
||||
if not files:
|
||||
logger.info("没有未处理的文件")
|
||||
return False
|
||||
|
||||
logger.info(f"未处理的文件 ({len(files)}):")
|
||||
for file in files:
|
||||
logger.info(f" {file}")
|
||||
|
||||
return True
|
||||
|
||||
def main(args: Optional[List[str]] = None) -> int:
|
||||
"""
|
||||
OCR命令行主函数
|
||||
|
||||
Args:
|
||||
args: 命令行参数,如果为None则使用sys.argv
|
||||
|
||||
Returns:
|
||||
退出状态码
|
||||
"""
|
||||
parser = create_parser()
|
||||
parsed_args = parser.parse_args(args)
|
||||
|
||||
if parsed_args.command is None:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
try:
|
||||
# 创建配置管理器
|
||||
config = ConfigManager(parsed_args.config) if parsed_args.config else ConfigManager()
|
||||
|
||||
# 创建OCR服务
|
||||
ocr_service = OCRService(config)
|
||||
|
||||
# 根据命令执行不同功能
|
||||
if parsed_args.command == 'process':
|
||||
success = process_file(ocr_service, parsed_args.input)
|
||||
elif parsed_args.command == 'batch':
|
||||
success = process_batch(ocr_service, parsed_args.batch_size, parsed_args.max_workers)
|
||||
elif parsed_args.command == 'list':
|
||||
success = list_unprocessed(ocr_service)
|
||||
else:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
return 0 if success else 1
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"执行过程中发生错误: {e}")
|
||||
return 1
|
||||
|
||||
finally:
|
||||
# 关闭日志
|
||||
close_logger(__name__)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@ -113,11 +113,21 @@ class OrderService:
|
||||
return special_svc.preprocess_rongcheng_yigou(file_path)
|
||||
|
||||
# 3. 识别:杨碧月 (Yang Biyue)
|
||||
from .special_suppliers_service import SpecialSuppliersService
|
||||
special_svc = SpecialSuppliersService(self.config)
|
||||
# 我们直接复用 SpecialSuppliersService 里的逻辑,但要确保它只返回路径
|
||||
# 修改 SpecialSuppliersService.process_yang_biyue 使其支持仅返回预处理路径
|
||||
return special_svc.process_yang_biyue_only(file_path)
|
||||
# 特征:经手人列包含“杨碧月”
|
||||
handler_col = None
|
||||
for col in df_head.columns:
|
||||
# 在前50行中搜索“经手人”关键字
|
||||
if df_head[col].astype(str).str.contains('经手人').any():
|
||||
handler_col = col
|
||||
break
|
||||
|
||||
if handler_col is not None:
|
||||
# 检查该列是否有“杨碧月”
|
||||
if df_head[handler_col].astype(str).str.contains('杨碧月').any():
|
||||
logger.info("识别到杨碧月订单,执行专用预处理...")
|
||||
from .special_suppliers_service import SpecialSuppliersService
|
||||
special_svc = SpecialSuppliersService(self.config)
|
||||
return special_svc.process_yang_biyue_only(file_path)
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"智能预处理识别失败: {e}")
|
||||
|
||||
@ -37,24 +37,41 @@ class SpecialSuppliersService:
|
||||
if handler_col is None or not df[handler_col].astype(str).str.contains('杨碧月').any():
|
||||
return None
|
||||
|
||||
# 识别到杨碧月订单,执行专用清洗
|
||||
logger.info("识别到杨碧月订单,正在执行专用清洗...")
|
||||
|
||||
# 定义列映射关系
|
||||
# 定义列映射关系 (映射到 ExcelProcessor 期望的中文列名)
|
||||
# 使用精确匹配优先,防止“结算单位”匹配到“单位”
|
||||
column_map = {
|
||||
'商品条码': 'barcode',
|
||||
'商品名称': 'name',
|
||||
'商品规格': 'specification',
|
||||
'单位': 'unit',
|
||||
'数量': 'quantity',
|
||||
'含税单价': 'unit_price',
|
||||
'含税金额': 'total_price'
|
||||
'商品条码': '商品条码',
|
||||
'商品名称': '商品名称',
|
||||
'商品规格': '规格',
|
||||
'单位': '单位',
|
||||
'数量': '数量',
|
||||
'含税单价': '单价',
|
||||
'含税金额': '金额'
|
||||
}
|
||||
|
||||
# 提取并重命名列
|
||||
found_cols = {}
|
||||
# 1. 第一遍:尝试精确匹配
|
||||
for target_zh, std_name in column_map.items():
|
||||
for col in df.columns:
|
||||
if target_zh in str(col):
|
||||
if str(col).strip() == target_zh:
|
||||
found_cols[col] = std_name
|
||||
break
|
||||
|
||||
# 2. 第二遍:对未匹配成功的列尝试模糊匹配(但要排除特定干扰词)
|
||||
for target_zh, std_name in column_map.items():
|
||||
if std_name in found_cols.values():
|
||||
continue
|
||||
for col in df.columns:
|
||||
col_str = str(col)
|
||||
if target_zh in col_str:
|
||||
# 排除干扰列
|
||||
if target_zh == '单位' and '结算单位' in col_str:
|
||||
continue
|
||||
if target_zh == '数量' and '基本单位数量' in col_str:
|
||||
continue
|
||||
found_cols[col] = std_name
|
||||
break
|
||||
|
||||
@ -66,7 +83,7 @@ class SpecialSuppliersService:
|
||||
df_clean = df_clean.rename(columns=found_cols)
|
||||
|
||||
# 过滤掉空的条码行
|
||||
df_clean = df_clean.dropna(subset=['barcode'])
|
||||
df_clean = df_clean.dropna(subset=['商品条码'])
|
||||
|
||||
# 保存预处理文件
|
||||
out_dir = os.path.dirname(src_path)
|
||||
|
||||
88
clean.py
88
clean.py
@ -1,88 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
清理脚本 - 用于删除无关的文件和日志
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import glob
|
||||
|
||||
def clean_logs():
|
||||
"""清理日志文件"""
|
||||
print("清理日志文件...")
|
||||
|
||||
# 删除.active文件
|
||||
active_files = glob.glob("logs/*.active")
|
||||
for file in active_files:
|
||||
try:
|
||||
os.remove(file)
|
||||
print(f"已删除: {file}")
|
||||
except Exception as e:
|
||||
print(f"删除文件时出错 {file}: {e}")
|
||||
|
||||
# 保留最新的日志,删除旧的备份
|
||||
log_files = glob.glob("logs/*.log.*")
|
||||
for file in log_files:
|
||||
try:
|
||||
os.remove(file)
|
||||
print(f"已删除: {file}")
|
||||
except Exception as e:
|
||||
print(f"删除文件时出错 {file}: {e}")
|
||||
|
||||
def clean_temp_files():
|
||||
"""清理临时文件"""
|
||||
print("清理临时文件...")
|
||||
|
||||
# 清空临时目录
|
||||
temp_dir = "data/temp"
|
||||
if os.path.exists(temp_dir):
|
||||
for file in os.listdir(temp_dir):
|
||||
file_path = os.path.join(temp_dir, file)
|
||||
try:
|
||||
if os.path.isfile(file_path):
|
||||
os.remove(file_path)
|
||||
print(f"已删除: {file_path}")
|
||||
elif os.path.isdir(file_path):
|
||||
shutil.rmtree(file_path)
|
||||
print(f"已删除目录: {file_path}")
|
||||
except Exception as e:
|
||||
print(f"删除文件时出错 {file_path}: {e}")
|
||||
|
||||
# 删除备份文件
|
||||
backup_files = glob.glob("data/*.bak") + glob.glob("config/*.bak")
|
||||
for file in backup_files:
|
||||
try:
|
||||
os.remove(file)
|
||||
print(f"已删除: {file}")
|
||||
except Exception as e:
|
||||
print(f"删除文件时出错 {file}: {e}")
|
||||
|
||||
def clean_pycache():
|
||||
"""清理Python缓存文件"""
|
||||
print("清理Python缓存文件...")
|
||||
|
||||
# 查找并删除所有__pycache__目录
|
||||
for root, dirs, files in os.walk("."):
|
||||
for dir in dirs:
|
||||
if dir == "__pycache__":
|
||||
cache_dir = os.path.join(root, dir)
|
||||
try:
|
||||
shutil.rmtree(cache_dir)
|
||||
print(f"已删除目录: {cache_dir}")
|
||||
except Exception as e:
|
||||
print(f"删除目录时出错 {cache_dir}: {e}")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("开始清理无关文件...")
|
||||
|
||||
clean_logs()
|
||||
clean_temp_files()
|
||||
clean_pycache()
|
||||
|
||||
print("清理完成!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,30 +0,0 @@
|
||||
# 更新日志
|
||||
|
||||
## v1.1.0 (2025-05-30)
|
||||
|
||||
### 新特性
|
||||
- 添加对特殊条码6958620703716的处理,支持同时设置规格和条码映射
|
||||
- 增强不规范规格格式的解析能力(如"IL*12"、"6oo*12"等)
|
||||
- 支持带重量单位的规格解析(如"5kg*6")
|
||||
- 添加数量为空时通过金额和单价自动计算数量的功能
|
||||
|
||||
### 修复
|
||||
- 修复条码映射功能在特殊处理后不生效的问题
|
||||
- 修复OrderService中缺少merge_all_purchase_orders方法导致合并采购单报错的问题
|
||||
- 修复了条码映射对话框无法同时添加特殊处理和映射的问题
|
||||
|
||||
### 改进
|
||||
- 改进了BarcodeMapper类,使其支持同时进行特殊处理和条码映射
|
||||
- 改进了规格解析逻辑,增加了对各种单位和格式的支持
|
||||
- 添加条码映射对话框中可视化标记映射关系
|
||||
- 更新了条码映射配置文件,增加了更多特殊条码处理
|
||||
- 改进商品验证器,在数量为空但单价和金额存在时,自动计算数量
|
||||
|
||||
## v1.0.0 (2025-05-01)
|
||||
|
||||
### 初始版本
|
||||
- 基础OCR识别功能
|
||||
- Excel处理功能
|
||||
- 采购单合并功能
|
||||
- 烟草订单处理功能
|
||||
- 图形用户界面
|
||||
@ -1,309 +0,0 @@
|
||||
# 益选-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订单处理系统
|
||||
作者:欢欢欢
|
||||
|
||||
本项目采用模块化设计,遵循最佳实践,致力于为用户提供高效、准确的采购单自动化处理解决方案。
|
||||
@ -1,43 +0,0 @@
|
||||
# 益选-OCR订单处理系统
|
||||
|
||||
一个集OCR识别、Excel处理和订单合并功能于一体的采购单处理系统。
|
||||
|
||||
## 主要功能
|
||||
|
||||
- **OCR识别**:识别图片中的商品信息,包括条码、名称、数量、单价等
|
||||
- **Excel处理**:将OCR识别结果处理成规范的Excel采购单
|
||||
- **采购单合并**:合并多个采购单,汇总相同商品
|
||||
- **条码映射**:支持将特定条码映射为其他条码,适应不同系统要求
|
||||
- **规格处理**:智能解析商品规格,实现单位自动转换
|
||||
- **烟草订单处理**:专门处理烟草公司订单
|
||||
|
||||
## 技术特点
|
||||
|
||||
- 基于Python开发,使用Tkinter构建图形界面
|
||||
- 采用模块化设计,易于扩展和维护
|
||||
- 自动处理各种不规范数据格式
|
||||
- 配置文件支持,可自定义各种处理参数
|
||||
- 日志记录,便于问题排查
|
||||
|
||||
## 使用方法
|
||||
|
||||
1. 运行`启动器.py`打开主界面
|
||||
2. 根据需要选择相应功能按钮
|
||||
3. 按照提示操作,完成数据处理
|
||||
|
||||
## 系统要求
|
||||
|
||||
- Python 3.8+
|
||||
- 所需第三方库:详见`requirements.txt`
|
||||
|
||||
## 最近更新
|
||||
|
||||
请查看[更新日志](CHANGELOG.md)了解最新版本变更。
|
||||
|
||||
## 贡献者
|
||||
|
||||
- 欢欢欢
|
||||
|
||||
## 版权
|
||||
|
||||
© 2025 益选-OCR订单处理系统
|
||||
@ -1,634 +0,0 @@
|
||||
# 益选-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订单处理系统的技术实现细节,包括系统架构设计、模块职责划分、核心算法流程、数据流设计以及关键技术实现。系统设计遵循软件工程最佳实践,确保系统的可靠性、可维护性和可扩展性。
|
||||
@ -1,476 +0,0 @@
|
||||
# 益选-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订单处理系统,获得更好的使用体验和业务价值。
|
||||
@ -1,79 +0,0 @@
|
||||
# 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` 备份)
|
||||
- 依赖安装风险:提供一键安装与离线安装说明
|
||||
- 模板差异风险:在校验失败时阻断流程并提示修复路径
|
||||
|
||||
## 实施说明
|
||||
- 每周开始前将与您确认要启动的任务;每个任务完成后提交变更摘要与验证结果
|
||||
- 如发现新需求或变化,计划将滚动更新,并在执行前与您确认
|
||||
161
doc/更新日志.md
161
doc/更新日志.md
@ -1,161 +0,0 @@
|
||||
# OCR订单处理系统 - 更新日志
|
||||
|
||||
## v1.5 (2025-05-09)
|
||||
|
||||
### 功能改进
|
||||
- 烟草订单处理结果展示:改进烟草订单处理完成后的结果展示界面
|
||||
- 美化结果展示界面,显示订单时间、总金额和处理条目数
|
||||
- 添加文件信息展示,包括文件大小和创建时间
|
||||
- 提供打开文件、打开所在文件夹等便捷操作按钮
|
||||
- 统一与Excel处理结果展示风格,提升用户体验
|
||||
- 增强结果文件路径解析能力,确保正确找到并显示结果文件
|
||||
- 条码映射编辑功能:
|
||||
- 添加图形化条码映射编辑工具,方便管理条码映射和特殊处理规则
|
||||
- 支持添加、修改和删除条码映射关系
|
||||
- 支持配置特殊处理规则,如乘数、目标单位、固定单价等
|
||||
- 自动保存到配置文件,便于后续使用
|
||||
|
||||
### 问题修复
|
||||
- 修复烟草订单处理时出现双重弹窗问题
|
||||
- 修复烟草订单处理完成后结果展示弹窗无法正常显示的问题
|
||||
- 修复ConfigParser兼容性问题,支持标准ConfigParser对象
|
||||
- 修复百度OCR客户端中getint方法调用不兼容问题
|
||||
- 修复OCRService中缺少batch_process方法的问题,确保OCR功能正常工作
|
||||
- 改进日志管理,确保所有日志正确关闭
|
||||
- 优化UI界面,统一按钮样式
|
||||
- 修复启动器中处理烟草订单按钮的显示样式
|
||||
- 修复run.py中close_logger调用缺少参数的问题
|
||||
|
||||
### 代码改进
|
||||
- 改进TobaccoService类对配置的处理方式,使用标准get方法
|
||||
- 添加fallback机制以增强配置健壮性
|
||||
- 优化启动器中结果预览逻辑,避免重复弹窗
|
||||
- 统一UI组件风格,提升用户体验
|
||||
- 增强错误处理,提供更清晰的错误信息
|
||||
|
||||
## v1.4 (2025-05-09)
|
||||
|
||||
### 新功能
|
||||
- 烟草订单处理:新增烟草公司特定格式订单明细文件处理功能
|
||||
- 支持自动处理标准烟草订单明细格式
|
||||
- 根据烟草公司"盒码"作为条码生成银豹采购单
|
||||
- 自动将"订单量"转换为"采购量"并计算采购单价
|
||||
- 处理结果以银豹采购单格式保存,方便直接导入
|
||||
|
||||
### 功能优化
|
||||
- 配置兼容性:优化配置处理逻辑,兼容标准ConfigParser对象
|
||||
- 启动器优化:启动器界面增加"处理烟草订单"功能按钮
|
||||
- 代码结构优化:将烟草订单处理功能模块化,集成到整体服务架构
|
||||
|
||||
## v1.3 (2025-07-20)
|
||||
|
||||
### 功能优化
|
||||
- 采购单赠品处理逻辑优化:修改了银豹采购单中赠品的处理方式
|
||||
- 之前:赠品数量单独填写在"赠送量"列,与正常采购量分开处理
|
||||
- 现在:将赠品数量合并到采购量中,赠送量列留空
|
||||
- 有正常商品且有赠品的情况:采购量 = 正常商品数量 + 赠品数量,单价 = 原单价 × 正常商品数量 ÷ 总数量
|
||||
- 只有赠品的情况:采购量填写赠品数量,单价为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)
|
||||
|
||||
### 功能更新
|
||||
- 单位自动推断:当单位为空但有商品编码、规格、数量、单价等信息,且规格符合容量*数量格式时,自动将单位设置为"件"并按照件的处理规则进行转换
|
||||
- 规格解析优化:改进对容量*数量格式规格的解析,如"1.8L*8"能正确识别包装数量为8
|
||||
- 规格提取增强:从商品名称中提取"容量*数量"格式的规格时,能正确识别如"美汁源果粒橙1.8L*8瓶"中的"1.8L*8"部分
|
||||
- 条码映射功能:增加特定条码的自动映射功能,支持将特定条码自动转换为指定的目标条码
|
||||
- 6920584471055 → 6920584471017
|
||||
- 6925861571159 → 69021824
|
||||
- 6923644268923 → 6923644268480
|
||||
- 条码映射后会继续按照件/箱等单位的标准处理规则进行数量和单价的转换
|
||||
|
||||
## v1.0 (2025-05-02)
|
||||
|
||||
### 主要功能
|
||||
- 图像OCR识别:支持对采购单图片进行OCR识别并生成Excel文件
|
||||
- Excel数据处理:智能处理Excel文件,提取和转换商品信息
|
||||
- 采购单生成:按照模板格式生成标准采购单Excel文件
|
||||
- 采购单合并:支持多个采购单合并为一个总单
|
||||
- 图形界面:提供简洁直观的操作界面
|
||||
- 命令行支持:支持命令行调用,方便自动化处理
|
||||
|
||||
### 技术改进
|
||||
- 模块化架构:重构代码为配置、核心功能、服务和CLI等模块
|
||||
- 单位智能处理:完善的单位转换规则,支持多种计量单位
|
||||
- 规格智能推断:从商品名称自动推断规格信息
|
||||
- 日志管理:完善的日志记录系统,支持终端和GUI同步显示
|
||||
- 表头智能识别:自动识别Excel中的表头位置,兼容多种格式
|
||||
- 改进用户体验:界面优化,批量处理支持,实时状态反馈
|
||||
|
||||
## v1.5.1 (2024-03-21)
|
||||
- 修复了配置管理相关的问题:
|
||||
- 修复了`config.ini`文件被意外重置的问题
|
||||
- 优化了配置加载逻辑,确保保留现有配置值
|
||||
- 添加了配置缺失项自动补充功能
|
||||
- 新增系统设置功能:
|
||||
- 添加了图形化配置设置界面
|
||||
- 支持API设置、路径设置、性能设置和文件设置
|
||||
- 所有设置更改实时保存
|
||||
- 移除了统计报告功能,替换为更实用的系统设置功能
|
||||
- 优化了用户界面和交互体验
|
||||
|
||||
## v1.5.0 (2024-03-20)
|
||||
- 添加了统计与报告功能
|
||||
- 添加了键盘快捷键支持
|
||||
- 优化了用户界面
|
||||
- 删除了不必要的文件
|
||||
- 更新了README.md
|
||||
- 创建了更新日志文档
|
||||
|
||||
## v1.4.0 (2024-03-19)
|
||||
- 添加了自定义弹窗演示
|
||||
- 优化了错误处理
|
||||
- 改进了日志记录
|
||||
|
||||
## v1.3.0 (2024-03-18)
|
||||
- 添加了条码映射功能
|
||||
- 优化了文件处理逻辑
|
||||
- 改进了用户界面
|
||||
|
||||
## v1.2.0 (2024-03-17)
|
||||
- 添加了批量处理功能
|
||||
- 优化了性能
|
||||
- 改进了错误处理
|
||||
|
||||
## v1.1.0 (2024-03-16)
|
||||
- 添加了Excel处理功能
|
||||
- 优化了OCR识别
|
||||
- 改进了用户界面
|
||||
|
||||
## v1.0.0 (2024-03-15)
|
||||
- 初始版本发布
|
||||
- 基本OCR功能
|
||||
- 基本用户界面
|
||||
|
||||
## v1.5.2 (2024-03-21)
|
||||
- 修复了方法名称不匹配的问题:
|
||||
- 将`process_latest_excel`方法调用改为`process_excel`
|
||||
- 确保Excel处理功能正常工作
|
||||
- 优化了错误处理和日志记录
|
||||
|
||||
## v1.5.3 (2024-03-21)
|
||||
- 优化了完整流程处理逻辑:
|
||||
- 修改了OCR处理逻辑,当遇到已处理的图片时自动跳过并继续执行
|
||||
- 改进了错误处理,避免因图片已处理而中断流程
|
||||
- 优化了日志提示信息,提供更清晰的处理状态反馈
|
||||
- 改进了OCRService的process_image方法:
|
||||
- 添加了文件存在性检查
|
||||
- 添加了文件类型验证
|
||||
- 添加了已处理文件检查
|
||||
- 优化了错误处理和日志记录
|
||||
@ -9161,3 +9161,810 @@
|
||||
2026-03-30 14:41:33,387 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-30 14:41:47,795 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-30 14:41:49,672 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 08:50:15,731 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 08:50:15,891 - app.core.excel.converter - INFO - 提取规格: 益达口香糖元气蓝莓味5片装13.5g@ -> 13.5*None
|
||||
2026-03-31 08:50:15,892 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 益达口香糖元气蓝莓味5片装13.5g@ -> 13.5*None
|
||||
2026-03-31 08:50:15,894 - app.core.excel.converter - WARNING - 无法解析规格: 13.5*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,895 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 2.05, 单位:
|
||||
2026-03-31 08:50:15,895 - app.core.excel.converter - INFO - 提取规格: 奥利奥饼干草莓味夹心97g@ -> 97*None
|
||||
2026-03-31 08:50:15,896 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 奥利奥饼干草莓味夹心97g@ -> 97*None
|
||||
2026-03-31 08:50:15,896 - app.core.excel.converter - WARNING - 无法解析规格: 97*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,896 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 4.95, 单位:
|
||||
2026-03-31 08:50:15,897 - app.core.excel.converter - INFO - 提取规格: 奥利奥冰淇淋风味饼干抹茶味97g@ -> 97*None
|
||||
2026-03-31 08:50:15,897 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 奥利奥冰淇淋风味饼干抹茶味97g@ -> 97*None
|
||||
2026-03-31 08:50:15,897 - app.core.excel.converter - WARNING - 无法解析规格: 97*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,898 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 4.75, 单位:
|
||||
2026-03-31 08:50:15,898 - app.core.excel.converter - INFO - 提取规格: 奥利奥薄脆香草奥碎味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,898 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 奥利奥薄脆香草奥碎味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,899 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,899 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 6.19, 单位:
|
||||
2026-03-31 08:50:15,899 - app.core.excel.converter - INFO - 提取规格: 喜之郎果肉果冻葡萄苹果200g -> 200*None
|
||||
2026-03-31 08:50:15,899 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 喜之郎果肉果冻葡萄苹果200g -> 200*None
|
||||
2026-03-31 08:50:15,900 - app.core.excel.converter - WARNING - 无法解析规格: 200*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,900 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 3.0, 单位:
|
||||
2026-03-31 08:50:15,900 - app.core.excel.converter - INFO - 提取规格: 法丽兹曲奇抹茶慕斯巧克力味70g@ -> 70*None
|
||||
2026-03-31 08:50:15,901 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 法丽兹曲奇抹茶慕斯巧克力味70g@ -> 70*None
|
||||
2026-03-31 08:50:15,901 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,901 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.67, 单位:
|
||||
2026-03-31 08:50:15,901 - app.core.excel.converter - INFO - 提取规格: 太平梳打饼干海苔味100g@ -> 100*None
|
||||
2026-03-31 08:50:15,902 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 太平梳打饼干海苔味100g@ -> 100*None
|
||||
2026-03-31 08:50:15,902 - app.core.excel.converter - WARNING - 无法解析规格: 100*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,902 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.33, 单位:
|
||||
2026-03-31 08:50:15,903 - app.core.excel.converter - INFO - 提取规格: 新家园烤馍52g@ -> 52*None
|
||||
2026-03-31 08:50:15,903 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 新家园烤馍52g@ -> 52*None
|
||||
2026-03-31 08:50:15,903 - app.core.excel.converter - WARNING - 无法解析规格: 52*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,903 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 1.33, 单位:
|
||||
2026-03-31 08:50:15,904 - app.core.excel.converter - INFO - 提取规格: 达利园熊子饼115g@ -> 115*None
|
||||
2026-03-31 08:50:15,904 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园熊子饼115g@ -> 115*None
|
||||
2026-03-31 08:50:15,904 - app.core.excel.converter - WARNING - 无法解析规格: 115*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,904 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 1.97, 单位:
|
||||
2026-03-31 08:50:15,905 - app.core.excel.converter - INFO - 提取规格: 达利园好吃点榛仁酥饼146g@ -> 146*None
|
||||
2026-03-31 08:50:15,905 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园好吃点榛仁酥饼146g@ -> 146*None
|
||||
2026-03-31 08:50:15,905 - app.core.excel.converter - WARNING - 无法解析规格: 146*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,905 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 3.33, 单位:
|
||||
2026-03-31 08:50:15,906 - app.core.excel.converter - INFO - 提取规格: 达利园好吃点杏仁酥饼146g@ -> 146*None
|
||||
2026-03-31 08:50:15,906 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园好吃点杏仁酥饼146g@ -> 146*None
|
||||
2026-03-31 08:50:15,906 - app.core.excel.converter - WARNING - 无法解析规格: 146*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,906 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 3.33, 单位:
|
||||
2026-03-31 08:50:15,906 - app.core.excel.converter - INFO - 提取规格: 达利园好吃点香脆核桃饼108g@ -> 108*None
|
||||
2026-03-31 08:50:15,907 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园好吃点香脆核桃饼108g@ -> 108*None
|
||||
2026-03-31 08:50:15,907 - app.core.excel.converter - WARNING - 无法解析规格: 108*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,907 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 2.5, 单位:
|
||||
2026-03-31 08:50:15,907 - app.core.excel.converter - INFO - 提取规格: 达利园好吃点香脆腰果饼108g@ -> 108*None
|
||||
2026-03-31 08:50:15,908 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园好吃点香脆腰果饼108g@ -> 108*None
|
||||
2026-03-31 08:50:15,908 - app.core.excel.converter - WARNING - 无法解析规格: 108*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,908 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 2.5, 单位:
|
||||
2026-03-31 08:50:15,908 - app.core.excel.converter - INFO - 提取规格: 康师傅3+2苏打饼干香浓奶油125g@ -> 125*None
|
||||
2026-03-31 08:50:15,909 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 康师傅3+2苏打饼干香浓奶油125g@ -> 125*None
|
||||
2026-03-31 08:50:15,909 - app.core.excel.converter - WARNING - 无法解析规格: 125*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,909 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 4.42, 单位:
|
||||
2026-03-31 08:50:15,909 - app.core.excel.converter - INFO - 提取规格: 米老头青稞米棒芝麻味150g@ -> 150*None
|
||||
2026-03-31 08:50:15,909 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 米老头青稞米棒芝麻味150g@ -> 150*None
|
||||
2026-03-31 08:50:15,910 - app.core.excel.converter - WARNING - 无法解析规格: 150*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,910 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 4.09, 单位:
|
||||
2026-03-31 08:50:15,910 - app.core.excel.converter - INFO - 提取规格: 旺旺雪饼84g@ -> 84*None
|
||||
2026-03-31 08:50:15,910 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 旺旺雪饼84g@ -> 84*None
|
||||
2026-03-31 08:50:15,910 - app.core.excel.converter - WARNING - 无法解析规格: 84*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,911 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 4.28, 单位:
|
||||
2026-03-31 08:50:15,911 - app.core.excel.converter - INFO - 提取规格: 旺旺仙贝52g@ -> 52*None
|
||||
2026-03-31 08:50:15,911 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 旺旺仙贝52g@ -> 52*None
|
||||
2026-03-31 08:50:15,911 - app.core.excel.converter - WARNING - 无法解析规格: 52*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,911 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.76, 单位:
|
||||
2026-03-31 08:50:15,911 - app.core.excel.converter - INFO - 提取规格: 亨裕蛋味酥39g -> 39*None
|
||||
2026-03-31 08:50:15,912 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 亨裕蛋味酥39g -> 39*None
|
||||
2026-03-31 08:50:15,912 - app.core.excel.converter - WARNING - 无法解析规格: 39*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,912 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 10.0, 单价: 0.62, 单位:
|
||||
2026-03-31 08:50:15,913 - app.core.excel.converter - INFO - 提取规格: 金富士海苔味三角饼干128g@ -> 128*None
|
||||
2026-03-31 08:50:15,913 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 金富士海苔味三角饼干128g@ -> 128*None
|
||||
2026-03-31 08:50:15,913 - app.core.excel.converter - WARNING - 无法解析规格: 128*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,913 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.81, 单位:
|
||||
2026-03-31 08:50:15,914 - app.core.excel.converter - INFO - 提取规格: 怡派手工薄脆饼干318g -> 318*None
|
||||
2026-03-31 08:50:15,914 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 怡派手工薄脆饼干318g -> 318*None
|
||||
2026-03-31 08:50:15,915 - app.core.excel.converter - WARNING - 无法解析规格: 318*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,915 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 6.47, 单位:
|
||||
2026-03-31 08:50:15,915 - app.core.excel.converter - INFO - 提取规格: 雀巢威化脆脆鲨花生味夹心【32条装】18.6g@ -> 18.6*None
|
||||
2026-03-31 08:50:15,915 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 雀巢威化脆脆鲨花生味夹心【32条装】18.6g@ -> 18.6*None
|
||||
2026-03-31 08:50:15,916 - app.core.excel.converter - WARNING - 无法解析规格: 18.6*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,916 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 32.0, 单价: 0.91, 单位:
|
||||
2026-03-31 08:50:15,916 - app.core.excel.converter - INFO - 提取规格: 卫龙亲嘴烧麦辣鸡汁味24g@ -> 24*None
|
||||
2026-03-31 08:50:15,917 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙亲嘴烧麦辣鸡汁味24g@ -> 24*None
|
||||
2026-03-31 08:50:15,917 - app.core.excel.converter - WARNING - 无法解析规格: 24*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,917 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.51, 单位:
|
||||
2026-03-31 08:50:15,917 - app.core.excel.converter - INFO - 提取规格: 卫龙亲嘴烧经典香辣风味24g@ -> 24*None
|
||||
2026-03-31 08:50:15,918 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙亲嘴烧经典香辣风味24g@ -> 24*None
|
||||
2026-03-31 08:50:15,918 - app.core.excel.converter - WARNING - 无法解析规格: 24*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,918 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.51, 单位:
|
||||
2026-03-31 08:50:15,919 - app.core.excel.converter - INFO - 提取规格: 卫龙亲嘴烧麻辣牛肉风味24g@ -> 24*None
|
||||
2026-03-31 08:50:15,919 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙亲嘴烧麻辣牛肉风味24g@ -> 24*None
|
||||
2026-03-31 08:50:15,919 - app.core.excel.converter - WARNING - 无法解析规格: 24*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,919 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.52, 单位:
|
||||
2026-03-31 08:50:15,919 - app.core.excel.converter - INFO - 提取规格: 杨记脆鸭肫香辣味22g -> 22*None
|
||||
2026-03-31 08:50:15,920 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 杨记脆鸭肫香辣味22g -> 22*None
|
||||
2026-03-31 08:50:15,920 - app.core.excel.converter - WARNING - 无法解析规格: 22*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,920 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 2.19, 单位:
|
||||
2026-03-31 08:50:15,920 - app.core.excel.converter - INFO - 提取规格: 杨记脆鸭肫椒麻味22g -> 22*None
|
||||
2026-03-31 08:50:15,920 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 杨记脆鸭肫椒麻味22g -> 22*None
|
||||
2026-03-31 08:50:15,921 - app.core.excel.converter - WARNING - 无法解析规格: 22*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,921 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 2.19, 单位:
|
||||
2026-03-31 08:50:15,921 - app.core.excel.converter - INFO - 提取规格: 登荣龙须牛肉丝20g -> 20*None
|
||||
2026-03-31 08:50:15,921 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 登荣龙须牛肉丝20g -> 20*None
|
||||
2026-03-31 08:50:15,921 - app.core.excel.converter - WARNING - 无法解析规格: 20*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,921 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.71, 单位:
|
||||
2026-03-31 08:50:15,922 - app.core.excel.converter - INFO - 提取规格: 登荣香辣爽口鸡23g -> 23*None
|
||||
2026-03-31 08:50:15,922 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 登荣香辣爽口鸡23g -> 23*None
|
||||
2026-03-31 08:50:15,922 - app.core.excel.converter - WARNING - 无法解析规格: 23*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,922 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.71, 单位:
|
||||
2026-03-31 08:50:15,923 - app.core.excel.converter - INFO - 提取规格: 卫龙魔芋爽麻酱素毛肚微辣18g@ -> 18*None
|
||||
2026-03-31 08:50:15,923 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙魔芋爽麻酱素毛肚微辣18g@ -> 18*None
|
||||
2026-03-31 08:50:15,923 - app.core.excel.converter - WARNING - 无法解析规格: 18*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,923 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 40.0, 单价: 0.62, 单位:
|
||||
2026-03-31 08:50:15,924 - app.core.excel.converter - INFO - 提取规格: 劲仔小鱼卤香味12g@ -> 12*None
|
||||
2026-03-31 08:50:15,924 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔小鱼卤香味12g@ -> 12*None
|
||||
2026-03-31 08:50:15,924 - app.core.excel.converter - WARNING - 无法解析规格: 12*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,924 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.68, 单位:
|
||||
2026-03-31 08:50:15,925 - app.core.excel.converter - INFO - 提取规格: 劲仔小鱼香辣小鱼12g@ -> 12*None
|
||||
2026-03-31 08:50:15,925 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔小鱼香辣小鱼12g@ -> 12*None
|
||||
2026-03-31 08:50:15,925 - app.core.excel.converter - WARNING - 无法解析规格: 12*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,926 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.65, 单位:
|
||||
2026-03-31 08:50:15,926 - app.core.excel.converter - INFO - 提取规格: 劲仔小鱼糖醋小鱼12g@ -> 12*None
|
||||
2026-03-31 08:50:15,926 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔小鱼糖醋小鱼12g@ -> 12*None
|
||||
2026-03-31 08:50:15,926 - app.core.excel.converter - WARNING - 无法解析规格: 12*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,927 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.68, 单位:
|
||||
2026-03-31 08:50:15,927 - app.core.excel.converter - INFO - 提取规格: 劲仔手撕肉干麻辣味10g@ -> 10*None
|
||||
2026-03-31 08:50:15,927 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔手撕肉干麻辣味10g@ -> 10*None
|
||||
2026-03-31 08:50:15,928 - app.core.excel.converter - WARNING - 无法解析规格: 10*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,928 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 1.14, 单位:
|
||||
2026-03-31 08:50:15,928 - app.core.excel.converter - INFO - 提取规格: 劲仔手撕肉干香辣味10g@ -> 10*None
|
||||
2026-03-31 08:50:15,929 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔手撕肉干香辣味10g@ -> 10*None
|
||||
2026-03-31 08:50:15,929 - app.core.excel.converter - WARNING - 无法解析规格: 10*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,929 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 1.14, 单位:
|
||||
2026-03-31 08:50:15,929 - app.core.excel.converter - INFO - 提取规格: 卫龙麻辣麻辣小麻小辣16g@ -> 16*None
|
||||
2026-03-31 08:50:15,930 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙麻辣麻辣小麻小辣16g@ -> 16*None
|
||||
2026-03-31 08:50:15,930 - app.core.excel.converter - WARNING - 无法解析规格: 16*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,930 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.58, 单位:
|
||||
2026-03-31 08:50:15,931 - app.core.excel.converter - INFO - 提取规格: 子弟原切马铃薯片巴西烤肉味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,931 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 子弟原切马铃薯片巴西烤肉味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,931 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,931 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 5.33, 单位:
|
||||
2026-03-31 08:50:15,932 - app.core.excel.converter - INFO - 提取规格: 子弟原切马铃薯片美滋番茄味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,932 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 子弟原切马铃薯片美滋番茄味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,932 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,933 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 5.33, 单位:
|
||||
2026-03-31 08:50:15,933 - app.core.excel.converter - INFO - 提取规格: 子弟原切马铃薯片经典麻辣味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,933 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 子弟原切马铃薯片经典麻辣味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,934 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,934 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 5.33, 单位:
|
||||
2026-03-31 08:50:15,934 - app.core.excel.converter - INFO - 提取规格: 子弟原切马铃薯片劲爆麻辣味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,934 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 子弟原切马铃薯片劲爆麻辣味95g@ -> 95*None
|
||||
2026-03-31 08:50:15,935 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,935 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 5.33, 单位:
|
||||
2026-03-31 08:50:15,935 - app.core.excel.converter - INFO - 提取规格: 乐事美国经典原味70g@ -> 70*None
|
||||
2026-03-31 08:50:15,936 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 乐事美国经典原味70g@ -> 70*None
|
||||
2026-03-31 08:50:15,936 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,936 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 4.18, 单位:
|
||||
2026-03-31 08:50:15,937 - app.core.excel.converter - INFO - 提取规格: 乐事墨西哥鸡汁番茄味70g@ -> 70*None
|
||||
2026-03-31 08:50:15,937 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 乐事墨西哥鸡汁番茄味70g@ -> 70*None
|
||||
2026-03-31 08:50:15,937 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,937 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 4.18, 单位:
|
||||
2026-03-31 08:50:15,938 - app.core.excel.converter - INFO - 提取规格: 飘零大叔蜜辣去骨鸭掌45g@ -> 45*None
|
||||
2026-03-31 08:50:15,938 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 飘零大叔蜜辣去骨鸭掌45g@ -> 45*None
|
||||
2026-03-31 08:50:15,938 - app.core.excel.converter - WARNING - 无法解析规格: 45*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,938 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 8.57, 单位:
|
||||
2026-03-31 08:50:15,939 - app.core.excel.converter - INFO - 提取规格: 茂林炭烤鱿鱼丝60g -> 60*None
|
||||
2026-03-31 08:50:15,939 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 茂林炭烤鱿鱼丝60g -> 60*None
|
||||
2026-03-31 08:50:15,939 - app.core.excel.converter - WARNING - 无法解析规格: 60*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,939 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 8.47, 单位:
|
||||
2026-03-31 08:50:15,940 - app.core.excel.converter - INFO - 提取规格: 王小卤虎皮凤爪火锅味105g@ -> 105*None
|
||||
2026-03-31 08:50:15,940 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 王小卤虎皮凤爪火锅味105g@ -> 105*None
|
||||
2026-03-31 08:50:15,940 - app.core.excel.converter - WARNING - 无法解析规格: 105*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,941 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 10.38, 单位:
|
||||
2026-03-31 08:50:15,941 - app.core.excel.converter - INFO - 提取规格: 王小卤虎皮凤爪卤香味 105g@ -> 105*None
|
||||
2026-03-31 08:50:15,941 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 王小卤虎皮凤爪卤香味 105g@ -> 105*None
|
||||
2026-03-31 08:50:15,942 - app.core.excel.converter - WARNING - 无法解析规格: 105*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,942 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 10.38, 单位:
|
||||
2026-03-31 08:50:15,942 - app.core.excel.converter - INFO - 提取规格: 王小卤虎皮凤爪香辣味 105g@ -> 105*None
|
||||
2026-03-31 08:50:15,942 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 王小卤虎皮凤爪香辣味 105g@ -> 105*None
|
||||
2026-03-31 08:50:15,943 - app.core.excel.converter - WARNING - 无法解析规格: 105*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,943 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 10.38, 单位:
|
||||
2026-03-31 08:50:15,943 - app.core.excel.converter - INFO - 提取规格: 王小卤虎皮凤爪椒麻味105g@ -> 105*None
|
||||
2026-03-31 08:50:15,943 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 王小卤虎皮凤爪椒麻味105g@ -> 105*None
|
||||
2026-03-31 08:50:15,944 - app.core.excel.converter - WARNING - 无法解析规格: 105*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,944 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 10.38, 单位:
|
||||
2026-03-31 08:50:15,944 - app.core.excel.converter - INFO - 提取规格: 杨记老卤双爪多味70g -> 70*None
|
||||
2026-03-31 08:50:15,944 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 杨记老卤双爪多味70g -> 70*None
|
||||
2026-03-31 08:50:15,945 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,945 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 3.81, 单位:
|
||||
2026-03-31 08:50:15,945 - app.core.excel.converter - INFO - 提取规格: 逍遥嘴花椒鸡味180g -> 180*None
|
||||
2026-03-31 08:50:15,945 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 逍遥嘴花椒鸡味180g -> 180*None
|
||||
2026-03-31 08:50:15,946 - app.core.excel.converter - WARNING - 无法解析规格: 180*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,946 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.86, 单位:
|
||||
2026-03-31 08:50:15,946 - app.core.excel.converter - INFO - 提取规格: 川牛娃泡椒牛肉50g -> 50*None
|
||||
2026-03-31 08:50:15,946 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 川牛娃泡椒牛肉50g -> 50*None
|
||||
2026-03-31 08:50:15,946 - app.core.excel.converter - WARNING - 无法解析规格: 50*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,946 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 4.76, 单位:
|
||||
2026-03-31 08:50:15,947 - app.core.excel.converter - INFO - 提取规格: 飘零大叔川香半筋半肉48g@ -> 48*None
|
||||
2026-03-31 08:50:15,947 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 飘零大叔川香半筋半肉48g@ -> 48*None
|
||||
2026-03-31 08:50:15,947 - app.core.excel.converter - WARNING - 无法解析规格: 48*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,948 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 7.81, 单位:
|
||||
2026-03-31 08:50:15,948 - app.core.excel.converter - INFO - 提取规格: 展华大辣棒麻辣牛肉味138g -> 138*None
|
||||
2026-03-31 08:50:15,948 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 展华大辣棒麻辣牛肉味138g -> 138*None
|
||||
2026-03-31 08:50:15,948 - app.core.excel.converter - WARNING - 无法解析规格: 138*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,948 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.95, 单位:
|
||||
2026-03-31 08:50:15,949 - app.core.excel.converter - INFO - 提取规格: 登荣素口水鸡65g -> 65*None
|
||||
2026-03-31 08:50:15,949 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 登荣素口水鸡65g -> 65*None
|
||||
2026-03-31 08:50:15,949 - app.core.excel.converter - WARNING - 无法解析规格: 65*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,949 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 1.52, 单位:
|
||||
2026-03-31 08:50:15,949 - app.core.excel.converter - INFO - 提取规格: 48g乐媳妇山椒凤爪 -> 48*None
|
||||
2026-03-31 08:50:15,950 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 48g乐媳妇山椒凤爪 -> 48*None
|
||||
2026-03-31 08:50:15,950 - app.core.excel.converter - WARNING - 无法解析规格: 48*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,950 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 10.0, 单价: 2.09, 单位:
|
||||
2026-03-31 08:50:15,950 - app.core.excel.converter - INFO - 提取规格: 蓉小优泡椒味臭干子70g@ -> 70*None
|
||||
2026-03-31 08:50:15,950 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 蓉小优泡椒味臭干子70g@ -> 70*None
|
||||
2026-03-31 08:50:15,951 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,951 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 1.33, 单位:
|
||||
2026-03-31 08:50:15,951 - app.core.excel.converter - INFO - 提取规格: 吴婷红油馍片82g -> 82*None
|
||||
2026-03-31 08:50:15,951 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 吴婷红油馍片82g -> 82*None
|
||||
2026-03-31 08:50:15,951 - app.core.excel.converter - WARNING - 无法解析规格: 82*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,952 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 2.29, 单位:
|
||||
2026-03-31 08:50:15,952 - app.core.excel.converter - INFO - 提取规格: 禛香肥牛味大豆制品素食风味80g -> 80*None
|
||||
2026-03-31 08:50:15,952 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 禛香肥牛味大豆制品素食风味80g -> 80*None
|
||||
2026-03-31 08:50:15,952 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,952 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 1.71, 单位:
|
||||
2026-03-31 08:50:15,953 - app.core.excel.converter - INFO - 提取规格: (50g+30g)卫龙魔芋爽(酸辣泡椒素毛肚)@ -> 50*None
|
||||
2026-03-31 08:50:15,953 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): (50g+30g)卫龙魔芋爽(酸辣泡椒素毛肚)@ -> 50*None
|
||||
2026-03-31 08:50:15,953 - app.core.excel.converter - WARNING - 无法解析规格: 50*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,953 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.91, 单位:
|
||||
2026-03-31 08:50:15,954 - app.core.excel.converter - INFO - 提取规格: 卫龙大面筋106g@ -> 106*None
|
||||
2026-03-31 08:50:15,954 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙大面筋106g@ -> 106*None
|
||||
2026-03-31 08:50:15,954 - app.core.excel.converter - WARNING - 无法解析规格: 106*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,954 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.91, 单位:
|
||||
2026-03-31 08:50:15,955 - app.core.excel.converter - INFO - 提取规格: 小滑头薄片(经典)72g -> 72*None
|
||||
2026-03-31 08:50:15,955 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 小滑头薄片(经典)72g -> 72*None
|
||||
2026-03-31 08:50:15,955 - app.core.excel.converter - WARNING - 无法解析规格: 72*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,955 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 1.43, 单位:
|
||||
2026-03-31 08:50:15,956 - app.core.excel.converter - INFO - 提取规格: 卫龙魔芋爽香辣素毛肚(50g+30g)@ -> 50*None
|
||||
2026-03-31 08:50:15,956 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙魔芋爽香辣素毛肚(50g+30g)@ -> 50*None
|
||||
2026-03-31 08:50:15,956 - app.core.excel.converter - WARNING - 无法解析规格: 50*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,956 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 7.0, 单价: 2.47, 单位:
|
||||
2026-03-31 08:50:15,957 - app.core.excel.converter - INFO - 提取规格: 郎阿哥牛羊配辣味90g -> 90*None
|
||||
2026-03-31 08:50:15,957 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 郎阿哥牛羊配辣味90g -> 90*None
|
||||
2026-03-31 08:50:15,957 - app.core.excel.converter - WARNING - 无法解析规格: 90*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,958 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.09, 单位:
|
||||
2026-03-31 08:50:15,958 - app.core.excel.converter - INFO - 提取规格: 旺旺馒头118g@ -> 118*None
|
||||
2026-03-31 08:50:15,958 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 旺旺馒头118g@ -> 118*None
|
||||
2026-03-31 08:50:15,959 - app.core.excel.converter - WARNING - 无法解析规格: 118*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,959 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 5.24, 单位:
|
||||
2026-03-31 08:50:15,959 - app.core.excel.converter - INFO - 提取规格: 80g调皮猴鹌鹑蛋(麻辣味) -> 80*None
|
||||
2026-03-31 08:50:15,960 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 80g调皮猴鹌鹑蛋(麻辣味) -> 80*None
|
||||
2026-03-31 08:50:15,960 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,960 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 2.38, 单位:
|
||||
2026-03-31 08:50:15,961 - app.core.excel.converter - INFO - 提取规格: 有友泡椒牛皮晶山椒70g@ -> 70*None
|
||||
2026-03-31 08:50:15,961 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 有友泡椒牛皮晶山椒70g@ -> 70*None
|
||||
2026-03-31 08:50:15,961 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,962 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 3.51, 单位:
|
||||
2026-03-31 08:50:15,962 - app.core.excel.converter - INFO - 提取规格: 许之郎猪蹄盐焗味150g -> 150*None
|
||||
2026-03-31 08:50:15,962 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 许之郎猪蹄盐焗味150g -> 150*None
|
||||
2026-03-31 08:50:15,963 - app.core.excel.converter - WARNING - 无法解析规格: 150*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,963 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 9.52, 单位:
|
||||
2026-03-31 08:50:15,963 - app.core.excel.converter - INFO - 提取规格: 160g东莱辣卤猪蹄 -> 160*None
|
||||
2026-03-31 08:50:15,964 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 160g东莱辣卤猪蹄 -> 160*None
|
||||
2026-03-31 08:50:15,964 - app.core.excel.converter - WARNING - 无法解析规格: 160*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,964 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 10.28, 单位:
|
||||
2026-03-31 08:50:15,964 - app.core.excel.converter - INFO - 提取规格: 杨记麻辣腿100g -> 100*None
|
||||
2026-03-31 08:50:15,965 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 杨记麻辣腿100g -> 100*None
|
||||
2026-03-31 08:50:15,965 - app.core.excel.converter - WARNING - 无法解析规格: 100*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,965 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 5.05, 单位:
|
||||
2026-03-31 08:50:15,966 - app.core.excel.converter - INFO - 提取规格: 周小贱功夫鸭脖黑鸭味55g -> 55*None
|
||||
2026-03-31 08:50:15,966 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 周小贱功夫鸭脖黑鸭味55g -> 55*None
|
||||
2026-03-31 08:50:15,966 - app.core.excel.converter - WARNING - 无法解析规格: 55*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,966 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 4.28, 单位:
|
||||
2026-03-31 08:50:15,967 - app.core.excel.converter - INFO - 提取规格: 老灶煮花生400g -> 400*None
|
||||
2026-03-31 08:50:15,967 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 老灶煮花生400g -> 400*None
|
||||
2026-03-31 08:50:15,967 - app.core.excel.converter - WARNING - 无法解析规格: 400*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,967 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 8.76, 单位:
|
||||
2026-03-31 08:50:15,968 - app.core.excel.converter - INFO - 提取规格: 老灶花生186g -> 186*None
|
||||
2026-03-31 08:50:15,968 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 老灶花生186g -> 186*None
|
||||
2026-03-31 08:50:15,968 - app.core.excel.converter - WARNING - 无法解析规格: 186*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,969 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 4.9, 单位:
|
||||
2026-03-31 08:50:15,969 - app.core.excel.converter - INFO - 提取规格: 老灶煮花生蒜香味130g -> 130*None
|
||||
2026-03-31 08:50:15,969 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 老灶煮花生蒜香味130g -> 130*None
|
||||
2026-03-31 08:50:15,969 - app.core.excel.converter - WARNING - 无法解析规格: 130*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,970 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 3.5, 单位:
|
||||
2026-03-31 08:50:15,970 - app.core.excel.converter - INFO - 提取规格: 香香嘴卤制豆腐干香辣味80g@ -> 80*None
|
||||
2026-03-31 08:50:15,970 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 香香嘴卤制豆腐干香辣味80g@ -> 80*None
|
||||
2026-03-31 08:50:15,970 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,970 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.67, 单位:
|
||||
2026-03-31 08:50:15,971 - app.core.excel.converter - INFO - 提取规格: 香香嘴卤制豆腐干五香味80g@ -> 80*None
|
||||
2026-03-31 08:50:15,971 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 香香嘴卤制豆腐干五香味80g@ -> 80*None
|
||||
2026-03-31 08:50:15,971 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,971 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.67, 单位:
|
||||
2026-03-31 08:50:15,972 - app.core.excel.converter - INFO - 提取规格: 80g千百度啦咝豆干(麻辣味) -> 80*None
|
||||
2026-03-31 08:50:15,972 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 80g千百度啦咝豆干(麻辣味) -> 80*None
|
||||
2026-03-31 08:50:15,972 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,972 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 2.53, 单位:
|
||||
2026-03-31 08:50:15,973 - app.core.excel.converter - INFO - 提取规格: 洽洽瓜子焦糖味@108g -> 108*None
|
||||
2026-03-31 08:50:15,973 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 洽洽瓜子焦糖味@108g -> 108*None
|
||||
2026-03-31 08:50:15,974 - app.core.excel.converter - WARNING - 无法解析规格: 108*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,974 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 5.07, 单位:
|
||||
2026-03-31 08:50:15,975 - app.core.excel.converter - INFO - 提取规格: 洽洽奶香瓜子285g@ -> 285*None
|
||||
2026-03-31 08:50:15,975 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 洽洽奶香瓜子285g@ -> 285*None
|
||||
2026-03-31 08:50:15,975 - app.core.excel.converter - WARNING - 无法解析规格: 285*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,975 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 9.65, 单位:
|
||||
2026-03-31 08:50:15,976 - app.core.excel.converter - INFO - 提取规格: 洽洽香瓜子260g@ -> 260*None
|
||||
2026-03-31 08:50:15,976 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 洽洽香瓜子260g@ -> 260*None
|
||||
2026-03-31 08:50:15,976 - app.core.excel.converter - WARNING - 无法解析规格: 260*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,976 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 8.57, 单位:
|
||||
2026-03-31 08:50:15,977 - app.core.excel.converter - INFO - 提取规格: 徽记生瓜子涨115g -> 115*None
|
||||
2026-03-31 08:50:15,977 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 徽记生瓜子涨115g -> 115*None
|
||||
2026-03-31 08:50:15,978 - app.core.excel.converter - WARNING - 无法解析规格: 115*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,978 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 4.09, 单位:
|
||||
2026-03-31 08:50:15,978 - app.core.excel.converter - INFO - 提取规格: 老程华重庆怪味胡豆190g -> 190*None
|
||||
2026-03-31 08:50:15,978 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 老程华重庆怪味胡豆190g -> 190*None
|
||||
2026-03-31 08:50:15,979 - app.core.excel.converter - WARNING - 无法解析规格: 190*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,979 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.9, 单位:
|
||||
2026-03-31 08:50:15,979 - app.core.excel.converter - INFO - 提取规格: 维巧九制梅肉透明装110g -> 110*None
|
||||
2026-03-31 08:50:15,980 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 维巧九制梅肉透明装110g -> 110*None
|
||||
2026-03-31 08:50:15,980 - app.core.excel.converter - WARNING - 无法解析规格: 110*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,980 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.71, 单位:
|
||||
2026-03-31 08:50:15,981 - app.core.excel.converter - INFO - 提取规格: 五哥牛皮糖原味140g -> 140*None
|
||||
2026-03-31 08:50:15,981 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 五哥牛皮糖原味140g -> 140*None
|
||||
2026-03-31 08:50:15,981 - app.core.excel.converter - WARNING - 无法解析规格: 140*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,982 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.43, 单位:
|
||||
2026-03-31 08:50:15,982 - app.core.excel.converter - INFO - 提取规格: 大白兔奶糖114g@ -> 114*None
|
||||
2026-03-31 08:50:15,982 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 大白兔奶糖114g@ -> 114*None
|
||||
2026-03-31 08:50:15,983 - app.core.excel.converter - WARNING - 无法解析规格: 114*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,983 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 5.7, 单位:
|
||||
2026-03-31 08:50:15,984 - app.core.excel.converter - INFO - 提取规格: 素味居山椒土豆80g -> 80*None
|
||||
2026-03-31 08:50:15,984 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 素味居山椒土豆80g -> 80*None
|
||||
2026-03-31 08:50:15,984 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,985 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 1.33, 单位:
|
||||
2026-03-31 08:50:15,985 - app.core.excel.converter - INFO - 提取规格: 有友泡椒凤爪山椒味210g@ -> 210*None
|
||||
2026-03-31 08:50:15,985 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 有友泡椒凤爪山椒味210g@ -> 210*None
|
||||
2026-03-31 08:50:15,986 - app.core.excel.converter - WARNING - 无法解析规格: 210*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,986 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 12.66, 单位:
|
||||
2026-03-31 08:50:15,987 - app.core.excel.converter - INFO - 提取规格: 丫丫队长鸡脚筋老卤盐焗味50g -> 50*None
|
||||
2026-03-31 08:50:15,987 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 丫丫队长鸡脚筋老卤盐焗味50g -> 50*None
|
||||
2026-03-31 08:50:15,987 - app.core.excel.converter - WARNING - 无法解析规格: 50*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,988 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 2.38, 单位:
|
||||
2026-03-31 08:50:15,988 - app.core.excel.converter - INFO - 提取规格: 有友山椒竹笋120g@ -> 120*None
|
||||
2026-03-31 08:50:15,988 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 有友山椒竹笋120g@ -> 120*None
|
||||
2026-03-31 08:50:15,989 - app.core.excel.converter - WARNING - 无法解析规格: 120*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,989 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.75, 单位:
|
||||
2026-03-31 08:50:15,990 - app.core.excel.converter - INFO - 提取规格: 有友泡椒笋尖泡椒100g@ -> 100*None
|
||||
2026-03-31 08:50:15,990 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 有友泡椒笋尖泡椒100g@ -> 100*None
|
||||
2026-03-31 08:50:15,991 - app.core.excel.converter - WARNING - 无法解析规格: 100*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,991 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 3.95, 单位:
|
||||
2026-03-31 08:50:15,991 - app.core.excel.converter - INFO - 提取规格: 素味居泡山椒笋尖100g -> 100*None
|
||||
2026-03-31 08:50:15,991 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 素味居泡山椒笋尖100g -> 100*None
|
||||
2026-03-31 08:50:15,992 - app.core.excel.converter - WARNING - 无法解析规格: 100*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,992 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.72, 单位:
|
||||
2026-03-31 08:50:15,993 - app.core.excel.converter - INFO - 提取规格: 吴氏远久猫耳朵192g -> 192*None
|
||||
2026-03-31 08:50:15,993 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 吴氏远久猫耳朵192g -> 192*None
|
||||
2026-03-31 08:50:15,993 - app.core.excel.converter - WARNING - 无法解析规格: 192*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,994 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 2.47, 单位:
|
||||
2026-03-31 08:50:15,994 - app.core.excel.converter - INFO - 提取规格: 寻唐记锅巴麻辣味70g -> 70*None
|
||||
2026-03-31 08:50:15,994 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 寻唐记锅巴麻辣味70g -> 70*None
|
||||
2026-03-31 08:50:15,995 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,995 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 1.9, 单位:
|
||||
2026-03-31 08:50:15,995 - app.core.excel.converter - INFO - 提取规格: 好时达地摊锅巴豪横高辣味108g -> 108*None
|
||||
2026-03-31 08:50:15,996 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 好时达地摊锅巴豪横高辣味108g -> 108*None
|
||||
2026-03-31 08:50:15,996 - app.core.excel.converter - WARNING - 无法解析规格: 108*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,996 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 2.48, 单位:
|
||||
2026-03-31 08:50:15,997 - app.core.excel.converter - INFO - 提取规格: 美好火腿肠56g@ -> 56*None
|
||||
2026-03-31 08:50:15,997 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 美好火腿肠56g@ -> 56*None
|
||||
2026-03-31 08:50:15,997 - app.core.excel.converter - WARNING - 无法解析规格: 56*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,997 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 80.0, 单价: 1.37, 单位:
|
||||
2026-03-31 08:50:15,998 - app.core.excel.converter - INFO - 提取规格: 卫龙亲嘴烧川香风味24g@ -> 24*None
|
||||
2026-03-31 08:50:15,998 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙亲嘴烧川香风味24g@ -> 24*None
|
||||
2026-03-31 08:50:15,999 - app.core.excel.converter - WARNING - 无法解析规格: 24*None,使用默认值1*1
|
||||
2026-03-31 08:50:15,999 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.51, 单位:
|
||||
2026-03-31 08:50:15,999 - app.core.excel.converter - INFO - 提取规格: 魔法士脆士可挡疯狂烤肉味35g -> 35*None
|
||||
2026-03-31 08:50:16,000 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 魔法士脆士可挡疯狂烤肉味35g -> 35*None
|
||||
2026-03-31 08:50:16,000 - app.core.excel.converter - WARNING - 无法解析规格: 35*None,使用默认值1*1
|
||||
2026-03-31 08:50:16,000 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 30.0, 单价: 0.76, 单位:
|
||||
2026-03-31 08:50:16,001 - app.core.excel.converter - INFO - 提取规格: 美好甜玉米90g@ -> 90*None
|
||||
2026-03-31 08:50:16,001 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 美好甜玉米90g@ -> 90*None
|
||||
2026-03-31 08:50:16,001 - app.core.excel.converter - WARNING - 无法解析规格: 90*None,使用默认值1*1
|
||||
2026-03-31 08:50:17,774 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 08:52:46,013 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 08:52:47,191 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 09:00:01,692 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 09:00:02,146 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
|
||||
2026-03-31 09:00:02,147 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
|
||||
2026-03-31 09:00:02,148 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
|
||||
2026-03-31 09:00:02,149 - app.core.excel.converter - INFO - 解析二级规格: 1*18 -> 1*18
|
||||
2026-03-31 09:00:02,149 - app.core.excel.converter - INFO - 解析二级规格: 1*45 -> 1*45
|
||||
2026-03-31 09:00:02,150 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:00:02,150 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:00:02,151 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:00:02,152 - app.core.excel.converter - INFO - 解析二级规格: 1*35 -> 1*35
|
||||
2026-03-31 09:00:02,152 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:00:02,153 - app.core.excel.converter - INFO - 解析二级规格: 1*30 -> 1*30
|
||||
2026-03-31 09:00:02,153 - app.core.excel.converter - INFO - 解析二级规格: 1*50 -> 1*50
|
||||
2026-03-31 09:00:02,154 - app.core.excel.converter - INFO - 解析二级规格: 1*50 -> 1*50
|
||||
2026-03-31 09:00:02,155 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:00:02,155 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:03:11,828 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 09:03:11,990 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
|
||||
2026-03-31 09:03:11,991 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
|
||||
2026-03-31 09:03:11,992 - app.core.excel.converter - INFO - 解析二级规格: 1*24 -> 1*24
|
||||
2026-03-31 09:03:11,993 - app.core.excel.converter - INFO - 解析二级规格: 1*18 -> 1*18
|
||||
2026-03-31 09:03:11,995 - app.core.excel.converter - INFO - 解析二级规格: 1*45 -> 1*45
|
||||
2026-03-31 09:03:11,996 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:03:11,997 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:03:11,999 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:03:12,000 - app.core.excel.converter - INFO - 解析二级规格: 1*35 -> 1*35
|
||||
2026-03-31 09:03:12,002 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:03:12,003 - app.core.excel.converter - INFO - 解析二级规格: 1*30 -> 1*30
|
||||
2026-03-31 09:03:12,004 - app.core.excel.converter - INFO - 解析二级规格: 1*50 -> 1*50
|
||||
2026-03-31 09:03:12,005 - app.core.excel.converter - INFO - 解析二级规格: 1*50 -> 1*50
|
||||
2026-03-31 09:03:12,007 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:03:12,008 - app.core.excel.converter - INFO - 解析二级规格: 1*40 -> 1*40
|
||||
2026-03-31 09:03:13,872 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 09:05:33,093 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 09:05:33,207 - app.core.excel.converter - INFO - 提取规格: 益达口香糖元气蓝莓味5片装13.5g@ -> 13.5*None
|
||||
2026-03-31 09:05:33,207 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 益达口香糖元气蓝莓味5片装13.5g@ -> 13.5*None
|
||||
2026-03-31 09:05:33,209 - app.core.excel.converter - WARNING - 无法解析规格: 13.5*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,209 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 2.05, 单位:
|
||||
2026-03-31 09:05:33,211 - app.core.excel.converter - INFO - 提取规格: 奥利奥饼干草莓味夹心97g@ -> 97*None
|
||||
2026-03-31 09:05:33,211 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 奥利奥饼干草莓味夹心97g@ -> 97*None
|
||||
2026-03-31 09:05:33,212 - app.core.excel.converter - WARNING - 无法解析规格: 97*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,212 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 4.95, 单位:
|
||||
2026-03-31 09:05:33,212 - app.core.excel.converter - INFO - 提取规格: 奥利奥冰淇淋风味饼干抹茶味97g@ -> 97*None
|
||||
2026-03-31 09:05:33,213 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 奥利奥冰淇淋风味饼干抹茶味97g@ -> 97*None
|
||||
2026-03-31 09:05:33,214 - app.core.excel.converter - WARNING - 无法解析规格: 97*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,214 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 4.75, 单位:
|
||||
2026-03-31 09:05:33,215 - app.core.excel.converter - INFO - 提取规格: 奥利奥薄脆香草奥碎味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,215 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 奥利奥薄脆香草奥碎味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,216 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,216 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 6.19, 单位:
|
||||
2026-03-31 09:05:33,217 - app.core.excel.converter - INFO - 提取规格: 喜之郎果肉果冻葡萄苹果200g -> 200*None
|
||||
2026-03-31 09:05:33,217 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 喜之郎果肉果冻葡萄苹果200g -> 200*None
|
||||
2026-03-31 09:05:33,218 - app.core.excel.converter - WARNING - 无法解析规格: 200*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,218 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 3.0, 单位:
|
||||
2026-03-31 09:05:33,219 - app.core.excel.converter - INFO - 提取规格: 法丽兹曲奇抹茶慕斯巧克力味70g@ -> 70*None
|
||||
2026-03-31 09:05:33,220 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 法丽兹曲奇抹茶慕斯巧克力味70g@ -> 70*None
|
||||
2026-03-31 09:05:33,220 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,221 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.67, 单位:
|
||||
2026-03-31 09:05:33,222 - app.core.excel.converter - INFO - 提取规格: 太平梳打饼干海苔味100g@ -> 100*None
|
||||
2026-03-31 09:05:33,222 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 太平梳打饼干海苔味100g@ -> 100*None
|
||||
2026-03-31 09:05:33,223 - app.core.excel.converter - WARNING - 无法解析规格: 100*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,223 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.33, 单位:
|
||||
2026-03-31 09:05:33,224 - app.core.excel.converter - INFO - 提取规格: 新家园烤馍52g@ -> 52*None
|
||||
2026-03-31 09:05:33,224 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 新家园烤馍52g@ -> 52*None
|
||||
2026-03-31 09:05:33,225 - app.core.excel.converter - WARNING - 无法解析规格: 52*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,225 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 1.33, 单位:
|
||||
2026-03-31 09:05:33,226 - app.core.excel.converter - INFO - 提取规格: 达利园熊子饼115g@ -> 115*None
|
||||
2026-03-31 09:05:33,226 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园熊子饼115g@ -> 115*None
|
||||
2026-03-31 09:05:33,227 - app.core.excel.converter - WARNING - 无法解析规格: 115*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,227 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 1.97, 单位:
|
||||
2026-03-31 09:05:33,227 - app.core.excel.converter - INFO - 提取规格: 达利园好吃点榛仁酥饼146g@ -> 146*None
|
||||
2026-03-31 09:05:33,228 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园好吃点榛仁酥饼146g@ -> 146*None
|
||||
2026-03-31 09:05:33,229 - app.core.excel.converter - WARNING - 无法解析规格: 146*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,229 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 3.33, 单位:
|
||||
2026-03-31 09:05:33,229 - app.core.excel.converter - INFO - 提取规格: 达利园好吃点杏仁酥饼146g@ -> 146*None
|
||||
2026-03-31 09:05:33,230 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园好吃点杏仁酥饼146g@ -> 146*None
|
||||
2026-03-31 09:05:33,230 - app.core.excel.converter - WARNING - 无法解析规格: 146*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,231 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 3.33, 单位:
|
||||
2026-03-31 09:05:33,231 - app.core.excel.converter - INFO - 提取规格: 达利园好吃点香脆核桃饼108g@ -> 108*None
|
||||
2026-03-31 09:05:33,231 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园好吃点香脆核桃饼108g@ -> 108*None
|
||||
2026-03-31 09:05:33,232 - app.core.excel.converter - WARNING - 无法解析规格: 108*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,232 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 2.5, 单位:
|
||||
2026-03-31 09:05:33,233 - app.core.excel.converter - INFO - 提取规格: 达利园好吃点香脆腰果饼108g@ -> 108*None
|
||||
2026-03-31 09:05:33,233 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 达利园好吃点香脆腰果饼108g@ -> 108*None
|
||||
2026-03-31 09:05:33,234 - app.core.excel.converter - WARNING - 无法解析规格: 108*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,235 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 2.5, 单位:
|
||||
2026-03-31 09:05:33,236 - app.core.excel.converter - INFO - 提取规格: 康师傅3+2苏打饼干香浓奶油125g@ -> 125*None
|
||||
2026-03-31 09:05:33,236 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 康师傅3+2苏打饼干香浓奶油125g@ -> 125*None
|
||||
2026-03-31 09:05:33,237 - app.core.excel.converter - WARNING - 无法解析规格: 125*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,237 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 4.42, 单位:
|
||||
2026-03-31 09:05:33,238 - app.core.excel.converter - INFO - 提取规格: 米老头青稞米棒芝麻味150g@ -> 150*None
|
||||
2026-03-31 09:05:33,238 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 米老头青稞米棒芝麻味150g@ -> 150*None
|
||||
2026-03-31 09:05:33,238 - app.core.excel.converter - WARNING - 无法解析规格: 150*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,238 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 4.09, 单位:
|
||||
2026-03-31 09:05:33,239 - app.core.excel.converter - INFO - 提取规格: 旺旺雪饼84g@ -> 84*None
|
||||
2026-03-31 09:05:33,240 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 旺旺雪饼84g@ -> 84*None
|
||||
2026-03-31 09:05:33,241 - app.core.excel.converter - WARNING - 无法解析规格: 84*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,241 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 4.28, 单位:
|
||||
2026-03-31 09:05:33,242 - app.core.excel.converter - INFO - 提取规格: 旺旺仙贝52g@ -> 52*None
|
||||
2026-03-31 09:05:33,242 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 旺旺仙贝52g@ -> 52*None
|
||||
2026-03-31 09:05:33,243 - app.core.excel.converter - WARNING - 无法解析规格: 52*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,243 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.76, 单位:
|
||||
2026-03-31 09:05:33,243 - app.core.excel.converter - INFO - 提取规格: 亨裕蛋味酥39g -> 39*None
|
||||
2026-03-31 09:05:33,243 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 亨裕蛋味酥39g -> 39*None
|
||||
2026-03-31 09:05:33,245 - app.core.excel.converter - WARNING - 无法解析规格: 39*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,245 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 10.0, 单价: 0.62, 单位:
|
||||
2026-03-31 09:05:33,245 - app.core.excel.converter - INFO - 提取规格: 金富士海苔味三角饼干128g@ -> 128*None
|
||||
2026-03-31 09:05:33,245 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 金富士海苔味三角饼干128g@ -> 128*None
|
||||
2026-03-31 09:05:33,246 - app.core.excel.converter - WARNING - 无法解析规格: 128*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,246 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.81, 单位:
|
||||
2026-03-31 09:05:33,248 - app.core.excel.converter - INFO - 提取规格: 怡派手工薄脆饼干318g -> 318*None
|
||||
2026-03-31 09:05:33,248 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 怡派手工薄脆饼干318g -> 318*None
|
||||
2026-03-31 09:05:33,249 - app.core.excel.converter - WARNING - 无法解析规格: 318*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,249 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 6.47, 单位:
|
||||
2026-03-31 09:05:33,250 - app.core.excel.converter - INFO - 提取规格: 雀巢威化脆脆鲨花生味夹心【32条装】18.6g@ -> 18.6*None
|
||||
2026-03-31 09:05:33,250 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 雀巢威化脆脆鲨花生味夹心【32条装】18.6g@ -> 18.6*None
|
||||
2026-03-31 09:05:33,251 - app.core.excel.converter - WARNING - 无法解析规格: 18.6*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,251 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 32.0, 单价: 0.91, 单位:
|
||||
2026-03-31 09:05:33,251 - app.core.excel.converter - INFO - 提取规格: 卫龙亲嘴烧麦辣鸡汁味24g@ -> 24*None
|
||||
2026-03-31 09:05:33,252 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙亲嘴烧麦辣鸡汁味24g@ -> 24*None
|
||||
2026-03-31 09:05:33,253 - app.core.excel.converter - WARNING - 无法解析规格: 24*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,253 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.51, 单位:
|
||||
2026-03-31 09:05:33,254 - app.core.excel.converter - INFO - 提取规格: 卫龙亲嘴烧经典香辣风味24g@ -> 24*None
|
||||
2026-03-31 09:05:33,254 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙亲嘴烧经典香辣风味24g@ -> 24*None
|
||||
2026-03-31 09:05:33,255 - app.core.excel.converter - WARNING - 无法解析规格: 24*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,255 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.51, 单位:
|
||||
2026-03-31 09:05:33,255 - app.core.excel.converter - INFO - 提取规格: 卫龙亲嘴烧麻辣牛肉风味24g@ -> 24*None
|
||||
2026-03-31 09:05:33,256 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙亲嘴烧麻辣牛肉风味24g@ -> 24*None
|
||||
2026-03-31 09:05:33,256 - app.core.excel.converter - WARNING - 无法解析规格: 24*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,257 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.52, 单位:
|
||||
2026-03-31 09:05:33,258 - app.core.excel.converter - INFO - 提取规格: 杨记脆鸭肫香辣味22g -> 22*None
|
||||
2026-03-31 09:05:33,258 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 杨记脆鸭肫香辣味22g -> 22*None
|
||||
2026-03-31 09:05:33,258 - app.core.excel.converter - WARNING - 无法解析规格: 22*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,259 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 2.19, 单位:
|
||||
2026-03-31 09:05:33,260 - app.core.excel.converter - INFO - 提取规格: 杨记脆鸭肫椒麻味22g -> 22*None
|
||||
2026-03-31 09:05:33,260 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 杨记脆鸭肫椒麻味22g -> 22*None
|
||||
2026-03-31 09:05:33,261 - app.core.excel.converter - WARNING - 无法解析规格: 22*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,261 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 2.19, 单位:
|
||||
2026-03-31 09:05:33,261 - app.core.excel.converter - INFO - 提取规格: 登荣龙须牛肉丝20g -> 20*None
|
||||
2026-03-31 09:05:33,261 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 登荣龙须牛肉丝20g -> 20*None
|
||||
2026-03-31 09:05:33,263 - app.core.excel.converter - WARNING - 无法解析规格: 20*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,263 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.71, 单位:
|
||||
2026-03-31 09:05:33,263 - app.core.excel.converter - INFO - 提取规格: 登荣香辣爽口鸡23g -> 23*None
|
||||
2026-03-31 09:05:33,264 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 登荣香辣爽口鸡23g -> 23*None
|
||||
2026-03-31 09:05:33,264 - app.core.excel.converter - WARNING - 无法解析规格: 23*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,265 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.71, 单位:
|
||||
2026-03-31 09:05:33,265 - app.core.excel.converter - INFO - 提取规格: 卫龙魔芋爽麻酱素毛肚微辣18g@ -> 18*None
|
||||
2026-03-31 09:05:33,266 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙魔芋爽麻酱素毛肚微辣18g@ -> 18*None
|
||||
2026-03-31 09:05:33,266 - app.core.excel.converter - WARNING - 无法解析规格: 18*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,267 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 40.0, 单价: 0.62, 单位:
|
||||
2026-03-31 09:05:33,268 - app.core.excel.converter - INFO - 提取规格: 劲仔小鱼卤香味12g@ -> 12*None
|
||||
2026-03-31 09:05:33,268 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔小鱼卤香味12g@ -> 12*None
|
||||
2026-03-31 09:05:33,269 - app.core.excel.converter - WARNING - 无法解析规格: 12*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,269 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.68, 单位:
|
||||
2026-03-31 09:05:33,270 - app.core.excel.converter - INFO - 提取规格: 劲仔小鱼香辣小鱼12g@ -> 12*None
|
||||
2026-03-31 09:05:33,270 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔小鱼香辣小鱼12g@ -> 12*None
|
||||
2026-03-31 09:05:33,270 - app.core.excel.converter - WARNING - 无法解析规格: 12*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,271 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.65, 单位:
|
||||
2026-03-31 09:05:33,271 - app.core.excel.converter - INFO - 提取规格: 劲仔小鱼糖醋小鱼12g@ -> 12*None
|
||||
2026-03-31 09:05:33,271 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔小鱼糖醋小鱼12g@ -> 12*None
|
||||
2026-03-31 09:05:33,273 - app.core.excel.converter - WARNING - 无法解析规格: 12*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,273 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.68, 单位:
|
||||
2026-03-31 09:05:33,273 - app.core.excel.converter - INFO - 提取规格: 劲仔手撕肉干麻辣味10g@ -> 10*None
|
||||
2026-03-31 09:05:33,274 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔手撕肉干麻辣味10g@ -> 10*None
|
||||
2026-03-31 09:05:33,275 - app.core.excel.converter - WARNING - 无法解析规格: 10*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,275 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 1.14, 单位:
|
||||
2026-03-31 09:05:33,276 - app.core.excel.converter - INFO - 提取规格: 劲仔手撕肉干香辣味10g@ -> 10*None
|
||||
2026-03-31 09:05:33,276 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 劲仔手撕肉干香辣味10g@ -> 10*None
|
||||
2026-03-31 09:05:33,277 - app.core.excel.converter - WARNING - 无法解析规格: 10*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,277 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 1.14, 单位:
|
||||
2026-03-31 09:05:33,277 - app.core.excel.converter - INFO - 提取规格: 卫龙麻辣麻辣小麻小辣16g@ -> 16*None
|
||||
2026-03-31 09:05:33,278 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙麻辣麻辣小麻小辣16g@ -> 16*None
|
||||
2026-03-31 09:05:33,279 - app.core.excel.converter - WARNING - 无法解析规格: 16*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,279 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.58, 单位:
|
||||
2026-03-31 09:05:33,279 - app.core.excel.converter - INFO - 提取规格: 子弟原切马铃薯片巴西烤肉味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,280 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 子弟原切马铃薯片巴西烤肉味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,281 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,282 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 5.33, 单位:
|
||||
2026-03-31 09:05:33,282 - app.core.excel.converter - INFO - 提取规格: 子弟原切马铃薯片美滋番茄味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,283 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 子弟原切马铃薯片美滋番茄味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,283 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,283 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 5.33, 单位:
|
||||
2026-03-31 09:05:33,285 - app.core.excel.converter - INFO - 提取规格: 子弟原切马铃薯片经典麻辣味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,285 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 子弟原切马铃薯片经典麻辣味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,286 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,286 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 5.33, 单位:
|
||||
2026-03-31 09:05:33,286 - app.core.excel.converter - INFO - 提取规格: 子弟原切马铃薯片劲爆麻辣味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,286 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 子弟原切马铃薯片劲爆麻辣味95g@ -> 95*None
|
||||
2026-03-31 09:05:33,287 - app.core.excel.converter - WARNING - 无法解析规格: 95*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,288 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 5.33, 单位:
|
||||
2026-03-31 09:05:33,288 - app.core.excel.converter - INFO - 提取规格: 乐事美国经典原味70g@ -> 70*None
|
||||
2026-03-31 09:05:33,288 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 乐事美国经典原味70g@ -> 70*None
|
||||
2026-03-31 09:05:33,290 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,290 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 4.18, 单位:
|
||||
2026-03-31 09:05:33,290 - app.core.excel.converter - INFO - 提取规格: 乐事墨西哥鸡汁番茄味70g@ -> 70*None
|
||||
2026-03-31 09:05:33,291 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 乐事墨西哥鸡汁番茄味70g@ -> 70*None
|
||||
2026-03-31 09:05:33,291 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,291 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 4.18, 单位:
|
||||
2026-03-31 09:05:33,292 - app.core.excel.converter - INFO - 提取规格: 飘零大叔蜜辣去骨鸭掌45g@ -> 45*None
|
||||
2026-03-31 09:05:33,292 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 飘零大叔蜜辣去骨鸭掌45g@ -> 45*None
|
||||
2026-03-31 09:05:33,293 - app.core.excel.converter - WARNING - 无法解析规格: 45*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,294 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 8.57, 单位:
|
||||
2026-03-31 09:05:33,294 - app.core.excel.converter - INFO - 提取规格: 茂林炭烤鱿鱼丝60g -> 60*None
|
||||
2026-03-31 09:05:33,295 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 茂林炭烤鱿鱼丝60g -> 60*None
|
||||
2026-03-31 09:05:33,297 - app.core.excel.converter - WARNING - 无法解析规格: 60*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,297 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 8.47, 单位:
|
||||
2026-03-31 09:05:33,299 - app.core.excel.converter - INFO - 提取规格: 王小卤虎皮凤爪火锅味105g@ -> 105*None
|
||||
2026-03-31 09:05:33,299 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 王小卤虎皮凤爪火锅味105g@ -> 105*None
|
||||
2026-03-31 09:05:33,300 - app.core.excel.converter - WARNING - 无法解析规格: 105*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,300 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 10.38, 单位:
|
||||
2026-03-31 09:05:33,302 - app.core.excel.converter - INFO - 提取规格: 王小卤虎皮凤爪卤香味 105g@ -> 105*None
|
||||
2026-03-31 09:05:33,302 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 王小卤虎皮凤爪卤香味 105g@ -> 105*None
|
||||
2026-03-31 09:05:33,303 - app.core.excel.converter - WARNING - 无法解析规格: 105*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,303 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 10.38, 单位:
|
||||
2026-03-31 09:05:33,304 - app.core.excel.converter - INFO - 提取规格: 王小卤虎皮凤爪香辣味 105g@ -> 105*None
|
||||
2026-03-31 09:05:33,304 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 王小卤虎皮凤爪香辣味 105g@ -> 105*None
|
||||
2026-03-31 09:05:33,306 - app.core.excel.converter - WARNING - 无法解析规格: 105*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,306 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 10.38, 单位:
|
||||
2026-03-31 09:05:33,306 - app.core.excel.converter - INFO - 提取规格: 王小卤虎皮凤爪椒麻味105g@ -> 105*None
|
||||
2026-03-31 09:05:33,307 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 王小卤虎皮凤爪椒麻味105g@ -> 105*None
|
||||
2026-03-31 09:05:33,308 - app.core.excel.converter - WARNING - 无法解析规格: 105*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,309 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 10.38, 单位:
|
||||
2026-03-31 09:05:33,309 - app.core.excel.converter - INFO - 提取规格: 杨记老卤双爪多味70g -> 70*None
|
||||
2026-03-31 09:05:33,310 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 杨记老卤双爪多味70g -> 70*None
|
||||
2026-03-31 09:05:33,311 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,311 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 3.81, 单位:
|
||||
2026-03-31 09:05:33,312 - app.core.excel.converter - INFO - 提取规格: 逍遥嘴花椒鸡味180g -> 180*None
|
||||
2026-03-31 09:05:33,312 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 逍遥嘴花椒鸡味180g -> 180*None
|
||||
2026-03-31 09:05:33,314 - app.core.excel.converter - WARNING - 无法解析规格: 180*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,314 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.86, 单位:
|
||||
2026-03-31 09:05:33,315 - app.core.excel.converter - INFO - 提取规格: 川牛娃泡椒牛肉50g -> 50*None
|
||||
2026-03-31 09:05:33,315 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 川牛娃泡椒牛肉50g -> 50*None
|
||||
2026-03-31 09:05:33,317 - app.core.excel.converter - WARNING - 无法解析规格: 50*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,317 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 4.76, 单位:
|
||||
2026-03-31 09:05:33,318 - app.core.excel.converter - INFO - 提取规格: 飘零大叔川香半筋半肉48g@ -> 48*None
|
||||
2026-03-31 09:05:33,318 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 飘零大叔川香半筋半肉48g@ -> 48*None
|
||||
2026-03-31 09:05:33,319 - app.core.excel.converter - WARNING - 无法解析规格: 48*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,320 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 7.81, 单位:
|
||||
2026-03-31 09:05:33,320 - app.core.excel.converter - INFO - 提取规格: 展华大辣棒麻辣牛肉味138g -> 138*None
|
||||
2026-03-31 09:05:33,321 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 展华大辣棒麻辣牛肉味138g -> 138*None
|
||||
2026-03-31 09:05:33,322 - app.core.excel.converter - WARNING - 无法解析规格: 138*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,322 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.95, 单位:
|
||||
2026-03-31 09:05:33,323 - app.core.excel.converter - INFO - 提取规格: 登荣素口水鸡65g -> 65*None
|
||||
2026-03-31 09:05:33,324 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 登荣素口水鸡65g -> 65*None
|
||||
2026-03-31 09:05:33,324 - app.core.excel.converter - WARNING - 无法解析规格: 65*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,325 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 1.52, 单位:
|
||||
2026-03-31 09:05:33,326 - app.core.excel.converter - INFO - 提取规格: 48g乐媳妇山椒凤爪 -> 48*None
|
||||
2026-03-31 09:05:33,326 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 48g乐媳妇山椒凤爪 -> 48*None
|
||||
2026-03-31 09:05:33,328 - app.core.excel.converter - WARNING - 无法解析规格: 48*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,328 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 10.0, 单价: 2.09, 单位:
|
||||
2026-03-31 09:05:33,329 - app.core.excel.converter - INFO - 提取规格: 蓉小优泡椒味臭干子70g@ -> 70*None
|
||||
2026-03-31 09:05:33,329 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 蓉小优泡椒味臭干子70g@ -> 70*None
|
||||
2026-03-31 09:05:33,329 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,330 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 1.33, 单位:
|
||||
2026-03-31 09:05:33,331 - app.core.excel.converter - INFO - 提取规格: 吴婷红油馍片82g -> 82*None
|
||||
2026-03-31 09:05:33,331 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 吴婷红油馍片82g -> 82*None
|
||||
2026-03-31 09:05:33,332 - app.core.excel.converter - WARNING - 无法解析规格: 82*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,332 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 2.29, 单位:
|
||||
2026-03-31 09:05:33,334 - app.core.excel.converter - INFO - 提取规格: 禛香肥牛味大豆制品素食风味80g -> 80*None
|
||||
2026-03-31 09:05:33,334 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 禛香肥牛味大豆制品素食风味80g -> 80*None
|
||||
2026-03-31 09:05:33,335 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,335 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 1.71, 单位:
|
||||
2026-03-31 09:05:33,336 - app.core.excel.converter - INFO - 提取规格: (50g+30g)卫龙魔芋爽(酸辣泡椒素毛肚)@ -> 50*None
|
||||
2026-03-31 09:05:33,337 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): (50g+30g)卫龙魔芋爽(酸辣泡椒素毛肚)@ -> 50*None
|
||||
2026-03-31 09:05:33,337 - app.core.excel.converter - WARNING - 无法解析规格: 50*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,338 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.91, 单位:
|
||||
2026-03-31 09:05:33,338 - app.core.excel.converter - INFO - 提取规格: 卫龙大面筋106g@ -> 106*None
|
||||
2026-03-31 09:05:33,339 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙大面筋106g@ -> 106*None
|
||||
2026-03-31 09:05:33,340 - app.core.excel.converter - WARNING - 无法解析规格: 106*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,340 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.91, 单位:
|
||||
2026-03-31 09:05:33,341 - app.core.excel.converter - INFO - 提取规格: 小滑头薄片(经典)72g -> 72*None
|
||||
2026-03-31 09:05:33,341 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 小滑头薄片(经典)72g -> 72*None
|
||||
2026-03-31 09:05:33,343 - app.core.excel.converter - WARNING - 无法解析规格: 72*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,343 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 1.43, 单位:
|
||||
2026-03-31 09:05:33,344 - app.core.excel.converter - INFO - 提取规格: 卫龙魔芋爽香辣素毛肚(50g+30g)@ -> 50*None
|
||||
2026-03-31 09:05:33,344 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙魔芋爽香辣素毛肚(50g+30g)@ -> 50*None
|
||||
2026-03-31 09:05:33,345 - app.core.excel.converter - WARNING - 无法解析规格: 50*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,345 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 7.0, 单价: 2.47, 单位:
|
||||
2026-03-31 09:05:33,346 - app.core.excel.converter - INFO - 提取规格: 郎阿哥牛羊配辣味90g -> 90*None
|
||||
2026-03-31 09:05:33,346 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 郎阿哥牛羊配辣味90g -> 90*None
|
||||
2026-03-31 09:05:33,347 - app.core.excel.converter - WARNING - 无法解析规格: 90*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,347 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.09, 单位:
|
||||
2026-03-31 09:05:33,348 - app.core.excel.converter - INFO - 提取规格: 旺旺馒头118g@ -> 118*None
|
||||
2026-03-31 09:05:33,348 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 旺旺馒头118g@ -> 118*None
|
||||
2026-03-31 09:05:33,349 - app.core.excel.converter - WARNING - 无法解析规格: 118*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,350 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 5.24, 单位:
|
||||
2026-03-31 09:05:33,350 - app.core.excel.converter - INFO - 提取规格: 80g调皮猴鹌鹑蛋(麻辣味) -> 80*None
|
||||
2026-03-31 09:05:33,351 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 80g调皮猴鹌鹑蛋(麻辣味) -> 80*None
|
||||
2026-03-31 09:05:33,351 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,352 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 2.38, 单位:
|
||||
2026-03-31 09:05:33,353 - app.core.excel.converter - INFO - 提取规格: 有友泡椒牛皮晶山椒70g@ -> 70*None
|
||||
2026-03-31 09:05:33,353 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 有友泡椒牛皮晶山椒70g@ -> 70*None
|
||||
2026-03-31 09:05:33,354 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,354 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 3.51, 单位:
|
||||
2026-03-31 09:05:33,355 - app.core.excel.converter - INFO - 提取规格: 许之郎猪蹄盐焗味150g -> 150*None
|
||||
2026-03-31 09:05:33,355 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 许之郎猪蹄盐焗味150g -> 150*None
|
||||
2026-03-31 09:05:33,356 - app.core.excel.converter - WARNING - 无法解析规格: 150*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,356 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 9.52, 单位:
|
||||
2026-03-31 09:05:33,357 - app.core.excel.converter - INFO - 提取规格: 160g东莱辣卤猪蹄 -> 160*None
|
||||
2026-03-31 09:05:33,358 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 160g东莱辣卤猪蹄 -> 160*None
|
||||
2026-03-31 09:05:33,358 - app.core.excel.converter - WARNING - 无法解析规格: 160*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,359 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 10.28, 单位:
|
||||
2026-03-31 09:05:33,360 - app.core.excel.converter - INFO - 提取规格: 杨记麻辣腿100g -> 100*None
|
||||
2026-03-31 09:05:33,360 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 杨记麻辣腿100g -> 100*None
|
||||
2026-03-31 09:05:33,361 - app.core.excel.converter - WARNING - 无法解析规格: 100*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,361 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 5.05, 单位:
|
||||
2026-03-31 09:05:33,362 - app.core.excel.converter - INFO - 提取规格: 周小贱功夫鸭脖黑鸭味55g -> 55*None
|
||||
2026-03-31 09:05:33,362 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 周小贱功夫鸭脖黑鸭味55g -> 55*None
|
||||
2026-03-31 09:05:33,364 - app.core.excel.converter - WARNING - 无法解析规格: 55*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,364 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 4.28, 单位:
|
||||
2026-03-31 09:05:33,365 - app.core.excel.converter - INFO - 提取规格: 老灶煮花生400g -> 400*None
|
||||
2026-03-31 09:05:33,366 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 老灶煮花生400g -> 400*None
|
||||
2026-03-31 09:05:33,366 - app.core.excel.converter - WARNING - 无法解析规格: 400*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,366 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 8.76, 单位:
|
||||
2026-03-31 09:05:33,367 - app.core.excel.converter - INFO - 提取规格: 老灶花生186g -> 186*None
|
||||
2026-03-31 09:05:33,368 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 老灶花生186g -> 186*None
|
||||
2026-03-31 09:05:33,369 - app.core.excel.converter - WARNING - 无法解析规格: 186*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,369 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 4.9, 单位:
|
||||
2026-03-31 09:05:33,370 - app.core.excel.converter - INFO - 提取规格: 老灶煮花生蒜香味130g -> 130*None
|
||||
2026-03-31 09:05:33,370 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 老灶煮花生蒜香味130g -> 130*None
|
||||
2026-03-31 09:05:33,371 - app.core.excel.converter - WARNING - 无法解析规格: 130*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,371 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 3.5, 单位:
|
||||
2026-03-31 09:05:33,372 - app.core.excel.converter - INFO - 提取规格: 香香嘴卤制豆腐干香辣味80g@ -> 80*None
|
||||
2026-03-31 09:05:33,372 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 香香嘴卤制豆腐干香辣味80g@ -> 80*None
|
||||
2026-03-31 09:05:33,373 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,373 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.67, 单位:
|
||||
2026-03-31 09:05:33,373 - app.core.excel.converter - INFO - 提取规格: 香香嘴卤制豆腐干五香味80g@ -> 80*None
|
||||
2026-03-31 09:05:33,374 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 香香嘴卤制豆腐干五香味80g@ -> 80*None
|
||||
2026-03-31 09:05:33,375 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,375 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.67, 单位:
|
||||
2026-03-31 09:05:33,375 - app.core.excel.converter - INFO - 提取规格: 80g千百度啦咝豆干(麻辣味) -> 80*None
|
||||
2026-03-31 09:05:33,377 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 80g千百度啦咝豆干(麻辣味) -> 80*None
|
||||
2026-03-31 09:05:33,377 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,377 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 2.53, 单位:
|
||||
2026-03-31 09:05:33,378 - app.core.excel.converter - INFO - 提取规格: 洽洽瓜子焦糖味@108g -> 108*None
|
||||
2026-03-31 09:05:33,378 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 洽洽瓜子焦糖味@108g -> 108*None
|
||||
2026-03-31 09:05:33,379 - app.core.excel.converter - WARNING - 无法解析规格: 108*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,379 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 5.07, 单位:
|
||||
2026-03-31 09:05:33,380 - app.core.excel.converter - INFO - 提取规格: 洽洽奶香瓜子285g@ -> 285*None
|
||||
2026-03-31 09:05:33,380 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 洽洽奶香瓜子285g@ -> 285*None
|
||||
2026-03-31 09:05:33,381 - app.core.excel.converter - WARNING - 无法解析规格: 285*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,381 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 9.65, 单位:
|
||||
2026-03-31 09:05:33,381 - app.core.excel.converter - INFO - 提取规格: 洽洽香瓜子260g@ -> 260*None
|
||||
2026-03-31 09:05:33,382 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 洽洽香瓜子260g@ -> 260*None
|
||||
2026-03-31 09:05:33,383 - app.core.excel.converter - WARNING - 无法解析规格: 260*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,383 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 8.57, 单位:
|
||||
2026-03-31 09:05:33,383 - app.core.excel.converter - INFO - 提取规格: 徽记生瓜子涨115g -> 115*None
|
||||
2026-03-31 09:05:33,383 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 徽记生瓜子涨115g -> 115*None
|
||||
2026-03-31 09:05:33,384 - app.core.excel.converter - WARNING - 无法解析规格: 115*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,385 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 4.09, 单位:
|
||||
2026-03-31 09:05:33,385 - app.core.excel.converter - INFO - 提取规格: 老程华重庆怪味胡豆190g -> 190*None
|
||||
2026-03-31 09:05:33,385 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 老程华重庆怪味胡豆190g -> 190*None
|
||||
2026-03-31 09:05:33,386 - app.core.excel.converter - WARNING - 无法解析规格: 190*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,386 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.9, 单位:
|
||||
2026-03-31 09:05:33,387 - app.core.excel.converter - INFO - 提取规格: 维巧九制梅肉透明装110g -> 110*None
|
||||
2026-03-31 09:05:33,387 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 维巧九制梅肉透明装110g -> 110*None
|
||||
2026-03-31 09:05:33,388 - app.core.excel.converter - WARNING - 无法解析规格: 110*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,388 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.71, 单位:
|
||||
2026-03-31 09:05:33,389 - app.core.excel.converter - INFO - 提取规格: 五哥牛皮糖原味140g -> 140*None
|
||||
2026-03-31 09:05:33,389 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 五哥牛皮糖原味140g -> 140*None
|
||||
2026-03-31 09:05:33,390 - app.core.excel.converter - WARNING - 无法解析规格: 140*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,390 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 3.43, 单位:
|
||||
2026-03-31 09:05:33,391 - app.core.excel.converter - INFO - 提取规格: 大白兔奶糖114g@ -> 114*None
|
||||
2026-03-31 09:05:33,391 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 大白兔奶糖114g@ -> 114*None
|
||||
2026-03-31 09:05:33,391 - app.core.excel.converter - WARNING - 无法解析规格: 114*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,392 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 5.7, 单位:
|
||||
2026-03-31 09:05:33,393 - app.core.excel.converter - INFO - 提取规格: 素味居山椒土豆80g -> 80*None
|
||||
2026-03-31 09:05:33,393 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 素味居山椒土豆80g -> 80*None
|
||||
2026-03-31 09:05:33,393 - app.core.excel.converter - WARNING - 无法解析规格: 80*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,394 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 1.33, 单位:
|
||||
2026-03-31 09:05:33,394 - app.core.excel.converter - INFO - 提取规格: 有友泡椒凤爪山椒味210g@ -> 210*None
|
||||
2026-03-31 09:05:33,395 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 有友泡椒凤爪山椒味210g@ -> 210*None
|
||||
2026-03-31 09:05:33,395 - app.core.excel.converter - WARNING - 无法解析规格: 210*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,396 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 12.66, 单位:
|
||||
2026-03-31 09:05:33,396 - app.core.excel.converter - INFO - 提取规格: 丫丫队长鸡脚筋老卤盐焗味50g -> 50*None
|
||||
2026-03-31 09:05:33,396 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 丫丫队长鸡脚筋老卤盐焗味50g -> 50*None
|
||||
2026-03-31 09:05:33,397 - app.core.excel.converter - WARNING - 无法解析规格: 50*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,398 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 2.38, 单位:
|
||||
2026-03-31 09:05:33,398 - app.core.excel.converter - INFO - 提取规格: 有友山椒竹笋120g@ -> 120*None
|
||||
2026-03-31 09:05:33,398 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 有友山椒竹笋120g@ -> 120*None
|
||||
2026-03-31 09:05:33,399 - app.core.excel.converter - WARNING - 无法解析规格: 120*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,400 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 5.0, 单价: 2.75, 单位:
|
||||
2026-03-31 09:05:33,400 - app.core.excel.converter - INFO - 提取规格: 有友泡椒笋尖泡椒100g@ -> 100*None
|
||||
2026-03-31 09:05:33,401 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 有友泡椒笋尖泡椒100g@ -> 100*None
|
||||
2026-03-31 09:05:33,401 - app.core.excel.converter - WARNING - 无法解析规格: 100*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,401 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 3.95, 单位:
|
||||
2026-03-31 09:05:33,403 - app.core.excel.converter - INFO - 提取规格: 素味居泡山椒笋尖100g -> 100*None
|
||||
2026-03-31 09:05:33,403 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 素味居泡山椒笋尖100g -> 100*None
|
||||
2026-03-31 09:05:33,404 - app.core.excel.converter - WARNING - 无法解析规格: 100*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,404 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 6.0, 单价: 2.72, 单位:
|
||||
2026-03-31 09:05:33,404 - app.core.excel.converter - INFO - 提取规格: 吴氏远久猫耳朵192g -> 192*None
|
||||
2026-03-31 09:05:33,405 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 吴氏远久猫耳朵192g -> 192*None
|
||||
2026-03-31 09:05:33,406 - app.core.excel.converter - WARNING - 无法解析规格: 192*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,406 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 2.0, 单价: 2.47, 单位:
|
||||
2026-03-31 09:05:33,406 - app.core.excel.converter - INFO - 提取规格: 寻唐记锅巴麻辣味70g -> 70*None
|
||||
2026-03-31 09:05:33,406 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 寻唐记锅巴麻辣味70g -> 70*None
|
||||
2026-03-31 09:05:33,408 - app.core.excel.converter - WARNING - 无法解析规格: 70*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,408 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 3.0, 单价: 1.9, 单位:
|
||||
2026-03-31 09:05:33,409 - app.core.excel.converter - INFO - 提取规格: 好时达地摊锅巴豪横高辣味108g -> 108*None
|
||||
2026-03-31 09:05:33,409 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 好时达地摊锅巴豪横高辣味108g -> 108*None
|
||||
2026-03-31 09:05:33,410 - app.core.excel.converter - WARNING - 无法解析规格: 108*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,410 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 4.0, 单价: 2.48, 单位:
|
||||
2026-03-31 09:05:33,410 - app.core.excel.converter - INFO - 提取规格: 美好火腿肠56g@ -> 56*None
|
||||
2026-03-31 09:05:33,411 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 美好火腿肠56g@ -> 56*None
|
||||
2026-03-31 09:05:33,412 - app.core.excel.converter - WARNING - 无法解析规格: 56*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,412 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 80.0, 单价: 1.37, 单位:
|
||||
2026-03-31 09:05:33,413 - app.core.excel.converter - INFO - 提取规格: 卫龙亲嘴烧川香风味24g@ -> 24*None
|
||||
2026-03-31 09:05:33,413 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 卫龙亲嘴烧川香风味24g@ -> 24*None
|
||||
2026-03-31 09:05:33,414 - app.core.excel.converter - WARNING - 无法解析规格: 24*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,415 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 20.0, 单价: 0.51, 单位:
|
||||
2026-03-31 09:05:33,415 - app.core.excel.converter - INFO - 提取规格: 魔法士脆士可挡疯狂烤肉味35g -> 35*None
|
||||
2026-03-31 09:05:33,415 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 魔法士脆士可挡疯狂烤肉味35g -> 35*None
|
||||
2026-03-31 09:05:33,416 - app.core.excel.converter - WARNING - 无法解析规格: 35*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,417 - app.core.excel.converter - INFO - 其他单位处理: 保持原样 数量: 30.0, 单价: 0.76, 单位:
|
||||
2026-03-31 09:05:33,417 - app.core.excel.converter - INFO - 提取规格: 美好甜玉米90g@ -> 90*None
|
||||
2026-03-31 09:05:33,417 - app.core.excel.converter - INFO - 从名称推断规格(通用模式): 美好甜玉米90g@ -> 90*None
|
||||
2026-03-31 09:05:33,418 - app.core.excel.converter - WARNING - 无法解析规格: 90*None,使用默认值1*1
|
||||
2026-03-31 09:05:33,868 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 09:07:58,234 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
2026-03-31 09:07:58,352 - app.core.excel.converter - INFO - 成功加载条码映射配置,共62项
|
||||
|
||||
@ -4572,3 +4572,34 @@
|
||||
2026-03-30 14:24:03,126 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品6941760902583单位处理: 保持原样 数量: 2.0, 单价: 0, 单位: 6941760902583
|
||||
2026-03-30 14:28:39,658 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品单位处理: 保持原样 数量: 2.0, 单价: 0, 单位:
|
||||
2026-03-30 14:41:12,237 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品单位处理: 保持原样 数量: 2.0, 单价: 0, 单位:
|
||||
2026-03-31 08:50:16,001 - app.core.excel.handlers.unit_converter_handlers - INFO - 赠品单位处理: 保持原样 数量: 2.0, 单价: 0, 单位:
|
||||
2026-03-31 09:00:02,147 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 24.0, 单价: 84.0 -> 3.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,148 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 24.0, 单价: 84.0 -> 3.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,148 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 24.0, 单价: 84.0 -> 3.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,149 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 18.0, 单价: 63.0 -> 3.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,149 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 45.0, 单价: 118.0 -> 2.6222222222222222, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,150 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 120.0 -> 3.0, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,151 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 120.0 -> 3.0, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,151 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 68.0 -> 1.7, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,152 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 35.0, 单价: 113.0 -> 3.2285714285714286, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,152 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 45.0 -> 1.125, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,153 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 30.0, 单价: 75.0 -> 2.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,153 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 50.0, 单价: 30.0 -> 0.6, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,154 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 50.0, 单价: 30.0 -> 0.6, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,155 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 78.0 -> 1.95, 单位: 件 -> 瓶
|
||||
2026-03-31 09:00:02,155 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 100.0 -> 2.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:11,990 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 24.0, 单价: 84.0 -> 3.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:11,991 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 24.0, 单价: 84.0 -> 3.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:11,992 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 24.0, 单价: 84.0 -> 3.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:11,993 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 18.0, 单价: 63.0 -> 3.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:11,995 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 45.0, 单价: 118.0 -> 2.6222222222222222, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:11,996 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 120.0 -> 3.0, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:11,998 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 120.0 -> 3.0, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:11,999 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 68.0 -> 1.7, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:12,000 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 35.0, 单价: 113.0 -> 3.2285714285714286, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:12,002 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 45.0 -> 1.125, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:12,003 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 30.0, 单价: 75.0 -> 2.5, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:12,005 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 50.0, 单价: 30.0 -> 0.6, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:12,006 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 50.0, 单价: 30.0 -> 0.6, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:12,007 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 78.0 -> 1.95, 单位: 件 -> 瓶
|
||||
2026-03-31 09:03:12,008 - app.core.excel.handlers.unit_converter_handlers - INFO - 件单位处理: 数量: 1.0 -> 40.0, 单价: 100.0 -> 2.5, 单位: 件 -> 瓶
|
||||
|
||||
@ -341,3 +341,29 @@
|
||||
2026-03-30 14:41:47,796 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-30 14:41:49,673 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-30 14:41:49,673 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 08:50:15,740 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 08:50:15,754 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 08:50:17,775 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 08:50:17,775 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 08:52:46,014 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 08:52:46,014 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 08:52:47,191 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 08:52:47,192 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 09:00:01,693 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 09:00:01,693 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 09:03:11,828 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 09:03:11,829 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 09:03:13,872 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 09:03:13,872 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 09:05:33,093 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 09:05:33,094 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 09:05:33,868 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 09:05:33,868 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 09:05:36,165 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2026-03-31 09:05:36,165 - app.core.excel.merger - INFO - 找到 1 个采购单Excel文件
|
||||
2026-03-31 09:07:58,235 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 09:07:58,235 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 09:07:58,352 - app.core.excel.merger - INFO - 使用输出目录: E:\2025Code\python\orc-order-v2\data\output
|
||||
2026-03-31 09:07:58,353 - app.core.excel.merger - INFO - 初始化PurchaseOrderMerger完成,模板文件: E:\2025Code\python\orc-order-v2\templates\银豹-采购单模板.xls
|
||||
2026-03-31 09:08:00,645 - app.core.excel.merger - INFO - 搜索目录 data/result 中的采购单Excel文件
|
||||
2026-03-31 09:08:00,646 - app.core.excel.merger - INFO - 找到 2 个采购单Excel文件
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -6776,3 +6776,18 @@
|
||||
2026-03-30 14:24:03,127 - app.core.excel.validators - WARNING - 条码验证失败: 条码长度异常: 1000, 长度=4
|
||||
2026-03-30 14:24:03,127 - app.core.excel.validators - INFO - 修正条码长度: 从14位截断到13位
|
||||
2026-03-30 14:24:03,127 - app.core.excel.validators - WARNING - 数量验证失败: 数量不包含数字
|
||||
2026-03-31 08:52:46,099 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,100 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,100 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,100 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,100 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,101 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,101 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,101 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,101 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,102 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,102 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,102 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,103 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,103 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
2026-03-31 08:52:46,103 - app.core.excel.validators - WARNING - 数量验证失败: 数量必须大于0,当前值: 0.0
|
||||
|
||||
@ -815,3 +815,42 @@
|
||||
2026-03-30 14:41:47,865 - app.services.order_service - INFO - 检测到特殊供应商,已生成预处理文件: E:/2025Code/python/orc-order-v2/data/output\预处理之后_订单明细20260330133908.xlsx
|
||||
2026-03-30 14:41:49,670 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-30 14:41:49,674 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 08:50:15,691 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 08:50:15,754 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 08:50:15,757 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/订单1774849009841.xlsx
|
||||
2026-03-31 08:50:15,811 - app.services.order_service - INFO - 识别到蓉城易购订单,执行专用预处理...
|
||||
2026-03-31 08:50:15,872 - app.services.order_service - INFO - 检测到特殊供应商,已生成预处理文件: E:/2025Code/python/orc-order-v2/data/output\预处理之后_订单1774849009841.xlsx
|
||||
2026-03-31 08:50:17,773 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 08:50:17,775 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 08:52:46,011 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 08:52:46,014 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 08:52:46,029 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/原始数据.xlsx
|
||||
2026-03-31 08:52:46,087 - app.services.order_service - INFO - 检测到特殊供应商,已生成预处理文件: E:/2025Code/python/orc-order-v2/data/output\预处理之后_原始数据.xlsx
|
||||
2026-03-31 08:52:47,190 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 08:52:47,192 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 09:00:01,690 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 09:00:01,694 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 09:00:01,694 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: data/output/原始数据.xlsx
|
||||
2026-03-31 09:00:01,984 - app.services.order_service - INFO - 识别到杨碧月订单,执行专用预处理...
|
||||
2026-03-31 09:00:02,134 - app.services.order_service - INFO - 检测到特殊供应商,已生成预处理文件: data/output\预处理之后_原始数据.xlsx
|
||||
2026-03-31 09:03:11,825 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 09:03:11,829 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 09:03:11,832 - app.services.order_service - INFO - OrderService开始处理指定Excel文件: E:/2025Code/python/orc-order-v2/data/output/原始数据.xlsx
|
||||
2026-03-31 09:03:11,886 - app.services.order_service - INFO - 识别到杨碧月订单,执行专用预处理...
|
||||
2026-03-31 09:03:11,970 - app.services.order_service - INFO - 检测到特殊供应商,已生成预处理文件: E:/2025Code/python/orc-order-v2/data/output\预处理之后_原始数据.xlsx
|
||||
2026-03-31 09:03:13,869 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 09:03:13,873 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 09:05:33,091 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 09:05:33,094 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 09:05:33,098 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2026-03-31 09:05:33,126 - app.services.order_service - INFO - 识别到蓉城易购订单,执行专用预处理...
|
||||
2026-03-31 09:05:33,174 - app.services.order_service - INFO - 检测到特殊供应商,已生成预处理文件: data/output\预处理之后_订单1774849009841.xlsx
|
||||
2026-03-31 09:05:33,865 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 09:05:33,869 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 09:07:58,232 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 09:07:58,236 - app.services.order_service - INFO - OrderService初始化完成
|
||||
2026-03-31 09:07:58,241 - app.services.order_service - INFO - OrderService开始处理最新Excel文件
|
||||
2026-03-31 09:07:58,250 - app.services.order_service - INFO - 识别到烟草公司订单,执行专用预处理...
|
||||
2026-03-31 09:07:58,289 - app.services.order_service - INFO - 检测到特殊供应商,已生成预处理文件: data/output\预处理之后_订单明细20260331090709.xlsx
|
||||
2026-03-31 09:07:58,350 - app.services.order_service - INFO - 初始化OrderService
|
||||
2026-03-31 09:07:58,354 - app.services.order_service - INFO - OrderService初始化完成
|
||||
|
||||
@ -47,3 +47,5 @@
|
||||
2026-03-30 14:28:39,828 - app.services.tobacco_service - INFO - 烟草订单预处理完成: data/output\预处理之后_订单明细20260330133908.xlsx
|
||||
2026-03-30 14:41:47,819 - app.services.tobacco_service - INFO - 执行烟草订单专用预处理: E:/2025Code/python/orc-order-v2/data/output/订单明细20260330133908.xlsx
|
||||
2026-03-30 14:41:47,865 - app.services.tobacco_service - INFO - 烟草订单预处理完成: E:/2025Code/python/orc-order-v2/data/output\预处理之后_订单明细20260330133908.xlsx
|
||||
2026-03-31 09:07:58,250 - app.services.tobacco_service - INFO - 执行烟草订单专用预处理: data/output\订单明细20260331090709.xlsx
|
||||
2026-03-31 09:07:58,289 - app.services.tobacco_service - INFO - 烟草订单预处理完成: data/output\预处理之后_订单明细20260331090709.xlsx
|
||||
|
||||
206
run.py
206
run.py
@ -1,206 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
OCR订单处理系统 - 主入口
|
||||
---------------------
|
||||
提供命令行接口,整合OCR识别、Excel处理和订单合并功能。
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from typing import List, Optional
|
||||
|
||||
from app.config.settings import ConfigManager
|
||||
from app.core.utils.log_utils import get_logger, close_all_loggers, set_log_level
|
||||
from app.services.ocr_service import OCRService
|
||||
from app.services.order_service import OrderService
|
||||
from app.services.tobacco_service import TobaccoService
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
def parse_args():
|
||||
"""
|
||||
解析命令行参数
|
||||
|
||||
Returns:
|
||||
解析后的参数
|
||||
"""
|
||||
parser = argparse.ArgumentParser(description='OCR订单处理系统')
|
||||
|
||||
# 通用选项
|
||||
parser.add_argument('--config', type=str, help='配置文件路径')
|
||||
parser.add_argument('--log-level', type=str, choices=['debug', 'info', 'warning', 'error', 'critical'], help='日志级别')
|
||||
|
||||
# 子命令
|
||||
subparsers = parser.add_subparsers(dest='command', help='子命令')
|
||||
|
||||
# OCR识别命令
|
||||
ocr_parser = subparsers.add_parser('ocr', help='OCR识别')
|
||||
ocr_parser.add_argument('--input', type=str, help='输入图片路径')
|
||||
ocr_parser.add_argument('--batch', action='store_true', help='批量处理')
|
||||
ocr_parser.add_argument('--batch-size', type=int, default=5, help='批处理大小')
|
||||
ocr_parser.add_argument('--max-workers', type=int, default=4, help='最大线程数')
|
||||
|
||||
# Excel处理命令
|
||||
excel_parser = subparsers.add_parser('excel', help='Excel处理')
|
||||
excel_parser.add_argument('--input', type=str, help='输入Excel文件路径')
|
||||
|
||||
# 合并命令
|
||||
merge_parser = subparsers.add_parser('merge', help='合并采购单')
|
||||
merge_parser.add_argument('--input', type=str, help='输入采购单文件路径(逗号分隔)')
|
||||
|
||||
# 完整流程命令
|
||||
pipeline_parser = subparsers.add_parser('pipeline', help='完整处理流程')
|
||||
pipeline_parser.add_argument('--input', type=str, help='输入图片路径')
|
||||
pipeline_parser.add_argument('--merge', action='store_true', help='是否合并采购单')
|
||||
|
||||
# 烟草订单处理
|
||||
tobacco_parser = subparsers.add_parser('tobacco', help='处理烟草订单')
|
||||
tobacco_parser.add_argument('--input', type=str, help='输入订单明细文件路径')
|
||||
|
||||
# 解析参数
|
||||
parsed_args = parser.parse_args()
|
||||
|
||||
return parsed_args
|
||||
|
||||
def main():
|
||||
"""
|
||||
主函数入口
|
||||
|
||||
Returns:
|
||||
退出码
|
||||
"""
|
||||
# 解析命令行参数
|
||||
args = parse_args()
|
||||
|
||||
if not args.command:
|
||||
argparse.ArgumentParser().print_help()
|
||||
return 1
|
||||
|
||||
# 加载配置
|
||||
config_path = args.config
|
||||
config_manager = ConfigManager(config_path)
|
||||
config = config_manager.config
|
||||
|
||||
# 设置日志级别
|
||||
log_level = getattr(args, 'log_level', None)
|
||||
if log_level:
|
||||
set_log_level(log_level)
|
||||
|
||||
try:
|
||||
if args.command == 'ocr':
|
||||
# OCR识别处理
|
||||
ocr_service = OCRService(config)
|
||||
if args.batch:
|
||||
# 批量处理
|
||||
total, success = ocr_service.batch_process(
|
||||
batch_size=args.batch_size,
|
||||
max_workers=args.max_workers
|
||||
)
|
||||
return 0 if success > 0 else 1
|
||||
else:
|
||||
# 处理单个文件
|
||||
result = ocr_service.process_image(args.input)
|
||||
return 0 if result else 1
|
||||
|
||||
elif args.command == 'excel':
|
||||
# Excel处理
|
||||
order_service = OrderService(config)
|
||||
if args.input:
|
||||
# 处理指定文件
|
||||
result = order_service.process_excel(args.input)
|
||||
else:
|
||||
# 处理最新文件
|
||||
result = order_service.process_excel()
|
||||
return 0 if result else 1
|
||||
|
||||
elif args.command == 'merge':
|
||||
# 合并采购单
|
||||
order_service = OrderService(config)
|
||||
if args.input:
|
||||
# 合并指定文件
|
||||
file_list = args.input.split(',')
|
||||
result = order_service.merge_purchase_orders(file_list)
|
||||
else:
|
||||
# 合并所有采购单
|
||||
result = order_service.merge_all_purchase_orders()
|
||||
return 0 if result else 1
|
||||
|
||||
elif args.command == 'pipeline':
|
||||
# 完整流程
|
||||
ocr_service = OCRService(config)
|
||||
order_service = OrderService(config)
|
||||
|
||||
# 1. OCR处理
|
||||
if args.input:
|
||||
# 处理单个文件
|
||||
excel_file = ocr_service.process_image(args.input)
|
||||
else:
|
||||
# 批量处理
|
||||
total, success = ocr_service.batch_process()
|
||||
if total == 0:
|
||||
logger.warning("没有找到需要处理的图片")
|
||||
elif success == 0:
|
||||
logger.warning("OCR处理没有成功处理任何新文件")
|
||||
excel_file = None # 批量处理不返回具体文件
|
||||
|
||||
# 2. Excel处理
|
||||
if excel_file:
|
||||
# 处理指定的Excel文件
|
||||
result = order_service.process_excel(excel_file)
|
||||
else:
|
||||
# 处理最新的Excel文件
|
||||
result = order_service.process_excel()
|
||||
|
||||
if not result:
|
||||
logger.error("Excel处理失败")
|
||||
return 1
|
||||
|
||||
# 3. 合并采购单(可选)
|
||||
if args.merge:
|
||||
result = order_service.merge_all_purchase_orders()
|
||||
if not result:
|
||||
logger.warning("合并采购单失败")
|
||||
# 不影响整体流程,继续执行
|
||||
|
||||
return 0
|
||||
|
||||
elif args.command == 'tobacco':
|
||||
# 烟草订单处理
|
||||
tobacco_service = TobaccoService(config)
|
||||
if args.input:
|
||||
# 处理指定文件
|
||||
logger.info(f"开始处理烟草订单,输入文件: {args.input}")
|
||||
result = tobacco_service.process_tobacco_order(args.input)
|
||||
else:
|
||||
# 处理最新文件
|
||||
logger.info("开始烟草公司订单处理")
|
||||
result = tobacco_service.process_tobacco_order()
|
||||
|
||||
# 检查结果是否为None
|
||||
if result is None:
|
||||
logger.error("烟草订单处理失败")
|
||||
return 1
|
||||
else:
|
||||
logger.info(f"烟草订单处理成功,输出文件: {result}")
|
||||
# 确保result是绝对路径
|
||||
if not os.path.isabs(result):
|
||||
result = os.path.abspath(result)
|
||||
logger.info(f"烟草订单处理完成,绝对路径: {result}")
|
||||
return 0
|
||||
|
||||
else:
|
||||
logger.error(f"未知命令: {args.command}")
|
||||
return 1
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"执行过程中发生错误: {e}", exc_info=True)
|
||||
return 1
|
||||
finally:
|
||||
# 关闭所有日志记录器
|
||||
close_all_loggers()
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
52
启动器.py
52
启动器.py
@ -35,7 +35,6 @@ from app.core.utils.log_utils import set_log_level
|
||||
# 导入服务类
|
||||
from app.services.ocr_service import OCRService
|
||||
from app.services.order_service import OrderService
|
||||
from app.services.tobacco_service import TobaccoService
|
||||
from app.services.processor_service import ProcessorService
|
||||
|
||||
# 全局变量,用于跟踪任务状态
|
||||
@ -1581,14 +1580,6 @@ def merge_orders_with_status(log_widget, status_bar):
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
def process_tobacco_orders_with_status(log_widget, status_bar):
|
||||
"""处理烟草订单 (已统一走智能识别流程)"""
|
||||
process_excel_file_with_status(log_widget, status_bar)
|
||||
|
||||
def process_rongcheng_yigou_with_status(log_widget, status_bar):
|
||||
"""处理蓉城易购订单 (已统一走智能识别流程)"""
|
||||
process_excel_file_with_status(log_widget, status_bar)
|
||||
|
||||
def process_excel_file_with_status(log_widget, status_bar):
|
||||
"""处理Excel文件"""
|
||||
def run_in_thread():
|
||||
@ -2016,44 +2007,7 @@ def main():
|
||||
px_height=32
|
||||
).pack(side=tk.LEFT, padx=(3, 0))
|
||||
|
||||
# Excel处理区
|
||||
excel_section = tk.LabelFrame(
|
||||
panel_content,
|
||||
text="特殊处理",
|
||||
bg=THEMES[THEME_MODE]["card_bg"],
|
||||
fg=THEMES[THEME_MODE]["fg"],
|
||||
font=("Microsoft YaHei UI", 10, "bold"),
|
||||
relief="flat",
|
||||
borderwidth=0
|
||||
)
|
||||
excel_section.pack(fill=tk.X, pady=(0, 8))
|
||||
|
||||
excel_buttons_frame = tk.Frame(excel_section, bg=THEMES[THEME_MODE]["card_bg"])
|
||||
excel_buttons_frame.pack(fill=tk.X, padx=8, pady=6)
|
||||
|
||||
# Excel按钮行1
|
||||
excel_row1 = tk.Frame(excel_buttons_frame, bg=THEMES[THEME_MODE]["card_bg"])
|
||||
excel_row1.pack(fill=tk.X, pady=3)
|
||||
|
||||
# 蓉城易购
|
||||
create_modern_button(
|
||||
excel_row1,
|
||||
"蓉城易购",
|
||||
lambda: process_rongcheng_yigou_with_status(log_text, status_bar),
|
||||
"primary",
|
||||
px_width=72,
|
||||
px_height=32
|
||||
).pack(side=tk.LEFT, padx=(0, 3))
|
||||
|
||||
# 烟草公司
|
||||
create_modern_button(
|
||||
excel_row1,
|
||||
"烟草公司",
|
||||
lambda: process_tobacco_orders_with_status(log_text, status_bar),
|
||||
"primary",
|
||||
px_width=72,
|
||||
px_height=32
|
||||
).pack(side=tk.LEFT, padx=(3, 0))
|
||||
# Excel处理区 (移除了特殊的蓉城和烟草按钮,现在统一走智能处理)
|
||||
# 列映射向导与模板管理入口已移至右侧系统设置区
|
||||
|
||||
# 工具功能区
|
||||
@ -2763,9 +2717,6 @@ def bind_keyboard_shortcuts(root, log_widget, status_bar):
|
||||
# Ctrl+M - 合并采购单
|
||||
root.bind('<Control-m>', lambda e: merge_orders_with_status(log_widget, status_bar))
|
||||
|
||||
# Ctrl+T - 处理烟草订单
|
||||
root.bind('<Control-t>', lambda e: process_tobacco_orders_with_status(log_widget, status_bar))
|
||||
|
||||
# F5 - 刷新/清除缓存
|
||||
root.bind('<F5>', lambda e: clean_cache(log_widget))
|
||||
|
||||
@ -2794,7 +2745,6 @@ def show_shortcuts_help():
|
||||
Ctrl+B: OCR批量识别
|
||||
Ctrl+P: 完整处理流程
|
||||
Ctrl+M: 合并采购单
|
||||
Ctrl+T: 处理烟草订单
|
||||
F5: 清除处理缓存
|
||||
Esc: 退出程序
|
||||
"""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user