Activate once: persist hub URL/token locally and skip dialog on later launches.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+4
-3
@@ -3,13 +3,14 @@
|
||||
## 功能
|
||||
|
||||
- 连接本机已登录 MT5,市价开平、ATR 止损止盈、保本、满仓灰显等(由原 `MT5黄金方案/Desktop` 迁入)
|
||||
- **通用包 + 首次激活**:启动时填写中控地址与激活码
|
||||
- **打开复盘**:主界面按钮用浏览器打开中控 `/login`,用网页账号直接登录复盘
|
||||
- **通用包 + 首次激活**:仅第一次填写中控地址与激活码,写入本机后以后自动连接
|
||||
- **打开复盘**:用已保存的中控地址打开 `/login`,无需再输入
|
||||
- **自动上报**:开仓/平仓成功后 `POST /api/v1/trades`,并上传 M1/M5/M15/H1 K 线供网页复盘
|
||||
|
||||
## 本地配置
|
||||
|
||||
激活信息保存在:`%USERPROFILE%\.gold_monitor\device.json`
|
||||
激活信息保存在:`%USERPROFILE%\.gold_monitor\device.json`(含 `server`、`token` 等)。
|
||||
已激活后启动不再弹窗;删掉该文件才会再次要求激活。
|
||||
|
||||
## 开发运行
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""首次激活对话框:服务器地址 + 激活码。"""
|
||||
"""首次激活对话框:仅第一次填写中控地址 + 激活码;之后自动读取本地配置。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import tkinter as tk
|
||||
@@ -7,7 +7,7 @@ from tkinter import messagebox, ttk
|
||||
from typing import Optional
|
||||
|
||||
import hub_client
|
||||
from device_store import load_device, machine_fingerprint
|
||||
from device_store import is_activated, load_device, machine_fingerprint
|
||||
|
||||
|
||||
def _bring_front(win: tk.Misc) -> None:
|
||||
@@ -23,8 +23,18 @@ def _bring_front(win: tk.Misc) -> None:
|
||||
|
||||
|
||||
def ensure_activated(parent: Optional[tk.Misc] = None) -> bool:
|
||||
"""已激活且能 ping 通则通过;否则弹出激活窗。返回是否可继续。"""
|
||||
device = load_device()
|
||||
"""
|
||||
- 已激活(本地有 server + token):直接放行,不再弹窗;中控地址固定复用。
|
||||
- 未激活:弹出首次激活窗,成功后写入 device.json。
|
||||
"""
|
||||
if is_activated():
|
||||
# 后台轻量探测(失败也不打扰,主界面仍可用,上报会静默失败)
|
||||
try:
|
||||
hub_client.ping()
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
|
||||
owns_root = False
|
||||
if parent is not None:
|
||||
root = parent
|
||||
@@ -33,29 +43,17 @@ def ensure_activated(parent: Optional[tk.Misc] = None) -> bool:
|
||||
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
|
||||
|
||||
# 单独可见窗口,避免「正在启动」残窗 + 按钮被裁切
|
||||
if owns_root:
|
||||
win = root
|
||||
else:
|
||||
win = tk.Toplevel(root)
|
||||
win.title("激活黄金辅助")
|
||||
win.title("首次激活 · 黄金辅助")
|
||||
win.minsize(520, 420)
|
||||
win.geometry("520x420")
|
||||
win.resizable(True, True)
|
||||
result = {"ok": False}
|
||||
device = load_device()
|
||||
|
||||
# 底部按钮区先占位,保证高 DPI 下仍可见
|
||||
btn_bar = ttk.Frame(win, padding=(16, 10, 16, 16))
|
||||
btn_bar.pack(side=tk.BOTTOM, fill=tk.X)
|
||||
|
||||
@@ -64,17 +62,17 @@ def ensure_activated(parent: Optional[tk.Misc] = None) -> bool:
|
||||
|
||||
ttk.Label(
|
||||
body,
|
||||
text="首次使用请输入中控地址与激活码(网页下载中心生成)",
|
||||
text="首次使用:填写中控地址与激活码。激活成功后会保存在本机,以后打开无需再填。",
|
||||
wraplength=470,
|
||||
).pack(anchor="w")
|
||||
|
||||
ttk.Label(body, text="服务器地址(例:http://192.168.1.10:5800)").pack(
|
||||
ttk.Label(body, text="中控地址(例:http://192.168.1.10:5800)").pack(
|
||||
anchor="w", pady=(14, 4)
|
||||
)
|
||||
var_server = tk.StringVar(value=device.get("server") or "http://127.0.0.1:5800")
|
||||
ttk.Entry(body, textvariable=var_server).pack(fill=tk.X, ipady=3)
|
||||
|
||||
ttk.Label(body, text="激活码").pack(anchor="w", pady=(12, 4))
|
||||
ttk.Label(body, text="激活码(网页下载中心生成)").pack(anchor="w", pady=(12, 4))
|
||||
var_code = tk.StringVar()
|
||||
ttk.Entry(body, textvariable=var_code).pack(fill=tk.X, ipady=3)
|
||||
|
||||
@@ -86,14 +84,15 @@ def ensure_activated(parent: Optional[tk.Misc] = None) -> bool:
|
||||
status.pack(anchor="w", pady=(14, 0))
|
||||
|
||||
def do_skip():
|
||||
# 离线:不写 token,下次仍会提示首次激活
|
||||
result["ok"] = True
|
||||
win.destroy()
|
||||
|
||||
def do_ok():
|
||||
server = var_server.get().strip()
|
||||
server = var_server.get().strip().rstrip("/")
|
||||
code = var_code.get().strip()
|
||||
if not server or not code:
|
||||
status.configure(text="请填写服务器与激活码", foreground="#f6465d")
|
||||
status.configure(text="请填写中控地址与激活码", foreground="#f6465d")
|
||||
return
|
||||
status.configure(text="正在激活…", foreground="#888")
|
||||
win.update_idletasks()
|
||||
@@ -103,13 +102,17 @@ def ensure_activated(parent: Optional[tk.Misc] = None) -> bool:
|
||||
)
|
||||
result["ok"] = True
|
||||
messagebox.showinfo(
|
||||
"激活成功", "已绑定账户与机器,成交将上报复盘中心。", parent=win
|
||||
"激活成功",
|
||||
f"已绑定中控:{server}\n以后打开将自动连接,无需再输入。",
|
||||
parent=win,
|
||||
)
|
||||
win.destroy()
|
||||
except hub_client.HubError as exc:
|
||||
status.configure(text=str(exc), foreground="#f6465d")
|
||||
|
||||
ttk.Button(btn_bar, text="离线使用", command=do_skip).pack(side=tk.LEFT, ipadx=8, ipady=4)
|
||||
ttk.Button(btn_bar, text="离线使用(下次仍会提示激活)", command=do_skip).pack(
|
||||
side=tk.LEFT, ipadx=6, ipady=4
|
||||
)
|
||||
ttk.Button(btn_bar, text="确认激活", command=do_ok).pack(side=tk.RIGHT, ipadx=12, ipady=4)
|
||||
win.bind("<Return>", lambda _e: do_ok())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user