Refactor DiscreteMaterialPlanExtractor to use logout function from auth module and update headless mode in main script

This commit is contained in:
Misaka_Company
2026-01-16 15:20:05 +08:00
parent 93f986260e
commit bb9348d12b
4 changed files with 133 additions and 36 deletions

129
utils/auth.py Normal file
View File

@@ -0,0 +1,129 @@
"""
认证模块 - 负责用友BIP系统的登录和退出操作
"""
from playwright.sync_api import Playwright, Browser, BrowserContext, Page, Frame
def login(
playwright: Playwright,
username: str,
password: str,
url: str = "https://68.11.34.30:8082/yonbip/resources/uap/rbac/login/main/index.html",
headless: bool = False,
ignore_https_errors: bool = True,
verbose: bool = True
) -> tuple[Browser, BrowserContext, Page, Frame]:
"""
登录用友BIP系统
参数:
playwright: Playwright实例
username: 用户名
password: 密码
url: 登录页面URL
headless: 是否使用无头模式
ignore_https_errors: 是否忽略HTTPS错误
verbose: 是否打印详细日志
返回:
tuple: (browser, context, page, main_frame)
- browser: 浏览器实例
- context: 浏览器上下文
- page: 页面对象
- main_frame: 登录后的主iframe (forwardFrame)
"""
import time
# 启动浏览器
browser = playwright.chromium.launch(headless=headless)
# 创建上下文
context = browser.new_context(ignore_https_errors=ignore_https_errors)
# 创建页面
page = context.new_page()
# 导航到登录页面
page.goto(url)
# 提取主 iframe (forwardFrame)
main_frame = page.locator("#forwardFrame").content_frame
# 填写用户名
main_frame.get_by_role("textbox", name="用户名").fill(username)
# 填写密码
main_frame.get_by_role("textbox", name="密码").fill(password)
# 点击登录按钮
main_frame.get_by_role("button", name="登录").click()
# 处理强制登录弹窗(判断是否存在)
confirm_btn = main_frame.get_by_role("button", name="确定")
if confirm_btn.count() > 0:
confirm_btn.click()
if verbose:
print("强制登录")
else:
if verbose:
print("正常登录")
return browser, context, page, main_frame
def logout(main_frame: Frame, verbose: bool = True) -> None:
"""
执行账号注销
参数:
main_frame: 主 iframe 对象 (forwardFrame)
verbose: 是否打印详细日志
"""
import time
if verbose:
print("点击账号菜单按钮...")
# 元素1账号菜单按钮logo 图标)
main_frame.get_by_role("img", name="logo").click()
# 等待菜单出现
time.sleep(1)
if verbose:
print("点击退出登录按钮...")
# 元素2"退出登录"按钮
main_frame.get_by_text("退出登录").click()
# 等待确认框出现
time.sleep(1)
if verbose:
print("等待退出登录确认框...")
# 元素3退出登录确认框判断是否出现
try:
confirm_text = main_frame.get_by_text("退出确定要退出当前账号吗?")
if verbose:
print("找到确认框,点击确定按钮")
# 元素4确认按钮
main_frame.get_by_role("button", name="确定(Y)").click()
except:
if verbose:
print("未找到确认框,可能已自动退出")
time.sleep(2) # 等待注销完成
def close_session(browser: Browser, context: BrowserContext) -> None:
"""
关闭浏览器会话
参数:
browser: 浏览器实例
context: 浏览器上下文
"""
context.close()
browser.close()

View File

@@ -6,6 +6,7 @@ import os
import pandas as pd
from playwright.sync_api import sync_playwright
from utils.excel_converter import ExcelConverter
from utils.auth import login, logout
class DiscreteMaterialPlanExtractor:
@@ -186,8 +187,6 @@ class DiscreteMaterialPlanExtractor:
Returns:
输出文件路径
"""
from login import login
with sync_playwright() as playwright:
# 调用登录模块
browser, context, page, main_frame = login(
@@ -236,7 +235,7 @@ class DiscreteMaterialPlanExtractor:
# 执行账号注销
self._print("\n开始执行账号注销...")
self.logout(main_frame)
logout(main_frame, verbose=self.verbose)
# 转换并合并文件
if downloaded_files:
@@ -256,37 +255,6 @@ class DiscreteMaterialPlanExtractor:
return output_file
def logout(self, main_frame):
"""执行账号注销"""
# 元素1账号菜单按钮logo 图标)
self._print("点击账号菜单按钮...")
main_frame.get_by_role("img", name="logo").click()
# 等待菜单出现
import time
time.sleep(1)
# 元素2"退出登录"按钮
self._print("点击退出登录按钮...")
main_frame.get_by_text("退出登录").click()
# 等待确认框出现
time.sleep(1)
# 元素3退出登录确认框判断是否出现
self._print("等待退出登录确认框...")
try:
confirm_text = main_frame.get_by_text("退出确定要退出当前账号吗?")
self._print("找到确认框,点击确定按钮")
# 元素4确认按钮
main_frame.get_by_role("button", name="确定(Y)").click()
except:
self._print("未找到确认框,可能已自动退出")
time.sleep(2) # 等待注销完成
def main():
"""测试函数"""
extractor = DiscreteMaterialPlanExtractor(