orc-order-v2/run.py

330 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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_logger
from app.services.ocr_service import OCRService
from app.services.order_service import OrderService
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='子命令')
# 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, help='批处理大小')
ocr_parser.add_argument('--max-workers', type=int, 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='输入图片文件路径,如果不指定则处理所有图片')
return parser
def run_ocr(ocr_service: OCRService, args) -> bool:
"""
运行OCR识别
Args:
ocr_service: OCR服务
args: 命令行参数
Returns:
处理是否成功
"""
if args.input:
if not os.path.exists(args.input):
logger.error(f"输入文件不存在: {args.input}")
return False
if not ocr_service.validate_image(args.input):
logger.error(f"输入文件无效: {args.input}")
return False
logger.info(f"处理单个图片: {args.input}")
result = ocr_service.process_image(args.input)
if result:
logger.info(f"OCR处理成功输出文件: {result}")
return True
else:
logger.error("OCR处理失败")
return False
elif args.batch:
logger.info("批量处理模式")
total, success = ocr_service.process_images_batch(args.batch_size, args.max_workers)
if total == 0:
logger.warning("没有找到需要处理的文件")
return False
logger.info(f"批量处理完成,总计: {total},成功: {success}")
return success > 0
else:
# 列出未处理的文件
files = ocr_service.get_unprocessed_images()
if not files:
logger.info("没有未处理的文件")
return True
logger.info(f"未处理的文件 ({len(files)}):")
for file in files:
logger.info(f" {file}")
return True
def run_excel(order_service: OrderService, args) -> bool:
"""
运行Excel处理
Args:
order_service: 订单服务
args: 命令行参数
Returns:
处理是否成功
"""
if args.input:
if not os.path.exists(args.input):
logger.error(f"输入文件不存在: {args.input}")
return False
logger.info(f"处理Excel文件: {args.input}")
result = order_service.process_excel(args.input)
else:
latest_file = order_service.get_latest_excel()
if not latest_file:
logger.warning("未找到可处理的Excel文件")
return False
logger.info(f"处理最新的Excel文件: {latest_file}")
result = order_service.process_excel(latest_file)
if result:
logger.info(f"Excel处理成功输出文件: {result}")
return True
else:
logger.error("Excel处理失败")
return False
def run_merge(order_service: OrderService, args) -> bool:
"""
运行订单合并
Args:
order_service: 订单服务
args: 命令行参数
Returns:
处理是否成功
"""
if args.input:
# 分割输入文件列表
file_paths = [path.strip() for path in args.input.split(',')]
# 检查文件是否存在
for path in file_paths:
if not os.path.exists(path):
logger.error(f"输入文件不存在: {path}")
return False
logger.info(f"合并指定的采购单文件: {file_paths}")
result = order_service.merge_orders(file_paths)
else:
# 获取所有采购单文件
file_paths = order_service.get_purchase_orders()
if not file_paths:
logger.warning("未找到采购单文件")
return False
logger.info(f"合并所有采购单文件: {len(file_paths)}")
result = order_service.merge_orders()
if result:
logger.info(f"订单合并成功,输出文件: {result}")
return True
else:
logger.error("订单合并失败")
return False
def run_pipeline(ocr_service: OCRService, order_service: OrderService, args) -> bool:
"""
运行完整流程
Args:
ocr_service: OCR服务
order_service: 订单服务
args: 命令行参数
Returns:
处理是否成功
"""
# 1. OCR识别
logger.info("=== 流程步骤 1: OCR识别 ===")
if args.input:
if not os.path.exists(args.input):
logger.error(f"输入文件不存在: {args.input}")
return False
if not ocr_service.validate_image(args.input):
logger.error(f"输入文件无效: {args.input}")
return False
logger.info(f"处理单个图片: {args.input}")
ocr_result = ocr_service.process_image(args.input)
if not ocr_result:
logger.error("OCR处理失败")
return False
logger.info(f"OCR处理成功输出文件: {ocr_result}")
else:
# 批量处理所有图片
logger.info("批量处理所有图片")
total, success = ocr_service.process_images_batch()
if total == 0:
logger.warning("没有找到需要处理的图片")
# 继续下一步因为可能已经有处理好的Excel文件
elif success == 0:
logger.error("OCR处理失败没有成功处理的图片")
return False
else:
logger.info(f"OCR处理完成总计: {total},成功: {success}")
# 2. Excel处理
logger.info("=== 流程步骤 2: Excel处理 ===")
latest_file = order_service.get_latest_excel()
if not latest_file:
logger.warning("未找到可处理的Excel文件")
return False
logger.info(f"处理最新的Excel文件: {latest_file}")
excel_result = order_service.process_excel(latest_file)
if not excel_result:
logger.error("Excel处理失败")
return False
logger.info(f"Excel处理成功输出文件: {excel_result}")
# 3. 订单合并
logger.info("=== 流程步骤 3: 订单合并 ===")
# 获取所有采购单文件
file_paths = order_service.get_purchase_orders()
if not file_paths:
logger.warning("未找到采购单文件,跳过合并步骤")
logger.info("=== 完整流程处理成功(未执行合并步骤)===")
# 非错误状态,继续执行
return True
# 有文件需要合并
logger.info(f"发现 {len(file_paths)} 个采购单文件")
if len(file_paths) == 1:
logger.warning(f"只有1个采购单文件 {file_paths[0]},无需合并")
logger.info("=== 完整流程处理成功(只有一个文件,跳过合并)===")
return True
logger.info(f"合并所有采购单文件: {len(file_paths)}")
merge_result = order_service.merge_orders()
if not merge_result:
logger.error("订单合并失败")
return False
logger.info(f"订单合并成功,输出文件: {merge_result}")
logger.info("=== 完整流程处理成功 ===")
return True
def main(args: Optional[List[str]] = None) -> int:
"""
主函数
Args:
args: 命令行参数如果为None则使用sys.argv
Returns:
退出状态码
"""
parser = create_parser()
parsed_args = parser.parse_args(args)
if parsed_args.command is None:
parser.print_help()
return 1
try:
# 创建配置管理器
config = ConfigManager(parsed_args.config) if parsed_args.config else ConfigManager()
# 创建服务
ocr_service = OCRService(config)
order_service = OrderService(config)
# 根据命令执行不同功能
if parsed_args.command == 'ocr':
success = run_ocr(ocr_service, parsed_args)
elif parsed_args.command == 'excel':
success = run_excel(order_service, parsed_args)
elif parsed_args.command == 'merge':
success = run_merge(order_service, parsed_args)
elif parsed_args.command == 'pipeline':
success = run_pipeline(ocr_service, order_service, parsed_args)
else:
parser.print_help()
return 1
return 0 if success else 1
except Exception as e:
logger.error(f"执行过程中发生错误: {e}")
import traceback
logger.error(traceback.format_exc())
return 1
finally:
# 关闭日志
close_logger(__name__)
if __name__ == '__main__':
sys.exit(main())