diff --git a/src/main/java/com/mathgenerator/controller/QuizController.java b/src/main/java/com/mathgenerator/controller/QuizController.java index abce998..830e06d 100644 --- a/src/main/java/com/mathgenerator/controller/QuizController.java +++ b/src/main/java/com/mathgenerator/controller/QuizController.java @@ -62,7 +62,7 @@ public class QuizController { } /** - * 显示当前的题目和选项 + * 显示当前的题目和选项 (已更新,增加ABCD前缀) */ private void displayCurrentQuestion() { ChoiceQuestion currentQuestion = questions.get(currentQuestionIndex); @@ -72,8 +72,10 @@ public class QuizController { questionTextLabel.setText(currentQuestion.questionText()); List radioButtons = List.of(option1, option2, option3, option4); + String[] prefixes = {"A. ", "B. ", "C. ", "D. "}; // 定义选项前缀 for (int i = 0; i < radioButtons.size(); i++) { - radioButtons.get(i).setText(currentQuestion.options().get(i)); + // 将前缀和选项文本结合起来 + radioButtons.get(i).setText(prefixes[i] + currentQuestion.options().get(i)); } optionsGroup.selectToggle(null); // 清除上一次的选择 diff --git a/src/main/java/com/mathgenerator/controller/RegisterController.java b/src/main/java/com/mathgenerator/controller/RegisterController.java index 83d105e..d7fd31a 100644 --- a/src/main/java/com/mathgenerator/controller/RegisterController.java +++ b/src/main/java/com/mathgenerator/controller/RegisterController.java @@ -50,36 +50,52 @@ public class RegisterController { @FXML private void handleRegisterAction(ActionEvent event) { - // 1. 字段校验 + // 1. 字段校验 (已简化,不再校验密码) String username = usernameField.getText(); + String email = emailField.getText(); - // --- 2. 使用工具类进行校验 --- - if (!ValidationUtils.isUsernameValid(username)) { - statusLabel.setText("注册失败:用户名不能为空且不能包含空格!"); + if (!ValidationUtils.isUsernameValid(username) || !ValidationUtils.isEmailValid(email) || + verificationCodeField.getText().isEmpty()) { + statusLabel.setText("所有字段都不能为空且格式正确!"); return; } - // ... - if (!ValidationUtils.isPasswordValid(passwordField.getText())) { // 同样可以替换密码校验 - statusLabel.setText("密码格式错误!必须为6-10位,且包含大小写字母和数字。"); + if (this.sentCode == null || !this.sentCode.equals(verificationCodeField.getText())) { + statusLabel.setText("验证码错误!"); return; } - // 2. 调用后端服务进行注册 - boolean success = userService.register( - usernameField.getText(), - emailField.getText(), - passwordField.getText() - ); + // 2. 调用后端服务进行无密码注册 + boolean success = userService.register(username, email); - // 3. 根据结果更新UI + // 3. 根据结果更新UI或跳转 if (success) { - statusLabel.setText("注册成功!请返回登录。"); - registerButton.setDisable(true); + statusLabel.setText("注册成功!请设置您的密码。"); + // 成功后,加载设置密码界面,并传递用户名 + loadSetPasswordScene(username); } else { statusLabel.setText("注册失败:用户名或邮箱已被占用。"); } } + /** + * (新增) 加载设置密码界面,并传递用户名。 + */ + private void loadSetPasswordScene(String username) { + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/mathgenerator/view/SetPasswordView.fxml")); + Parent root = loader.load(); + + SetPasswordController controller = loader.getController(); + controller.initData(username); // 将用户名传递给新界面的控制器 + + Stage stage = (Stage) registerButton.getScene().getWindow(); + stage.setScene(new Scene(root)); + stage.setTitle("设置密码"); + } catch (IOException e) { + e.printStackTrace(); + } + } + @FXML private void handleBackToLoginAction(ActionEvent event) { loadScene("/com/mathgenerator/view/LoginView.fxml"); diff --git a/src/main/java/com/mathgenerator/controller/SetPasswordController.java b/src/main/java/com/mathgenerator/controller/SetPasswordController.java new file mode 100644 index 0000000..278c80c --- /dev/null +++ b/src/main/java/com/mathgenerator/controller/SetPasswordController.java @@ -0,0 +1,80 @@ +package com.mathgenerator.controller; + +import com.mathgenerator.model.User; +import com.mathgenerator.service.UserService; +import com.mathgenerator.util.ValidationUtils; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.PasswordField; +import javafx.stage.Stage; + +import java.io.IOException; + +public class SetPasswordController { + + private final UserService userService = new UserService(); + private String username; + + @FXML private Label promptLabel; + @FXML private PasswordField newPasswordField; + @FXML private PasswordField confirmPasswordField; + @FXML private Button confirmButton; + @FXML private Label statusLabel; + + /** + * 接收从注册界面传递过来的用户名 + */ + public void initData(String username) { + this.username = username; + promptLabel.setText("为您的账户 " + username + " 设置密码"); + } + + @FXML + private void handleConfirmAction(ActionEvent event) { + String newPassword = newPasswordField.getText(); + String confirmPassword = confirmPasswordField.getText(); + + if (!newPassword.equals(confirmPassword)) { + statusLabel.setText("两次输入的密码不匹配!"); + return; + } + if (!ValidationUtils.isPasswordValid(newPassword)) { + statusLabel.setText("新密码格式错误!必须为6-10位,且包含大小写字母和数字。"); + return; + } + + // 调用后端服务设置密码 + boolean success = userService.setPassword(this.username, newPassword); + + if (success) { + statusLabel.setText("密码设置成功!正在进入主菜单..."); + // 密码设置成功后,获取完整的用户信息并直接跳转到主菜单 + userService.findUserByUsername(this.username).ifPresent(this::loadMainMenu); + } else { + statusLabel.setText("密码设置失败,请稍后重试或重新注册。"); + } + } + + /** + * 加载主菜单界面,并传递用户信息 (实现自动登录) + */ + private void loadMainMenu(User user) { + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/mathgenerator/view/MainMenuView.fxml")); + Parent root = loader.load(); + MainMenuController controller = loader.getController(); + controller.initData(user); // 将完整的User对象传递给主菜单 + + Stage stage = (Stage) confirmButton.getScene().getWindow(); + stage.setScene(new Scene(root)); + stage.setTitle("主菜单"); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/mathgenerator/service/UserService.java b/src/main/java/com/mathgenerator/service/UserService.java index 7a6375b..2c816a7 100644 --- a/src/main/java/com/mathgenerator/service/UserService.java +++ b/src/main/java/com/mathgenerator/service/UserService.java @@ -35,18 +35,20 @@ public class UserService { } private Map loadUsersFromFile() { - try { - if (Files.exists(USER_FILE_PATH) && Files.size(USER_FILE_PATH) > 0) { - try (FileReader reader = new FileReader(USER_FILE_PATH.toFile())) { - Type type = new TypeToken>() {}.getType(); - Map loadedUsers = gson.fromJson(reader, type); - return loadedUsers != null ? new ConcurrentHashMap<>(loadedUsers) : new ConcurrentHashMap<>(); - } - } + // 如果文件不存在,直接返回一个空的Map,不再创建默认用户 + if (!Files.exists(USER_FILE_PATH)) { + return new ConcurrentHashMap<>(); + } + + try (FileReader reader = new FileReader(USER_FILE_PATH.toFile())) { + Type type = new TypeToken>() {}.getType(); + Map loadedUsers = gson.fromJson(reader, type); + // 如果文件为空或格式错误,也返回一个空的Map + return loadedUsers != null ? new ConcurrentHashMap<>(loadedUsers) : new ConcurrentHashMap<>(); } catch (IOException e) { System.err.println("错误:加载用户文件失败 - " + e.getMessage()); + return new ConcurrentHashMap<>(); } - return new ConcurrentHashMap<>(); } private void saveUsers() { @@ -103,32 +105,49 @@ public class UserService { } /** - * 注册新用户。 - * @return 成功返回true, 否则返回false + * (已修正) 注册一个没有初始密码的新用户。 + * @param username 新用户的用户名 + * @param email 新用户的邮箱 + * @return 注册成功返回true, 如果用户名或邮箱已存在则返回false。 */ - public boolean register(String username, String email, String password) { - // 1. 基础校验:防止 null 或空白输入 - if (username == null || email == null || password == null || - username.trim().isEmpty() || email.trim().isEmpty() || password.trim().isEmpty()) { - return false; + public boolean register(String username, String email) { + if (userDatabase.containsKey(username)) { + return false; // 用户名已存在 } - - // 2. 检查用户名或邮箱是否已存在(使用 Objects.equals 安全比较) - boolean usernameExists = userDatabase.containsKey(username); - boolean emailExists = userDatabase.values().stream() - .anyMatch(u -> Objects.equals(u.email(), email)); - - if (usernameExists || emailExists) { - return false; // 用户名或邮箱已存在 + // 检查数据库中已存在的用户的email是否与新email相同 + // 使用 email.equals(u.email()) 可以安全地处理 u.email() 为 null 的情况 + if (userDatabase.values().stream() + .anyMatch(u -> email.equals(u.email()))) { + return false; // 邮箱已存在 } - // 3. 创建新用户并保存 - User newUser = new User(username, email, password); + // --- 核心修正在这里 --- + // 创建用户时,密码字段设为 null,表示该用户处于“待设置密码”状态 + User newUser = new User(username, email, null); userDatabase.put(username, newUser); saveUsers(); return true; } + /** + * (新增) 为指定用户设置初始密码。 + * @param username 要设置密码的用户名 + * @param password 要设置的新密码 + * @return 成功设置返回 true, 如果用户不存在则返回 false + */ + public boolean setPassword(String username, String password) { + return findUserByUsername(username) + .map(user -> { + // 只有当用户当前密码为 null 时才允许设置 + if (user.password() == null) { + User updatedUser = new User(user.username(), user.email(), password); + userDatabase.put(username, updatedUser); + saveUsers(); + return true; + } + return false; // 用户已经有密码,不能通过此方法设置 + }).orElse(false); + } /** * 验证密码是否符合复杂度要求。 * @param password 待验证的密码 diff --git a/src/main/resources/com/mathgenerator/view/RegisterView.fxml b/src/main/resources/com/mathgenerator/view/RegisterView.fxml index 082d3fe..5012e91 100644 --- a/src/main/resources/com/mathgenerator/view/RegisterView.fxml +++ b/src/main/resources/com/mathgenerator/view/RegisterView.fxml @@ -24,8 +24,6 @@