From 26835e265afb4bbda108181180b83c5132b6450a Mon Sep 17 00:00:00 2001 From: houhuan Date: Mon, 30 Mar 2026 13:38:05 +0800 Subject: [PATCH] refactor: unify special suppliers processing into a single intelligent flow --- app/services/order_service.py | 45 ++++++++++------- 启动器.py | 95 ++--------------------------------- 2 files changed, 31 insertions(+), 109 deletions(-) diff --git a/app/services/order_service.py b/app/services/order_service.py index a67e6d9..7d21e1a 100644 --- a/app/services/order_service.py +++ b/app/services/order_service.py @@ -84,15 +84,35 @@ class OrderService: return self.excel_processor.process_specific_file(file_path, progress_cb=progress_cb) def _check_special_preprocess(self, file_path: str) -> Optional[str]: - """检查并执行特殊的预处理""" + """检查并执行特殊的预处理(支持杨碧月、烟草公司、蓉城易购)""" try: from app.core.utils.file_utils import smart_read_excel import pandas as pd + import re - # 仅读取前几行进行识别 + # 仅读取前 50 行进行智能识别 df_head = smart_read_excel(file_path, nrows=50) + df_str = df_head.astype(str) - # 1. 检查“杨碧月” + # 1. 识别:烟草公司 (Tobacco) + # 特征:通常包含“烟草”、“卷烟”等关键字,且有特定的表头结构 + is_tobacco = df_str.apply(lambda x: x.str.contains('烟草|卷烟|营销中心')).any().any() + if is_tobacco: + logger.info("识别到烟草公司订单,执行专用预处理...") + from .tobacco_service import TobaccoService + tobacco_svc = TobaccoService(self.config) + return tobacco_svc.process_tobacco_order(file_path) + + # 2. 识别:蓉城易购 (Rongcheng Yigou) + # 特征:通常文件名包含“订单”或内容包含“订购单位”等 + is_rongcheng = df_str.apply(lambda x: x.str.contains('蓉城易购|订购单位|出库小计')).any().any() + if is_rongcheng: + logger.info("识别到蓉城易购订单,执行专用预处理...") + from .special_suppliers_service import SpecialSuppliersService + special_svc = SpecialSuppliersService(self.config) + return special_svc.process_rongcheng_yigou(file_path) + + # 3. 识别:杨碧月 (Yang Biyue) handler_col = None for col in df_head.columns: if '经手人' in str(col): @@ -100,38 +120,27 @@ class OrderService: break if handler_col is not None and df_head[handler_col].astype(str).str.contains('杨碧月').any(): - logger.info("识别到杨碧月订单,执行预处理...") - # 重新读取完整数据 + logger.info("识别到杨碧月订单,执行通用预处理...") df = smart_read_excel(file_path) column_map = { '商品条码': '商品条码', '商品名称': '商品名称', '规格': '规格', '单位': '单位', '数量': '数量', '单价': '单价', '金额': '金额' } found_cols = {} - # 优先级排序,确保更精确的匹配 for target_zh, std_name in column_map.items(): for col in df.columns: col_str = str(col) - if target_zh == col_str: # 精确匹配优先 - found_cols[col] = std_name - break + if target_zh == col_str: found_cols[col] = std_name; break if std_name not in found_cols.values(): for col in df.columns: - col_str = str(col) - if target_zh in col_str: # 模糊匹配 - found_cols[col] = std_name - break + if target_zh in str(col): found_cols[col] = std_name; break if len(found_cols) >= 4: df_clean = df[list(found_cols.keys())].copy() df_clean = df_clean.rename(columns=found_cols) - - # 确保数量和价格是数值 - # 这里的列名已经改回中文了 for c in ['数量', '单价', '金额']: if c in df_clean.columns: df_clean[c] = pd.to_numeric(df_clean[c], errors='coerce').fillna(0) - df_clean = df_clean.dropna(subset=['商品条码']) out_dir = os.path.dirname(file_path) final_path = os.path.join(out_dir, "预处理之后.xlsx") @@ -139,7 +148,7 @@ class OrderService: return final_path except Exception as e: - logger.warning(f"预处理识别失败: {e}") + logger.warning(f"智能预处理识别失败: {e}") return None def get_purchase_orders(self) -> List[str]: diff --git a/启动器.py b/启动器.py index 92a7214..1c57cd7 100644 --- a/启动器.py +++ b/启动器.py @@ -1582,99 +1582,12 @@ def merge_orders_with_status(log_widget, status_bar): thread.start() def process_tobacco_orders_with_status(log_widget, status_bar): - """处理烟草订单""" - def run_in_thread(): - try: - reporter = ProgressReporter(status_bar) - reporter.running() - reporter.set("正在处理烟草订单...", 10) - add_to_log(log_widget, "开始处理烟草订单\n", "info") - - init_gui_logger(log_widget) - - # 创建烟草服务实例 - config_manager = ConfigManager() - tobacco_service = TobaccoService(config_manager) - - # 执行烟草订单处理 - result = tobacco_service.process_tobacco_order() - - if result: - add_to_log(log_widget, "烟草订单处理完成\n", "success") - try: - add_recent_file(result) - except Exception: - pass - pass - else: - add_to_log(log_widget, "烟草订单处理失败\n", "error") - - except Exception as e: - add_to_log(log_widget, f"烟草订单处理出错: {str(e)}\n", "error") - finally: - dispose_gui_logger() - reporter.done() - - # 在新线程中运行 - thread = Thread(target=run_in_thread) - thread.daemon = True - thread.start() - - + """处理烟草订单 (已统一走智能识别流程)""" + process_excel_file_with_status(log_widget, status_bar) def process_rongcheng_yigou_with_status(log_widget, status_bar): - def run_in_thread(): - try: - reporter = ProgressReporter(status_bar) - reporter.running() - add_to_log(log_widget, "开始处理蓉城易购\n", "info") - - s = load_user_settings() - out_dir = os.path.abspath(s.get('output_folder', 'data/output')) - candidates = [] - if os.path.exists(out_dir): - for f in os.listdir(out_dir): - if re.match(r'^订单\d+\.xlsx$', f.lower()): - p = os.path.join(out_dir, f) - candidates.append((p, os.path.getmtime(p))) - - if not candidates: - add_to_log(log_widget, "未在输出目录找到蓉城易购订单文件\n", "warning") - reporter.done() - return - - candidates.sort(key=lambda x: x[1], reverse=True) - src_path = candidates[0][0] - - from app.services.special_suppliers_service import SpecialSuppliersService - service = SpecialSuppliersService(ConfigManager()) - - result = service.process_rongcheng_yigou( - src_path, - progress_cb=lambda p, m: (reporter.set(m, p), add_to_log(log_widget, f"{m}\n", "info")) - ) - - if result: - add_to_log(log_widget, f"处理完成: {result}\n", "success") - add_recent_file(result) - try: - validate_unit_price_against_item_data(result, log_widget) - except Exception: pass - open_result_directory_from_settings() - reporter.set("处理完成", 100) - else: - add_to_log(log_widget, "处理失败\n", "error") - except Exception as e: - add_to_log(log_widget, f"处理出错: {str(e)}\n", "error") - finally: - reporter.done() - - thread = Thread(target=run_in_thread) - thread.daemon = True - thread.start() - thread = Thread(target=run_in_thread) - thread.daemon = True - thread.start() + """处理蓉城易购订单 (已统一走智能识别流程)""" + process_excel_file_with_status(log_widget, status_bar) def process_excel_file_with_status(log_widget, status_bar): """处理Excel文件"""