xxx
This commit is contained in:
@@ -8,6 +8,10 @@ from PyQt5.QtCore import (
|
||||
QPoint, QRect, QSize, pyqtProperty
|
||||
)
|
||||
from PyQt5.QtGui import QPainter, QColor, QPen
|
||||
import os
|
||||
from pathlib import Path
|
||||
from urllib.parse import quote
|
||||
import requests
|
||||
|
||||
class ActivationStatusWidget(QFrame):
|
||||
"""激活状态显示组件"""
|
||||
@@ -111,11 +115,18 @@ class ActivationWidget(QFrame):
|
||||
layout.addWidget(header_frame)
|
||||
|
||||
# 添加提示文本
|
||||
# info_text = QLabel(
|
||||
# "获取会员激活码,请通过以下方式:\n\n"
|
||||
# "官方自助网站:cursorpro.com.cn\n"
|
||||
# "代理听泉助手vx联系:behikcigar\n"
|
||||
# "天猫商店:https://e.tb.cn/h.TC2gtKSiccfl5MD?tk=GZvHenPgE4o CZ193\n\n"
|
||||
# "诚挚祝愿,欢迎加盟合作!"
|
||||
# )
|
||||
info_text = QLabel(
|
||||
"获取会员激活码,请通过以下方式:\n\n"
|
||||
"官方自助网站:cursorpro.com.cn\n"
|
||||
"微信客服号:behikcigar\n"
|
||||
"商店铺:xxx\n\n"
|
||||
"代理听泉助手vx联系:behikcigar\n"
|
||||
"购买链接:https://www.houfaka.com/links/3BD4C127\n\n"
|
||||
"诚挚祝愿,欢迎加盟合作!"
|
||||
)
|
||||
info_text.setStyleSheet("""
|
||||
@@ -153,7 +164,7 @@ class ActivationWidget(QFrame):
|
||||
# 复制微信按钮
|
||||
copy_wx_btn = QPushButton("复制微信")
|
||||
copy_wx_btn.setCursor(Qt.PointingHandCursor)
|
||||
copy_wx_btn.clicked.connect(lambda: self._copy_to_clipboard("bshkcigar", "已复制微信号"))
|
||||
copy_wx_btn.clicked.connect(lambda: self._copy_to_clipboard("behikcigar", "已复制微信号"))
|
||||
copy_wx_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #198754;
|
||||
@@ -169,13 +180,31 @@ class ActivationWidget(QFrame):
|
||||
""")
|
||||
btn_layout.addWidget(copy_wx_btn)
|
||||
|
||||
# 确定按钮
|
||||
ok_btn = QPushButton("确定")
|
||||
ok_btn.setCursor(Qt.PointingHandCursor)
|
||||
ok_btn.clicked.connect(msg.accept)
|
||||
ok_btn.setStyleSheet("""
|
||||
# 复制淘宝店铺按钮
|
||||
# copy_tb_btn = QPushButton("复制天猫店铺")
|
||||
# copy_tb_btn.setCursor(Qt.PointingHandCursor)
|
||||
# copy_tb_btn.clicked.connect(lambda: self._copy_to_clipboard("https://e.tb.cn/h.TC2gtKSiccfl5MD?tk=GZvHenPgE4o CZ193", "已复制淘宝店铺"))
|
||||
# copy_tb_btn.setStyleSheet("""
|
||||
# QPushButton {
|
||||
# background-color: #ff5100;
|
||||
# color: white;
|
||||
# border: none;
|
||||
# padding: 6px 16px;
|
||||
# border-radius: 3px;
|
||||
# font-size: 13px;
|
||||
# }
|
||||
# QPushButton:hover {
|
||||
# background-color: #c42b1c;
|
||||
# }
|
||||
# """)
|
||||
# btn_layout.addWidget(copy_tb_btn)
|
||||
|
||||
copy_tb_btn = QPushButton("复制购买链接")
|
||||
copy_tb_btn.setCursor(Qt.PointingHandCursor)
|
||||
copy_tb_btn.clicked.connect(lambda: self._copy_to_clipboard("https://www.houfaka.com/links/3BD4C127", "已复制"))
|
||||
copy_tb_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #6c757d;
|
||||
background-color: #ff5100;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 6px 16px;
|
||||
@@ -183,10 +212,29 @@ class ActivationWidget(QFrame):
|
||||
font-size: 13px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #5c636a;
|
||||
background-color: #c42b1c;
|
||||
}
|
||||
""")
|
||||
btn_layout.addWidget(ok_btn)
|
||||
btn_layout.addWidget(copy_tb_btn)
|
||||
|
||||
# 确定按钮
|
||||
# ok_btn = QPushButton("确定")
|
||||
# ok_btn.setCursor(Qt.PointingHandCursor)
|
||||
# ok_btn.clicked.connect(msg.accept)
|
||||
# ok_btn.setStyleSheet("""
|
||||
# QPushButton {
|
||||
# background-color: #6c757d;
|
||||
# color: white;
|
||||
# border: none;
|
||||
# padding: 6px 16px;
|
||||
# border-radius: 3px;
|
||||
# font-size: 13px;
|
||||
# }
|
||||
# QPushButton:hover {
|
||||
# background-color: #5c636a;
|
||||
# }
|
||||
# """)
|
||||
# btn_layout.addWidget(ok_btn)
|
||||
|
||||
layout.addLayout(btn_layout)
|
||||
|
||||
@@ -214,7 +262,7 @@ class ActivationWidget(QFrame):
|
||||
|
||||
# 标题
|
||||
title = QLabel("激活(听泉)会员,多个激活码可叠加整体时长")
|
||||
title.setStyleSheet("color: #28a745; font-size: 14px; font-weight: bold; border: none;") # 绿色标题
|
||||
title.setStyleSheet("color: #28a745; font-size: 14px; line-height: 15px;min-height: 15px; font-weight: bold; border: none;") # 绿色标题
|
||||
layout.addWidget(title)
|
||||
|
||||
# 激活码输入区域
|
||||
@@ -227,6 +275,8 @@ class ActivationWidget(QFrame):
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
min-height: 20px;
|
||||
line-height: 20px;
|
||||
padding: 8px;
|
||||
color: #495057;
|
||||
}
|
||||
@@ -242,6 +292,8 @@ class ActivationWidget(QFrame):
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 22px;
|
||||
min-height: 20px;
|
||||
line-height: 20px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -371,7 +423,7 @@ class MemberStatusWidget(QFrame):
|
||||
|
||||
职责:
|
||||
1. 显示会员状态信息
|
||||
2. 显示设备信息
|
||||
2. 显示公告信息
|
||||
3. 根据不同状态显示不同样式
|
||||
|
||||
属性:
|
||||
@@ -381,11 +433,23 @@ class MemberStatusWidget(QFrame):
|
||||
- 会员状态(正常/未激活)
|
||||
- 到期时间
|
||||
- 剩余天数
|
||||
- 设备信息(系统、设备名、IP、地区)
|
||||
- 公告区域(从API获取,每2分钟更新一次)
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setup_ui()
|
||||
|
||||
# 保存最后一次状态更新的数据
|
||||
self.last_status = {}
|
||||
|
||||
# 创建定时器,每2分钟更新一次公告
|
||||
self.announcement_timer = QTimer(self)
|
||||
self.announcement_timer.setInterval(120000) # 2分钟 = 120000毫秒
|
||||
self.announcement_timer.timeout.connect(self.refresh_announcement)
|
||||
self.announcement_timer.start()
|
||||
|
||||
# 初始化后,延迟一秒检查并显示重要公告
|
||||
QTimer.singleShot(1000, self.check_important_announcement)
|
||||
|
||||
def setup_ui(self):
|
||||
layout = QVBoxLayout(self)
|
||||
@@ -397,7 +461,7 @@ class MemberStatusWidget(QFrame):
|
||||
container_layout = QVBoxLayout(container)
|
||||
container_layout.setSpacing(5) # 减小组件间距
|
||||
container_layout.setContentsMargins(0,0,0,0) # 减小内边距
|
||||
container.setFixedHeight(220) # 根据需要调整这个值
|
||||
container.setFixedHeight(240) # 根据需要调整这个值
|
||||
|
||||
# 状态信息
|
||||
self.status_text = QTextEdit()
|
||||
@@ -455,15 +519,157 @@ class MemberStatusWidget(QFrame):
|
||||
""")
|
||||
|
||||
layout.addWidget(container)
|
||||
|
||||
def check_important_announcement(self):
|
||||
"""检查并显示重要公告(level=5)"""
|
||||
announcement_data = self.get_announcement(return_full_data=True)
|
||||
if announcement_data and announcement_data.get("level") == 5:
|
||||
self.show_announcement_dialog(announcement_data.get("txt", ""))
|
||||
|
||||
def show_announcement_dialog(self, content):
|
||||
"""显示公告弹窗"""
|
||||
msg = QDialog(self)
|
||||
msg.setWindowTitle("重要公告")
|
||||
msg.setMinimumWidth(400)
|
||||
msg.setWindowFlags(msg.windowFlags() & ~Qt.WindowContextHelpButtonHint)
|
||||
|
||||
# 创建布局
|
||||
layout = QVBoxLayout()
|
||||
layout.setSpacing(12)
|
||||
layout.setContentsMargins(20, 15, 20, 15)
|
||||
|
||||
# 创建顶部框
|
||||
header_frame = QFrame()
|
||||
header_frame.setStyleSheet("""
|
||||
QFrame {
|
||||
background-color: #e6f7ff;
|
||||
border: 1px solid #91d5ff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QLabel {
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
""")
|
||||
header_layout = QHBoxLayout(header_frame)
|
||||
header_layout.setContentsMargins(12, 10, 12, 10)
|
||||
header_layout.setSpacing(10)
|
||||
|
||||
icon_label = QLabel()
|
||||
icon_label.setPixmap(self.style().standardIcon(QStyle.SP_MessageBoxInformation).pixmap(20, 20))
|
||||
header_layout.addWidget(icon_label)
|
||||
|
||||
text_label = QLabel("重要公告")
|
||||
text_label.setStyleSheet("font-size: 14px; font-weight: bold; color: #1890ff; background: transparent;")
|
||||
header_layout.addWidget(text_label)
|
||||
header_layout.addStretch()
|
||||
|
||||
layout.addWidget(header_frame)
|
||||
|
||||
# 公告内容
|
||||
content_text = QTextEdit()
|
||||
content_text.setReadOnly(True)
|
||||
content_text.setHtml(content)
|
||||
content_text.setStyleSheet("""
|
||||
QTextEdit {
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
background-color: #fafafa;
|
||||
min-height: 120px;
|
||||
}
|
||||
""")
|
||||
layout.addWidget(content_text)
|
||||
|
||||
# 确认按钮
|
||||
btn_layout = QHBoxLayout()
|
||||
btn_layout.addStretch()
|
||||
|
||||
ok_btn = QPushButton("我知道了")
|
||||
ok_btn.setCursor(Qt.PointingHandCursor)
|
||||
ok_btn.clicked.connect(msg.accept)
|
||||
ok_btn.setStyleSheet("""
|
||||
QPushButton {
|
||||
background-color: #1890ff;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #40a9ff;
|
||||
}
|
||||
""")
|
||||
btn_layout.addWidget(ok_btn)
|
||||
|
||||
layout.addLayout(btn_layout)
|
||||
|
||||
# 设置对话框样式和布局
|
||||
msg.setStyleSheet("""
|
||||
QDialog {
|
||||
background-color: white;
|
||||
}
|
||||
""")
|
||||
msg.setLayout(layout)
|
||||
|
||||
# 显示对话框
|
||||
msg.exec_()
|
||||
|
||||
def refresh_announcement(self):
|
||||
"""定时刷新公告内容"""
|
||||
if self.last_status:
|
||||
# 使用最后一次的状态数据更新界面,只刷新公告部分
|
||||
self.update_status(self.last_status, refresh_announcement_only=True)
|
||||
|
||||
def get_announcement(self, return_full_data=False):
|
||||
"""从API获取公告内容
|
||||
|
||||
Args:
|
||||
return_full_data: 是否返回完整的公告数据字典,包含level等信息
|
||||
"""
|
||||
try:
|
||||
response = requests.get("http://api.cursorpro.com.cn/admin/api.version/ad", timeout=5)
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
# 解析JSON响应
|
||||
json_data = response.json()
|
||||
# 检查code是否为0(成功)
|
||||
if json_data.get("code") == 0:
|
||||
# 获取公告数据
|
||||
announcement_data = json_data.get("data", {})
|
||||
|
||||
# 根据参数决定返回完整数据还是仅文本
|
||||
if return_full_data:
|
||||
return announcement_data
|
||||
else:
|
||||
return announcement_data.get("txt", "")
|
||||
else:
|
||||
# 如果code不是0,返回错误信息
|
||||
error_msg = f"获取公告失败: {json_data.get('msg', '未知错误')}"
|
||||
return {} if return_full_data else error_msg
|
||||
except ValueError:
|
||||
# JSON解析错误
|
||||
error_msg = "解析公告数据失败"
|
||||
return {} if return_full_data else error_msg
|
||||
else:
|
||||
error_msg = f"获取公告失败,状态码: {response.status_code}"
|
||||
return {} if return_full_data else error_msg
|
||||
except Exception as e:
|
||||
error_msg = f"获取公告失败: {str(e)}"
|
||||
return {} if return_full_data else error_msg
|
||||
|
||||
def update_status(self, status: Dict):
|
||||
def update_status(self, status: Dict, refresh_announcement_only=False):
|
||||
"""更新状态显示"""
|
||||
try:
|
||||
# 保存最后一次状态数据用于刷新公告
|
||||
if not refresh_announcement_only:
|
||||
self.last_status = status.copy()
|
||||
|
||||
# 获取状态信息
|
||||
is_activated = status.get("is_activated", False)
|
||||
expire_time = status.get("expire_time", "未知")
|
||||
days_left = status.get("days_left", 0)
|
||||
device_info = status.get("device_info", {})
|
||||
|
||||
# 构建状态文本
|
||||
status_text = []
|
||||
@@ -479,15 +685,14 @@ class MemberStatusWidget(QFrame):
|
||||
days_color = "#10B981" if days_left > 30 else "#F59E0B" if days_left > 7 else "#EF4444"
|
||||
status_text.append(f'剩余天数:<span style="color: {days_color};">{days_left}天</span>')
|
||||
|
||||
|
||||
|
||||
status_text.append("<br/>")
|
||||
# 设备信息
|
||||
status_text.append("\n设备信息:")
|
||||
status_text.append(f"系统:{device_info.get('os', 'Windows')}")
|
||||
status_text.append(f"设备名:{device_info.get('device_name', '未知')}")
|
||||
status_text.append(f"IP地址:{device_info.get('ip', '未知')}")
|
||||
status_text.append(f"地区:{device_info.get('location', '未知')}")
|
||||
|
||||
# 公告区域
|
||||
announcement = self.get_announcement()
|
||||
status_text.append('<div style="margin-top: 2px; padding: 2px; background-color: #f0f9ff; border-left: 4px solid #3b82f6; border-radius: 4px; max-height: 80px; overflow-y: auto;">')
|
||||
status_text.append('<span style="font-weight: bold; color: #3b82f6;">公告:</span><br/>')
|
||||
status_text.append(f'{announcement}')
|
||||
status_text.append('</div>')
|
||||
|
||||
# 更新文本
|
||||
self.status_text.setHtml("<br>".join(status_text))
|
||||
@@ -496,6 +701,16 @@ class MemberStatusWidget(QFrame):
|
||||
# 如果发生异常,显示错误信息
|
||||
error_text = f'<span style="color: #EF4444;">状态更新失败: {str(e)}</span>'
|
||||
self.status_text.setHtml(error_text)
|
||||
|
||||
def hideEvent(self, event):
|
||||
"""窗口隐藏时停止定时器"""
|
||||
self.announcement_timer.stop()
|
||||
super().hideEvent(event)
|
||||
|
||||
def showEvent(self, event):
|
||||
"""窗口显示时启动定时器"""
|
||||
self.announcement_timer.start()
|
||||
super().showEvent(event)
|
||||
|
||||
class LoadingSpinner(QWidget):
|
||||
"""自定义加载动画组件"""
|
||||
|
||||
Reference in New Issue
Block a user