From c176063bfab440da3e1d98995d5af74a6b15e317 Mon Sep 17 00:00:00 2001 From: Misaka_Company Date: Fri, 23 Jan 2026 16:50:14 +0800 Subject: [PATCH] feat: add material matching logic for discrete material plan cleaner - Add db/materials_to_delete.py for querying materials to delete by manager - Add manager_name parameter to DiscreteMaterialPlanCleaner - Implement material keyword matching logic in process_order - Update file paths from orderID.txt to ProductionID.txt Co-Authored-By: Claude Sonnet 4.5 --- db/materials_to_delete.py | 28 ++++++++++++++++++++++++ main.py | 3 +-- main_clean.py | 5 +++-- utils/离散备料计划维护数据清理.py | 36 +++++++++++++++++++++++++++---- 4 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 db/materials_to_delete.py diff --git a/db/materials_to_delete.py b/db/materials_to_delete.py new file mode 100644 index 0000000..3f933f2 --- /dev/null +++ b/db/materials_to_delete.py @@ -0,0 +1,28 @@ +""" +待删除物料查询组件 +从数据库查询指定负责人需要删除的物料名称 +""" +from db.connection import get_connection + + +def get_materials_to_delete(manager_name): + """ + 根据负责人名称查询待删除物料名称列表 + + Args: + manager_name: 负责人姓名 + + Returns: + 物料名称列表(关键字) + """ + query = """ + SELECT [MaterialName] + FROM [dbo].[MaterialsToBeDeleted] + WHERE [ManagerName] = ? + """ + + with get_connection() as conn: + results = conn.execute_query(query, (manager_name,)) + # 提取物料名称并去除空值 + material_names = [row['MaterialName'] for row in results if row['MaterialName']] + return material_names diff --git a/main.py b/main.py index c8224e0..158a46b 100644 --- a/main.py +++ b/main.py @@ -15,13 +15,12 @@ def main(): ) # 设置文件路径 - order_id_file = os.path.join(os.path.dirname(__file__), "orderID.txt") + order_id_file = os.path.join(os.path.dirname(__file__), "ProductionID.txt") output_file = r"D:/python/playwrite/data/离散备料计划维护_合并.xlsx" # 执行提取 extractor.extract(order_id_file, output_file) - input("按回车退出...") if __name__ == "__main__": diff --git a/main_clean.py b/main_clean.py index d87a711..02cb96e 100644 --- a/main_clean.py +++ b/main_clean.py @@ -10,12 +10,13 @@ def main(): cleaner = DiscreteMaterialPlanCleaner( username="BLDpengqiangqiang", password="Cqbld123456.", - headless=False, + manager_name="彭羽", + headless=True, verbose=True ) # 设置文件路径 - order_id_file = os.path.join(os.path.dirname(__file__), "orderID.txt") + order_id_file = os.path.join(os.path.dirname(__file__), "ProductionID.txt") # 执行清理 cleaner.clean(order_id_file) diff --git a/utils/离散备料计划维护数据清理.py b/utils/离散备料计划维护数据清理.py index 5ec243c..607f74c 100644 --- a/utils/离散备料计划维护数据清理.py +++ b/utils/离散备料计划维护数据清理.py @@ -6,23 +6,26 @@ import os from playwright.sync_api import sync_playwright from utils.auth import login, logout from db.production_order_query import read_production_ids, query_production_order_numbers +from db.materials_to_delete import get_materials_to_delete class DiscreteMaterialPlanCleaner: """离散备料计划维护数据清理器""" - def __init__(self, username, password, headless=False, verbose=True): + def __init__(self, username, password, manager_name, headless=False, verbose=True): """ 初始化清理器 Args: username: 登录用户名 password: 登录密码 + manager_name: 负责人姓名 headless: 是否无头模式运行 verbose: 是否打印详细日志 """ self.username = username self.password = password + self.manager_name = manager_name self.headless = headless self.verbose = verbose @@ -51,7 +54,7 @@ class DiscreteMaterialPlanCleaner: return order_ids - def process_order(self, inner_frame, order_id, order_index, page1, debug_mode=False, debug_order=None): + def process_order(self, inner_frame, order_id, order_index, page1, materials_to_delete=None, debug_mode=False, debug_order=None): """清理单个订单的数据 Args: @@ -59,9 +62,12 @@ class DiscreteMaterialPlanCleaner: order_id: 订单号 order_index: 订单索引 page1: 页面对象 + materials_to_delete: 待删除物料关键字列表 debug_mode: 是否启用调试模式 debug_order: 调试订单号 """ + if materials_to_delete is None: + materials_to_delete = [] from playwright.sync_api import TimeoutError import re import time @@ -178,7 +184,8 @@ class DiscreteMaterialPlanCleaner: # 获取材料名称 input_box = child_form.locator("div").filter(has_text=re.compile(r"^材料名称$")).locator("input[type='text']") - self._print(f"材料名称:{input_box.input_value()}") + material_name = input_box.input_value() + self._print(f"材料名称:{material_name}") # 获取累计待发数量 input_box = child_form.locator("div").filter(has_text=re.compile(r"^累计待发数量$")).locator("input[type='text']") @@ -188,6 +195,21 @@ class DiscreteMaterialPlanCleaner: input_box = child_form.locator("div").filter(has_text=re.compile(r"^累计出库数量$")).locator("input[type='text']") self._print(f"累计出库数量:{input_box.input_value()}") + # 检查是否需要清理该物料 + should_delete = False + matched_keyword = None + for keyword in materials_to_delete: + if keyword in material_name: + should_delete = True + matched_keyword = keyword + break + + if should_delete: + self._print(f">>> 需要清理:材料名称【{material_name}】匹配关键字【{matched_keyword}】") + # TODO: 执行删除操作 + else: + self._print(f"保留:材料名称【{material_name}】无需清理") + if id != detail_count - 1: child_form.get_by_role("button").filter(has_text=re.compile(r"^$")).nth(2).click() else: @@ -246,6 +268,11 @@ class DiscreteMaterialPlanCleaner: debug_mode: 是否启用调试模式 debug_order: 调试订单索引 """ + # 获取待删除物料列表 + self._print(f"正在查询负责人 [{self.manager_name}] 的待删除物料列表...") + materials_to_delete = get_materials_to_delete(self.manager_name) + self._print(f"查询到 {len(materials_to_delete)} 个待删除物料关键字") + with sync_playwright() as playwright: # 调用登录模块 browser, context, page, main_frame = login( @@ -285,7 +312,7 @@ class DiscreteMaterialPlanCleaner: for order_index, order_id in enumerate(order_ids): self._print(f"\n=== 开始处理第 {order_index + 1} 个订单,订单号: {order_id} ===") self.process_order( - inner_frame, order_id, order_index, page1, + inner_frame, order_id, order_index, page1, materials_to_delete, debug_mode=debug_mode, debug_order=debug_order ) @@ -305,6 +332,7 @@ def main(): cleaner = DiscreteMaterialPlanCleaner( username="BLDpengqiangqiang", password="Cqbld123456.", + manager_name="彭羽", headless=False, verbose=True )