feat: 移除 Client 真实采购手工授权 (#114)
This commit is contained in:
+14
-259
@@ -35,11 +35,6 @@ from .current_client_service import (
|
||||
)
|
||||
from .http_admin_gateway import DEFAULT_ADMIN_BASE_URL, HttpAdminGateway
|
||||
from .selected_android_device_service import SelectedAndroidDeviceService
|
||||
from .live_purchase_authorization import (
|
||||
LIVE_CONFIRMATION_TEXT,
|
||||
LivePurchaseAuthorization,
|
||||
LivePurchaseAuthorizationService,
|
||||
)
|
||||
from .settings_repository import SettingsRepository
|
||||
from .settings_ui import AndroidDeviceRow
|
||||
from .task_models import TaskType
|
||||
@@ -300,85 +295,6 @@ class AndroidDeviceSettingWorker(QObject):
|
||||
self.completed.emit()
|
||||
|
||||
|
||||
class LivePurchaseAuthorizationWorker(QObject):
|
||||
"""后台保存 live 授权,并尽力把最新能力登记到 Admin。"""
|
||||
|
||||
saved = pyqtSignal(object)
|
||||
failed = pyqtSignal(str)
|
||||
registrationFailed = pyqtSignal(str)
|
||||
completed = pyqtSignal()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
service: LivePurchaseAuthorizationService,
|
||||
gateway: Optional[ClientRegistrationGateway],
|
||||
client_id: str,
|
||||
client_name: str,
|
||||
device_serial: str,
|
||||
action: str,
|
||||
confirmation_text: str,
|
||||
gateway_error: str = "",
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self._service = service
|
||||
self._gateway = gateway
|
||||
self._client_id = str(client_id or "").strip()
|
||||
self._client_name = str(client_name or "").strip()
|
||||
self._device_serial = device_serial
|
||||
self._action = action
|
||||
self._confirmation_text = confirmation_text
|
||||
self._gateway_error = gateway_error
|
||||
|
||||
@pyqtSlot()
|
||||
def run(self) -> None:
|
||||
try:
|
||||
try:
|
||||
if self._action == "enable":
|
||||
authorization = self._service.enable(
|
||||
self._client_id,
|
||||
self._device_serial,
|
||||
self._confirmation_text,
|
||||
)
|
||||
else:
|
||||
authorization = self._service.disable()
|
||||
except Exception as exc:
|
||||
self.failed.emit(str(exc) or "真实下单授权保存失败")
|
||||
return
|
||||
|
||||
self.saved.emit(authorization)
|
||||
if not self._client_id:
|
||||
return
|
||||
if self._gateway is None:
|
||||
self.registrationFailed.emit(
|
||||
self._gateway_error or "Admin Gateway 尚未配置"
|
||||
)
|
||||
return
|
||||
device = (
|
||||
AndroidDeviceInfo(self._device_serial)
|
||||
if self._device_serial
|
||||
else None
|
||||
)
|
||||
supported_types = (
|
||||
(TaskType.COLLECT, TaskType.PURCHASE)
|
||||
if device is not None
|
||||
else (TaskType.COLLECT,)
|
||||
)
|
||||
capabilities = ClaimCapabilities(
|
||||
device=device,
|
||||
supported_types=supported_types,
|
||||
purchase_mode="live" if authorization.enabled else "dry_run",
|
||||
)
|
||||
try:
|
||||
self._gateway.register_client(
|
||||
ClientInfo(self._client_id, self._client_name),
|
||||
capabilities,
|
||||
)
|
||||
except Exception as exc:
|
||||
self.registrationFailed.emit(str(exc) or "Admin 登记失败")
|
||||
finally:
|
||||
self.completed.emit()
|
||||
|
||||
|
||||
class SettingsPageEventBinder(QObject):
|
||||
"""绑定设备管理控件,并向应用层发出稳定事件。"""
|
||||
|
||||
@@ -387,7 +303,6 @@ class SettingsPageEventBinder(QObject):
|
||||
currentDeviceSaveRequested = pyqtSignal(str, str)
|
||||
saveRequested = pyqtSignal(str, str)
|
||||
deleteRequested = pyqtSignal(str)
|
||||
liveAuthorizationRequested = pyqtSignal(str, str)
|
||||
androidDeviceConfigurationChanged = pyqtSignal(str)
|
||||
|
||||
def __init__(
|
||||
@@ -429,11 +344,7 @@ class SettingsPageEventBinder(QObject):
|
||||
self._android_setting_thread: Optional[QThread] = None
|
||||
self._android_setting_worker: Optional[AndroidDeviceSettingWorker] = None
|
||||
self._saved_android_serial = ""
|
||||
self._live_purchase_busy = False
|
||||
self._live_purchase_thread: Optional[QThread] = None
|
||||
self._live_purchase_worker: Optional[
|
||||
LivePurchaseAuthorizationWorker
|
||||
] = None
|
||||
self._refresh_registration_after_android_setting = False
|
||||
self._live_purchase_adapter_ready = bool(
|
||||
live_purchase_adapter_ready
|
||||
)
|
||||
@@ -450,10 +361,6 @@ class SettingsPageEventBinder(QObject):
|
||||
parent=self,
|
||||
)
|
||||
self._client_service = CurrentClientService(repository)
|
||||
self._live_purchase_service = LivePurchaseAuthorizationService(
|
||||
repository
|
||||
)
|
||||
self._live_authorization = self._live_purchase_service.load()
|
||||
self._selected_android_device_service = SelectedAndroidDeviceService(
|
||||
repository
|
||||
)
|
||||
@@ -484,18 +391,6 @@ class SettingsPageEventBinder(QObject):
|
||||
page.saveButton.clicked.connect(self._request_save)
|
||||
self.saveRequested.connect(self._start_save_android_device)
|
||||
page.deleteButton.clicked.connect(self._request_delete)
|
||||
page.livePurchaseEnableButton.clicked.connect(
|
||||
self._request_enable_live_purchase
|
||||
)
|
||||
page.livePurchaseDisableButton.clicked.connect(
|
||||
self._request_disable_live_purchase
|
||||
)
|
||||
page.livePurchaseConfirmationInput.textChanged.connect(
|
||||
self._sync_button_state
|
||||
)
|
||||
self.liveAuthorizationRequested.connect(
|
||||
self._start_live_authorization
|
||||
)
|
||||
self.deleteRequested.connect(self._start_delete_android_device)
|
||||
page.deviceTableModel.checkedDeviceChanged.connect(
|
||||
self._on_checked_device_changed
|
||||
@@ -507,7 +402,6 @@ class SettingsPageEventBinder(QObject):
|
||||
|
||||
self._load_current_client()
|
||||
self._load_selected_android_device()
|
||||
self._show_live_authorization(self._live_authorization)
|
||||
self._sync_button_state()
|
||||
if self._saved_android_serial:
|
||||
QTimer.singleShot(0, self._request_restore_saved_android_device)
|
||||
@@ -543,11 +437,10 @@ class SettingsPageEventBinder(QObject):
|
||||
|
||||
try:
|
||||
device = self._selected_android_device()
|
||||
displayed_client_id = self._page.deviceIdInput.text().strip()
|
||||
purchase_mode = self._live_purchase_service.purchase_mode_for(
|
||||
displayed_client_id,
|
||||
device.address if device is not None else "",
|
||||
live_adapter_ready=self._live_purchase_adapter_ready,
|
||||
purchase_mode = (
|
||||
"live"
|
||||
if device is not None and self._live_purchase_adapter_ready
|
||||
else "dry_run"
|
||||
)
|
||||
supported_types = (
|
||||
(TaskType.COLLECT, TaskType.PURCHASE)
|
||||
@@ -591,128 +484,6 @@ class SettingsPageEventBinder(QObject):
|
||||
self._worker = worker
|
||||
thread.start()
|
||||
|
||||
@pyqtSlot()
|
||||
def _request_enable_live_purchase(self) -> None:
|
||||
if self._live_purchase_busy:
|
||||
return
|
||||
if not self._live_purchase_adapter_ready:
|
||||
self._page.set_live_purchase_authorization(
|
||||
enabled=False,
|
||||
message="真实下单执行器未就绪,只允许采购演练",
|
||||
)
|
||||
return
|
||||
confirmation = self._page.livePurchaseConfirmationInput.text()
|
||||
self.liveAuthorizationRequested.emit("enable", confirmation)
|
||||
|
||||
@pyqtSlot()
|
||||
def _request_disable_live_purchase(self) -> None:
|
||||
if not self._live_purchase_busy:
|
||||
self.liveAuthorizationRequested.emit("disable", "")
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
def _start_live_authorization(
|
||||
self, action: str, confirmation_text: str
|
||||
) -> None:
|
||||
if self._closing or self._live_purchase_busy:
|
||||
return
|
||||
current = self._client_service.load()
|
||||
serial = self._selected_android_device_service.load()
|
||||
if action == "enable" and (
|
||||
not current.client_id or not serial
|
||||
):
|
||||
self._page.set_live_purchase_authorization(
|
||||
enabled=False,
|
||||
message="请先保存当前 Client 和 Android 设备",
|
||||
)
|
||||
return
|
||||
|
||||
self._live_purchase_busy = True
|
||||
self._sync_button_state()
|
||||
self._page.set_live_purchase_authorization(
|
||||
enabled=self._live_authorization.enabled,
|
||||
client_id=self._live_authorization.client_id,
|
||||
device_serial=self._live_authorization.device_serial,
|
||||
confirmed_at=self._live_authorization.confirmed_at,
|
||||
message=(
|
||||
"正在启用真实下单…"
|
||||
if action == "enable"
|
||||
else "正在关闭真实下单…"
|
||||
),
|
||||
)
|
||||
thread = QThread(self)
|
||||
worker = LivePurchaseAuthorizationWorker(
|
||||
self._live_purchase_service,
|
||||
self._admin_gateway,
|
||||
current.client_id,
|
||||
current.client_name,
|
||||
serial,
|
||||
action,
|
||||
confirmation_text,
|
||||
self._gateway_error,
|
||||
)
|
||||
worker.moveToThread(thread)
|
||||
thread.started.connect(worker.run)
|
||||
worker.saved.connect(self._on_live_authorization_saved)
|
||||
worker.failed.connect(self._on_live_authorization_failed)
|
||||
worker.registrationFailed.connect(
|
||||
self._on_live_registration_failed
|
||||
)
|
||||
worker.completed.connect(thread.quit)
|
||||
worker.completed.connect(worker.deleteLater)
|
||||
thread.finished.connect(self._on_live_authorization_finished)
|
||||
thread.finished.connect(thread.deleteLater)
|
||||
self._live_purchase_thread = thread
|
||||
self._live_purchase_worker = worker
|
||||
thread.start()
|
||||
|
||||
@pyqtSlot(object)
|
||||
def _on_live_authorization_saved(
|
||||
self, authorization: LivePurchaseAuthorization
|
||||
) -> None:
|
||||
if self._closing:
|
||||
return
|
||||
self._live_authorization = authorization
|
||||
self._page.livePurchaseConfirmationInput.clear()
|
||||
self._show_live_authorization(authorization)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _on_live_authorization_failed(self, message: str) -> None:
|
||||
if not self._closing:
|
||||
self._show_live_authorization(
|
||||
self._live_authorization,
|
||||
f"授权修改失败:{message};原设置未改变",
|
||||
)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _on_live_registration_failed(self, message: str) -> None:
|
||||
if not self._closing:
|
||||
state = "已启用" if self._live_authorization.enabled else "已关闭"
|
||||
self._show_live_authorization(
|
||||
self._live_authorization,
|
||||
f"本地{state},Admin 登记失败:{message};领取时会再次声明能力",
|
||||
)
|
||||
|
||||
@pyqtSlot()
|
||||
def _on_live_authorization_finished(self) -> None:
|
||||
self._live_purchase_worker = None
|
||||
self._live_purchase_thread = None
|
||||
self._live_purchase_busy = False
|
||||
if not self._closing:
|
||||
self._sync_button_state()
|
||||
|
||||
def _show_live_authorization(
|
||||
self,
|
||||
authorization: LivePurchaseAuthorization,
|
||||
message: str = "",
|
||||
) -> None:
|
||||
self._page.set_live_purchase_authorization(
|
||||
enabled=authorization.enabled,
|
||||
client_id=authorization.client_id,
|
||||
device_serial=authorization.device_serial,
|
||||
confirmed_at=authorization.confirmed_at,
|
||||
message=message,
|
||||
)
|
||||
|
||||
@pyqtSlot()
|
||||
def _request_search(self) -> None:
|
||||
if (
|
||||
@@ -1121,25 +892,6 @@ class SettingsPageEventBinder(QObject):
|
||||
self._page.deleteButton.setEnabled(
|
||||
device_commands_enabled and bool(self._saved_android_serial)
|
||||
)
|
||||
live_commands_enabled = (
|
||||
not self._closing
|
||||
and not self._busy
|
||||
and not self._current_device_busy
|
||||
and not self._live_purchase_busy
|
||||
)
|
||||
confirmation_matches = (
|
||||
self._page.livePurchaseConfirmationInput.text().strip()
|
||||
== LIVE_CONFIRMATION_TEXT
|
||||
)
|
||||
self._page.livePurchaseEnableButton.setEnabled(
|
||||
live_commands_enabled
|
||||
and self._live_purchase_adapter_ready
|
||||
and not self._live_authorization.enabled
|
||||
and confirmation_matches
|
||||
)
|
||||
self._page.livePurchaseDisableButton.setEnabled(
|
||||
live_commands_enabled and self._live_authorization.enabled
|
||||
)
|
||||
|
||||
def set_busy(self, busy: bool, message: str = "") -> None:
|
||||
"""切换界面忙碌状态,防止用户重复提交设备命令。"""
|
||||
@@ -1182,7 +934,7 @@ class SettingsPageEventBinder(QObject):
|
||||
)
|
||||
|
||||
def _selected_android_device(self) -> Optional[AndroidDeviceInfo]:
|
||||
serial = self._page.deviceTableModel.checked_serial.strip()
|
||||
serial = self._selected_android_device_service.load().strip()
|
||||
return AndroidDeviceInfo(serial) if serial else None
|
||||
|
||||
@pyqtSlot(object)
|
||||
@@ -1364,6 +1116,10 @@ class SettingsPageEventBinder(QObject):
|
||||
"当前使用设备:未选择(本地配置已删除)"
|
||||
)
|
||||
self.androidDeviceConfigurationChanged.emit("")
|
||||
displayed_client_id = self._page.deviceIdInput.text().strip()
|
||||
self._refresh_registration_after_android_setting = bool(
|
||||
displayed_client_id and displayed_client_id != DEVICE_ID_PLACEHOLDER
|
||||
)
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
def _on_android_device_setting_failed(
|
||||
@@ -1375,6 +1131,7 @@ class SettingsPageEventBinder(QObject):
|
||||
self._page.deviceStatusLabel.setText(
|
||||
f"{action_text}失败:{message};原设备配置未更改,可重试"
|
||||
)
|
||||
self._refresh_registration_after_android_setting = False
|
||||
|
||||
@pyqtSlot()
|
||||
def _on_android_device_setting_finished(self) -> None:
|
||||
@@ -1383,6 +1140,9 @@ class SettingsPageEventBinder(QObject):
|
||||
self._android_setting_busy = False
|
||||
if not self._closing:
|
||||
self._sync_button_state()
|
||||
if self._refresh_registration_after_android_setting:
|
||||
self._refresh_registration_after_android_setting = False
|
||||
QTimer.singleShot(0, self._request_save_current_device)
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
def _on_local_saved(self, client_id: str, client_name: str) -> None:
|
||||
@@ -1449,11 +1209,6 @@ class SettingsPageEventBinder(QObject):
|
||||
thread.quit()
|
||||
thread.wait(4000)
|
||||
|
||||
live_thread = self._live_purchase_thread
|
||||
if live_thread is not None and live_thread.isRunning():
|
||||
live_thread.quit()
|
||||
live_thread.wait(4000)
|
||||
|
||||
search_worker = self._search_worker
|
||||
search_thread = self._search_thread
|
||||
if search_worker is not None:
|
||||
|
||||
Reference in New Issue
Block a user