diff --git a/db/materials_to_delete.py b/db/materials_to_delete.py index 2d7e86a..c12dd0d 100644 --- a/db/materials_to_delete.py +++ b/db/materials_to_delete.py @@ -3,7 +3,7 @@ 从数据库查询指定负责人需要删除的物料编码 """ -from typing import List, Dict, Any +from typing import List, Dict, Any, Optional from db.connection import get_connection @@ -49,6 +49,46 @@ def get_all_materials_to_delete() -> List[Dict[str, Any]]: return results +def get_materials_to_delete_by_managers( + manager_names: Optional[List[str]] = None, +) -> List[str]: + """ + 根据负责人列表查询待删除物料编码 + + Args: + manager_names: 负责人姓名列表 + - None 或空列表:返回所有物料编码 + - 有值:返回指定负责人的物料编码 + + Returns: + 物料编码列表 + """ + if not manager_names: + # 查询所有物料编码 + query = """ + SELECT [MaterialCode] + FROM [dbo].[MaterialsToBeDeleted] + WHERE [MaterialCode] IS NOT NULL + """ + with get_connection() as conn: + results = conn.execute_query(query) + material_codes = [row["MaterialCode"] for row in results if row["MaterialCode"]] + return material_codes + else: + # 使用 IN 子句查询多个负责人 + placeholders = ", ".join(["?"] * len(manager_names)) + query = f""" + SELECT [MaterialCode] + FROM [dbo].[MaterialsToBeDeleted] + WHERE [MaterialCode] IS NOT NULL + AND [ManagerName] IN ({placeholders}) + """ + with get_connection() as conn: + results = conn.execute_query(query, tuple(manager_names)) + material_codes = [row["MaterialCode"] for row in results if row["MaterialCode"]] + return material_codes + + def should_delete_material(manager_name: str, material_code: str) -> bool: """ 检查指定物料编码是否需要删除 diff --git a/utils/discrete_material_plan_cleaner.py b/utils/discrete_material_plan_cleaner.py index 664bc21..f1d3e7b 100644 --- a/utils/discrete_material_plan_cleaner.py +++ b/utils/discrete_material_plan_cleaner.py @@ -11,6 +11,7 @@ import os import re import time import logging +from typing import Union, List, Optional from playwright.sync_api import sync_playwright, TimeoutError # 统一顶部导入 @@ -19,7 +20,7 @@ from db.production_order_query import ( read_production_ids, query_production_order_numbers, ) -from db.materials_to_delete import get_materials_to_delete +from db.materials_to_delete import get_materials_to_delete_by_managers # --- 日志配置 --- logging.basicConfig( @@ -33,12 +34,27 @@ logger = logging.getLogger(__name__) class DiscreteMaterialPlanCleaner: """离散备料计划维护数据清理器""" - def __init__(self, username, password, manager_name, headless=False, verbose=True): + def __init__( + self, + username, + password, + manager_names: Union[str, List[str], None] = None, + headless=False, + verbose=True, + ): self.username = username self.password = password - self.manager_name = manager_name self.headless = headless self.verbose = verbose + + # 参数规范化:支持 str、List[str]、None + if manager_names is None: + self.manager_names = None # 表示全部 + elif isinstance(manager_names, str): + self.manager_names = [manager_names] if manager_names.strip() else None + else: + self.manager_names = manager_names if manager_names else None + # 核心优化:使用 set 存储待删除编码,查询复杂度为 $O(1)$ self.to_delete_set = set() @@ -71,9 +87,13 @@ class DiscreteMaterialPlanCleaner: def preload_data(self): """批量预取数据库数据""" - self._log(f"正在从数据库提取负责人 [{self.manager_name}] 的待删除物料清单...") - # 假设返回的是 material_code 列表 - raw_list = get_materials_to_delete(self.manager_name) + if self.manager_names is None: + self._log("正在从数据库提取所有负责人的待删除物料清单...") + else: + names_str = "、".join(self.manager_names) + self._log(f"正在从数据库提取负责人 [{names_str}] 的待删除物料清单...") + + raw_list = get_materials_to_delete_by_managers(self.manager_names) self.to_delete_set = set(raw_list) self._log(f"预加载完成,共计 {len(self.to_delete_set)} 条不合规物料编码。") @@ -305,7 +325,7 @@ def main(): cleaner = DiscreteMaterialPlanCleaner( username="BLDpengqiangqiang", password="your_password_here", - manager_name="彭羽", + manager_names="彭羽", # 支持字符串、列表或 None headless=False, )