|
|
|
|
@ -1,70 +1,260 @@
|
|
|
|
|
#include "registerwidget.h"
|
|
|
|
|
#include "usermanage.h"
|
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
|
#include <QGridLayout>
|
|
|
|
|
#include <QRandomGenerator>
|
|
|
|
|
#include <QTime>
|
|
|
|
|
|
|
|
|
|
RegisterWidget::RegisterWidget(QWidget *parent) : QWidget(parent)
|
|
|
|
|
RegisterWidget::RegisterWidget(QWidget *parent) : QWidget(parent), countdownSeconds(0)
|
|
|
|
|
{
|
|
|
|
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
|
|
|
|
// 设置最小尺寸
|
|
|
|
|
setMinimumSize(500, 600);
|
|
|
|
|
|
|
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
|
|
|
|
mainLayout->setSpacing(20);
|
|
|
|
|
mainLayout->setContentsMargins(40, 30, 40, 30);
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
QLabel *titleLabel = new QLabel("用户注册");
|
|
|
|
|
titleLabel->setAlignment(Qt::AlignCenter);
|
|
|
|
|
titleLabel->setStyleSheet("font-size: 20px; font-weight: bold; margin: 20px;");
|
|
|
|
|
titleLabel->setStyleSheet("font-size: 28px; font-weight: bold; margin: 20px; color: #2c3e50;");
|
|
|
|
|
|
|
|
|
|
// 创建网格布局用于表单
|
|
|
|
|
QGridLayout *formLayout = new QGridLayout();
|
|
|
|
|
formLayout->setSpacing(15);
|
|
|
|
|
formLayout->setColumnMinimumWidth(0, 100);
|
|
|
|
|
formLayout->setColumnStretch(1, 1);
|
|
|
|
|
|
|
|
|
|
// 邮箱输入
|
|
|
|
|
QLabel *emailLabel = new QLabel("邮箱:");
|
|
|
|
|
emailLabel->setStyleSheet("font-size: 14px; font-weight: bold;");
|
|
|
|
|
emailEdit = new QLineEdit();
|
|
|
|
|
emailEdit->setPlaceholderText("请输入您的邮箱");
|
|
|
|
|
emailEdit->setMinimumHeight(35);
|
|
|
|
|
emailEdit->setStyleSheet("QLineEdit { padding: 8px; font-size: 14px; border: 1px solid #bdc3c7; border-radius: 4px; }");
|
|
|
|
|
|
|
|
|
|
// 发送验证码按钮
|
|
|
|
|
sendCodeButton = new QPushButton("发送验证码");
|
|
|
|
|
sendCodeButton->setFixedWidth(120);
|
|
|
|
|
sendCodeButton->setMinimumHeight(35);
|
|
|
|
|
sendCodeButton->setStyleSheet("QPushButton {"
|
|
|
|
|
"background-color: #3498db;"
|
|
|
|
|
"color: white;"
|
|
|
|
|
"border: none;"
|
|
|
|
|
"font-size: 12px;"
|
|
|
|
|
"border-radius: 4px;"
|
|
|
|
|
"}"
|
|
|
|
|
"QPushButton:hover {"
|
|
|
|
|
"background-color: #2980b9;"
|
|
|
|
|
"}"
|
|
|
|
|
"QPushButton:disabled {"
|
|
|
|
|
"background-color: #bdc3c7;"
|
|
|
|
|
"}");
|
|
|
|
|
|
|
|
|
|
// 验证码输入
|
|
|
|
|
QLabel *codeLabel = new QLabel("验证码:");
|
|
|
|
|
codeLabel->setStyleSheet("font-size: 14px; font-weight: bold;");
|
|
|
|
|
verificationCodeEdit = new QLineEdit();
|
|
|
|
|
verificationCodeEdit->setPlaceholderText("请输入收到的验证码");
|
|
|
|
|
verificationCodeEdit->setMinimumHeight(35);
|
|
|
|
|
verificationCodeEdit->setStyleSheet("QLineEdit { padding: 8px; font-size: 14px; border: 1px solid #bdc3c7; border-radius: 4px; }");
|
|
|
|
|
|
|
|
|
|
// 注册码
|
|
|
|
|
QLabel *codeLabel = new QLabel("注册码:");
|
|
|
|
|
registerCodeEdit = new QLineEdit();
|
|
|
|
|
registerCodeEdit->setText(generateRegisterCode());
|
|
|
|
|
registerCodeEdit->setReadOnly(true);
|
|
|
|
|
// 计时器标签
|
|
|
|
|
timerLabel = new QLabel();
|
|
|
|
|
timerLabel->setStyleSheet("color: #e74c3c; font-size: 14px; font-weight: bold;");
|
|
|
|
|
timerLabel->setFixedWidth(60);
|
|
|
|
|
timerLabel->setAlignment(Qt::AlignCenter);
|
|
|
|
|
|
|
|
|
|
// 用户名输入
|
|
|
|
|
QLabel *usernameLabel = new QLabel("用户名:");
|
|
|
|
|
usernameLabel->setStyleSheet("font-size: 14px; font-weight: bold;");
|
|
|
|
|
usernameEdit = new QLineEdit();
|
|
|
|
|
usernameEdit->setPlaceholderText("请输入用户名(2-20个字符)");
|
|
|
|
|
usernameEdit->setMinimumHeight(35);
|
|
|
|
|
usernameEdit->setStyleSheet("QLineEdit { padding: 8px; font-size: 14px; border: 1px solid #bdc3c7; border-radius: 4px; }");
|
|
|
|
|
|
|
|
|
|
// 年级选择
|
|
|
|
|
QLabel *gradeLabel = new QLabel("选择年级:");
|
|
|
|
|
gradeLabel->setStyleSheet("font-size: 14px; font-weight: bold;");
|
|
|
|
|
gradeComboBox = new QComboBox();
|
|
|
|
|
gradeComboBox->addItem("小学");
|
|
|
|
|
gradeComboBox->addItem("初中");
|
|
|
|
|
gradeComboBox->addItem("高中");
|
|
|
|
|
gradeComboBox->setMinimumHeight(35);
|
|
|
|
|
gradeComboBox->setStyleSheet("QComboBox { padding: 8px; font-size: 14px; border: 1px solid #bdc3c7; border-radius: 4px; }");
|
|
|
|
|
|
|
|
|
|
// 密码输入
|
|
|
|
|
QLabel *passwordLabel = new QLabel("密码 (6-10位,包含大小写字母和数字):");
|
|
|
|
|
QLabel *passwordLabel = new QLabel("密码:");
|
|
|
|
|
passwordLabel->setStyleSheet("font-size: 14px; font-weight: bold;");
|
|
|
|
|
passwordEdit = new QLineEdit();
|
|
|
|
|
passwordEdit->setEchoMode(QLineEdit::Password);
|
|
|
|
|
passwordEdit->setPlaceholderText("6-10位,包含大小写字母和数字");
|
|
|
|
|
passwordEdit->setMinimumHeight(35);
|
|
|
|
|
passwordEdit->setStyleSheet("QLineEdit { padding: 8px; font-size: 14px; border: 1px solid #bdc3c7; border-radius: 4px; }");
|
|
|
|
|
|
|
|
|
|
// 确认密码
|
|
|
|
|
QLabel *confirmPasswordLabel = new QLabel("确认密码:");
|
|
|
|
|
confirmPasswordLabel->setStyleSheet("font-size: 14px; font-weight: bold;");
|
|
|
|
|
confirmPasswordEdit = new QLineEdit();
|
|
|
|
|
confirmPasswordEdit->setEchoMode(QLineEdit::Password);
|
|
|
|
|
confirmPasswordEdit->setPlaceholderText("请再次输入密码");
|
|
|
|
|
confirmPasswordEdit->setMinimumHeight(35);
|
|
|
|
|
confirmPasswordEdit->setStyleSheet("QLineEdit { padding: 8px; font-size: 14px; border: 1px solid #bdc3c7; border-radius: 4px; }");
|
|
|
|
|
|
|
|
|
|
// 设置表单布局
|
|
|
|
|
int row = 0;
|
|
|
|
|
|
|
|
|
|
// 邮箱行
|
|
|
|
|
formLayout->addWidget(emailLabel, row, 0, Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
QHBoxLayout *emailLayout = new QHBoxLayout();
|
|
|
|
|
emailLayout->setSpacing(10);
|
|
|
|
|
emailLayout->addWidget(emailEdit);
|
|
|
|
|
emailLayout->addWidget(sendCodeButton);
|
|
|
|
|
formLayout->addLayout(emailLayout, row, 1);
|
|
|
|
|
row++;
|
|
|
|
|
|
|
|
|
|
// 验证码行
|
|
|
|
|
formLayout->addWidget(codeLabel, row, 0, Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
QHBoxLayout *codeLayout = new QHBoxLayout();
|
|
|
|
|
codeLayout->setSpacing(10);
|
|
|
|
|
codeLayout->addWidget(verificationCodeEdit);
|
|
|
|
|
codeLayout->addWidget(timerLabel);
|
|
|
|
|
formLayout->addLayout(codeLayout, row, 1);
|
|
|
|
|
row++;
|
|
|
|
|
|
|
|
|
|
// 用户名行
|
|
|
|
|
formLayout->addWidget(usernameLabel, row, 0, Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
formLayout->addWidget(usernameEdit, row, 1);
|
|
|
|
|
row++;
|
|
|
|
|
|
|
|
|
|
// 年级行
|
|
|
|
|
formLayout->addWidget(gradeLabel, row, 0, Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
formLayout->addWidget(gradeComboBox, row, 1);
|
|
|
|
|
row++;
|
|
|
|
|
|
|
|
|
|
// 密码行
|
|
|
|
|
formLayout->addWidget(passwordLabel, row, 0, Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
formLayout->addWidget(passwordEdit, row, 1);
|
|
|
|
|
row++;
|
|
|
|
|
|
|
|
|
|
// 确认密码行
|
|
|
|
|
formLayout->addWidget(confirmPasswordLabel, row, 0, Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
formLayout->addWidget(confirmPasswordEdit, row, 1);
|
|
|
|
|
row++;
|
|
|
|
|
|
|
|
|
|
// 按钮区域
|
|
|
|
|
QWidget *buttonWidget = new QWidget();
|
|
|
|
|
QHBoxLayout *buttonLayout = new QHBoxLayout(buttonWidget);
|
|
|
|
|
buttonLayout->setSpacing(30);
|
|
|
|
|
buttonLayout->setContentsMargins(0, 30, 0, 0);
|
|
|
|
|
|
|
|
|
|
// 按钮
|
|
|
|
|
registerButton = new QPushButton("注册");
|
|
|
|
|
registerButton->setFixedSize(140, 45);
|
|
|
|
|
registerButton->setStyleSheet("QPushButton {"
|
|
|
|
|
"background-color: #27ae60;"
|
|
|
|
|
"color: white;"
|
|
|
|
|
"border: none;"
|
|
|
|
|
"font-size: 16px;"
|
|
|
|
|
"font-weight: bold;"
|
|
|
|
|
"border-radius: 6px;"
|
|
|
|
|
"}"
|
|
|
|
|
"QPushButton:hover {"
|
|
|
|
|
"background-color: #229954;"
|
|
|
|
|
"}");
|
|
|
|
|
|
|
|
|
|
backButton = new QPushButton("返回登录");
|
|
|
|
|
backButton->setFixedSize(140, 45);
|
|
|
|
|
backButton->setStyleSheet("QPushButton {"
|
|
|
|
|
"background-color: #95a5a6;"
|
|
|
|
|
"color: white;"
|
|
|
|
|
"border: none;"
|
|
|
|
|
"font-size: 16px;"
|
|
|
|
|
"font-weight: bold;"
|
|
|
|
|
"border-radius: 6px;"
|
|
|
|
|
"}"
|
|
|
|
|
"QPushButton:hover {"
|
|
|
|
|
"background-color: #7f8c8d;"
|
|
|
|
|
"}");
|
|
|
|
|
|
|
|
|
|
// 添加到布局
|
|
|
|
|
layout->addWidget(titleLabel);
|
|
|
|
|
layout->addWidget(emailLabel);
|
|
|
|
|
layout->addWidget(emailEdit);
|
|
|
|
|
layout->addWidget(codeLabel);
|
|
|
|
|
layout->addWidget(registerCodeEdit);
|
|
|
|
|
layout->addWidget(passwordLabel);
|
|
|
|
|
layout->addWidget(passwordEdit);
|
|
|
|
|
layout->addWidget(confirmPasswordLabel);
|
|
|
|
|
layout->addWidget(confirmPasswordEdit);
|
|
|
|
|
layout->addWidget(registerButton);
|
|
|
|
|
layout->addWidget(backButton);
|
|
|
|
|
buttonLayout->addStretch();
|
|
|
|
|
buttonLayout->addWidget(registerButton);
|
|
|
|
|
buttonLayout->addWidget(backButton);
|
|
|
|
|
buttonLayout->addStretch();
|
|
|
|
|
|
|
|
|
|
// 添加到主布局
|
|
|
|
|
mainLayout->addWidget(titleLabel);
|
|
|
|
|
mainLayout->addLayout(formLayout);
|
|
|
|
|
mainLayout->addStretch();
|
|
|
|
|
mainLayout->addWidget(buttonWidget);
|
|
|
|
|
|
|
|
|
|
// 初始化计时器
|
|
|
|
|
countdownTimer = new QTimer(this);
|
|
|
|
|
countdownTimer->setInterval(1000);
|
|
|
|
|
|
|
|
|
|
// 连接信号槽
|
|
|
|
|
connect(sendCodeButton, &QPushButton::clicked, this, &RegisterWidget::onSendCodeClicked);
|
|
|
|
|
connect(registerButton, &QPushButton::clicked, this, &RegisterWidget::onRegisterClicked);
|
|
|
|
|
connect(backButton, &QPushButton::clicked, this, &RegisterWidget::onBackClicked);
|
|
|
|
|
connect(countdownTimer, &QTimer::timeout, this, &RegisterWidget::updateTimer);
|
|
|
|
|
|
|
|
|
|
// 初始状态
|
|
|
|
|
resetCountdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterWidget::onSendCodeClicked()
|
|
|
|
|
{
|
|
|
|
|
QString email = emailEdit->text().trimmed();
|
|
|
|
|
|
|
|
|
|
if (!validateEmail(email)) {
|
|
|
|
|
QMessageBox::warning(this, "输入错误", "请输入有效的邮箱地址");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成并显示验证码
|
|
|
|
|
generatedCode = generateVerificationCode();
|
|
|
|
|
|
|
|
|
|
QMessageBox::information(this, "验证码",
|
|
|
|
|
QString("验证码已发送到 %1\n验证码:%2\n(实际项目中会发送到邮箱)")
|
|
|
|
|
.arg(email).arg(generatedCode));
|
|
|
|
|
|
|
|
|
|
// 开始倒计时
|
|
|
|
|
startCountdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterWidget::onRegisterClicked()
|
|
|
|
|
{
|
|
|
|
|
QString email = emailEdit->text();
|
|
|
|
|
QString email = emailEdit->text().trimmed();
|
|
|
|
|
QString username = usernameEdit->text().trimmed();
|
|
|
|
|
QString verificationCode = verificationCodeEdit->text().trimmed();
|
|
|
|
|
QString password = passwordEdit->text();
|
|
|
|
|
QString confirmPassword = confirmPasswordEdit->text();
|
|
|
|
|
QString grade = gradeComboBox->currentText();
|
|
|
|
|
|
|
|
|
|
// 邮箱格式验证
|
|
|
|
|
QRegularExpression emailRegex(R"(^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)");
|
|
|
|
|
if (!emailRegex.match(email).hasMatch()) {
|
|
|
|
|
// 验证输入
|
|
|
|
|
if (email.isEmpty() || username.isEmpty() || verificationCode.isEmpty() ||
|
|
|
|
|
password.isEmpty() || confirmPassword.isEmpty()) {
|
|
|
|
|
QMessageBox::warning(this, "输入错误", "请填写所有字段");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!validateEmail(email)) {
|
|
|
|
|
QMessageBox::warning(this, "输入错误", "请输入有效的邮箱地址");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 密码验证
|
|
|
|
|
// 验证验证码
|
|
|
|
|
if (verificationCode != generatedCode) {
|
|
|
|
|
QMessageBox::warning(this, "验证错误", "验证码错误");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查验证码是否过期
|
|
|
|
|
if (countdownSeconds <= 0) {
|
|
|
|
|
QMessageBox::warning(this, "验证错误", "验证码已过期,请重新获取");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证密码
|
|
|
|
|
if (password != confirmPassword) {
|
|
|
|
|
QMessageBox::warning(this, "输入错误", "两次输入的密码不一致");
|
|
|
|
|
return;
|
|
|
|
|
@ -76,12 +266,35 @@ void RegisterWidget::onRegisterClicked()
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QMessageBox::information(this, "注册成功", "注册成功!");
|
|
|
|
|
emit registerSuccess();
|
|
|
|
|
if (username.length() < 2 || username.length() > 20) {
|
|
|
|
|
QMessageBox::warning(this, "输入错误", "用户名长度应在2-20个字符之间");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 实际注册用户
|
|
|
|
|
UserManager userManager;
|
|
|
|
|
if (userManager.registerUser(username.toStdWString(),
|
|
|
|
|
password.toStdWString(),
|
|
|
|
|
grade.toStdWString())) {
|
|
|
|
|
QMessageBox::information(this, "注册成功", "注册成功!");
|
|
|
|
|
|
|
|
|
|
// 重置表单
|
|
|
|
|
emailEdit->clear();
|
|
|
|
|
usernameEdit->clear();
|
|
|
|
|
verificationCodeEdit->clear();
|
|
|
|
|
passwordEdit->clear();
|
|
|
|
|
confirmPasswordEdit->clear();
|
|
|
|
|
resetCountdown();
|
|
|
|
|
|
|
|
|
|
emit registerSuccess();
|
|
|
|
|
} else {
|
|
|
|
|
QMessageBox::warning(this, "注册失败", "用户名已存在,请选择其他用户名");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterWidget::onBackClicked()
|
|
|
|
|
{
|
|
|
|
|
resetCountdown();
|
|
|
|
|
emit showLogin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -101,13 +314,54 @@ bool RegisterWidget::validatePassword(const QString &password)
|
|
|
|
|
return hasUpper && hasLower && hasDigit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString RegisterWidget::generateRegisterCode()
|
|
|
|
|
bool RegisterWidget::validateEmail(const QString &email)
|
|
|
|
|
{
|
|
|
|
|
QRegularExpression emailRegex(R"(^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)");
|
|
|
|
|
return emailRegex.match(email).hasMatch();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString RegisterWidget::generateVerificationCode()
|
|
|
|
|
{
|
|
|
|
|
const QString possibleChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
|
|
|
const QString possibleChars = "0123456789";
|
|
|
|
|
QString code;
|
|
|
|
|
for (int i = 0; i < 8; ++i) {
|
|
|
|
|
|
|
|
|
|
// 使用传统的随机数生成
|
|
|
|
|
qsrand(QTime::currentTime().msec());
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; ++i) {
|
|
|
|
|
int index = qrand() % possibleChars.length();
|
|
|
|
|
code.append(possibleChars.at(index));
|
|
|
|
|
}
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterWidget::startCountdown()
|
|
|
|
|
{
|
|
|
|
|
countdownSeconds = 300; // 5分钟
|
|
|
|
|
sendCodeButton->setEnabled(false);
|
|
|
|
|
updateTimer();
|
|
|
|
|
countdownTimer->start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterWidget::resetCountdown()
|
|
|
|
|
{
|
|
|
|
|
countdownTimer->stop();
|
|
|
|
|
countdownSeconds = 0;
|
|
|
|
|
sendCodeButton->setEnabled(true);
|
|
|
|
|
timerLabel->clear();
|
|
|
|
|
generatedCode.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterWidget::updateTimer()
|
|
|
|
|
{
|
|
|
|
|
if (countdownSeconds > 0) {
|
|
|
|
|
countdownSeconds--;
|
|
|
|
|
int minutes = countdownSeconds / 60;
|
|
|
|
|
int seconds = countdownSeconds % 60;
|
|
|
|
|
timerLabel->setText(QString("%1:%2").arg(minutes, 2, 10, QLatin1Char('0'))
|
|
|
|
|
.arg(seconds, 2, 10, QLatin1Char('0')));
|
|
|
|
|
} else {
|
|
|
|
|
resetCountdown();
|
|
|
|
|
QMessageBox::information(this, "提示", "验证码已过期,请重新获取");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|