917 lines
34 KiB
Python
917 lines
34 KiB
Python
import sys
|
||
from pathlib import Path
|
||
import logging
|
||
import os
|
||
from PIL import Image
|
||
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||
QLabel, QLineEdit, QPushButton, QFrame, QTextEdit,
|
||
QMessageBox, QApplication, QSystemTrayIcon, QMenu,
|
||
QDialog, QProgressBar, QStyle)
|
||
from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal
|
||
from PyQt5.QtGui import QIcon, QPixmap
|
||
|
||
sys.path.append(str(Path(__file__).parent.parent))
|
||
|
||
from utils.config import Config
|
||
from account_switcher import AccountSwitcher
|
||
|
||
def get_version():
|
||
try:
|
||
version_file = Path(__file__).parent.parent / 'version.txt'
|
||
with open(version_file, 'r', encoding='utf-8') as f:
|
||
return f.read().strip()
|
||
except Exception as e:
|
||
logging.error(f"读取版本号失败: {str(e)}")
|
||
return "未知版本"
|
||
|
||
class LoadingDialog(QDialog):
|
||
"""加载对话框"""
|
||
def __init__(self, parent=None, message="请稍候..."):
|
||
super().__init__(parent)
|
||
self.setWindowTitle("处理中")
|
||
self.setFixedSize(300, 100)
|
||
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint)
|
||
|
||
layout = QVBoxLayout()
|
||
|
||
# 添加消息标签
|
||
self.message_label = QLabel(message)
|
||
self.message_label.setAlignment(Qt.AlignCenter)
|
||
layout.addWidget(self.message_label)
|
||
|
||
# 添加进度条
|
||
self.progress_bar = QProgressBar()
|
||
self.progress_bar.setTextVisible(False)
|
||
self.progress_bar.setRange(0, 0) # 设置为循环模式
|
||
layout.addWidget(self.progress_bar)
|
||
|
||
self.setLayout(layout)
|
||
|
||
# 设置样式
|
||
self.setStyleSheet("""
|
||
QDialog {
|
||
background-color: #f8f9fa;
|
||
}
|
||
QLabel {
|
||
color: #333333;
|
||
font-size: 14px;
|
||
padding: 10px;
|
||
}
|
||
QProgressBar {
|
||
border: 2px solid #e9ecef;
|
||
border-radius: 5px;
|
||
text-align: center;
|
||
}
|
||
QProgressBar::chunk {
|
||
background-color: #0d6efd;
|
||
width: 10px;
|
||
margin: 0.5px;
|
||
}
|
||
""")
|
||
|
||
class ApiWorker(QThread):
|
||
"""API请求工作线程"""
|
||
finished = pyqtSignal(tuple) # 发送结果信号
|
||
|
||
def __init__(self, func, *args, **kwargs):
|
||
super().__init__()
|
||
self.func = func
|
||
self.args = args
|
||
self.kwargs = kwargs
|
||
|
||
def run(self):
|
||
try:
|
||
result = self.func(*self.args, **self.kwargs)
|
||
self.finished.emit((True, result))
|
||
except Exception as e:
|
||
self.finished.emit((False, str(e)))
|
||
|
||
class MainWindow(QMainWindow):
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.config = Config()
|
||
self.switcher = AccountSwitcher()
|
||
|
||
# 添加激活状态缓存
|
||
self._activation_status = None # 缓存的激活状态
|
||
self._status_timer = None # 状态更新定时器
|
||
|
||
version = get_version()
|
||
cursor_version = self.switcher.get_cursor_version()
|
||
self.setWindowTitle(f"听泉Cursor助手 v{version} (本机Cursor版本: {cursor_version})")
|
||
self.setMinimumSize(600, 500)
|
||
|
||
# 设置窗口图标
|
||
icon_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "icon", "two.ico")
|
||
if os.path.exists(icon_path):
|
||
window_icon = QIcon(icon_path)
|
||
if not window_icon.isNull():
|
||
self.setWindowIcon(window_icon)
|
||
logging.info(f"成功设置窗口图标: {icon_path}")
|
||
|
||
# 创建系统托盘图标
|
||
self.tray_icon = QSystemTrayIcon(self)
|
||
self.tray_icon.setIcon(self.windowIcon())
|
||
self.tray_icon.setToolTip("听泉Cursor助手")
|
||
|
||
# 创建托盘菜单
|
||
tray_menu = QMenu()
|
||
show_action = tray_menu.addAction("显示主窗口")
|
||
show_action.triggered.connect(self.show)
|
||
quit_action = tray_menu.addAction("退出")
|
||
quit_action.triggered.connect(QApplication.instance().quit)
|
||
|
||
# 设置托盘菜单
|
||
self.tray_icon.setContextMenu(tray_menu)
|
||
|
||
# 连接托盘图标的信号
|
||
self.tray_icon.activated.connect(self.on_tray_icon_activated)
|
||
|
||
# 显示托盘图标
|
||
self.tray_icon.show()
|
||
|
||
# 创建主窗口部件
|
||
central_widget = QWidget()
|
||
self.setCentralWidget(central_widget)
|
||
|
||
# 创建主布局
|
||
main_layout = QVBoxLayout(central_widget)
|
||
|
||
# 设备ID区域
|
||
device_frame = QFrame()
|
||
device_layout = QHBoxLayout(device_frame)
|
||
device_layout.addWidget(QLabel("设备识别码(勿动):"))
|
||
self.hardware_id_edit = QLineEdit(self.switcher.hardware_id)
|
||
self.hardware_id_edit.setReadOnly(True)
|
||
device_layout.addWidget(self.hardware_id_edit)
|
||
copy_btn = QPushButton("复制ID")
|
||
copy_btn.clicked.connect(self.copy_device_id)
|
||
device_layout.addWidget(copy_btn)
|
||
main_layout.addWidget(device_frame)
|
||
|
||
# 会员状态区域
|
||
status_frame = QFrame()
|
||
status_layout = QVBoxLayout(status_frame)
|
||
status_layout.addWidget(QLabel("会员状态"))
|
||
self.status_text = QTextEdit()
|
||
self.status_text.setReadOnly(True)
|
||
self.status_text.setMinimumHeight(100)
|
||
status_layout.addWidget(self.status_text)
|
||
main_layout.addWidget(status_frame)
|
||
|
||
# 激活区域
|
||
activation_frame = QFrame()
|
||
activation_layout = QVBoxLayout(activation_frame)
|
||
|
||
# 使用说明
|
||
usage_label = QLabel()
|
||
usage_label.setText("使用说明:\n\n1. 输入激活码并点击激活\n2. 激活成功后点击\"刷新Cursor编辑器授权\"即可正常使用\n3. 如果刷新无效,请点击\"突破Cursor0.45.x限制\"\n4. 建议点击\"禁用Cursor版本更新\"保持长期稳定")
|
||
usage_label.setStyleSheet("""
|
||
QLabel {
|
||
color: #6c757d;
|
||
font-size: 13px;
|
||
padding: 10px;
|
||
background-color: #f8f9fa;
|
||
border-radius: 4px;
|
||
border: 1px solid #dee2e6;
|
||
}
|
||
""")
|
||
activation_layout.addWidget(usage_label)
|
||
|
||
# 激活码输入区域
|
||
activation_layout.addWidget(QLabel("激活(叠加)会员,多个激活码可叠加整体时长"))
|
||
input_frame = QFrame()
|
||
input_layout = QHBoxLayout(input_frame)
|
||
input_layout.addWidget(QLabel("激活码:"))
|
||
self.activation_edit = QLineEdit()
|
||
input_layout.addWidget(self.activation_edit)
|
||
activate_btn = QPushButton("激活")
|
||
activate_btn.clicked.connect(self.activate_account)
|
||
input_layout.addWidget(activate_btn)
|
||
activation_layout.addWidget(input_frame)
|
||
main_layout.addWidget(activation_frame)
|
||
|
||
# 操作按钮区域
|
||
btn_frame = QFrame()
|
||
btn_layout = QVBoxLayout(btn_frame)
|
||
|
||
# 设置按钮样式
|
||
button_style = """
|
||
QPushButton {
|
||
background-color: #0d6efd;
|
||
color: white;
|
||
border: none;
|
||
padding: 15px;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
min-width: 200px;
|
||
margin: 5px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #0b5ed7;
|
||
}
|
||
QPushButton:pressed {
|
||
background-color: #0a58ca;
|
||
}
|
||
"""
|
||
|
||
# 刷新授权按钮
|
||
refresh_btn = QPushButton("刷新Cursor编辑器授权")
|
||
refresh_btn.setStyleSheet(button_style)
|
||
refresh_btn.clicked.connect(self.refresh_cursor_auth)
|
||
refresh_btn.setMinimumHeight(50)
|
||
btn_layout.addWidget(refresh_btn)
|
||
|
||
# 突破限制按钮
|
||
bypass_btn = QPushButton("突破Cursor0.45.x限制")
|
||
bypass_btn.setStyleSheet(button_style.replace("#0d6efd", "#198754").replace("#0b5ed7", "#157347").replace("#0a58ca", "#146c43"))
|
||
bypass_btn.clicked.connect(self.dummy_function)
|
||
bypass_btn.setMinimumHeight(50)
|
||
btn_layout.addWidget(bypass_btn)
|
||
|
||
# 禁用更新按钮
|
||
disable_update_btn = QPushButton("禁用Cursor版本更新")
|
||
disable_update_btn.setStyleSheet(button_style.replace("#0d6efd", "#dc3545").replace("#0b5ed7", "#bb2d3b").replace("#0a58ca", "#b02a37"))
|
||
disable_update_btn.clicked.connect(self.disable_cursor_update)
|
||
disable_update_btn.setMinimumHeight(50)
|
||
btn_layout.addWidget(disable_update_btn)
|
||
|
||
# 设置按钮间距
|
||
btn_layout.setSpacing(10)
|
||
btn_layout.setContentsMargins(20, 10, 20, 10)
|
||
|
||
main_layout.addWidget(btn_frame)
|
||
|
||
# 启动时检查一次状态
|
||
QTimer.singleShot(0, self.check_status)
|
||
|
||
def on_tray_icon_activated(self, reason):
|
||
"""处理托盘图标的点击事件"""
|
||
if reason == QSystemTrayIcon.DoubleClick:
|
||
self.show()
|
||
self.activateWindow()
|
||
|
||
def closeEvent(self, event):
|
||
"""重写关闭事件,最小化到托盘而不是退出"""
|
||
if hasattr(self, 'tray_icon') and self.tray_icon.isVisible():
|
||
event.ignore()
|
||
self.hide()
|
||
self.tray_icon.showMessage(
|
||
"听泉Cursor助手",
|
||
"程序已最小化到系统托盘",
|
||
QSystemTrayIcon.Information,
|
||
2000
|
||
)
|
||
else:
|
||
event.accept()
|
||
|
||
if self._status_timer:
|
||
self._status_timer.stop()
|
||
super().closeEvent(event)
|
||
|
||
def copy_device_id(self):
|
||
"""复制设备ID到剪贴板"""
|
||
if not self.check_status():
|
||
return
|
||
QApplication.clipboard().setText(self.hardware_id_edit.text())
|
||
QMessageBox.information(self, "提示", "设备ID已复制到剪贴板")
|
||
|
||
def show_loading_dialog(self, message="请稍候..."):
|
||
"""显示加载对话框"""
|
||
self.loading_dialog = LoadingDialog(self, message)
|
||
self.loading_dialog.show()
|
||
|
||
def hide_loading_dialog(self):
|
||
"""隐藏加载对话框"""
|
||
if hasattr(self, 'loading_dialog'):
|
||
self.loading_dialog.hide()
|
||
self.loading_dialog.deleteLater()
|
||
|
||
def activate_account(self):
|
||
"""激活账号"""
|
||
code = self.activation_edit.text().strip()
|
||
if not code:
|
||
# 创建自定义消息框
|
||
msg = QDialog(self)
|
||
msg.setWindowTitle("提示")
|
||
msg.setFixedWidth(400)
|
||
msg.setWindowFlags(msg.windowFlags() & ~Qt.WindowContextHelpButtonHint)
|
||
|
||
# 创建布局
|
||
layout = QVBoxLayout()
|
||
|
||
# 添加图标和文本
|
||
icon_label = QLabel()
|
||
icon_label.setPixmap(self.style().standardIcon(QStyle.SP_MessageBoxWarning).pixmap(32, 32))
|
||
icon_label.setAlignment(Qt.AlignCenter)
|
||
layout.addWidget(icon_label)
|
||
|
||
text_label = QLabel("请输入激活码")
|
||
text_label.setAlignment(Qt.AlignCenter)
|
||
text_label.setStyleSheet("font-size: 14px; font-weight: bold; color: #333333; padding: 10px;")
|
||
layout.addWidget(text_label)
|
||
|
||
# 添加购买信息
|
||
info_text = "获取会员激活码,请通过以下方式:\n\n" \
|
||
"• 官方自助网站:cursor.nosqli.com\n" \
|
||
"• 微信客服:behikcigar\n" \
|
||
"• 闲鱼店铺:xxx\n\n" \
|
||
"————————————————————\n" \
|
||
"诚招代理商,欢迎加盟合作!"
|
||
|
||
info_label = QLabel(info_text)
|
||
info_label.setAlignment(Qt.AlignLeft)
|
||
info_label.setStyleSheet("""
|
||
QLabel {
|
||
color: #333333;
|
||
font-size: 14px;
|
||
padding: 15px;
|
||
background-color: #f8f9fa;
|
||
border-radius: 4px;
|
||
border: 1px solid #dee2e6;
|
||
margin: 10px;
|
||
}
|
||
""")
|
||
layout.addWidget(info_label)
|
||
|
||
# 添加复制按钮区域
|
||
btn_layout = QHBoxLayout()
|
||
|
||
# 复制网站按钮
|
||
copy_web_btn = QPushButton("复制网站")
|
||
copy_web_btn.clicked.connect(lambda: self.copy_and_show_tip(msg, "cursor.nosqli.com", "网站地址已复制到剪贴板"))
|
||
copy_web_btn.setStyleSheet("""
|
||
QPushButton {
|
||
background-color: #0d6efd;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 15px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #0b5ed7;
|
||
}
|
||
""")
|
||
btn_layout.addWidget(copy_web_btn)
|
||
|
||
# 复制微信按钮
|
||
copy_wx_btn = QPushButton("复制微信")
|
||
copy_wx_btn.clicked.connect(lambda: self.copy_and_show_tip(msg, "behikcigar", "微信号已复制到剪贴板"))
|
||
copy_wx_btn.setStyleSheet("""
|
||
QPushButton {
|
||
background-color: #198754;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 15px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #157347;
|
||
}
|
||
""")
|
||
btn_layout.addWidget(copy_wx_btn)
|
||
|
||
# 确定按钮
|
||
ok_btn = QPushButton("确定")
|
||
ok_btn.clicked.connect(msg.accept)
|
||
ok_btn.setStyleSheet("""
|
||
QPushButton {
|
||
background-color: #0d6efd;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 25px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
min-width: 100px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #0b5ed7;
|
||
}
|
||
""")
|
||
btn_layout.addWidget(ok_btn)
|
||
|
||
layout.addLayout(btn_layout)
|
||
msg.setLayout(layout)
|
||
msg.exec_()
|
||
return
|
||
|
||
try:
|
||
# 显示加载对话框
|
||
self.show_loading_dialog("正在验证激活码,请稍候...")
|
||
|
||
# 创建工作线程
|
||
self.worker = ApiWorker(self.switcher.check_activation_code, code)
|
||
self.worker.finished.connect(self.on_activation_complete)
|
||
self.worker.start()
|
||
|
||
except Exception as e:
|
||
self.hide_loading_dialog()
|
||
msg = QMessageBox(self)
|
||
msg.setWindowTitle("错误")
|
||
msg.setText(f"激活失败: {str(e)}")
|
||
msg.setIcon(QMessageBox.Critical)
|
||
msg.setStyleSheet("""
|
||
QMessageBox {
|
||
background-color: #f8f9fa;
|
||
min-width: 450px;
|
||
padding: 20px;
|
||
}
|
||
QMessageBox QLabel {
|
||
color: #333333;
|
||
font-size: 14px;
|
||
padding: 10px;
|
||
margin: 10px;
|
||
}
|
||
QMessageBox QLabel:first-child {
|
||
font-weight: bold;
|
||
color: #dc3545;
|
||
}
|
||
QPushButton {
|
||
background-color: #dc3545;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 25px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
min-width: 100px;
|
||
margin: 10px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #bb2d3b;
|
||
}
|
||
""")
|
||
msg.exec_()
|
||
|
||
def copy_and_show_tip(self, parent, text, tip):
|
||
"""复制文本并显示提示"""
|
||
QApplication.clipboard().setText(text)
|
||
QMessageBox.information(parent, "提示", tip)
|
||
|
||
def on_activation_complete(self, result):
|
||
"""激活完成回调"""
|
||
success, data = result
|
||
self.hide_loading_dialog()
|
||
|
||
if isinstance(data, tuple):
|
||
success, message, account_info = data
|
||
if success:
|
||
# 更新会员信息显示
|
||
self.update_status_display(account_info)
|
||
# 更新激活状态缓存
|
||
self._activation_status = True
|
||
|
||
# 更新状态定时器
|
||
days_left = account_info.get('days_left', 0)
|
||
seconds_left = days_left * 24 * 60 * 60
|
||
if self._status_timer:
|
||
self._status_timer.stop()
|
||
self._status_timer = QTimer(self)
|
||
self._status_timer.setSingleShot(True)
|
||
self._status_timer.timeout.connect(self.check_status)
|
||
update_interval = min(seconds_left - 60, 24 * 60 * 60) # 最长1天更新一次
|
||
if update_interval > 0:
|
||
self._status_timer.start(update_interval * 1000) # 转换为毫秒
|
||
|
||
msg = QMessageBox(self)
|
||
msg.setWindowTitle("激活成功")
|
||
msg.setText("激活成功!")
|
||
msg.setInformativeText(message)
|
||
msg.setIcon(QMessageBox.Information)
|
||
msg.setStyleSheet("""
|
||
QMessageBox {
|
||
background-color: #f8f9fa;
|
||
min-width: 500px;
|
||
padding: 20px;
|
||
}
|
||
QMessageBox QLabel {
|
||
color: #333333;
|
||
font-size: 14px;
|
||
padding: 10px;
|
||
margin: 10px;
|
||
}
|
||
QMessageBox QLabel:first-child {
|
||
font-weight: bold;
|
||
font-size: 16px;
|
||
color: #198754;
|
||
}
|
||
QPushButton {
|
||
background-color: #198754;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 25px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
min-width: 100px;
|
||
margin: 10px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #157347;
|
||
}
|
||
""")
|
||
msg.exec_()
|
||
# 清空激活码输入框
|
||
self.activation_edit.clear()
|
||
else:
|
||
msg = QMessageBox(self)
|
||
msg.setWindowTitle("激活失败")
|
||
msg.setText(message)
|
||
msg.setIcon(QMessageBox.Critical)
|
||
msg.setStyleSheet("""
|
||
QMessageBox {
|
||
background-color: #f8f9fa;
|
||
min-width: 450px;
|
||
padding: 20px;
|
||
}
|
||
QMessageBox QLabel {
|
||
color: #333333;
|
||
font-size: 14px;
|
||
padding: 10px;
|
||
margin: 10px;
|
||
}
|
||
QMessageBox QLabel:first-child {
|
||
font-weight: bold;
|
||
color: #dc3545;
|
||
}
|
||
QPushButton {
|
||
background-color: #dc3545;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 25px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
min-width: 100px;
|
||
margin: 10px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #bb2d3b;
|
||
}
|
||
""")
|
||
msg.exec_()
|
||
else:
|
||
QMessageBox.critical(self, "错误", f"激活失败: {data}")
|
||
|
||
# 激活后检查一次状态
|
||
self.check_status()
|
||
|
||
def update_status_display(self, status_info: dict):
|
||
"""更新状态显示"""
|
||
# 打印API返回的原始数据
|
||
logging.info("=== API返回数据 ===")
|
||
logging.info(f"状态信息: {status_info}")
|
||
if 'activation_records' in status_info:
|
||
logging.info("激活记录:")
|
||
for record in status_info['activation_records']:
|
||
logging.info(f"- 记录: {record}")
|
||
|
||
# 更新状态文本
|
||
status_map = {
|
||
"active": "正常",
|
||
"inactive": "未激活",
|
||
"expired": "已过期"
|
||
}
|
||
status_text = status_map.get(status_info.get('status', 'inactive'), "未知")
|
||
|
||
# 构建状态文本
|
||
status_lines = [
|
||
f"会员状态:{status_text}",
|
||
f"到期时间:{status_info.get('expire_time', '')}",
|
||
f"总天数:{status_info.get('total_days', 0)}天",
|
||
f"剩余天数:{status_info.get('days_left', 0)}天"
|
||
]
|
||
|
||
# 如果有激活记录,显示最近一次激活信息
|
||
activation_records = status_info.get('activation_records', [])
|
||
if activation_records:
|
||
latest_record = activation_records[-1] # 获取最新的激活记录
|
||
device_info = latest_record.get('device_info', {})
|
||
|
||
status_lines.extend([
|
||
"",
|
||
"最近激活信息:",
|
||
f"激活码:{latest_record.get('code', '')}",
|
||
f"激活时间:{latest_record.get('activation_time', '')}",
|
||
f"增加天数:{latest_record.get('days', 0)}天",
|
||
"",
|
||
"设备信息:",
|
||
f"系统:{device_info.get('os', '')}",
|
||
f"设备名:{device_info.get('device_name', '')}",
|
||
f"IP地址:{device_info.get('ip', '')}",
|
||
f"地区:{device_info.get('location', '--')}"
|
||
])
|
||
|
||
# 更新状态文本
|
||
self.status_text.setPlainText("\n".join(status_lines))
|
||
|
||
def check_status(self):
|
||
"""检查会员状态(从API获取)"""
|
||
try:
|
||
# 显示加载对话框
|
||
self.show_loading_dialog("正在检查会员状态,请稍候...")
|
||
|
||
# 创建工作线程
|
||
self.worker = ApiWorker(self.switcher.get_member_status)
|
||
self.worker.finished.connect(self.on_status_check_complete)
|
||
self.worker.start()
|
||
|
||
except Exception as e:
|
||
self.hide_loading_dialog()
|
||
QMessageBox.critical(self, "错误", f"检查状态失败: {str(e)}")
|
||
self._activation_status = False
|
||
return False
|
||
|
||
def on_status_check_complete(self, result):
|
||
"""状态检查完成回调"""
|
||
success, data = result
|
||
self.hide_loading_dialog()
|
||
|
||
if success and data:
|
||
self.update_status_display(data)
|
||
# 更新缓存的激活状态
|
||
self._activation_status = data.get('status') == 'active'
|
||
|
||
# 设置状态更新定时器
|
||
if self._activation_status:
|
||
# 获取剩余时间(秒)
|
||
days_left = data.get('days_left', 0)
|
||
seconds_left = days_left * 24 * 60 * 60
|
||
|
||
# 创建定时器,在到期前1分钟更新状态
|
||
if self._status_timer:
|
||
self._status_timer.stop()
|
||
self._status_timer = QTimer(self)
|
||
self._status_timer.setSingleShot(True)
|
||
self._status_timer.timeout.connect(self.check_status)
|
||
update_interval = min(seconds_left - 60, 24 * 60 * 60) # 最长1天更新一次
|
||
if update_interval > 0:
|
||
self._status_timer.start(update_interval * 1000) # 转换为毫秒
|
||
|
||
return self._activation_status
|
||
else:
|
||
# 更新为未激活状态
|
||
inactive_status = {
|
||
"hardware_id": self.switcher.hardware_id,
|
||
"expire_time": "",
|
||
"days_left": 0,
|
||
"total_days": 0,
|
||
"status": "inactive",
|
||
"activation_records": []
|
||
}
|
||
self.update_status_display(inactive_status)
|
||
self._activation_status = False
|
||
return False
|
||
|
||
def check_activation_status(self) -> bool:
|
||
"""检查是否已激活(使用缓存)
|
||
|
||
Returns:
|
||
bool: 是否已激活
|
||
"""
|
||
if self._activation_status is None:
|
||
# 首次检查,从API获取
|
||
return self.check_status()
|
||
|
||
if not self._activation_status:
|
||
# 创建自定义消息框
|
||
msg = QDialog(self)
|
||
msg.setWindowTitle("会员未激活")
|
||
msg.setFixedWidth(400)
|
||
msg.setWindowFlags(msg.windowFlags() & ~Qt.WindowContextHelpButtonHint)
|
||
|
||
# 创建布局
|
||
layout = QVBoxLayout()
|
||
|
||
# 添加图标和文本
|
||
icon_label = QLabel()
|
||
icon_label.setPixmap(self.style().standardIcon(QStyle.SP_MessageBoxWarning).pixmap(32, 32))
|
||
icon_label.setAlignment(Qt.AlignCenter)
|
||
layout.addWidget(icon_label)
|
||
|
||
text_label = QLabel("您还未激活会员或会员已过期")
|
||
text_label.setAlignment(Qt.AlignCenter)
|
||
text_label.setStyleSheet("font-size: 14px; font-weight: bold; color: #333333; padding: 10px;")
|
||
layout.addWidget(text_label)
|
||
|
||
# 添加购买信息
|
||
info_text = "获取会员激活码,请通过以下方式:\n\n" \
|
||
"• 官方自助网站:cursor.nosqli.com\n" \
|
||
"• 微信客服:behikcigar\n" \
|
||
"• 闲鱼店铺:xxx\n\n" \
|
||
"————————————————————\n" \
|
||
"诚招代理商,欢迎加盟合作!"
|
||
|
||
info_label = QLabel(info_text)
|
||
info_label.setAlignment(Qt.AlignLeft)
|
||
info_label.setStyleSheet("""
|
||
QLabel {
|
||
color: #333333;
|
||
font-size: 14px;
|
||
padding: 15px;
|
||
background-color: #f8f9fa;
|
||
border-radius: 4px;
|
||
border: 1px solid #dee2e6;
|
||
margin: 10px;
|
||
}
|
||
""")
|
||
layout.addWidget(info_label)
|
||
|
||
# 添加复制按钮区域
|
||
btn_layout = QHBoxLayout()
|
||
|
||
# 复制网站按钮
|
||
copy_web_btn = QPushButton("复制网站")
|
||
copy_web_btn.clicked.connect(lambda: self.copy_and_show_tip(msg, "cursor.nosqli.com", "网站地址已复制到剪贴板"))
|
||
copy_web_btn.setStyleSheet("""
|
||
QPushButton {
|
||
background-color: #0d6efd;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 15px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #0b5ed7;
|
||
}
|
||
""")
|
||
btn_layout.addWidget(copy_web_btn)
|
||
|
||
# 复制微信按钮
|
||
copy_wx_btn = QPushButton("复制微信")
|
||
copy_wx_btn.clicked.connect(lambda: self.copy_and_show_tip(msg, "behikcigar", "微信号已复制到剪贴板"))
|
||
copy_wx_btn.setStyleSheet("""
|
||
QPushButton {
|
||
background-color: #198754;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 15px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #157347;
|
||
}
|
||
""")
|
||
btn_layout.addWidget(copy_wx_btn)
|
||
|
||
# 确定按钮
|
||
ok_btn = QPushButton("确定")
|
||
ok_btn.clicked.connect(msg.accept)
|
||
ok_btn.setStyleSheet("""
|
||
QPushButton {
|
||
background-color: #0d6efd;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 25px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
min-width: 100px;
|
||
}
|
||
QPushButton:hover {
|
||
background-color: #0b5ed7;
|
||
}
|
||
""")
|
||
btn_layout.addWidget(ok_btn)
|
||
|
||
layout.addLayout(btn_layout)
|
||
msg.setLayout(layout)
|
||
msg.exec_()
|
||
|
||
return self._activation_status
|
||
|
||
def refresh_cursor_auth(self):
|
||
"""刷新Cursor授权"""
|
||
if not self.check_activation_status():
|
||
return
|
||
|
||
try:
|
||
# 显示加载对话框
|
||
self.show_loading_dialog("正在刷新授权,请稍候...")
|
||
|
||
# 创建工作线程
|
||
self.worker = ApiWorker(self.switcher.refresh_cursor_auth)
|
||
self.worker.finished.connect(self.on_refresh_auth_complete)
|
||
self.worker.start()
|
||
|
||
except Exception as e:
|
||
self.hide_loading_dialog()
|
||
self.show_custom_error("刷新授权失败", str(e))
|
||
|
||
def on_refresh_auth_complete(self, result):
|
||
"""刷新授权完成回调"""
|
||
success, data = result
|
||
self.hide_loading_dialog()
|
||
|
||
if isinstance(data, tuple):
|
||
success, message = data
|
||
if success:
|
||
self.show_custom_message("成功", "刷新授权成功", message, QStyle.SP_DialogApplyButton, "#198754")
|
||
else:
|
||
self.show_custom_error("刷新授权失败", message)
|
||
else:
|
||
self.show_custom_error("刷新授权失败", str(data))
|
||
|
||
def disable_cursor_update(self):
|
||
"""禁用Cursor更新"""
|
||
if not self.check_activation_status():
|
||
return
|
||
|
||
try:
|
||
success, message = self.switcher.disable_cursor_update()
|
||
if success:
|
||
self.show_custom_message("成功", "禁用更新成功", message, QStyle.SP_DialogApplyButton, "#198754")
|
||
else:
|
||
self.show_custom_error("禁用更新失败", message)
|
||
except Exception as e:
|
||
self.show_custom_error("禁用更新失败", str(e))
|
||
|
||
def dummy_function(self):
|
||
"""突破版本限制"""
|
||
if not self.check_activation_status():
|
||
return
|
||
|
||
self.show_custom_message(
|
||
"提示",
|
||
"功能未实现",
|
||
"此功能暂未实现,请等待后续更新。",
|
||
QStyle.SP_MessageBoxInformation,
|
||
"#0d6efd"
|
||
)
|
||
|
||
def show_custom_message(self, title, header, message, icon_type, color):
|
||
"""显示自定义消息框"""
|
||
msg = QDialog(self)
|
||
msg.setWindowTitle(title)
|
||
msg.setFixedWidth(400)
|
||
msg.setWindowFlags(msg.windowFlags() & ~Qt.WindowContextHelpButtonHint)
|
||
|
||
layout = QVBoxLayout()
|
||
|
||
# 添加图标
|
||
icon_label = QLabel()
|
||
icon_label.setPixmap(self.style().standardIcon(icon_type).pixmap(32, 32))
|
||
icon_label.setAlignment(Qt.AlignCenter)
|
||
layout.addWidget(icon_label)
|
||
|
||
# 添加标题
|
||
text_label = QLabel(header)
|
||
text_label.setAlignment(Qt.AlignCenter)
|
||
text_label.setStyleSheet(f"""
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
color: {color};
|
||
padding: 10px;
|
||
""")
|
||
layout.addWidget(text_label)
|
||
|
||
# 添加详细信息
|
||
info_label = QLabel(message)
|
||
info_label.setAlignment(Qt.AlignLeft)
|
||
info_label.setWordWrap(True)
|
||
info_label.setStyleSheet("""
|
||
QLabel {
|
||
color: #333333;
|
||
font-size: 14px;
|
||
padding: 15px;
|
||
background-color: #f8f9fa;
|
||
border-radius: 4px;
|
||
border: 1px solid #dee2e6;
|
||
margin: 10px;
|
||
}
|
||
""")
|
||
layout.addWidget(info_label)
|
||
|
||
# 确定按钮
|
||
btn_layout = QHBoxLayout()
|
||
ok_btn = QPushButton("确定")
|
||
ok_btn.clicked.connect(msg.accept)
|
||
ok_btn.setStyleSheet(f"""
|
||
QPushButton {{
|
||
background-color: {color};
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 25px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
min-width: 100px;
|
||
}}
|
||
QPushButton:hover {{
|
||
background-color: {color.replace('fd', 'd7') if 'fd' in color else color.replace('54', '47')};
|
||
}}
|
||
""")
|
||
btn_layout.addWidget(ok_btn)
|
||
|
||
layout.addLayout(btn_layout)
|
||
msg.setLayout(layout)
|
||
msg.exec_()
|
||
|
||
def show_custom_error(self, header, message):
|
||
"""显示自定义错误消息框"""
|
||
self.show_custom_message(
|
||
"错误",
|
||
header,
|
||
message,
|
||
QStyle.SP_MessageBoxCritical,
|
||
"#dc3545"
|
||
) |