diff --git a/src/main/java/com/example/mathsystemtogether/ExamController.java b/src/main/java/com/example/mathsystemtogether/ExamController.java index f219ddc..050a77d 100644 --- a/src/main/java/com/example/mathsystemtogether/ExamController.java +++ b/src/main/java/com/example/mathsystemtogether/ExamController.java @@ -45,7 +45,24 @@ public class ExamController { @FXML private Button logoutButton; @FXML private Label statusLabel; - + // 添加设置密码面板相关控件引用(需要在FXML中添加对应控件) + @FXML private VBox setPasswordPanel; + @FXML private PasswordField setPasswordField; + @FXML private PasswordField confirmPasswordField; + @FXML private Button confirmSetPasswordButton; + @FXML private Label setPasswordStatusLabel; + + // 添加修改密码面板相关控件引用 + @FXML private VBox changePasswordPanel; + @FXML private PasswordField oldPasswordField; + @FXML private PasswordField newPasswordField; + @FXML private PasswordField confirmNewPasswordField; + @FXML private Button confirmChangePasswordButton; + @FXML private Button cancelChangePasswordButton; + @FXML private Label changePasswordStatusLabel; + + // 添加修改密码按钮引用 + @FXML private Button changePasswordButton; // 数据成员 private Account currentAccount; private List examQuestions; @@ -75,11 +92,17 @@ public class ExamController { if (registerPanel != null) { registerPanel.setVisible(false); } + if (setPasswordPanel != null) { + setPasswordPanel.setVisible(false); + } + if (changePasswordPanel != null) { + changePasswordPanel.setVisible(false); + } } // 添加内部类用于存储注册信息 static class RegisterInfo { final String username; - final String password; + String password; final String email; final String registerCode; final Instant expireTime; @@ -102,12 +125,12 @@ public class ExamController { // 添加注册相关方法 @FXML private void handleRegister() { + String username = registerUsernameField.getText().trim(); - String password = registerPasswordField.getText(); String email = registerEmailField.getText().trim(); - if (username.isEmpty() || password.isEmpty() || email.isEmpty()) { - registerStatusLabel.setText("请填写所有字段"); + if (username.isEmpty() || email.isEmpty()) { + registerStatusLabel.setText("请填写用户名和邮箱"); registerStatusLabel.setStyle("-fx-text-fill: red;"); return; } @@ -119,14 +142,9 @@ public class ExamController { } try { - // 使用现有的邮箱验证码服务发送注册验证码 + // 发送注册验证码 emailCodeService.sendCode(email); - - // 生成注册码并存储待验证信息 - String registerCode = String.valueOf(100000 + new Random().nextInt(900000)); - pendingRegistrations.put(email, new RegisterInfo(username, password, email, registerCode)); - - registerStatusLabel.setText("注册验证码已发送到邮箱,请查收"); + registerStatusLabel.setText("验证码已发送到邮箱,请查收"); registerStatusLabel.setStyle("-fx-text-fill: green;"); } catch (Exception e) { registerStatusLabel.setText("发送验证码失败:" + e.getMessage()); @@ -149,25 +167,12 @@ private void handleVerifyRegisterCode() { boolean isValid = emailCodeService.verifyCode(email, code); if (isValid) { - // 验证通过,完成注册 - RegisterInfo registerInfo = pendingRegistrations.get(email); - if (registerInfo != null) { - Level defaultLevel = Level.小学; - userMap.put(registerInfo.username, new Account(registerInfo.username, registerInfo.password, defaultLevel)); - pendingRegistrations.remove(email); // 移除已注册的信息 - - registerStatusLabel.setText("注册成功!可以使用新账号登录"); - registerStatusLabel.setStyle("-fx-text-fill: green;"); + registerStatusLabel.setText("验证码验证成功,请设置密码"); + registerStatusLabel.setStyle("-fx-text-fill: green;"); - // 清空注册面板 - registerUsernameField.clear(); - registerPasswordField.clear(); - registerEmailField.clear(); - registerCodeField.clear(); - registerPanel.setVisible(false); - } else { - registerStatusLabel.setText("注册信息已过期,请重新注册"); - registerStatusLabel.setStyle("-fx-text-fill: red;"); + // 显示设置密码面板 + if (setPasswordPanel != null) { + setPasswordPanel.setVisible(true); } } else { registerStatusLabel.setText("验证码错误或已过期"); @@ -185,9 +190,257 @@ private void handleVerifyRegisterCode() { @FXML private void hideRegisterPanel() { + // 隐藏注册面板 + if (registerPanel != null) { + registerPanel.setVisible(false); + } + + // 显示登录面板相关组件 + if (usernameField != null) usernameField.setVisible(true); + if (passwordField != null) passwordField.setVisible(true); + if (emailField != null) emailField.setVisible(true); + if (emailCodeField != null) emailCodeField.setVisible(true); + if (sendCodeButton != null) sendCodeButton.setVisible(true); + if (verifyCodeButton != null) verifyCodeButton.setVisible(true); + if (loginButton != null) loginButton.setVisible(true); + if (emailStatusLabel != null) emailStatusLabel.setVisible(true); + if (loginStatusLabel != null) loginStatusLabel.setVisible(true); + + // 清空注册相关字段 + if (registerUsernameField != null) registerUsernameField.clear(); + if (registerEmailField != null) registerEmailField.clear(); + if (registerCodeField != null) registerCodeField.clear(); + if (registerStatusLabel != null) registerStatusLabel.setText(""); + } + @FXML + private void showSetPasswordPanel() { + if (setPasswordPanel != null) { + setPasswordPanel.setVisible(true); + } + } + + /** + * 隐藏设置密码面板 + */ + @FXML + private void hideSetPasswordPanel() { + if (setPasswordPanel != null) { + setPasswordPanel.setVisible(false); + } + } + + /** + * 确认设置密码 + */ + @FXML +private void handleSetPassword() { + String password = setPasswordField.getText(); + String confirmPassword = confirmPasswordField.getText(); + + if (password.isEmpty() || confirmPassword.isEmpty()) { + setPasswordStatusLabel.setText("请输入密码"); + setPasswordStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + if (!password.equals(confirmPassword)) { + setPasswordStatusLabel.setText("两次输入的密码不一致"); + setPasswordStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + if (!isValidPassword(password)) { + setPasswordStatusLabel.setText("密码必须为6-10位,包含大小写字母和数字"); + setPasswordStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + // 获取邮箱(从注册邮箱字段) + String email = registerEmailField.getText().trim(); + RegisterInfo registerInfo = pendingRegistrations.get(email); + + if (registerInfo != null) { + // 更新注册信息中的密码 + registerInfo.password = password; + + // 完成注册 + userMap.put(registerInfo.username, new Account(registerInfo.username, password, Level.小学)); + pendingRegistrations.remove(email); + + setPasswordStatusLabel.setText("注册成功!可以使用新账号登录"); + setPasswordStatusLabel.setStyle("-fx-text-fill: green;"); + + // 清空所有注册相关输入框 + registerUsernameField.clear(); + registerEmailField.clear(); + registerCodeField.clear(); + setPasswordField.clear(); + confirmPasswordField.clear(); + + // 隐藏面板 + if (setPasswordPanel != null) { + setPasswordPanel.setVisible(false); + } if (registerPanel != null) { registerPanel.setVisible(false); } + + // 显示登录面板 + hideRegisterPanel(); + } else { + setPasswordStatusLabel.setText("注册信息丢失,请重新注册"); + setPasswordStatusLabel.setStyle("-fx-text-fill: red;"); + } +} + +// 添加注册按钮事件处理方法 +@FXML +private void handleRegisterUser() { + String username = registerUsernameField.getText().trim(); + String email = registerEmailField.getText().trim(); + + if (username.isEmpty() || email.isEmpty()) { + registerStatusLabel.setText("请填写用户名和邮箱"); + registerStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + if (userMap.containsKey(username)) { + registerStatusLabel.setText("用户名已存在"); + registerStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + try { + // 发送注册验证码 + emailCodeService.sendCode(email); + + // 生成临时注册信息(密码将在后续设置) + String tempPassword = ""; // 临时空密码 + RegisterInfo registerInfo = new RegisterInfo(username, tempPassword, email, ""); + pendingRegistrations.put(email, registerInfo); + + registerStatusLabel.setText("注册验证码已发送到邮箱,请查收"); + registerStatusLabel.setStyle("-fx-text-fill: green;"); + } catch (Exception e) { + registerStatusLabel.setText("发送验证码失败:" + e.getMessage()); + registerStatusLabel.setStyle("-fx-text-fill: red;"); + } +} + + /** + * 显示修改密码面板 + */ + @FXML + private void showChangePasswordPanel() { + if (changePasswordPanel != null && currentAccount != null) { + changePasswordPanel.setVisible(true); + changePasswordPanel.toFront(); + } + } + + /** + * 隐藏修改密码面板 + */ + @FXML + private void hideChangePasswordPanel() { + if (changePasswordPanel != null) { + changePasswordPanel.setVisible(false); + // 清空输入框 + oldPasswordField.clear(); + newPasswordField.clear(); + confirmNewPasswordField.clear(); + changePasswordStatusLabel.setText(""); + } + } + + /** + * 确认修改密码 + */ + @FXML + private void handleChangePassword() { + if (currentAccount == null) { + changePasswordStatusLabel.setText("请先登录"); + changePasswordStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + String oldPassword = oldPasswordField.getText(); + String newPassword = newPasswordField.getText(); + String confirmNewPassword = confirmNewPasswordField.getText(); + + if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmNewPassword.isEmpty()) { + changePasswordStatusLabel.setText("请填写所有字段"); + changePasswordStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + // 验证原密码 + if (!currentAccount.password.equals(oldPassword)) { + changePasswordStatusLabel.setText("原密码错误"); + changePasswordStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + // 验证新密码一致性 + if (!newPassword.equals(confirmNewPassword)) { + changePasswordStatusLabel.setText("新密码两次输入不一致"); + changePasswordStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + // 验证新密码强度 + if (!isValidPassword(newPassword)) { + changePasswordStatusLabel.setText("新密码必须为6-10位,包含大小写字母和数字"); + changePasswordStatusLabel.setStyle("-fx-text-fill: red;"); + return; + } + + // 更新密码 + Account account = userMap.get(currentAccount.username); + if (account != null) { + account.password = newPassword; // 注意:需要修改Account类使password可修改 + currentAccount.password = newPassword; + changePasswordStatusLabel.setText("密码修改成功"); + changePasswordStatusLabel.setStyle("-fx-text-fill: green;"); + + // 清空输入框 + oldPasswordField.clear(); + newPasswordField.clear(); + confirmNewPasswordField.clear(); + + // 隐藏面板 + hideChangePasswordPanel(); + } + } + + /** + * 验证密码强度 + * @param password 密码 + * @return 是否符合要求 + */ + private boolean isValidPassword(String password) { + // 长度检查 + if (password.length() < 6 || password.length() > 10) { + return false; + } + + // 检查是否包含大小写字母和数字 + boolean hasUpper = false; + boolean hasLower = false; + boolean hasDigit = false; + + for (char c : password.toCharArray()) { + if (Character.isUpperCase(c)) { + hasUpper = true; + } else if (Character.isLowerCase(c)) { + hasLower = true; + } else if (Character.isDigit(c)) { + hasDigit = true; + } + } + + return hasUpper && hasLower && hasDigit; } private void initAccounts() { // 小学三个账号 @@ -278,11 +531,7 @@ private void handleVerifyRegisterCode() { String selectedLevel = levelComboBox.getValue(); ChoiceQuestionGenerator.Level level = ChoiceQuestionGenerator.Level.valueOf(selectedLevel); - if (!emailVerified) { - statusLabel.setText("请先完成邮箱验证码验证"); - statusLabel.setStyle("-fx-text-fill: red;"); - return; - } + // 生成考试题目 questionGenerator = new ChoiceQuestionGenerator(); @@ -327,32 +576,34 @@ private void handleVerifyRegisterCode() { } } - @FXML - private void handleVerifyEmailCode() { - String email = emailField != null ? emailField.getText().trim() : ""; - String code = emailCodeField != null ? emailCodeField.getText().trim() : ""; - if (email.isEmpty() || code.isEmpty()) { - if (emailStatusLabel != null) { - emailStatusLabel.setText("请输入邮箱和验证码"); - emailStatusLabel.setStyle("-fx-text-fill: red;"); - } - return; +// 修正 handleVerifyEmailCode 方法,应该用于登录前的邮箱验证而不是注册 +@FXML +private void handleVerifyEmailCode() { + String email = emailField != null ? emailField.getText().trim() : ""; + String code = emailCodeField != null ? emailCodeField.getText().trim() : ""; + if (email.isEmpty() || code.isEmpty()) { + if (emailStatusLabel != null) { + emailStatusLabel.setText("请输入邮箱和验证码"); + emailStatusLabel.setStyle("-fx-text-fill: red;"); } - boolean ok = emailCodeService.verifyCode(email, code); - if (ok) { - emailVerified = true; - if (emailStatusLabel != null) { - emailStatusLabel.setText("邮箱验证成功,可开始考试"); - emailStatusLabel.setStyle("-fx-text-fill: green;"); - } - } else { - emailVerified = false; - if (emailStatusLabel != null) { - emailStatusLabel.setText("验证码错误或已过期"); - emailStatusLabel.setStyle("-fx-text-fill: red;"); - } + return; + } + boolean ok = emailCodeService.verifyCode(email, code); + if (ok) { + emailVerified = true; + if (emailStatusLabel != null) { + emailStatusLabel.setText("邮箱验证成功,可开始考试"); + emailStatusLabel.setStyle("-fx-text-fill: green;"); + } + } else { + emailVerified = false; + if (emailStatusLabel != null) { + emailStatusLabel.setText("验证码错误或已过期"); + emailStatusLabel.setStyle("-fx-text-fill: red;"); } } +} + private void startExam() { try { @@ -385,7 +636,7 @@ private void handleVerifyRegisterCode() { // 内部类 static class Account { final String username; - final String password; + String password; final Level level; Account(String username, String password, Level level) { diff --git a/src/main/resources/com/example/mathsystemtogether/exam-view.fxml b/src/main/resources/com/example/mathsystemtogether/exam-view.fxml index 46b5366..1902a93 100644 --- a/src/main/resources/com/example/mathsystemtogether/exam-view.fxml +++ b/src/main/resources/com/example/mathsystemtogether/exam-view.fxml @@ -31,7 +31,7 @@ - +