167 lines
7.0 KiB
Python
167 lines
7.0 KiB
Python
import base64
|
||
|
||
from loguru import logger
|
||
from PyQt6.QtCore import Qt, QThread, pyqtSignal
|
||
from PyQt6.QtGui import (QColor, QPainter, QPainterPath, QPen, QPixmap)
|
||
|
||
from ..api import miaoStarsBasicApi
|
||
from ...core import cfg, qconfig, userConfig
|
||
|
||
|
||
class CaptchaThread(QThread):
|
||
captchaReady = pyqtSignal(QPixmap)
|
||
captchaFailed = pyqtSignal(str)
|
||
|
||
def __init__(self):
|
||
super().__init__()
|
||
|
||
@staticmethod
|
||
def _createRoundedPixmap(pixmap, radius=10):
|
||
"""创建圆角图片"""
|
||
try:
|
||
# 获取原始图片尺寸
|
||
if pixmap.isNull():
|
||
logger.error("原始图片为空,无法创建圆角图片")
|
||
return pixmap
|
||
size = pixmap.size()
|
||
# 创建透明背景的图片
|
||
rounded_pixmap = QPixmap(size)
|
||
rounded_pixmap.fill(Qt.GlobalColor.transparent)
|
||
# 创建对象
|
||
painter = QPainter(rounded_pixmap)
|
||
painter.setRenderHints(
|
||
QPainter.RenderHint.Antialiasing
|
||
| QPainter.RenderHint.SmoothPixmapTransform
|
||
)
|
||
# 创建圆角矩形路径
|
||
path = QPainterPath()
|
||
path.addRoundedRect(0, 0, size.width(), size.height(), radius, radius)
|
||
# 设置裁剪区域
|
||
painter.setClipPath(path)
|
||
# 绘制原始图片
|
||
painter.drawPixmap(0, 0, pixmap)
|
||
# 绘制边框
|
||
pen = QPen(QColor(200, 200, 200)) # 浅灰色边框
|
||
pen.setWidth(1)
|
||
painter.setPen(pen)
|
||
painter.drawRoundedRect(
|
||
0, 0, size.width() - 1, size.height() - 1, radius, radius
|
||
)
|
||
|
||
painter.end()
|
||
return rounded_pixmap
|
||
except Exception as e:
|
||
logger.error(f"创建圆角图片失败:{e}")
|
||
return pixmap # 如果出错,返回原始图片
|
||
|
||
def run(self):
|
||
try:
|
||
logger.debug("开始获取验证码")
|
||
response = miaoStarsBasicApi.getCaptcha()
|
||
logger.debug(f"验证码API返回响应: {response}")
|
||
|
||
if response["code"] == 0:
|
||
# 确保data字段存在且为字符串
|
||
if "data" in response and isinstance(response["data"], str):
|
||
# 分割base64前缀和实际数据
|
||
try:
|
||
captchaImageData = response["data"].split(",")[1]
|
||
logger.debug(f"成功提取base64数据,长度: {len(captchaImageData)}")
|
||
|
||
# 解码base64数据
|
||
captchaImage = base64.b64decode(captchaImageData)
|
||
logger.debug(f"成功解码base64数据,长度: {len(captchaImage)} bytes")
|
||
|
||
# 加载图片
|
||
pixmap = QPixmap()
|
||
load_success = pixmap.loadFromData(captchaImage)
|
||
|
||
if load_success:
|
||
logger.debug(f"成功加载图片,尺寸: {pixmap.width()}x{pixmap.height()}")
|
||
# 创建圆角图片
|
||
pixmap = self._createRoundedPixmap(pixmap, radius=10)
|
||
self.captchaReady.emit(pixmap)
|
||
else:
|
||
logger.error("图片加载失败")
|
||
self.captchaFailed.emit("验证码图片加载失败")
|
||
self.captchaReady.emit(QPixmap(":app/images/loadFailure.png"))
|
||
except (IndexError, ValueError, TypeError) as e:
|
||
logger.error(f"验证码数据格式错误: {e}")
|
||
self.captchaFailed.emit(f"验证码数据格式错误: {str(e)}")
|
||
self.captchaReady.emit(QPixmap(":app/images/loadFailure.png"))
|
||
else:
|
||
logger.error("验证码响应中缺少有效的data字段")
|
||
self.captchaFailed.emit("验证码数据无效")
|
||
self.captchaReady.emit(QPixmap(":app/images/loadFailure.png"))
|
||
else:
|
||
error_msg = response.get("msg", "获取验证码失败")
|
||
logger.error(f"获取验证码失败: {error_msg}")
|
||
self.captchaFailed.emit(error_msg)
|
||
self.captchaReady.emit(QPixmap(":app/images/loadFailure.png"))
|
||
except Exception as e:
|
||
logger.exception(f"获取验证码过程中发生异常: {e}")
|
||
self.captchaFailed.emit(str(e))
|
||
self.captchaReady.emit(QPixmap(":app/images/loadFailure.png"))
|
||
|
||
|
||
class LoginThread(QThread):
|
||
successLogin = pyqtSignal()
|
||
errorLogin = pyqtSignal(str)
|
||
|
||
def __init__(self, email: str, password: str, captchaCode: str):
|
||
super().__init__()
|
||
logger.debug(f"初始化许可证服务线程 - 邮箱: {email}")
|
||
self.email = email
|
||
self.password = password
|
||
self.captchaCode = captchaCode
|
||
|
||
def run(self):
|
||
logger.info(f"开始验证用户登录 - 邮箱: {self.email}")
|
||
try:
|
||
loginResponse = miaoStarsBasicApi.login(
|
||
self.email, self.password, self.captchaCode
|
||
)
|
||
if loginResponse["code"] == 0:
|
||
self.successLogin.emit()
|
||
qconfig.set(cfg.email, self.email)
|
||
qconfig.set(cfg.activationCode, self.password)
|
||
userConfig.userData = loginResponse
|
||
# 从登录响应中提取token并保存
|
||
# 在basicApi的login方法中已经处理了token的设置,这里保存到userConfig中以便程序启动时恢复
|
||
token = miaoStarsBasicApi.token
|
||
if token:
|
||
userConfig.setToken(token)
|
||
else:
|
||
self.errorLogin.emit(loginResponse["msg"])
|
||
|
||
except Exception as e:
|
||
logger.error(f"登录验证过程中发生异常: {e}")
|
||
self.errorLogin.emit("系统错误,请稍后重试")
|
||
|
||
|
||
class RegisterThread(QThread):
|
||
successRegister = pyqtSignal()
|
||
errorRegister = pyqtSignal(str)
|
||
|
||
def __init__(self, email: str, password: str, captchaCode: str):
|
||
super().__init__()
|
||
logger.debug(f"初始化许可证服务线程 - 邮箱: {email}")
|
||
self.email = email
|
||
self.password = password
|
||
self.captchaCode = captchaCode
|
||
|
||
def run(self):
|
||
logger.info(f"开始验证用户注册 - 邮箱: {self.email}")
|
||
try:
|
||
registerRespond = miaoStarsBasicApi.register(
|
||
self.email, self.password, self.captchaCode
|
||
)
|
||
if registerRespond["code"] == 203:
|
||
self.successRegister.emit()
|
||
else:
|
||
logger.error(f"注册失败: {registerRespond['msg']}")
|
||
self.errorRegister.emit(registerRespond["msg"])
|
||
except Exception as e:
|
||
logger.error(f"登录验证过程中发生异常: {e}")
|
||
self.errorRegister.emit("系统错误,请稍后重试")
|