From d06b323cd9b8fa8b9a2c7a6142eb5d7b9458e714 Mon Sep 17 00:00:00 2001 From: smallbailangui Date: Tue, 7 Oct 2025 22:48:39 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=9C=AA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generator/PrimarySchoolGenerator.java | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/main/java/com/mathgenerator/generator/PrimarySchoolGenerator.java b/src/main/java/com/mathgenerator/generator/PrimarySchoolGenerator.java index 9ed1061..530e6dc 100644 --- a/src/main/java/com/mathgenerator/generator/PrimarySchoolGenerator.java +++ b/src/main/java/com/mathgenerator/generator/PrimarySchoolGenerator.java @@ -172,25 +172,6 @@ public class PrimarySchoolGenerator implements QuestionGenerator { parts.add(startIndex, "("); } - // 在 PrimarySchoolGenerator.java 中添加这个方法 - /** - * 仅生成题目字符串,不包含答案和选项。 - * 这是为了方便子类(初中、高中)继承和修改题干。 - * @return 题目文本字符串 - */ - public String generateBasicQuestionText() { - ThreadLocalRandom random = ThreadLocalRandom.current(); - int operandCount = random.nextInt(2, 5); - List parts = new ArrayList<>(); - parts.add(String.valueOf(getOperand())); - for (int i = 1; i < operandCount; i++) { - parts.add(getRandomOperator()); - parts.add(String.valueOf(getOperand())); - } - if (operandCount > 2 && random.nextBoolean()) { - addParentheses(parts); - } - return String.join(" ", parts); - } + } \ No newline at end of file -- 2.34.1 From a3d3576f2025f67fd8936f87a7add53e8f9a6d9b Mon Sep 17 00:00:00 2001 From: smallbailangui Date: Tue, 7 Oct 2025 23:09:25 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E7=A9=BA=E6=A0=BC=E6=BC=8F=E6=B4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/LoginController.java | 10 +++- .../controller/RegisterController.java | 21 +++----- .../mathgenerator/util/ValidationUtils.java | 52 +++++++++++++++++++ 3 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/mathgenerator/util/ValidationUtils.java diff --git a/src/main/java/com/mathgenerator/controller/LoginController.java b/src/main/java/com/mathgenerator/controller/LoginController.java index 7c7150d..264c0c0 100644 --- a/src/main/java/com/mathgenerator/controller/LoginController.java +++ b/src/main/java/com/mathgenerator/controller/LoginController.java @@ -15,7 +15,7 @@ import javafx.stage.Stage; import java.io.IOException; import java.util.Optional; - +import com.mathgenerator.util.ValidationUtils; public class LoginController { // 依赖注入后端服务 @@ -46,7 +46,13 @@ public class LoginController { String username = usernameField.getText(); String password = passwordField.getText(); - if (username.isEmpty() || password.isEmpty()) { + // --- 2. 使用工具类进行校验 --- + if (!ValidationUtils.isUsernameValid(username)) { + statusLabel.setText("登录失败:用户名不能为空且不能包含空格。"); + return; + } + + if (password.isEmpty()) { statusLabel.setText("用户名和密码不能为空!"); return; } diff --git a/src/main/java/com/mathgenerator/controller/RegisterController.java b/src/main/java/com/mathgenerator/controller/RegisterController.java index 0227866..83d105e 100644 --- a/src/main/java/com/mathgenerator/controller/RegisterController.java +++ b/src/main/java/com/mathgenerator/controller/RegisterController.java @@ -12,7 +12,7 @@ import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.stage.Stage; import java.io.IOException; - +import com.mathgenerator.util.ValidationUtils; public class RegisterController { private final UserService userService = new UserService(); @@ -51,20 +51,15 @@ public class RegisterController { @FXML private void handleRegisterAction(ActionEvent event) { // 1. 字段校验 - if (usernameField.getText().isEmpty() || emailField.getText().isEmpty() || - verificationCodeField.getText().isEmpty() || passwordField.getText().isEmpty()) { - statusLabel.setText("所有字段都不能为空!"); - return; - } - if (!passwordField.getText().equals(confirmPasswordField.getText())) { - statusLabel.setText("两次输入的密码不匹配!"); - return; - } - if (this.sentCode == null || !this.sentCode.equals(verificationCodeField.getText())) { - statusLabel.setText("验证码错误!"); + String username = usernameField.getText(); + + // --- 2. 使用工具类进行校验 --- + if (!ValidationUtils.isUsernameValid(username)) { + statusLabel.setText("注册失败:用户名不能为空且不能包含空格!"); return; } - if (!UserService.isPasswordValid(passwordField.getText())) { + // ... + if (!ValidationUtils.isPasswordValid(passwordField.getText())) { // 同样可以替换密码校验 statusLabel.setText("密码格式错误!必须为6-10位,且包含大小写字母和数字。"); return; } diff --git a/src/main/java/com/mathgenerator/util/ValidationUtils.java b/src/main/java/com/mathgenerator/util/ValidationUtils.java new file mode 100644 index 0000000..845a2f7 --- /dev/null +++ b/src/main/java/com/mathgenerator/util/ValidationUtils.java @@ -0,0 +1,52 @@ +package com.mathgenerator.util; + +import java.util.regex.Pattern; + +/** + * 一个包含静态校验方法的工具类。 + * 用于集中管理项目中所有的数据格式验证逻辑。 + */ +public final class ValidationUtils { + + // 密码策略: 6-10位, 必须包含大小写字母和数字 + private static final Pattern PASSWORD_PATTERN = + Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{6,10}$"); + + // 用户名策略: 不包含任何空白字符 + private static final Pattern USERNAME_NO_WHITESPACE_PATTERN = + Pattern.compile("^\\S+$"); + + // 私有构造函数,防止这个工具类被实例化 + private ValidationUtils() {} + + /** + * 验证用户名格式是否有效。 + * 当前规则:不允许包含任何空格或空白字符。 + * @param username 待验证的用户名 + * @return 如果有效返回true, 否则返回false + */ + public static boolean isUsernameValid(String username) { + if (username == null || username.isEmpty()) { + return false; + } + return USERNAME_NO_WHITESPACE_PATTERN.matcher(username).matches(); + } + + /** + * 验证密码是否符合复杂度要求。 + * @param password 待验证的密码 + * @return 如果符合要求返回true + */ + public static boolean isPasswordValid(String password) { + return password != null && PASSWORD_PATTERN.matcher(password).matches(); + } + + /** + * 验证邮箱格式是否有效 (简单校验)。 + * @param email 待验证的邮箱 + * @return 如果格式基本正确返回true + */ + public static boolean isEmailValid(String email) { + return email != null && !email.isEmpty() && email.contains("@"); + } +} \ No newline at end of file -- 2.34.1 From c95f7757947a6f6a931d00472897c9c5867252b5 Mon Sep 17 00:00:00 2001 From: smallbailangui Date: Wed, 8 Oct 2025 20:06:05 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ChangePasswordController.java | 90 +++++++++++++++++++ .../controller/MainMenuController.java | 23 ++++- .../view/ChangePasswordView.fxml | 31 +++++++ 3 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/mathgenerator/controller/ChangePasswordController.java create mode 100644 src/main/resources/com/mathgenerator/view/ChangePasswordView.fxml diff --git a/src/main/java/com/mathgenerator/controller/ChangePasswordController.java b/src/main/java/com/mathgenerator/controller/ChangePasswordController.java new file mode 100644 index 0000000..ceab172 --- /dev/null +++ b/src/main/java/com/mathgenerator/controller/ChangePasswordController.java @@ -0,0 +1,90 @@ +package com.mathgenerator.controller; + +import com.mathgenerator.model.User; +import com.mathgenerator.service.UserService; +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 ChangePasswordController { + + private final UserService userService = new UserService(); + private User currentUser; + + @FXML private PasswordField oldPasswordField; + @FXML private PasswordField newPasswordField; + @FXML private PasswordField confirmNewPasswordField; + @FXML private Button confirmButton; + @FXML private Button backButton; + @FXML private Label statusLabel; + + /** + * 初始化控制器,接收当前用户信息 + */ + public void initData(User user) { + this.currentUser = user; + } + + @FXML + private void handleConfirmAction(ActionEvent event) { + // 1. 获取输入 + String oldPassword = oldPasswordField.getText(); + String newPassword = newPasswordField.getText(); + String confirmNewPassword = confirmNewPasswordField.getText(); + + // 2. 输入校验 + if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmNewPassword.isEmpty()) { + statusLabel.setText("所有密码字段都不能为空!"); + return; + } + if (!newPassword.equals(confirmNewPassword)) { + statusLabel.setText("两次输入的新密码不匹配!"); + return; + } + if (!UserService.isPasswordValid(newPassword)) { + statusLabel.setText("新密码格式错误!必须为6-10位,且包含大小写字母和数字。"); + return; + } + + // 3. 调用后端服务修改密码 + boolean success = userService.changePassword( + currentUser.username(), + oldPassword, + newPassword + ); + + // 4. 更新UI反馈 + if (success) { + statusLabel.setText("密码修改成功!请返回主菜单。"); + confirmButton.setDisable(true); // 防止重复点击 + } else { + statusLabel.setText("修改失败:当前密码错误。"); + } + } + + /** + * 处理返回按钮事件,返回主菜单 + */ + @FXML + private void handleBackAction(ActionEvent event) { + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/mathgenerator/view/MainMenuView.fxml")); + Parent root = loader.load(); + MainMenuController controller = loader.getController(); + controller.initData(currentUser); // 将用户信息传回主菜单 + + Stage stage = (Stage) backButton.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/controller/MainMenuController.java b/src/main/java/com/mathgenerator/controller/MainMenuController.java index 867deff..60f7930 100644 --- a/src/main/java/com/mathgenerator/controller/MainMenuController.java +++ b/src/main/java/com/mathgenerator/controller/MainMenuController.java @@ -48,11 +48,26 @@ public class MainMenuController { @FXML private void handleChangePasswordAction(ActionEvent event) { - // TODO: 跳转到修改密码界面 - statusLabel.setText("修改密码功能待实现。"); - } + try { + // 1\. 加载 FXML 文件 + FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/mathgenerator/view/ChangePasswordView.fxml")); + Parent root = loader.load(); + // 2\. 获取新界面的控制器 + ChangePasswordController controller = loader.getController(); - @FXML + // 3\. 调用控制器的方法,传递当前用户信息 + controller.initData(currentUser); + + // 4\. 显示新场景 + Stage stage = (Stage) logoutButton.getScene().getWindow(); + stage.setScene(new Scene(root)); + stage.setTitle("修改密码"); + + } catch (IOException e) { + e.printStackTrace(); + } + } + @FXML private void handleLogoutAction(ActionEvent event) { // 跳转回登录界面 loadScene("/com/mathgenerator/view/LoginView.fxml"); diff --git a/src/main/resources/com/mathgenerator/view/ChangePasswordView.fxml b/src/main/resources/com/mathgenerator/view/ChangePasswordView.fxml new file mode 100644 index 0000000..480d327 --- /dev/null +++ b/src/main/resources/com/mathgenerator/view/ChangePasswordView.fxml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + +