# -*- coding: utf-8 -*- """首次激活对话框:服务器地址 + 激活码。""" from __future__ import annotations import tkinter as tk from tkinter import messagebox, ttk from typing import Optional import hub_client from device_store import load_device, machine_fingerprint def _bring_front(win: tk.Misc) -> None: """确保对话框在 Windows 上可见(避免挂在 withdraw 根窗后不显示)。""" try: win.update_idletasks() win.deiconify() win.lift() win.focus_force() win.attributes("-topmost", True) win.after(200, lambda: win.attributes("-topmost", False)) except Exception: pass def ensure_activated(parent: Optional[tk.Misc] = None) -> bool: """已激活且能 ping 通则通过;否则弹出激活窗。返回是否可继续。""" device = load_device() owns_root = False root: tk.Misc if parent is not None: root = parent else: root = tk.Tk() root.title("黄金市价辅助") root.geometry("360x80") ttk.Label(root, text="正在启动…").pack(expand=True, padx=16, pady=16) root.update() owns_root = True try: if device.get("token") and device.get("server"): if hub_client.ping(): return True _bring_front(root) if not messagebox.askyesno( "激活校验", "无法连接中控或令牌失效,是否重新激活?\n选「否」将以离线模式继续(不上报复盘)。", parent=root, ): return True win = tk.Toplevel(root) win.title("激活黄金辅助") win.geometry("480x300") win.resizable(False, False) # 不要 transient 到已隐藏的父窗,否则 Windows 上常不显示 result = {"ok": False} frm = ttk.Frame(win, padding=16) frm.pack(fill=tk.BOTH, expand=True) ttk.Label(frm, text="首次使用请输入中控地址与激活码(网页下载中心生成)").pack(anchor="w") ttk.Label(frm, text="服务器地址(例:http://192.168.1.10:5800)").pack(anchor="w", pady=(12, 4)) var_server = tk.StringVar(value=device.get("server") or "http://127.0.0.1:5800") ttk.Entry(frm, textvariable=var_server, width=48).pack(fill=tk.X) ttk.Label(frm, text="激活码").pack(anchor="w", pady=(12, 4)) var_code = tk.StringVar() ttk.Entry(frm, textvariable=var_code, width=48).pack(fill=tk.X) ttk.Label(frm, text="本机名称(可改)").pack(anchor="w", pady=(12, 4)) var_name = tk.StringVar(value=device.get("machine_name") or "") ttk.Entry(frm, textvariable=var_name, width=48).pack(fill=tk.X) status = ttk.Label(frm, text="", foreground="#888") status.pack(anchor="w", pady=(10, 0)) def do_skip(): result["ok"] = True win.destroy() def do_ok(): server = var_server.get().strip() code = var_code.get().strip() if not server or not code: status.configure(text="请填写服务器与激活码", foreground="#f6465d") return try: hub_client.activate( server, code, machine_fingerprint(), var_name.get().strip() or "PC" ) result["ok"] = True messagebox.showinfo( "激活成功", "已绑定账户与机器,成交将上报复盘中心。", parent=win ) win.destroy() except hub_client.HubError as exc: status.configure(text=str(exc), foreground="#f6465d") btns = ttk.Frame(frm) btns.pack(fill=tk.X, pady=(16, 0)) ttk.Button(btns, text="离线使用", command=do_skip).pack(side=tk.LEFT) ttk.Button(btns, text="激活", command=do_ok).pack(side=tk.RIGHT) win.protocol("WM_DELETE_WINDOW", do_skip) _bring_front(win) win.grab_set() root.wait_window(win) return result["ok"] finally: if owns_root: try: root.destroy() except Exception: pass