|
|
package com.personalproject.ui.scenes;
|
|
|
|
|
|
import javafx.geometry.Insets;
|
|
|
import javafx.geometry.Pos;
|
|
|
import javafx.scene.control.*;
|
|
|
import javafx.scene.layout.*;
|
|
|
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;
|
|
|
|
|
|
/**
|
|
|
* Scene for handling user registration.
|
|
|
*/
|
|
|
public class RegistrationScene extends BorderPane {
|
|
|
|
|
|
private final Stage primaryStage;
|
|
|
private final MathLearningController controller;
|
|
|
private TextField usernameField;
|
|
|
private TextField emailField;
|
|
|
private ComboBox<DifficultyLevel> difficultyComboBox;
|
|
|
private Button sendCodeButton;
|
|
|
private TextField registrationCodeField;
|
|
|
private Button verifyCodeButton;
|
|
|
private PasswordField passwordField;
|
|
|
private PasswordField confirmPasswordField;
|
|
|
private Button setPasswordButton;
|
|
|
private Button backButton;
|
|
|
private VBox registrationForm;
|
|
|
|
|
|
/**
|
|
|
* Constructor for RegistrationScene.
|
|
|
*
|
|
|
* @param primaryStage The main stage of the application
|
|
|
* @param controller The math learning controller
|
|
|
*/
|
|
|
public RegistrationScene(Stage primaryStage, MathLearningController controller) {
|
|
|
this.primaryStage = primaryStage;
|
|
|
this.controller = controller;
|
|
|
initializeUI();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Initializes the UI components.
|
|
|
*/
|
|
|
private void initializeUI() {
|
|
|
// Create the main layout
|
|
|
VBox mainLayout = new VBox(15);
|
|
|
mainLayout.setAlignment(Pos.CENTER);
|
|
|
mainLayout.setPadding(new Insets(20));
|
|
|
|
|
|
// Title
|
|
|
Label titleLabel = new Label("用户注册");
|
|
|
titleLabel.setFont(Font.font("System", FontWeight.BOLD, 24));
|
|
|
|
|
|
// Registration Form
|
|
|
registrationForm = new VBox(15);
|
|
|
registrationForm.setAlignment(Pos.CENTER);
|
|
|
|
|
|
// Step 1: Basic Info
|
|
|
GridPane basicInfoForm = new GridPane();
|
|
|
basicInfoForm.setHgap(10);
|
|
|
basicInfoForm.setVgap(10);
|
|
|
basicInfoForm.setAlignment(Pos.CENTER);
|
|
|
|
|
|
Label usernameLabel = new Label("用户名:");
|
|
|
usernameField = new TextField();
|
|
|
usernameField.setPrefWidth(200);
|
|
|
|
|
|
Label emailLabel = new Label("邮箱:");
|
|
|
emailField = new TextField();
|
|
|
emailField.setPrefWidth(200);
|
|
|
|
|
|
Label difficultyLabel = new Label("默认难度:");
|
|
|
difficultyComboBox = new ComboBox<>();
|
|
|
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);
|
|
|
|
|
|
// Step 2: Verification (hidden initially)
|
|
|
VBox verificationSection = new VBox(10);
|
|
|
verificationSection.setAlignment(Pos.CENTER);
|
|
|
verificationSection.setVisible(false);
|
|
|
verificationSection.setManaged(false);
|
|
|
|
|
|
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);
|
|
|
|
|
|
// Step 3: Password Setting (hidden initially)
|
|
|
VBox passwordSection = new VBox(10);
|
|
|
passwordSection.setAlignment(Pos.CENTER);
|
|
|
passwordSection.setVisible(false);
|
|
|
passwordSection.setManaged(false);
|
|
|
|
|
|
Label passwordLabel = new Label("设置密码 (6-10位,包含大小写字母和数字):");
|
|
|
passwordField = new PasswordField();
|
|
|
passwordField.setPrefWidth(200);
|
|
|
|
|
|
Label confirmPasswordLabel = new Label("确认密码:");
|
|
|
confirmPasswordField = new PasswordField();
|
|
|
confirmPasswordField.setPrefWidth(200);
|
|
|
|
|
|
setPasswordButton = new Button("设置密码");
|
|
|
setPasswordButton.setPrefWidth(120);
|
|
|
|
|
|
passwordSection.getChildren().addAll(passwordLabel, passwordField, confirmPasswordLabel,
|
|
|
confirmPasswordField, setPasswordButton);
|
|
|
registrationForm.getChildren().add(passwordSection);
|
|
|
|
|
|
// Back button
|
|
|
backButton = new Button("返回");
|
|
|
backButton.setPrefWidth(100);
|
|
|
|
|
|
// Add components to main layout
|
|
|
mainLayout.getChildren().addAll(titleLabel, registrationForm, backButton);
|
|
|
|
|
|
setCenter(mainLayout);
|
|
|
|
|
|
// Add event handlers
|
|
|
addEventHandlers(sendCodeButton, verificationSection, verifyCodeButton, passwordSection);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Adds event handlers to UI components.
|
|
|
*/
|
|
|
private void addEventHandlers(Button sendCodeButton, VBox verificationSection,
|
|
|
Button verifyCodeButton, VBox passwordSection) {
|
|
|
sendCodeButton.setOnAction(e -> handleSendCode(verificationSection));
|
|
|
verifyCodeButton.setOnAction(e -> handleVerifyCode(passwordSection));
|
|
|
setPasswordButton.setOnAction(e -> handleSetPassword());
|
|
|
backButton.setOnAction(e -> handleBack());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Handles sending registration code.
|
|
|
*/
|
|
|
private void handleSendCode(VBox verificationSection) {
|
|
|
String username = usernameField.getText().trim();
|
|
|
String email = emailField.getText().trim();
|
|
|
DifficultyLevel difficultyLevel = difficultyComboBox.getValue();
|
|
|
|
|
|
if (username.isEmpty() || email.isEmpty()) {
|
|
|
showAlert(Alert.AlertType.WARNING, "警告", "请输入用户名和邮箱");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!controller.isValidEmail(email)) {
|
|
|
showAlert(Alert.AlertType.ERROR, "邮箱格式错误", "请输入有效的邮箱地址");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// Initiate registration
|
|
|
boolean success = controller.initiateRegistration(username, email, difficultyLevel);
|
|
|
|
|
|
if (success) {
|
|
|
showAlert(Alert.AlertType.INFORMATION, "注册码已发送", "注册码已发送至您的邮箱,请查收。");
|
|
|
verificationSection.setVisible(true);
|
|
|
verificationSection.setManaged(true);
|
|
|
} else {
|
|
|
showAlert(Alert.AlertType.ERROR, "注册失败", "用户名或邮箱可能已存在,请重试。");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Handles verification of registration code.
|
|
|
*/
|
|
|
private void handleVerifyCode(VBox passwordSection) {
|
|
|
String username = usernameField.getText().trim();
|
|
|
String registrationCode = registrationCodeField.getText().trim();
|
|
|
|
|
|
if (registrationCode.isEmpty()) {
|
|
|
showAlert(Alert.AlertType.WARNING, "警告", "请输入注册码");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
boolean verified = controller.verifyRegistrationCode(username, registrationCode);
|
|
|
|
|
|
if (verified) {
|
|
|
showAlert(Alert.AlertType.INFORMATION, "验证成功", "注册码验证成功!");
|
|
|
passwordSection.setVisible(true);
|
|
|
passwordSection.setManaged(true);
|
|
|
} else {
|
|
|
showAlert(Alert.AlertType.ERROR, "验证失败", "注册码验证失败,请检查后重试。");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Handles setting the user password.
|
|
|
*/
|
|
|
private void handleSetPassword() {
|
|
|
String username = usernameField.getText().trim();
|
|
|
String password = passwordField.getText();
|
|
|
String confirmPassword = confirmPasswordField.getText();
|
|
|
|
|
|
if (password.isEmpty() || confirmPassword.isEmpty()) {
|
|
|
showAlert(Alert.AlertType.WARNING, "警告", "请输入并确认密码");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!password.equals(confirmPassword)) {
|
|
|
showAlert(Alert.AlertType.ERROR, "密码不匹配", "两次输入的密码不一致");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!controller.isValidPassword(password)) {
|
|
|
showAlert(Alert.AlertType.ERROR, "密码不符合要求",
|
|
|
"密码长度必须为6-10位,且包含大小写字母和数字");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
boolean success = controller.setPassword(username, password);
|
|
|
|
|
|
if (success) {
|
|
|
showAlert(Alert.AlertType.INFORMATION, "注册成功", "注册成功!请登录。");
|
|
|
handleBack(); // Go back to login screen
|
|
|
} else {
|
|
|
showAlert(Alert.AlertType.ERROR, "设置密码失败", "设置密码失败,请重试。");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Handles the back button action.
|
|
|
*/
|
|
|
private void handleBack() {
|
|
|
LoginScene loginScene = new LoginScene(primaryStage, controller);
|
|
|
primaryStage.getScene().setRoot(loginScene);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Shows an alert dialog.
|
|
|
*
|
|
|
* @param alertType Type of alert
|
|
|
* @param title Title of the alert
|
|
|
* @param message Message to display
|
|
|
*/
|
|
|
private void showAlert(Alert.AlertType alertType, String title, String message) {
|
|
|
Alert alert = new Alert(alertType);
|
|
|
alert.setTitle(title);
|
|
|
alert.setHeaderText(null);
|
|
|
alert.setContentText(message);
|
|
|
alert.showAndWait();
|
|
|
}
|
|
|
} |