feat: support multiple managers in DiscreteMaterialPlanCleaner
- Add get_materials_to_delete_by_managers() function in db/materials_to_delete.py - Supports querying by single manager, multiple managers, or all managers - Uses IN clause for multi-manager queries - Refactor DiscreteMaterialPlanCleaner to accept manager_names parameter - Accepts str, List[str], or None (for all managers) - Automatically normalizes parameter types in __init__ - Updates preload_data() with appropriate log messages Co-Authored-By: Claude (glm-5) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
从数据库查询指定负责人需要删除的物料编码
|
从数据库查询指定负责人需要删除的物料编码
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import List, Dict, Any
|
from typing import List, Dict, Any, Optional
|
||||||
from db.connection import get_connection
|
from db.connection import get_connection
|
||||||
|
|
||||||
|
|
||||||
@@ -49,6 +49,46 @@ def get_all_materials_to_delete() -> List[Dict[str, Any]]:
|
|||||||
return results
|
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:
|
def should_delete_material(manager_name: str, material_code: str) -> bool:
|
||||||
"""
|
"""
|
||||||
检查指定物料编码是否需要删除
|
检查指定物料编码是否需要删除
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Union, List, Optional
|
||||||
from playwright.sync_api import sync_playwright, TimeoutError
|
from playwright.sync_api import sync_playwright, TimeoutError
|
||||||
|
|
||||||
# 统一顶部导入
|
# 统一顶部导入
|
||||||
@@ -19,7 +20,7 @@ from db.production_order_query import (
|
|||||||
read_production_ids,
|
read_production_ids,
|
||||||
query_production_order_numbers,
|
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(
|
logging.basicConfig(
|
||||||
@@ -33,12 +34,27 @@ logger = logging.getLogger(__name__)
|
|||||||
class DiscreteMaterialPlanCleaner:
|
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.username = username
|
||||||
self.password = password
|
self.password = password
|
||||||
self.manager_name = manager_name
|
|
||||||
self.headless = headless
|
self.headless = headless
|
||||||
self.verbose = verbose
|
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)$
|
# 核心优化:使用 set 存储待删除编码,查询复杂度为 $O(1)$
|
||||||
self.to_delete_set = set()
|
self.to_delete_set = set()
|
||||||
|
|
||||||
@@ -71,9 +87,13 @@ class DiscreteMaterialPlanCleaner:
|
|||||||
|
|
||||||
def preload_data(self):
|
def preload_data(self):
|
||||||
"""批量预取数据库数据"""
|
"""批量预取数据库数据"""
|
||||||
self._log(f"正在从数据库提取负责人 [{self.manager_name}] 的待删除物料清单...")
|
if self.manager_names is None:
|
||||||
# 假设返回的是 material_code 列表
|
self._log("正在从数据库提取所有负责人的待删除物料清单...")
|
||||||
raw_list = get_materials_to_delete(self.manager_name)
|
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.to_delete_set = set(raw_list)
|
||||||
self._log(f"预加载完成,共计 {len(self.to_delete_set)} 条不合规物料编码。")
|
self._log(f"预加载完成,共计 {len(self.to_delete_set)} 条不合规物料编码。")
|
||||||
|
|
||||||
@@ -305,7 +325,7 @@ def main():
|
|||||||
cleaner = DiscreteMaterialPlanCleaner(
|
cleaner = DiscreteMaterialPlanCleaner(
|
||||||
username="BLDpengqiangqiang",
|
username="BLDpengqiangqiang",
|
||||||
password="your_password_here",
|
password="your_password_here",
|
||||||
manager_name="彭羽",
|
manager_names="彭羽", # 支持字符串、列表或 None
|
||||||
headless=False,
|
headless=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user