Files
kefu/deploy/patient-session-20260918/edit_gui.py
T
2026-09-21 10:34:06 +08:00

180 lines
9.3 KiB
Python

from pathlib import Path
p=Path(r'C:\kefu\wechat_rpa\wechat_gui_qt.py')
s=p.read_text(encoding='utf-8-sig')
start=s.index('class PatientBindingDialog('); end=s.index('class ConsoleBridge(',start)
c=s[start:end]
def replace(old,new):
global c
assert c.count(old)==1, (old[:80],c.count(old))
c=c.replace(old,new,1)
replace(' operationFinished = Signal(object)\n',' operationFinished = Signal(object)\n reauthenticationFinished = Signal(object)\n')
replace(' self.changed = False\n',' self.changed = False\n self._patient_session_expired = False\n self._busy = False\n')
replace(' layout.addWidget(self.hint_label)\n',''' layout.addWidget(self.hint_label)
self.reauthenticate_button = QPushButton("重新验证 ZYT 登录")
self.reauthenticate_button.clicked.connect(self._reauthenticate)
self.reauthenticate_button.hide()
layout.addWidget(self.reauthenticate_button)
''')
replace(' self.operationFinished.connect(self._operation_finished)\n',' self.operationFinished.connect(self._operation_finished)\n self.reauthenticationFinished.connect(self._reauthentication_finished)\n')
replace(''' self.search_input.setEnabled(self.can_search and not busy)
self.search_button.setEnabled(self.can_search and not busy)
self.bind_button.setEnabled(self.can_bind and not busy)
''',''' self._busy = busy
query_ready = not busy and not self._patient_session_expired
self.search_input.setEnabled(self.can_search and not busy)
self.search_button.setEnabled(self.can_search and query_ready)
self.bind_button.setEnabled(self.can_bind and query_ready)
self.reauthenticate_button.setEnabled(not busy)
''')
replace(' def _search(self) -> None:\n',''' def _show_patient_session_expired(self) -> None:
self._patient_session_expired = True
self._patients = []
self.result_table.setRowCount(0)
self.reauthenticate_button.show()
self._set_busy(False, "ZYT 患者查询登录已过期,请点击下方按钮重新验证当前账号。"
"验证后可重新搜索并核对患者,客服监听继续运行。")
def _reauthenticate(self) -> None:
if self._busy:
return
import backend_client
account = str(backend_client.load_settings().get("zyt_account") or "当前账号")
password, accepted = QInputDialog.getText(
self, "重新验证 ZYT 登录",
f"请输入 ZYT 账号 {account} 的密码:\n仅恢复患者查询登录,客服监听继续运行。",
QLineEdit.Password,
)
if not accepted:
return
if not password:
self.hint_label.setText("请输入当前 ZYT 账号的密码后重试。")
return
self._set_busy(True, "正在验证 ZYT 账号并恢复患者查询…")
person_id = str(self._selected_person().get("id") or "")
def work() -> None:
try:
backend_client.reauthenticate_patient_session(password)
context = backend_client.desktop_patient_context(
self.external_account_id, self.conversation_external_id,
person_id=person_id,
)
payload = {"ok": True, "context": context}
except Exception as exc:
payload = {"ok": False, "error": str(exc)}
try:
self.reauthenticationFinished.emit(payload)
except RuntimeError:
pass
threading.Thread(target=work, name="zyt-patient-reauthentication", daemon=True).start()
@Slot(object)
def _reauthentication_finished(self, payload: object) -> None:
values = dict(payload or {}) if isinstance(payload, dict) else {}
if not values.get("ok"):
self._set_busy(False, f"验证失败:{values.get('error') or '请重试'}")
return
self.context = dict(values.get("context") or {})
self.permissions = dict(self.context.get("permissions") or {})
self.can_search = bool(self.permissions.get("can_search"))
self.can_bind = bool(self.permissions.get("can_bind"))
self.can_unbind = bool(self.permissions.get("can_unbind"))
self.people = list(self.context.get("people") or [])
self._patient_session_expired = False
self.reauthenticate_button.hide()
self._patients = []
self.result_table.setRowCount(0)
self._person_changed()
self._set_busy(False, "ZYT 登录已恢复,请搜索并核对患者后确认绑定。")
if not self.can_search:
self.hint_label.setText(str(self.permissions.get("reason") or "当前账号没有患者查询权限。"))
elif self.search_input.text().strip():
self._search()
def _search(self) -> None:
if self._busy or self._patient_session_expired:
return
''')
# Escape the newline inside the password prompt's f-string in generated source.
c=c.replace('的密码:\n仅恢复患者查询登录,客服监听继续运行。",','的密码:\\n仅恢复患者查询登录,客服监听继续运行。",')
replace(' payload = {"ok": False, "error": str(exc)}\n try:\n self.searchFinished.emit(payload)',''' payload = {"ok": False, "error": str(exc),
"patient_session_expired": isinstance(exc, backend_client.PatientSessionExpired)}
try:
self.searchFinished.emit(payload)''')
replace(''' if not values.get("ok"):
self.hint_label.setText(f"查询失败:{values.get('error') or '未知错误'}")
''',''' if not values.get("ok"):
if values.get("patient_session_expired"):
self._show_patient_session_expired()
return
self.hint_label.setText(f"查询失败:{values.get('error') or '未知错误'}")
''')
replace(' def _bind_selected(self) -> None:\n',' def _bind_selected(self) -> None:\n if self._busy or self._patient_session_expired:\n return\n')
replace(' payload = {"ok": False, "action": action, "error": str(exc)}',''' payload = {"ok": False, "action": action, "error": str(exc),
"patient_session_expired": isinstance(exc, backend_client.PatientSessionExpired)}''')
replace(''' if not values.get("ok"):
self.hint_label.setText(
f"操作失败:{values.get('error') or '未知错误'}"
''',''' if not values.get("ok"):
if values.get("patient_session_expired"):
self._show_patient_session_expired()
return
self.hint_label.setText(
f"操作失败:{values.get('error') or '未知错误'}"
''')
s=s[:start]+c+s[end:]
s=s.replace('class MainWindow(QMainWindow):\n desktopSessionChecked = Signal(str, object)\n','class MainWindow(QMainWindow):\n desktopSessionChecked = Signal(str, object)\n patientSessionChecked = Signal(object)\n',1)
marker=' def _check_desktop_session(self) -> None:\n'
assert s.count(marker)==1
s=s.replace(marker,''' def _keepalive_patient_session(self) -> None:
if self._patient_keepalive_running or self._forced_logout_handled:
return
self._patient_keepalive_running = True
def check() -> None:
try:
import backend_client
result = backend_client.keepalive_zyt_session()
except Exception:
result = {"state": "unreachable"}
try:
self.patientSessionChecked.emit(result)
except RuntimeError:
pass
threading.Thread(target=check, name="zyt-session-keepalive", daemon=True).start()
@Slot(object)
def _patient_session_checked(self, result: object) -> None:
self._patient_keepalive_running = False
values = dict(result or {}) if isinstance(result, dict) else {}
state = str(values.get("state") or "unreachable")
if state == "skipped":
return
previous = self._patient_session_state
self._patient_session_state = state
if state == "expired" and previous != state:
self.append_log("ZYT 患者查询登录已过期,可在绑定患者窗口重新验证;客服监听继续运行。", "warn")
elif state == "active" and previous == "expired":
self.append_log("ZYT 患者查询登录已恢复。", "ok")
'''+marker,1)
marker=' self._desktop_session_check_running = False\n self._desktop_session_state = "valid"\n'
assert s.count(marker)==1
s=s.replace(marker,''' self._patient_keepalive_running = False
self._patient_session_state = "unknown"
self.patientSessionChecked.connect(self._patient_session_checked)
self.patient_session_timer = QTimer(self)
self.patient_session_timer.setInterval(30 * 60 * 1000)
self.patient_session_timer.timeout.connect(self._keepalive_patient_session)
if "--qt-smoke-test" not in sys.argv:
self.patient_session_timer.start()
QTimer.singleShot(5000, self._keepalive_patient_session)
'''+marker,1)
compile(s,str(p),'exec')
p.write_text(s,encoding='utf-8',newline='\n')
print('source GUI updated')