From 201f65d715563af20e1a13c4e63cc696070709ce Mon Sep 17 00:00:00 2001 From: Misaka_Company Date: Thu, 22 Jan 2026 18:14:56 +0800 Subject: [PATCH] feat: implement material plan data cleaning automation Remove manual exit prompt in main script to allow automated execution. Add logic in DiscreteMaterialPlanCleaner to navigate the "Material Plan" popup, handling nested iframes and waiting for data to load. Implement iteration over material details to extract codes and names, handling cases where no details exist. --- main_clean.py | 1 - utils/离散备料计划维护数据清理.py | 101 +++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/main_clean.py b/main_clean.py index 8514850..d87a711 100644 --- a/main_clean.py +++ b/main_clean.py @@ -20,7 +20,6 @@ def main(): # 执行清理 cleaner.clean(order_id_file) - input("按回车退出...") if __name__ == "__main__": diff --git a/utils/离散备料计划维护数据清理.py b/utils/离散备料计划维护数据清理.py index 5d32d2f..8b52047 100644 --- a/utils/离散备料计划维护数据清理.py +++ b/utils/离散备料计划维护数据清理.py @@ -77,7 +77,106 @@ class DiscreteMaterialPlanCleaner: if debug_mode and (debug_order is None or order_index == debug_order): self._print(f"=== 调试暂停:第 {order_index + 1} 个订单 ===") page1.pause() - page1.pause() + + inner_frame.locator("#hot-key-head_list").get_by_text("更多").click() + + + with page1.expect_popup() as page2_info: + inner_frame.get_by_text("备料计划").click() + page2 = page2_info.value + + # 获取 nested iframe + main_frame = page2.locator("#forwardFrame").content_frame + inner_frame_locator = main_frame.locator("#mainiframe") + inner_frame_locator.wait_for(state="visible", timeout=15000) + inner_frame = inner_frame_locator.content_frame + + # 等待备料计划页面加载完成(等待序列号加载出来) + self._print("等待备料计划页面加载完成...") + plan_code_locator = inner_frame.get_by_text(re.compile(r"^离散备料计划维护:")) + plan_code_locator.wait_for(state="visible", timeout=30000) + + # 循环检查编码是否已加载 + max_wait = 30 # 最多等待30秒 + wait_interval = 0.5 # 每0.5秒检查一次 + waited = 0 + plan_code = None + while waited < max_wait: + plan_text = plan_code_locator.inner_text() + match = re.search(r"离散备料计划维护:(.+)", plan_text) + if match and match.group(1).strip(): + plan_code = match.group(1).strip() + break + time.sleep(wait_interval) + waited += wait_interval + + if plan_code: + self._print(f"备料计划页面加载完成,编码: {plan_code}") + else: + self._print(f"警告: 备料计划页面加载超时") + + # 提取"详细信息"中的数字 + detail_element = inner_frame.get_by_text(re.compile(r"^详细信息 \(\d+\)$")) + detail_text = detail_element.inner_text() + # 使用正则表达式提取括号中的数字 + match = re.search(r"详细信息 \((\d+)\)", detail_text) + if match: + detail_count = int(match.group(1)) + self._print(f"详细信息数量: {detail_count}") + + + if detail_count > 0: + inner_frame.get_by_role("button", name="修改").click() + save_button_locator = inner_frame.get_by_role("button", name="保存") + save_button_locator.wait_for(state="visible", timeout=10000) + + inner_frame.get_by_text("展开").first.click() + page2.pause() + for id in range(detail_count): + id_lable_locator= inner_frame.get_by_text("序号 " + str(id + 1)).wait_for(state="visible", timeout=10000) + + #page2.pause() + # 提取"展开"页面中的内容 + detail_element = inner_frame.get_by_text(re.compile(r"^材料编码\d+$")) + #移除detail_text中的换行符 + detail_text = detail_element.inner_text().replace("\n", "") + # 使用正则表达式提取括号中的数字 + match = re.search(r"材料编码(\d+)", detail_text) + if match: + match_result = int(match.group(1)) + self._print(f"材料编码:{match_result}") + + + + input_box = inner_frame.locator("div").filter(has_text=re.compile(r"^材料名称$")).nth(2).locator("input[type='text']") + self._print(f"材料名称:{input_box.input_value()}") + + if id != detail_count - 1: + inner_frame.get_by_role("button").filter(has_text=re.compile(r"^$")).nth(2).click() + else: + inner_frame.get_by_role("button").filter(has_text=re.compile(r"^$")).nth(4).click() + #page2.pause() + + + + pass + + + + + + + else: + self._print(f"第 {order_index + 1} 个订单无数据需要清理,跳过...") + page2.close() + return + + + + + + + page2.close() time.sleep(1) pass