68 lines
3.8 KiB
Python
68 lines
3.8 KiB
Python
"""Wire explicit manual handoff for uncertain delivery without resending."""
|
|
import ast
|
|
import os
|
|
from pathlib import Path
|
|
|
|
METHOD=''' def _handoff_queue_tasks(self, keys) -> None:
|
|
requested = list(dict.fromkeys(str(key or "").strip() for key in (keys or []) if str(key or "").strip()))
|
|
if not requested:
|
|
return
|
|
pending = getattr(self.queue_page, "pending_states", {}) or {}
|
|
uncertain = any(task_review_state(pending.get(key))["deliveryUncertain"] for key in requested)
|
|
if uncertain:
|
|
answer = QMessageBox.question(
|
|
self, "核对发送结果后转人工",
|
|
"这条回复可能已经发出。请先在企业微信的原会话核对发送结果。\\n\\n"
|
|
"继续后将从自动队列移出,由人工跟进;保留发送记录,不会自动重发,也不会标记为已确认发送。\\n\\n"
|
|
"已核对,确认转人工处理?",
|
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
|
QMessageBox.StandardButton.No,
|
|
)
|
|
if answer != QMessageBox.StandardButton.Yes:
|
|
return
|
|
thread = getattr(self, "_thread", None)
|
|
try:
|
|
if thread is not None and thread.is_alive():
|
|
handoff = getattr(thread, "handoff_pending_tasks", None)
|
|
result = handoff(requested) if handoff else thread.cancel_pending_tasks(requested)
|
|
else:
|
|
from gui_runtime import handoff_pending_reply_file
|
|
QUEUE_PATH
|
|
result = handoff_pending_reply_file(requested, str(path))
|
|
except Exception as exc:
|
|
QMessageBox.warning(self, "转人工失败", str(exc))
|
|
return
|
|
if result.get("error"):
|
|
QMessageBox.warning(self, "转人工失败", str(result["error"]))
|
|
accepted = set(result.get("handed_off") or result.get("deleted") or [])
|
|
scheduled = set(result.get("scheduled") or [])
|
|
if accepted:
|
|
self.append_log(f"已将 {len(accepted)} 条任务转交人工,保留发送记录,不再自动重发。", "notify")
|
|
if scheduled:
|
|
self.append_log(f"已登记 {len(scheduled)} 条人工接管操作,监听线程就绪后执行。", "notify")
|
|
if result.get("protected"):
|
|
QMessageBox.information(self, "暂不能转人工", "任务正在发送或属于其他账号,请等待发送结束并在对应账号下处理。")
|
|
self.queue_page.refresh_data()
|
|
self._schedule_console_push(urgent=True)
|
|
'''
|
|
for root in (Path('C:/kefu/wechat_rpa'),Path('C:/wechat_rpa')):
|
|
path=root/'wechat_gui_qt.py';source=path.read_text(encoding='utf-8')
|
|
tree=ast.parse(source);cls=next(n for n in tree.body if isinstance(n,ast.ClassDef) and n.name=='MainWindow')
|
|
node=next(n for n in cls.body if isinstance(n,ast.FunctionDef) and n.name=='_handoff_queue_tasks')
|
|
lines=source.splitlines(keepends=True)
|
|
queue_path='path = queue_path_for_transport(self.runtime_settings.get("reply_transport", VISUAL), root=SCRIPT_DIR)' if (root/'reply_transport.py').exists() else 'path = SCRIPT_DIR / "pending_replies.json"'
|
|
source=''.join(lines[:node.lineno-1])+METHOD.replace('QUEUE_PATH',queue_path).rstrip()+'\n'+''.join(lines[node.end_lineno:])
|
|
# Do not retain explicit approvals if an asynchronous protocol check failed.
|
|
old=''' QTimer.singleShot(0, self.start_monitoring)
|
|
|
|
def _export_protocol_report'''
|
|
new=''' QTimer.singleShot(0, self.start_monitoring)
|
|
else:
|
|
self._deferred_review_approvals = []
|
|
|
|
def _export_protocol_report'''
|
|
source=source.replace(old,new,1)
|
|
compile(source,str(path),'exec')
|
|
temporary=path.with_name(path.name+'.review-patch.tmp');temporary.write_text(source,encoding='utf-8');os.replace(temporary,path)
|
|
print(root)
|