feat: 切换正式管理端默认地址 (#148)
This commit is contained in:
@@ -6,12 +6,29 @@ import uuid
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable, Optional
|
||||
|
||||
from .http_admin_gateway import DEFAULT_ADMIN_BASE_URL
|
||||
from .settings_repository import SettingsRepository
|
||||
|
||||
|
||||
CLIENT_ID_KEY = "admin.client_id"
|
||||
CLIENT_NAME_KEY = "admin.client_name"
|
||||
ADMIN_BASE_URL_KEY = "admin.base_url"
|
||||
LEGACY_ADMIN_BASE_URL = "http://127.0.0.1:8080"
|
||||
|
||||
|
||||
def load_admin_base_url(repository: SettingsRepository) -> str:
|
||||
"""读取管理端地址,并把空值或旧默认值迁移到当前默认地址。"""
|
||||
|
||||
saved_value = repository.get(ADMIN_BASE_URL_KEY)
|
||||
normalized_value = (
|
||||
saved_value.strip().rstrip("/")
|
||||
if isinstance(saved_value, str)
|
||||
else ""
|
||||
)
|
||||
if not normalized_value or normalized_value == LEGACY_ADMIN_BASE_URL:
|
||||
repository.set(ADMIN_BASE_URL_KEY, DEFAULT_ADMIN_BASE_URL)
|
||||
return DEFAULT_ADMIN_BASE_URL
|
||||
return normalized_value
|
||||
|
||||
|
||||
def generate_client_device_id() -> str:
|
||||
|
||||
@@ -22,7 +22,7 @@ from .admin_gateway import (
|
||||
from .task_models import TaskType
|
||||
|
||||
|
||||
DEFAULT_ADMIN_BASE_URL = "http://127.0.0.1:8080"
|
||||
DEFAULT_ADMIN_BASE_URL = "https://buy.833729.com"
|
||||
|
||||
|
||||
class HttpAdminGateway(AdminGateway):
|
||||
|
||||
@@ -43,8 +43,8 @@ from .admin_gateway import (
|
||||
AdminGateway,
|
||||
)
|
||||
from .collect_task_service import CollectServiceFactory, CollectTaskService
|
||||
from .current_client_service import CurrentClientService
|
||||
from .http_admin_gateway import DEFAULT_ADMIN_BASE_URL, HttpAdminGateway
|
||||
from .current_client_service import CurrentClientService, load_admin_base_url
|
||||
from .http_admin_gateway import HttpAdminGateway
|
||||
from .pdd_ui import PDDTaskPage, TaskRow
|
||||
from .pdd_device_service import (
|
||||
PersistentPddDeviceService,
|
||||
@@ -630,7 +630,7 @@ class PDDTaskPageEvent(QObject):
|
||||
self._owns_claim_gateway = claim_gateway is None
|
||||
self._claim_gateway_error = ""
|
||||
if self._claim_gateway is None:
|
||||
base_url = settings.get("admin.base_url", DEFAULT_ADMIN_BASE_URL)
|
||||
base_url = load_admin_base_url(settings)
|
||||
timeout_value = settings.get("admin.request_timeout_seconds", 3.0)
|
||||
try:
|
||||
timeout_seconds = float(timeout_value)
|
||||
|
||||
@@ -244,7 +244,7 @@ class SettingsPage(QWidget):
|
||||
self.deviceNameInput.setAccessibleName("当前客户端设备名")
|
||||
|
||||
self.adminBaseUrlInput = LineEdit(self)
|
||||
self.adminBaseUrlInput.setPlaceholderText("http://127.0.0.1:8080")
|
||||
self.adminBaseUrlInput.setPlaceholderText("https://buy.833729.com")
|
||||
self.adminBaseUrlInput.setClearButtonEnabled(True)
|
||||
self.adminBaseUrlInput.setAccessibleName("Admin 管理端地址")
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@ from .admin_gateway import (
|
||||
ClientRegistrationGateway,
|
||||
)
|
||||
from .current_client_service import (
|
||||
ADMIN_BASE_URL_KEY,
|
||||
CurrentClientService,
|
||||
generate_client_device_id,
|
||||
load_admin_base_url,
|
||||
)
|
||||
from .http_admin_gateway import DEFAULT_ADMIN_BASE_URL, HttpAdminGateway
|
||||
from .http_admin_gateway import HttpAdminGateway
|
||||
from .selected_android_device_service import SelectedAndroidDeviceService
|
||||
from .settings_repository import SettingsRepository
|
||||
from .settings_ui import AndroidDeviceRow
|
||||
@@ -381,7 +381,7 @@ class SettingsPageEventBinder(QObject):
|
||||
self._pending_admin_gateway = None
|
||||
self._gateway_error = ""
|
||||
if self._admin_gateway is None:
|
||||
base_url = repository.get("admin.base_url", DEFAULT_ADMIN_BASE_URL)
|
||||
base_url = load_admin_base_url(repository)
|
||||
timeout_value = repository.get("admin.request_timeout_seconds", 3.0)
|
||||
try:
|
||||
timeout_seconds = float(timeout_value)
|
||||
@@ -946,14 +946,8 @@ class SettingsPageEventBinder(QObject):
|
||||
"""页面创建时恢复本地 Client 信息。"""
|
||||
|
||||
try:
|
||||
base_url = self._settings_repository.get(
|
||||
ADMIN_BASE_URL_KEY,
|
||||
DEFAULT_ADMIN_BASE_URL,
|
||||
)
|
||||
displayed_base_url = (
|
||||
base_url.strip()
|
||||
if isinstance(base_url, str) and base_url.strip()
|
||||
else DEFAULT_ADMIN_BASE_URL
|
||||
displayed_base_url = load_admin_base_url(
|
||||
self._settings_repository
|
||||
)
|
||||
saved = self._client_service.load()
|
||||
except Exception as exc:
|
||||
|
||||
@@ -4,7 +4,11 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from src.current_client_service import CurrentClientService
|
||||
from src.current_client_service import (
|
||||
CurrentClientService,
|
||||
load_admin_base_url,
|
||||
)
|
||||
from src.http_admin_gateway import DEFAULT_ADMIN_BASE_URL
|
||||
from src.settings_repository import SettingsRepository
|
||||
|
||||
|
||||
@@ -52,6 +56,41 @@ class CurrentClientServiceTest(unittest.TestCase):
|
||||
self.assertEqual(saved.client_id, "CLIENT-GENERATED-1")
|
||||
self.assertEqual(saved.client_name, "新设备")
|
||||
|
||||
def test_missing_admin_base_url_is_saved_as_current_default(self):
|
||||
self.assertEqual(
|
||||
load_admin_base_url(self.repository),
|
||||
DEFAULT_ADMIN_BASE_URL,
|
||||
)
|
||||
self.assertEqual(
|
||||
self.repository.get("admin.base_url"),
|
||||
DEFAULT_ADMIN_BASE_URL,
|
||||
)
|
||||
|
||||
def test_legacy_admin_base_url_is_migrated(self):
|
||||
self.repository.set("admin.base_url", "http://127.0.0.1:8080/")
|
||||
|
||||
self.assertEqual(
|
||||
load_admin_base_url(self.repository),
|
||||
DEFAULT_ADMIN_BASE_URL,
|
||||
)
|
||||
self.assertEqual(
|
||||
self.repository.get("admin.base_url"),
|
||||
DEFAULT_ADMIN_BASE_URL,
|
||||
)
|
||||
|
||||
def test_custom_admin_base_url_is_preserved(self):
|
||||
custom_url = "https://admin.example.com/service/"
|
||||
self.repository.set("admin.base_url", custom_url)
|
||||
|
||||
self.assertEqual(
|
||||
load_admin_base_url(self.repository),
|
||||
"https://admin.example.com/service",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.repository.get("admin.base_url"),
|
||||
custom_url,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -13,7 +13,7 @@ from src.admin_gateway import (
|
||||
ClaimCapabilities,
|
||||
ClientInfo,
|
||||
)
|
||||
from src.http_admin_gateway import HttpAdminGateway
|
||||
from src.http_admin_gateway import DEFAULT_ADMIN_BASE_URL, HttpAdminGateway
|
||||
from src.task_models import TaskType
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ class HttpAdminGatewayTest(unittest.TestCase):
|
||||
self.assertTrue(receipt.accepted)
|
||||
self.assertEqual(
|
||||
opener.request.full_url,
|
||||
"http://127.0.0.1:8080/api/v1/client/tasks/COL-001/result",
|
||||
f"{DEFAULT_ADMIN_BASE_URL}/api/v1/client/tasks/COL-001/result",
|
||||
)
|
||||
headers = {
|
||||
key.lower(): value for key, value in opener.request.header_items()
|
||||
@@ -256,7 +256,7 @@ class HttpAdminGatewayTest(unittest.TestCase):
|
||||
self.assertEqual(opener.request.get_method(), "POST")
|
||||
self.assertEqual(
|
||||
opener.request.full_url,
|
||||
"http://127.0.0.1:8080/api/v1/client/tasks/claim",
|
||||
f"{DEFAULT_ADMIN_BASE_URL}/api/v1/client/tasks/claim",
|
||||
)
|
||||
headers = {
|
||||
key.lower(): value for key, value in opener.request.header_items()
|
||||
|
||||
@@ -290,7 +290,7 @@ class SettingsPageEventTest(unittest.TestCase):
|
||||
{
|
||||
"admin.client_id": "CLIENT-EXISTING",
|
||||
"admin.client_name": "原设备名",
|
||||
"admin.base_url": "http://127.0.0.1:8080",
|
||||
"admin.base_url": "http://127.0.0.1:9090",
|
||||
}
|
||||
)
|
||||
gateway = MockAdminGateway()
|
||||
@@ -309,7 +309,7 @@ class SettingsPageEventTest(unittest.TestCase):
|
||||
self.assertEqual(self.repository.get("admin.client_name"), "原设备名")
|
||||
self.assertEqual(
|
||||
self.repository.get("admin.base_url"),
|
||||
"http://127.0.0.1:8080",
|
||||
"http://127.0.0.1:9090",
|
||||
)
|
||||
self.assertEqual(gateway.registration_count, 0)
|
||||
self.assertIn("Admin 服务地址必须", page.currentDeviceStatusLabel.text())
|
||||
@@ -330,7 +330,10 @@ class SettingsPageEventTest(unittest.TestCase):
|
||||
page.currentDeviceSaveButton.click()
|
||||
self.app.processEvents()
|
||||
|
||||
self.assertIsNone(self.repository.get("admin.base_url"))
|
||||
self.assertEqual(
|
||||
self.repository.get("admin.base_url"),
|
||||
DEFAULT_ADMIN_BASE_URL,
|
||||
)
|
||||
self.assertEqual(gateway.registration_count, 0)
|
||||
self.assertIn("不能包含账号、密码", page.currentDeviceStatusLabel.text())
|
||||
page.eventBinder.shutdown()
|
||||
|
||||
@@ -284,7 +284,7 @@ class TaskTableModel(QAbstractTableModel):
|
||||
### 当前设备
|
||||
|
||||
- 第一行依次显示设备号和设备名;设备号只读,设备名可以修改,两组输入随窗口宽度平均伸缩;
|
||||
- 第二行显示“管理端地址”,对应 SQLite 中已有的 `admin.base_url`,没有保存值时显示默认地址;
|
||||
- 第二行显示“管理端地址”,对应 SQLite 中已有的 `admin.base_url`;默认地址为 `https://buy.833729.com`,没有保存值或保存值仍是旧默认地址 `http://127.0.0.1:8080` 时自动迁移,用户手动保存的其他地址不得覆盖;
|
||||
- 点击“保存”前先验证地址;只接受有效的 HTTP/HTTPS 地址,不能包含账号、密码、查询参数或片段。验证失败时不保存设备号、设备名或地址,并把焦点放回地址输入框;
|
||||
- 保存成功后立即用新地址登记 Client,后续任务领取、结果提交和失败提交也统一切换到新地址;已经发出的请求等待自身结束,不强制中断;
|
||||
- 保存不新增数据库表,不增加心跳,也不连接或操作 Android 设备。
|
||||
|
||||
Reference in New Issue
Block a user