fix: 优化重新采集取消交互 (#82)
This commit is contained in:
@@ -30,7 +30,7 @@ from PyQt5.QtCore import (
|
||||
pyqtSignal,
|
||||
pyqtSlot,
|
||||
)
|
||||
from qfluentwidgets import InfoBar, InfoBarPosition, MessageBox
|
||||
from qfluentwidgets import InfoBar, InfoBarPosition, MessageBox, PushButton
|
||||
|
||||
from .admin_gateway import (
|
||||
AdminGatewayError,
|
||||
@@ -134,7 +134,7 @@ class ClaimTaskWorker(QObject):
|
||||
@pyqtSlot()
|
||||
def run(self) -> None:
|
||||
try:
|
||||
if self._cancelled:
|
||||
if self._cancelled and not self._selected_task_id:
|
||||
return
|
||||
client_settings = self._client_service.load()
|
||||
if not client_settings.client_id:
|
||||
@@ -212,6 +212,8 @@ class PDDTaskPageEvent(QObject):
|
||||
self._claim_busy = False
|
||||
self._claim_thread: Optional[QThread] = None
|
||||
self._claim_worker: Optional[ClaimTaskWorker] = None
|
||||
self._rerun_cancel_requested = False
|
||||
self._rerun_feedback: Optional[InfoBar] = None
|
||||
self._auto_fetch_running = False
|
||||
self._stop_requested = False
|
||||
self._cycle_next_delay_ms: Optional[int] = None
|
||||
@@ -261,6 +263,7 @@ class PDDTaskPageEvent(QObject):
|
||||
page.searchRequested.connect(self.search_tasks)
|
||||
page.refreshRequested.connect(self.refresh_tasks)
|
||||
page.rerunRequested.connect(self.request_rerun)
|
||||
page.rerunCancelRequested.connect(self.request_cancel_rerun)
|
||||
page.autoFetchRequested.connect(self._request_claim_task)
|
||||
page.detailRequested.connect(self.show_task_detail)
|
||||
page.taskModel.loadMoreRequested.connect(self._load_page)
|
||||
@@ -345,7 +348,7 @@ class PDDTaskPageEvent(QObject):
|
||||
self._page.window(),
|
||||
)
|
||||
dialog.yesButton.setText("重新采集")
|
||||
dialog.cancelButton.setText("取消")
|
||||
dialog.cancelButton.setText("暂不重新采集")
|
||||
dialog.cancelButton.setFocus()
|
||||
if not dialog.exec():
|
||||
return
|
||||
@@ -367,6 +370,8 @@ class PDDTaskPageEvent(QObject):
|
||||
"""启动只处理指定任务的工作线程。"""
|
||||
|
||||
assert self._claim_gateway is not None
|
||||
self._close_rerun_feedback()
|
||||
self._rerun_cancel_requested = False
|
||||
self._claim_busy = True
|
||||
self._page.set_rerun_running(True)
|
||||
self._page.set_engine_status(f"正在重新采集任务 {task_id}…")
|
||||
@@ -394,32 +399,67 @@ class PDDTaskPageEvent(QObject):
|
||||
self._claim_worker = worker
|
||||
thread.start()
|
||||
|
||||
@pyqtSlot()
|
||||
def request_cancel_rerun(self) -> None:
|
||||
"""请求当前重新采集在下一个安全点停止。"""
|
||||
|
||||
worker = self._claim_worker
|
||||
if (
|
||||
self._closing
|
||||
or self._rerun_cancel_requested
|
||||
or not self._claim_busy
|
||||
or worker is None
|
||||
):
|
||||
return
|
||||
self._rerun_cancel_requested = True
|
||||
self._page.set_rerun_cancelling()
|
||||
self._page.set_engine_status(
|
||||
"正在停止重新采集…正在等待手机当前操作结束"
|
||||
)
|
||||
# uiautomator2/ADB 的单次调用无法安全强制中断。
|
||||
# Worker 会在调用返回后通过 cancelled 回调在安全点停止。
|
||||
worker.cancel()
|
||||
|
||||
@pyqtSlot(str, str, str)
|
||||
def _on_rerun_outcome(self, kind: str, message: str, _task_id: str) -> None:
|
||||
if self._closing:
|
||||
return
|
||||
self._reload()
|
||||
if self._rerun_cancel_requested:
|
||||
self._page.set_engine_status(
|
||||
"停止请求已处理,请查看任务最新状态"
|
||||
)
|
||||
return
|
||||
self._page.set_engine_status(message)
|
||||
if kind != "succeeded":
|
||||
self._show_claim_error("重新采集需要处理", message)
|
||||
self._show_rerun_error("重新采集需要处理", message)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _on_rerun_failed(self, message: str) -> None:
|
||||
if self._closing:
|
||||
return
|
||||
if self._rerun_cancel_requested:
|
||||
return
|
||||
self._page.set_engine_status(message)
|
||||
self._show_claim_error("重新采集失败", message)
|
||||
self._show_rerun_error("重新采集失败", message)
|
||||
|
||||
@pyqtSlot()
|
||||
def _on_rerun_thread_finished(self) -> None:
|
||||
cancel_requested = self._rerun_cancel_requested
|
||||
self._claim_worker = None
|
||||
self._claim_thread = None
|
||||
self._claim_busy = False
|
||||
self._rerun_cancel_requested = False
|
||||
if not self._closing:
|
||||
self._page.set_rerun_running(False)
|
||||
if cancel_requested:
|
||||
self._reload()
|
||||
self._page.set_engine_status(
|
||||
"停止请求已处理,请查看任务最新状态"
|
||||
)
|
||||
|
||||
def _show_rerun_warning(self, title: str, content: str) -> None:
|
||||
InfoBar.warning(
|
||||
bar = InfoBar.warning(
|
||||
title=title,
|
||||
content=content,
|
||||
isClosable=True,
|
||||
@@ -427,6 +467,51 @@ class PDDTaskPageEvent(QObject):
|
||||
position=InfoBarPosition.TOP_RIGHT,
|
||||
parent=self._page,
|
||||
)
|
||||
self._replace_rerun_feedback(bar)
|
||||
|
||||
def _show_rerun_error(self, title: str, content: str) -> None:
|
||||
"""显示一条可明确关闭的重新采集错误。"""
|
||||
|
||||
bar = InfoBar.error(
|
||||
title=title,
|
||||
content=content,
|
||||
isClosable=True,
|
||||
duration=-1,
|
||||
position=InfoBarPosition.TOP_RIGHT,
|
||||
parent=self._page,
|
||||
)
|
||||
self._replace_rerun_feedback(bar)
|
||||
|
||||
def _replace_rerun_feedback(self, bar: InfoBar) -> None:
|
||||
"""用新提示替换旧提示,避免连续失败后堆叠。"""
|
||||
|
||||
self._close_rerun_feedback()
|
||||
self._rerun_feedback = bar
|
||||
close_button = PushButton("关闭提示", bar)
|
||||
close_button.setAccessibleName("关闭重新采集提示")
|
||||
close_button.clicked.connect(
|
||||
lambda _checked=False, current=bar: self._close_rerun_feedback(current)
|
||||
)
|
||||
bar.addWidget(close_button)
|
||||
bar.destroyed.connect(
|
||||
lambda _object=None, current=bar: self._forget_rerun_feedback(current)
|
||||
)
|
||||
|
||||
def _close_rerun_feedback(self, expected: Optional[InfoBar] = None) -> None:
|
||||
"""关闭当前重新采集提示;旧提示不得关闭新提示。"""
|
||||
|
||||
bar = self._rerun_feedback
|
||||
if bar is None or (expected is not None and bar is not expected):
|
||||
return
|
||||
self._rerun_feedback = None
|
||||
try:
|
||||
bar.close()
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
def _forget_rerun_feedback(self, bar: InfoBar) -> None:
|
||||
if self._rerun_feedback is bar:
|
||||
self._rerun_feedback = None
|
||||
|
||||
@pyqtSlot()
|
||||
def _request_claim_task(self) -> None:
|
||||
@@ -763,6 +848,7 @@ class PDDTaskPageEvent(QObject):
|
||||
self._auto_fetch_running = False
|
||||
self._stop_requested = True
|
||||
self._next_cycle_timer.stop()
|
||||
self._close_rerun_feedback()
|
||||
|
||||
for window in list(self._detail_windows.values()):
|
||||
window.close()
|
||||
|
||||
Reference in New Issue
Block a user