You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
math-learing/src/main/java/com/personalproject/ui/scenes/RegistrationScene.java

289 lines
9.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.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.ScrollPane;
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;
/**
* 负责处理用户注册的场景.
*/
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;
/**
* RegistrationScene 的构造函数.
*
* @param primaryStage 应用程序的主舞台
* @param controller 数学学习控制器
*/
public RegistrationScene(Stage primaryStage, MathLearningController controller) {
this.primaryStage = primaryStage;
this.controller = controller;
initializeUi();
}
/**
* 初始化界面组件.
*/
private void initializeUi() {
// 创建主布局
VBox mainLayout = new VBox(15);
mainLayout.setAlignment(Pos.TOP_CENTER);
mainLayout.setPadding(new Insets(20));
// 标题
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);
final Label usernameLabel = new Label("用户名:");
usernameField = new TextField();
usernameField.setPrefWidth(200);
final Label emailLabel = new Label("邮箱:");
emailField = new TextField();
emailField.setPrefWidth(200);
final 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);
// 步骤2验证码验证初始隐藏
VBox verificationSection = new VBox(10);
verificationSection.setAlignment(Pos.CENTER);
verificationSection.setVisible(false);
verificationSection.setManaged(false);
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);
final Label passwordLabel = new Label("设置密码 (6-10位包含大小写字母和数字):");
passwordField = new PasswordField();
passwordField.setPrefWidth(200);
final 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);
// 返回按钮
backButton = new Button("返回");
backButton.setPrefWidth(100);
// 将组件添加到主布局
mainLayout.getChildren().addAll(titleLabel, registrationForm, backButton);
// 使用可滚动容器保证内容在小窗口中完整显示
ScrollPane scrollPane = new ScrollPane(mainLayout);
scrollPane.setFitToWidth(true);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
setCenter(scrollPane);
// 添加事件处理器
addEventHandlers(sendCodeButton, verificationSection, verifyCodeButton, passwordSection);
}
/**
* 为界面组件添加事件处理器.
*/
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());
}
/**
* 处理发送注册码的逻辑.
*/
private void handleSendCode(VBox verificationSection) {
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, "警告", "请输入用户名和邮箱");
return;
}
if (!controller.isValidEmail(email)) {
showAlert(Alert.AlertType.ERROR, "邮箱格式错误", "请输入有效的邮箱地址");
return;
}
// 发起注册
boolean success = controller.initiateRegistration(username, email, difficultyLevel);
if (success) {
showAlert(Alert.AlertType.INFORMATION, "注册码已发送", "注册码已发送至您的邮箱,请查收。");
verificationSection.setVisible(true);
verificationSection.setManaged(true);
} else {
showAlert(Alert.AlertType.ERROR, "注册失败", "用户名或邮箱可能已存在,请重试。");
}
}
/**
* 处理注册码验证.
*/
private void handleVerifyCode(VBox passwordSection) {
final String username = usernameField.getText().trim();
final 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, "验证失败", "注册码验证失败,请检查后重试。");
}
}
/**
* 处理设置用户密码的逻辑.
*/
private void handleSetPassword() {
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, "警告", "请输入并确认密码");
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) {
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);
primaryStage.getScene().setRoot(loginScene);
}
/**
* 显示提示对话框.
*
* @param alertType 提示类型
* @param title 对话框标题
* @param message 显示的消息
*/
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();
}
}