#!/usr/bin/env python # -*- coding: utf-8 -*- """处理结果预览对话框模块""" import os import re import datetime import tkinter as tk from tkinter import messagebox, scrolledtext from .theme import THEMES, get_theme_mode, apply_theme from .ui_widgets import center_window from app.core.utils.file_utils import format_file_size from app.config.settings import ConfigManager TOBACCO_PREVIEW_WINDOW = None def _get_output_dir(): """获取输出目录的绝对路径""" return ConfigManager().get_path('Paths', 'output_folder', fallback='data/output', create=True) def show_result_preview(command, output): """显示处理结果预览""" if "ocr" in command: show_ocr_result_preview(output) elif "excel" in command: show_excel_result_preview(output) elif "merge" in command: show_merge_result_preview(output) elif "pipeline" in command: show_pipeline_result_preview(output) else: messagebox.showinfo("处理完成", f"操作已成功完成!\n请在{_get_output_dir()}目录查看结果。") def show_ocr_result_preview(output): """显示OCR处理结果预览""" files_match = re.search(r'找到 (\d+) 个图片文件,其中 (\d+) 个未处理', output) processed_match = re.search(r'所有图片处理完成, 总计: (\d+), 成功: (\d+)', output) if processed_match: total = int(processed_match.group(1)) success = int(processed_match.group(2)) preview = tk.Toplevel() preview.title("OCR处理结果") preview.geometry("400x300") preview.resizable(False, False) center_window(preview) tk.Label(preview, text="OCR处理完成", font=("Arial", 16, "bold")).pack(pady=10) result_frame = tk.Frame(preview) result_frame.pack(pady=10, fill=tk.BOTH, expand=True) tk.Label(result_frame, text=f"总共处理: {total} 个文件", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text=f"成功处理: {success} 个文件", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text=f"失败数量: {total - success} 个文件", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) if success == total: result_text = "全部处理成功!" result_color = "#28a745" elif success > total * 0.8: result_text = "大部分处理成功。" result_color = "#ffc107" else: result_text = "处理失败较多,请检查日志。" result_color = "#dc3545" tk.Label(result_frame, text=result_text, font=("Arial", 12, "bold"), fg=result_color).pack(pady=10) button_frame = tk.Frame(preview) button_frame.pack(pady=10) tk.Button(button_frame, text="查看输出文件", command=lambda: os.startfile(_get_output_dir())).pack(side=tk.LEFT, padx=10) tk.Button(button_frame, text="关闭", command=preview.destroy).pack(side=tk.LEFT, padx=10) else: messagebox.showinfo("OCR处理完成", f"OCR处理已完成,请在{_get_output_dir()}目录查看结果。") def show_excel_result_preview(output): """显示Excel处理结果预览""" extract_match = re.search(r'提取到 (\d+) 个商品信息', output) file_match = re.search(r'采购单已保存到: (.+?)(?:\n|$)', output) if extract_match and file_match: products_count = int(extract_match.group(1)) output_file = file_match.group(1) preview = tk.Toplevel() preview.title("Excel处理结果") preview.geometry("450x320") preview.resizable(False, False) center_window(preview) tk.Label(preview, text="Excel处理完成", font=("Arial", 16, "bold")).pack(pady=10) result_frame = tk.Frame(preview) result_frame.pack(pady=10, fill=tk.BOTH, expand=True) tk.Label(result_frame, text=f"提取商品数量: {products_count} 个", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text=f"输出文件: {os.path.basename(output_file)}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text="采购单已成功生成!", font=("Arial", 12, "bold"), fg="#28a745").pack(pady=10) file_frame = tk.Frame(result_frame, relief=tk.GROOVE, borderwidth=1) file_frame.pack(fill=tk.X, padx=15, pady=5) tk.Label(file_frame, text="文件信息", font=("Arial", 10, "bold")).pack(anchor=tk.W, padx=10, pady=5) try: file_size = os.path.getsize(output_file) file_time = datetime.datetime.fromtimestamp(os.path.getmtime(output_file)) size_text = format_file_size(file_size) tk.Label(file_frame, text=f"文件大小: {size_text}", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2) tk.Label(file_frame, text=f"创建时间: {file_time.strftime('%Y-%m-%d %H:%M:%S')}", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2) except Exception: tk.Label(file_frame, text="无法获取文件信息", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2) button_frame = tk.Frame(preview) button_frame.pack(pady=10) tk.Button(button_frame, text="打开文件", command=lambda: os.startfile(output_file)).pack(side=tk.LEFT, padx=5) tk.Button(button_frame, text="打开所在文件夹", command=lambda: os.startfile(os.path.dirname(output_file))).pack(side=tk.LEFT, padx=5) tk.Button(button_frame, text="关闭", command=preview.destroy).pack(side=tk.LEFT, padx=5) else: messagebox.showinfo("Excel处理完成", f"Excel处理已完成,请在{_get_output_dir()}目录查看结果。") def show_merge_result_preview(output): """显示合并结果预览""" merged_match = re.search(r'合并了 (\d+) 个采购单', output) product_match = re.search(r'共处理 (\d+) 个商品', output) output_match = re.search(r'已保存到: (.+?)(?:\n|$)', output) if merged_match and output_match: merged_count = int(merged_match.group(1)) product_count = int(product_match.group(1)) if product_match else 0 output_file = output_match.group(1) preview = tk.Toplevel() preview.title("采购单合并结果") preview.geometry("450x300") preview.resizable(False, False) apply_theme(preview) tk.Label(preview, text="采购单合并完成", font=("Arial", 16, "bold")).pack(pady=10) result_frame = tk.Frame(preview) result_frame.pack(pady=10, fill=tk.BOTH, expand=True) tk.Label(result_frame, text=f"合并采购单数量: {merged_count} 个", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text=f"处理商品数量: {product_count} 个", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text=f"输出文件: {os.path.basename(output_file)}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) theme = THEMES[get_theme_mode()] tk.Label(result_frame, text="采购单已成功合并!", font=("Arial", 12, "bold"), fg=theme["success"]).pack(pady=10) button_frame = tk.Frame(preview) button_frame.pack(pady=10) tk.Button(button_frame, text="打开文件", command=lambda: os.startfile(output_file)).pack(side=tk.LEFT, padx=10) tk.Button(button_frame, text="打开所在文件夹", command=lambda: os.startfile(os.path.dirname(output_file))).pack(side=tk.LEFT, padx=10) tk.Button(button_frame, text="关闭", command=preview.destroy).pack(side=tk.LEFT, padx=10) else: messagebox.showinfo("采购单合并完成", f"采购单合并已完成,请在{_get_output_dir()}目录查看结果。") def show_pipeline_result_preview(output): """显示完整流程结果预览""" ocr_match = re.search(r'所有图片处理完成, 总计: (\d+), 成功: (\d+)', output) excel_match = re.search(r'提取到 (\d+) 个商品信息', output) output_file_match = re.search(r'采购单已保存到: (.+?)(?:\n|$)', output) preview = tk.Toplevel() preview.title("完整流程处理结果") preview.geometry("500x400") preview.resizable(False, False) center_window(preview) tk.Label(preview, text="完整处理流程已完成", font=("Arial", 16, "bold")).pack(pady=10) no_files_match = re.search(r'未找到可合并的文件', output) if no_files_match: tk.Label(preview, text="未找到可合并的文件,但其他步骤已成功执行", font=("Arial", 12)).pack(pady=0) result_frame = tk.Frame(preview) result_frame.pack(pady=10, fill=tk.BOTH, expand=True) result_text = scrolledtext.ScrolledText(result_frame, wrap=tk.WORD, height=15, width=60) result_text.pack(fill=tk.BOTH, expand=True, padx=15, pady=5) result_text.configure(state=tk.NORMAL) result_text.insert(tk.END, "===== 流程执行结果 =====\n\n", "title") result_text.insert(tk.END, "步骤1: OCR识别\n", "step") if ocr_match: total = int(ocr_match.group(1)) success = int(ocr_match.group(2)) result_text.insert(tk.END, f" 处理图片: {total} 个\n", "info") result_text.insert(tk.END, f" 成功识别: {success} 个\n", "info") if success == total: result_text.insert(tk.END, " 结果: 全部识别成功\n", "success") else: result_text.insert(tk.END, f" 结果: 部分识别成功 ({success}/{total})\n", "warning") else: result_text.insert(tk.END, " 结果: 无OCR处理或处理信息不完整\n", "warning") result_text.insert(tk.END, "\n步骤2: Excel处理\n", "step") if excel_match: products = int(excel_match.group(1)) result_text.insert(tk.END, f" 提取商品: {products} 个\n", "info") result_text.insert(tk.END, " 结果: 成功生成采购单\n", "success") if output_file_match: output_file = output_file_match.group(1) result_text.insert(tk.END, f" 输出文件: {os.path.basename(output_file)}\n", "info") else: result_text.insert(tk.END, " 结果: 无Excel处理或处理信息不完整\n", "warning") result_text.insert(tk.END, "\n===== 整体评估 =====\n", "title") has_errors = "错误" in output or "失败" in output no_files_match2 = re.search(r'未找到采购单文件', output) single_file_match = re.search(r'只有1个采购单文件', output) if no_files_match2: result_text.insert(tk.END, "没有找到可合并的文件,但处理流程已成功完成。\n", "warning") result_text.insert(tk.END, "可以选择打开Excel文件或查看输出文件夹。\n", "info") elif single_file_match: result_text.insert(tk.END, "只有一个采购单文件,无需合并,处理流程已成功完成。\n", "warning") result_text.insert(tk.END, "可以选择打开生成的Excel文件。\n", "info") elif ocr_match and excel_match and not has_errors: result_text.insert(tk.END, "流程完整执行成功!\n", "success") elif ocr_match or excel_match: result_text.insert(tk.END, "流程部分执行成功,请检查日志获取详情。\n", "warning") else: result_text.insert(tk.END, "流程执行可能存在问题,请查看详细日志。\n", "error") result_text.tag_configure("title", font=("Arial", 12, "bold")) result_text.tag_configure("step", font=("Arial", 11, "bold")) result_text.tag_configure("info", font=("Arial", 10)) result_text.tag_configure("success", font=("Arial", 10, "bold"), foreground="#28a745") result_text.tag_configure("warning", font=("Arial", 10, "bold"), foreground="#ffc107") result_text.tag_configure("error", font=("Arial", 10, "bold"), foreground="#dc3545") result_text.configure(state=tk.DISABLED) button_frame = tk.Frame(preview) button_frame.pack(pady=10) if output_file_match: output_file = output_file_match.group(1) tk.Button(button_frame, text="打开Excel文件", command=lambda: os.startfile(output_file)).pack(side=tk.LEFT, padx=10) else: if excel_match or no_files_match or single_file_match: output_dir = _get_output_dir() excel_files = [f for f in os.listdir(output_dir) if f.startswith('采购单_') and (f.endswith('.xls') or f.endswith('.xlsx'))] if excel_files: excel_files.sort(key=lambda x: os.path.getmtime(os.path.join(output_dir, x)), reverse=True) latest_file = os.path.join(output_dir, excel_files[0]) tk.Button(button_frame, text="打开最新Excel文件", command=lambda: os.startfile(latest_file)).pack(side=tk.LEFT, padx=10) tk.Button(button_frame, text="查看输出文件夹", command=lambda: os.startfile(_get_output_dir())).pack(side=tk.LEFT, padx=10) tk.Button(button_frame, text="关闭", command=preview.destroy).pack(side=tk.LEFT, padx=10) def show_tobacco_result_preview(returncode, output): """显示烟草订单处理结果预览""" global TOBACCO_PREVIEW_WINDOW if returncode != 0: return try: try: if TOBACCO_PREVIEW_WINDOW and TOBACCO_PREVIEW_WINDOW.winfo_exists(): TOBACCO_PREVIEW_WINDOW.lift() return except Exception: TOBACCO_PREVIEW_WINDOW = None result_file = None order_time = "(未知)" total_amount = "(未知)" items_count = 0 abs_path_match = re.search(r'烟草订单处理完成,绝对路径: (.+)(?:\n|$)', output) if abs_path_match: result_file = abs_path_match.group(1).strip() for line in output.split('\n'): if "烟草公司订单处理成功" in line and "订单时间" in line: time_match = re.search(r'订单时间: ([^,]+)', line) amount_match = re.search(r'总金额: ([^,]+)', line) items_match = re.search(r'处理条目: (\d+)', line) if time_match: order_time = time_match.group(1).strip() if amount_match: total_amount = amount_match.group(1).strip() if items_match: items_count = int(items_match.group(1).strip()) if not result_file or not os.path.exists(result_file): default_path = os.path.join(_get_output_dir(), "银豹采购单_烟草公司.xls") if os.path.exists(default_path): result_file = default_path preview = tk.Toplevel() preview.title("烟草订单处理结果") preview.geometry("450x320") preview.resizable(False, False) TOBACCO_PREVIEW_WINDOW = preview def _close_preview(): global TOBACCO_PREVIEW_WINDOW TOBACCO_PREVIEW_WINDOW = None try: preview.destroy() except Exception: pass preview.protocol("WM_DELETE_WINDOW", _close_preview) center_window(preview) tk.Label(preview, text="烟草订单处理完成", font=("Arial", 16, "bold")).pack(pady=10) result_frame = tk.Frame(preview) result_frame.pack(pady=10, fill=tk.BOTH, expand=True) tk.Label(result_frame, text=f"订单时间: {order_time}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text=f"订单总金额: {total_amount}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text=f"处理商品数量: {items_count} 个", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) if result_file and os.path.exists(result_file): tk.Label(result_frame, text=f"输出文件: {os.path.basename(result_file)}", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text="银豹采购单已成功生成!", font=("Arial", 12, "bold"), fg="#28a745").pack(pady=10) file_frame = tk.Frame(result_frame, relief=tk.GROOVE, borderwidth=1) file_frame.pack(fill=tk.X, padx=15, pady=5) tk.Label(file_frame, text="文件信息", font=("Arial", 10, "bold")).pack(anchor=tk.W, padx=10, pady=5) try: file_size = os.path.getsize(result_file) file_time = datetime.datetime.fromtimestamp(os.path.getmtime(result_file)) size_text = format_file_size(file_size) tk.Label(file_frame, text=f"文件大小: {size_text}", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2) tk.Label(file_frame, text=f"创建时间: {file_time.strftime('%Y-%m-%d %H:%M:%S')}", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2) except Exception: tk.Label(file_frame, text="无法获取文件信息", font=("Arial", 10)).pack(anchor=tk.W, padx=10, pady=2) button_frame = tk.Frame(preview) button_frame.pack(pady=10) tk.Button(button_frame, text="打开文件", command=lambda: os.startfile(result_file)).pack(side=tk.LEFT, padx=5) tk.Button(button_frame, text="打开所在文件夹", command=lambda: os.startfile(os.path.dirname(result_file))).pack(side=tk.LEFT, padx=5) tk.Button(button_frame, text="关闭", command=_close_preview).pack(side=tk.LEFT, padx=5) else: tk.Label(result_frame, text="未找到输出文件", font=("Arial", 12)).pack(anchor=tk.W, padx=20, pady=5) tk.Label(result_frame, text=f"请检查{_get_output_dir()}目录", font=("Arial", 12, "bold"), fg="#dc3545").pack(pady=10) button_frame = tk.Frame(preview) button_frame.pack(pady=10) tk.Button(button_frame, text="打开输出目录", command=lambda: os.startfile(_get_output_dir())).pack(side=tk.LEFT, padx=5) tk.Button(button_frame, text="关闭", command=_close_preview).pack(side=tk.LEFT, padx=5) preview.lift() preview.attributes('-topmost', True) preview.after_idle(lambda: preview.attributes('-topmost', False)) except Exception as e: messagebox.showerror( "处理异常", f"显示预览时发生错误: {e}\n请检查日志了解详细信息。" )