|
|
|
|
@ -1,18 +1,25 @@
|
|
|
|
|
package com.personalproject.ui.scenes;
|
|
|
|
|
|
|
|
|
|
import com.personalproject.controller.MathLearningController;
|
|
|
|
|
import com.personalproject.model.DifficultyLevel;
|
|
|
|
|
import com.personalproject.ui.views.MainMenuView;
|
|
|
|
|
import javafx.geometry.Insets;
|
|
|
|
|
import javafx.geometry.Pos;
|
|
|
|
|
import javafx.scene.control.*;
|
|
|
|
|
import javafx.scene.layout.*;
|
|
|
|
|
import javafx.scene.control.Alert;
|
|
|
|
|
import javafx.scene.control.Button;
|
|
|
|
|
import javafx.scene.control.ComboBox;
|
|
|
|
|
import javafx.scene.control.Label;
|
|
|
|
|
import javafx.scene.control.PasswordField;
|
|
|
|
|
import javafx.scene.control.TextField;
|
|
|
|
|
import javafx.scene.layout.BorderPane;
|
|
|
|
|
import javafx.scene.layout.GridPane;
|
|
|
|
|
import javafx.scene.layout.VBox;
|
|
|
|
|
import javafx.scene.text.Font;
|
|
|
|
|
import javafx.scene.text.FontWeight;
|
|
|
|
|
import javafx.stage.Stage;
|
|
|
|
|
import com.personalproject.controller.MathLearningController;
|
|
|
|
|
import com.personalproject.model.DifficultyLevel;
|
|
|
|
|
import com.personalproject.ui.scenes.LoginScene;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 负责处理用户注册的场景。
|
|
|
|
|
* 负责处理用户注册的场景.
|
|
|
|
|
*/
|
|
|
|
|
public class RegistrationScene extends BorderPane {
|
|
|
|
|
|
|
|
|
|
@ -31,120 +38,121 @@ public class RegistrationScene extends BorderPane {
|
|
|
|
|
private VBox registrationForm;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* RegistrationScene 的构造函数。
|
|
|
|
|
* RegistrationScene 的构造函数.
|
|
|
|
|
*
|
|
|
|
|
* @param primaryStage 应用程序的主舞台
|
|
|
|
|
* @param controller 数学学习控制器
|
|
|
|
|
* @param controller 数学学习控制器
|
|
|
|
|
*/
|
|
|
|
|
public RegistrationScene(Stage primaryStage, MathLearningController controller) {
|
|
|
|
|
this.primaryStage = primaryStage;
|
|
|
|
|
this.controller = controller;
|
|
|
|
|
initializeUI();
|
|
|
|
|
initializeUi();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化界面组件。
|
|
|
|
|
* 初始化界面组件.
|
|
|
|
|
*/
|
|
|
|
|
private void initializeUI() {
|
|
|
|
|
private void initializeUi() {
|
|
|
|
|
// 创建主布局
|
|
|
|
|
VBox mainLayout = new VBox(15);
|
|
|
|
|
mainLayout.setAlignment(Pos.CENTER);
|
|
|
|
|
mainLayout.setPadding(new Insets(20));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
Label titleLabel = new Label("用户注册");
|
|
|
|
|
final Label titleLabel = new Label("用户注册");
|
|
|
|
|
titleLabel.setFont(Font.font("System", FontWeight.BOLD, 24));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 注册表单
|
|
|
|
|
registrationForm = new VBox(15);
|
|
|
|
|
registrationForm.setAlignment(Pos.CENTER);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 步骤1:填写基础信息
|
|
|
|
|
GridPane basicInfoForm = new GridPane();
|
|
|
|
|
basicInfoForm.setHgap(10);
|
|
|
|
|
basicInfoForm.setVgap(10);
|
|
|
|
|
basicInfoForm.setAlignment(Pos.CENTER);
|
|
|
|
|
|
|
|
|
|
Label usernameLabel = new Label("用户名:");
|
|
|
|
|
|
|
|
|
|
final Label usernameLabel = new Label("用户名:");
|
|
|
|
|
usernameField = new TextField();
|
|
|
|
|
usernameField.setPrefWidth(200);
|
|
|
|
|
|
|
|
|
|
Label emailLabel = new Label("邮箱:");
|
|
|
|
|
|
|
|
|
|
final Label emailLabel = new Label("邮箱:");
|
|
|
|
|
emailField = new TextField();
|
|
|
|
|
emailField.setPrefWidth(200);
|
|
|
|
|
|
|
|
|
|
Label difficultyLabel = new Label("默认难度:");
|
|
|
|
|
|
|
|
|
|
final Label difficultyLabel = new Label("默认难度:");
|
|
|
|
|
difficultyComboBox = new ComboBox<>();
|
|
|
|
|
difficultyComboBox.getItems().addAll(DifficultyLevel.PRIMARY, DifficultyLevel.MIDDLE, DifficultyLevel.HIGH);
|
|
|
|
|
difficultyComboBox.getItems()
|
|
|
|
|
.addAll(DifficultyLevel.PRIMARY, DifficultyLevel.MIDDLE, DifficultyLevel.HIGH);
|
|
|
|
|
difficultyComboBox.setValue(DifficultyLevel.PRIMARY);
|
|
|
|
|
difficultyComboBox.setPrefWidth(200);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
basicInfoForm.add(usernameLabel, 0, 0);
|
|
|
|
|
basicInfoForm.add(usernameField, 1, 0);
|
|
|
|
|
basicInfoForm.add(emailLabel, 0, 1);
|
|
|
|
|
basicInfoForm.add(emailField, 1, 1);
|
|
|
|
|
basicInfoForm.add(difficultyLabel, 0, 2);
|
|
|
|
|
basicInfoForm.add(difficultyComboBox, 1, 2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sendCodeButton = new Button("发送注册码");
|
|
|
|
|
sendCodeButton.setPrefWidth(120);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
registrationForm.getChildren().addAll(basicInfoForm, sendCodeButton);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 步骤2:验证码验证(初始隐藏)
|
|
|
|
|
VBox verificationSection = new VBox(10);
|
|
|
|
|
verificationSection.setAlignment(Pos.CENTER);
|
|
|
|
|
verificationSection.setVisible(false);
|
|
|
|
|
verificationSection.setManaged(false);
|
|
|
|
|
|
|
|
|
|
Label codeLabel = new Label("注册码:");
|
|
|
|
|
|
|
|
|
|
final Label codeLabel = new Label("注册码:");
|
|
|
|
|
registrationCodeField = new TextField();
|
|
|
|
|
registrationCodeField.setPrefWidth(200);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
verifyCodeButton = new Button("验证注册码");
|
|
|
|
|
verifyCodeButton.setPrefWidth(120);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
verificationSection.getChildren().addAll(codeLabel, registrationCodeField, verifyCodeButton);
|
|
|
|
|
registrationForm.getChildren().add(verificationSection);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 步骤3:设置密码(初始隐藏)
|
|
|
|
|
VBox passwordSection = new VBox(10);
|
|
|
|
|
passwordSection.setAlignment(Pos.CENTER);
|
|
|
|
|
passwordSection.setVisible(false);
|
|
|
|
|
passwordSection.setManaged(false);
|
|
|
|
|
|
|
|
|
|
Label passwordLabel = new Label("设置密码 (6-10位,包含大小写字母和数字):");
|
|
|
|
|
|
|
|
|
|
final Label passwordLabel = new Label("设置密码 (6-10位,包含大小写字母和数字):");
|
|
|
|
|
passwordField = new PasswordField();
|
|
|
|
|
passwordField.setPrefWidth(200);
|
|
|
|
|
|
|
|
|
|
Label confirmPasswordLabel = new Label("确认密码:");
|
|
|
|
|
|
|
|
|
|
final Label confirmPasswordLabel = new Label("确认密码:");
|
|
|
|
|
confirmPasswordField = new PasswordField();
|
|
|
|
|
confirmPasswordField.setPrefWidth(200);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setPasswordButton = new Button("设置密码");
|
|
|
|
|
setPasswordButton.setPrefWidth(120);
|
|
|
|
|
|
|
|
|
|
passwordSection.getChildren().addAll(passwordLabel, passwordField, confirmPasswordLabel,
|
|
|
|
|
|
|
|
|
|
passwordSection.getChildren().addAll(passwordLabel, passwordField, confirmPasswordLabel,
|
|
|
|
|
confirmPasswordField, setPasswordButton);
|
|
|
|
|
registrationForm.getChildren().add(passwordSection);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 返回按钮
|
|
|
|
|
backButton = new Button("返回");
|
|
|
|
|
backButton.setPrefWidth(100);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 将组件添加到主布局
|
|
|
|
|
mainLayout.getChildren().addAll(titleLabel, registrationForm, backButton);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setCenter(mainLayout);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加事件处理器
|
|
|
|
|
addEventHandlers(sendCodeButton, verificationSection, verifyCodeButton, passwordSection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 为界面组件添加事件处理器。
|
|
|
|
|
* 为界面组件添加事件处理器.
|
|
|
|
|
*/
|
|
|
|
|
private void addEventHandlers(Button sendCodeButton, VBox verificationSection,
|
|
|
|
|
private void addEventHandlers(Button sendCodeButton, VBox verificationSection,
|
|
|
|
|
Button verifyCodeButton, VBox passwordSection) {
|
|
|
|
|
sendCodeButton.setOnAction(e -> handleSendCode(verificationSection));
|
|
|
|
|
verifyCodeButton.setOnAction(e -> handleVerifyCode(passwordSection));
|
|
|
|
|
@ -153,12 +161,12 @@ public class RegistrationScene extends BorderPane {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理发送注册码的逻辑。
|
|
|
|
|
* 处理发送注册码的逻辑.
|
|
|
|
|
*/
|
|
|
|
|
private void handleSendCode(VBox verificationSection) {
|
|
|
|
|
String username = usernameField.getText().trim();
|
|
|
|
|
String email = emailField.getText().trim();
|
|
|
|
|
DifficultyLevel difficultyLevel = difficultyComboBox.getValue();
|
|
|
|
|
final String username = usernameField.getText().trim();
|
|
|
|
|
final String email = emailField.getText().trim();
|
|
|
|
|
final DifficultyLevel difficultyLevel = difficultyComboBox.getValue();
|
|
|
|
|
|
|
|
|
|
if (username.isEmpty() || email.isEmpty()) {
|
|
|
|
|
showAlert(Alert.AlertType.WARNING, "警告", "请输入用户名和邮箱");
|
|
|
|
|
@ -183,11 +191,11 @@ public class RegistrationScene extends BorderPane {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理注册码验证。
|
|
|
|
|
* 处理注册码验证.
|
|
|
|
|
*/
|
|
|
|
|
private void handleVerifyCode(VBox passwordSection) {
|
|
|
|
|
String username = usernameField.getText().trim();
|
|
|
|
|
String registrationCode = registrationCodeField.getText().trim();
|
|
|
|
|
final String username = usernameField.getText().trim();
|
|
|
|
|
final String registrationCode = registrationCodeField.getText().trim();
|
|
|
|
|
|
|
|
|
|
if (registrationCode.isEmpty()) {
|
|
|
|
|
showAlert(Alert.AlertType.WARNING, "警告", "请输入注册码");
|
|
|
|
|
@ -206,12 +214,12 @@ public class RegistrationScene extends BorderPane {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理设置用户密码的逻辑。
|
|
|
|
|
* 处理设置用户密码的逻辑.
|
|
|
|
|
*/
|
|
|
|
|
private void handleSetPassword() {
|
|
|
|
|
String username = usernameField.getText().trim();
|
|
|
|
|
String password = passwordField.getText();
|
|
|
|
|
String confirmPassword = confirmPasswordField.getText();
|
|
|
|
|
final String username = usernameField.getText().trim();
|
|
|
|
|
final String password = passwordField.getText();
|
|
|
|
|
final String confirmPassword = confirmPasswordField.getText();
|
|
|
|
|
|
|
|
|
|
if (password.isEmpty() || confirmPassword.isEmpty()) {
|
|
|
|
|
showAlert(Alert.AlertType.WARNING, "警告", "请输入并确认密码");
|
|
|
|
|
@ -224,7 +232,7 @@ public class RegistrationScene extends BorderPane {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!controller.isValidPassword(password)) {
|
|
|
|
|
showAlert(Alert.AlertType.ERROR, "密码不符合要求",
|
|
|
|
|
showAlert(Alert.AlertType.ERROR, "密码不符合要求",
|
|
|
|
|
"密码长度必须为6-10位,且包含大小写字母和数字");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -232,15 +240,26 @@ public class RegistrationScene extends BorderPane {
|
|
|
|
|
boolean success = controller.setPassword(username, password);
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
showAlert(Alert.AlertType.INFORMATION, "注册成功", "注册成功!请登录。");
|
|
|
|
|
handleBack(); // 返回登录界面
|
|
|
|
|
var userAccountOptional = controller.getUserAccount(username);
|
|
|
|
|
if (userAccountOptional.isPresent()) {
|
|
|
|
|
showAlert(Alert.AlertType.INFORMATION, "注册成功", "注册成功!正在进入难度选择界面。");
|
|
|
|
|
MainMenuView mainMenuView = new MainMenuView(primaryStage, controller,
|
|
|
|
|
userAccountOptional.get());
|
|
|
|
|
if (primaryStage.getScene() != null) {
|
|
|
|
|
primaryStage.getScene().setRoot(mainMenuView);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
showAlert(Alert.AlertType.WARNING, "注册提示",
|
|
|
|
|
"注册成功,但未能加载用户信息,请使用新密码登录。");
|
|
|
|
|
handleBack();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
showAlert(Alert.AlertType.ERROR, "设置密码失败", "设置密码失败,请重试。");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理返回按钮的操作。
|
|
|
|
|
* 处理返回按钮的操作.
|
|
|
|
|
*/
|
|
|
|
|
private void handleBack() {
|
|
|
|
|
LoginScene loginScene = new LoginScene(primaryStage, controller);
|
|
|
|
|
@ -248,11 +267,11 @@ public class RegistrationScene extends BorderPane {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 显示提示对话框。
|
|
|
|
|
* 显示提示对话框.
|
|
|
|
|
*
|
|
|
|
|
* @param alertType 提示类型
|
|
|
|
|
* @param title 对话框标题
|
|
|
|
|
* @param message 显示的消息
|
|
|
|
|
* @param title 对话框标题
|
|
|
|
|
* @param message 显示的消息
|
|
|
|
|
*/
|
|
|
|
|
private void showAlert(Alert.AlertType alertType, String title, String message) {
|
|
|
|
|
Alert alert = new Alert(alertType);
|
|
|
|
|
|