diff --git a/app/gui/main_window.py b/app/gui/main_window.py index 3174eea..e504502 100644 --- a/app/gui/main_window.py +++ b/app/gui/main_window.py @@ -117,7 +117,6 @@ class MainWindow(QMainWindow): self._subscription_worker = None self._subscription_thread = None self._subscription_request_token = 0 - self._subscription_prompt_key = "" self._subscription_closed = False self.tabs = QTabWidget() self.tabs.setObjectName("mainTabs") @@ -233,13 +232,13 @@ class MainWindow(QMainWindow): widget.refresh_gateway_state() label = "自定义网关" if str(backend) == "direct" else "默认网关" self.show_status("设置已保存,当前使用%s" % label, level="success") - self.begin_subscription_check(show_prompt=False) + self.begin_subscription_check() @property def subscription_status(self): return self._subscription_status - def begin_subscription_check(self, *, show_prompt=True): + def begin_subscription_check(self): """Refresh membership state without blocking the Qt GUI thread.""" self._subscription_request_token += 1 @@ -253,17 +252,15 @@ class MainWindow(QMainWindow): cmhub_config_path=self.config.get("cmhub_config_path"), ) worker.finished.connect( - lambda payload, token=token, show_prompt=show_prompt: self._on_subscription_checked( + lambda payload, token=token: self._on_subscription_checked( token, payload, - show_prompt=show_prompt, ) ) worker.cancelled.connect( - lambda payload, token=token, show_prompt=show_prompt: self._on_subscription_checked( + lambda payload, token=token: self._on_subscription_checked( token, payload, - show_prompt=show_prompt, ) ) thread = run_worker(worker, thread_name="SubscriptionCheckWorker", start=False) @@ -282,24 +279,24 @@ class MainWindow(QMainWindow): self.show_status("正在验证会员状态,请稍后再%s" % action_name, level="info") return False self.show_status("%s:%s" % (action_name, status.user_message), level="warning") - self._show_subscription_access_prompt(status) + self.open_settings_tab() return False - def _on_subscription_checked(self, token, payload, *, show_prompt=True): + def _on_subscription_checked(self, token, payload): if self._subscription_closed or token != self._subscription_request_token: return result = payload.get("subscription") if isinstance(payload, dict) else None if not isinstance(result, subscription.SubscriptionStatus): result = subscription.SubscriptionStatus(subscription.STATUS_UNAVAILABLE) self._subscription_status = result - self._apply_subscription_status(result, show_prompt=show_prompt) + self._apply_subscription_status(result) def _forget_subscription_thread(self, thread): if self._subscription_thread is thread: self._subscription_thread = None self._subscription_worker = None - def _apply_subscription_status(self, status, *, show_prompt=True): + def _apply_subscription_status(self, status): self._subscription_status = status if status.state == subscription.STATUS_ACTIVE: expiry = subscription.format_expiry(status.expires_at) @@ -326,8 +323,6 @@ class MainWindow(QMainWindow): return self.open_settings_tab() self.show_status(status.user_message, level=self._subscription_level(status)) - if show_prompt: - self._show_subscription_access_prompt(status) @staticmethod def _subscription_level(status): @@ -345,35 +340,6 @@ class MainWindow(QMainWindow): for index, title in enumerate(TAB_TITLES): self.tabs.setTabEnabled(index, bool(enabled) or title == "设置") - def _show_subscription_access_prompt(self, status): - if self._subscription_closed: - return - if status.state in {subscription.STATUS_ACTIVE, subscription.STATUS_GRACE, subscription.STATUS_LEGACY}: - return - prompt_key = "|".join((status.state, status.notice_id, status.manage_url)) - if prompt_key and prompt_key == self._subscription_prompt_key: - return - self._subscription_prompt_key = prompt_key - box = QMessageBox(self) - box.setIcon(QMessageBox.Warning) - box.setWindowTitle("需要配置会员账号") - box.setText(status.user_message) - box.setInformativeText("请配置有效的 cmhub API Key,或前往线上会员中心开通、续费后重试。") - settings_button = box.addButton("打开设置", QMessageBox.AcceptRole) - manage_button = None - if status.manage_url: - manage_button = box.addButton("前往会员中心", QMessageBox.ActionRole) - exit_button = box.addButton("退出", QMessageBox.RejectRole) - box.setDefaultButton(settings_button) - box.setEscapeButton(exit_button) - box.exec() - if box.clickedButton() is settings_button: - self.open_settings_tab() - elif manage_button is not None and box.clickedButton() is manage_button: - QDesktopServices.openUrl(QUrl(status.manage_url)) - elif box.clickedButton() is exit_button: - self.close() - def _show_subscription_notice_once(self, status): notice_id = str(status.notice_id or "").strip() if not notice_id or notice_id == appconfig.subscription_notice_id(self.config): diff --git a/docs/tasks/T-686.md b/docs/tasks/T-686.md index ac0c04d..12ce3f1 100644 --- a/docs/tasks/T-686.md +++ b/docs/tasks/T-686.md @@ -29,7 +29,7 @@ cmhub 需提供 `GET /api/v1/cmshopee/subscription/status`。2026-07-21 无凭 ### 2. 启动访问状态与界面 - 强制升级检查完成后,在不阻塞 Qt 主线程的 worker 中查询订阅状态;账户验证和窗口销毁必须防止陈旧回调覆盖新状态。 -- 当订阅接口已启用时:未配置 Key、Key 无效、账号禁用、未订阅、订阅到期或撤销进入账号接入/订阅引导界面;只保留“打开设置”“前往线上会员中心”“退出”和本地数据备份/导出恢复路径,不启动新的产品工作流。 +- 当订阅接口已启用时:未配置 Key、Key 无效、账号禁用、未订阅、订阅到期或撤销自动切到“设置”并在状态栏提示;不弹出阻断式“需要配置会员账号”窗口,不启动新的产品工作流。 - 订阅有效或处于宽限期时进入正常工作区;在现有应用顶部标题区域右侧使用紧凑只读标签展示“账号名 · 套餐名 · 有效至日期”。不得修改 Windows 原生窗口标题来承载长文本。 - “前往会员中心”只能使用默认浏览器打开服务端 `manage_url`;客户端不新增登录、支付、订单或密码输入页面。所有新文案为中文,不能展示 API Key、设备摘要、支付数据或原始 HTTP 报错。 - 旧服务未启用接口时显示低干扰中文兼容提示,不弹出阻断式会员窗口;接口可用后首次状态/`notice_id` 变化再提示,避免每次启动重复弹窗。 @@ -87,3 +87,5 @@ git diff --check - 2026-07-21:任务创建;cmhub 订阅状态接口尚未上线,需在实现中保持 `404` 旧服务兼容。 - 2026-07-21:新增 `app/subscription.py` 和 `SubscriptionCheckWorker`,复用 cmhub 共享 HTTP 会话查询订阅状态;主窗口在显示后异步检查,顶部显示账号/套餐/有效期,受限状态只保留设置恢复入口。② AI生成、⑥商品套图和 AI帮写的新提交接入同一预检,旧服务 `404` 放行既有工作流。 - 2026-07-21:验证通过:`py -3.10 -m compileall app main.py`、`py -3.10 -m ruff check app tests main.py`、订阅/应用配置/AI/套图/GUI 定向测试,以及 `py -3.10 -m unittest discover -s tests`(664 项)。无凭据请求线上订阅状态接口返回 `404`,已由单测和运行时兼容分支覆盖;服务端上线后需使用测试 API Key 做一次真实有效/到期/未订阅联调,不属于本仓库可完成的接口发布工作。 +- 2026-07-22:产品决策调整:移除未配置或未开通会员时的阻断式弹窗;保留工作流访问限制、自动切换“设置”和状态栏提示,避免每次启动或新提交被会员配置窗口打断。 +- 2026-07-22:验证通过:`py -3.10 -m compileall app main.py`、`py -3.10 -m ruff check app tests main.py`、`py -3.10 -m unittest discover -s tests -p test_gui.py`,以及完整单测 `py -3.10 -m unittest discover -s tests`(664 项)。 diff --git a/tests/test_gui.py b/tests/test_gui.py index e0bd570..e686e39 100644 --- a/tests/test_gui.py +++ b/tests/test_gui.py @@ -11166,7 +11166,7 @@ class GuiTests(TempDirMixin, unittest.TestCase): expires_at="2026-08-20T23:59:59+08:00", ) - window._apply_subscription_status(status, show_prompt=False) + window._apply_subscription_status(status) self.assertIn("主账号 · 专业版 · 有效至2026-08-20", window._subscription_label.text()) self.assertTrue( @@ -11179,7 +11179,7 @@ class GuiTests(TempDirMixin, unittest.TestCase): self.addCleanup(window.close) status = subscription.SubscriptionStatus(subscription.STATUS_EXPIRED) - window._apply_subscription_status(status, show_prompt=False) + window._apply_subscription_status(status) for index, title in enumerate(TAB_TITLES): self.assertEqual(title == "设置", window.tabs.isTabEnabled(index))