From f77a0f8cc946970a7670f6b40bc8a8ee058d2cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=96=E5=85=AE=E5=86=89?= <15550273+wang-shengfa-11@user.noreply.gitee.com> Date: Fri, 10 Oct 2025 10:52:38 +0800 Subject: [PATCH] =?UTF-8?q?v2.0=20=E6=B7=BB=E5=8A=A0=E4=BA=86=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=90=8D=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=B9=B6=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=9F=BA=E6=9C=AC=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wsf/mathapp/controller/SceneManager.java | 20 +- .../wsf/mathapp/view/LevelSelectionView.java | 153 +++++++++++++-- .../java/com/wsf/mathapp/view/LoginView.java | 38 +++- .../com/wsf/mathapp/view/MainMenuView.java | 179 ++++++++++++++++-- .../com/wsf/mathapp/view/RegisterView.java | 78 ++++++-- .../java/com/wsf/mathapp/view/ResultView.java | 125 +++++++++++- users.txt | 4 +- 7 files changed, 521 insertions(+), 76 deletions(-) diff --git a/src/main/java/com/wsf/mathapp/controller/SceneManager.java b/src/main/java/com/wsf/mathapp/controller/SceneManager.java index 076f9f3..edbc218 100644 --- a/src/main/java/com/wsf/mathapp/controller/SceneManager.java +++ b/src/main/java/com/wsf/mathapp/controller/SceneManager.java @@ -12,6 +12,7 @@ public class SceneManager { private final QuestionCountView questionCountView; private final QuizView quizView; private final ResultView resultView; + private String currentUserName; public SceneManager(Stage primaryStage) { this.primaryStage = primaryStage; @@ -39,13 +40,24 @@ public class SceneManager { } public void showMainMenuView() { - primaryStage.setScene(mainMenuView.getScene()); + // 在显示主菜单前更新用户名 + if (mainMenuView != null) { + mainMenuView.updateUsername(currentUserName); + } + if (mainMenuView != null) { + primaryStage.setScene(mainMenuView.getScene()); + } } public void showLevelSelectionView() { - primaryStage.setScene(levelSelectionView.getScene()); + // 在显示级别选择界面前更新用户名 + if (levelSelectionView != null) { + levelSelectionView.updateUsername(currentUserName); + } + if (levelSelectionView != null) { + primaryStage.setScene(levelSelectionView.getScene()); + } } - public void showQuestionCountView() { primaryStage.setScene(questionCountView.getScene()); } @@ -67,4 +79,6 @@ public class SceneManager { public QuestionCountView getQuestionCountView() { return questionCountView; } public QuizView getQuizView() { return quizView; } public ResultView getResultView() { return resultView; } + public void setCurrentUserName(String currentUserName){ this.currentUserName = currentUserName;} + public String getCurrentUserName(){return this.currentUserName;} } \ No newline at end of file diff --git a/src/main/java/com/wsf/mathapp/view/LevelSelectionView.java b/src/main/java/com/wsf/mathapp/view/LevelSelectionView.java index 0279a15..94f675e 100644 --- a/src/main/java/com/wsf/mathapp/view/LevelSelectionView.java +++ b/src/main/java/com/wsf/mathapp/view/LevelSelectionView.java @@ -6,41 +6,117 @@ import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import javafx.scene.shape.Circle; import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; +import javafx.scene.text.Text; public class LevelSelectionView { private Scene scene; private final SceneManager sceneManager; + private String currentUsername; + + // 添加界面组件引用 + private Label usernameLabel; + private Text avatarText; public LevelSelectionView(SceneManager sceneManager) { this.sceneManager = sceneManager; + this.currentUsername = sceneManager.getCurrentUserName(); createScene(); } private void createScene() { - VBox root = new VBox(20); - root.setPadding(new Insets(40)); - root.setAlignment(Pos.CENTER); + // 创建主容器 + VBox mainContainer = new VBox(); + mainContainer.setPadding(new Insets(20)); - Label titleLabel = new Label("选择题目级别"); - titleLabel.setFont(Font.font(24)); + // 创建顶部用户信息栏 + HBox userInfoBar = createUserInfoBar(); + + // 创建级别选择内容区域 + VBox selectionContent = createSelectionContent(); + + mainContainer.getChildren().addAll(userInfoBar, selectionContent); + + scene = new Scene(mainContainer, 450, 550); + } + + private HBox createUserInfoBar() { + HBox userInfoBar = new HBox(15); + userInfoBar.setAlignment(Pos.CENTER_LEFT); + userInfoBar.setPadding(new Insets(0, 0, 30, 0)); + userInfoBar.setStyle("-fx-border-color: #e0e0e0; -fx-border-width: 0 0 1 0; -fx-padding: 0 0 15 0;"); + + // 创建圆形头像容器 + VBox avatarContainer = new VBox(); + avatarContainer.setAlignment(Pos.CENTER); + avatarContainer.setPrefSize(50, 50); + + // 创建圆形头像背景 + Circle avatarCircle = new Circle(22); + avatarCircle.setFill(Color.web("#4CAF50")); // 统一的绿色背景 + avatarCircle.setStroke(Color.WHITE); + avatarCircle.setStrokeWidth(2); + + // 添加阴影效果 + avatarCircle.setStyle("-fx-effect: drop shadow(gaussian, rgba(0,0,0,0.2), 5, 0.3, 2, 2);"); + + // 添加首字母文本 + avatarText = new Text(getFirstLetter()); + avatarText.setFill(Color.WHITE); + avatarText.setFont(Font.font("Arial", FontWeight.BOLD, 16)); + + // 使用StackPane将文本放在圆形中心 + javafx.scene.layout.StackPane avatarStack = new javafx.scene.layout.StackPane(); + avatarStack.getChildren().addAll(avatarCircle, avatarText); + avatarStack.setPrefSize(44, 44); + avatarStack.setAlignment(Pos.CENTER); + + avatarContainer.getChildren().add(avatarStack); - Button primaryButton = new Button("小学题目"); - primaryButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 14px;"); - primaryButton.setPrefSize(200, 50); + // 用户名标签 + usernameLabel = new Label(currentUsername != null ? currentUsername : "用户"); + usernameLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16)); + usernameLabel.setStyle("-fx-text-fill: #2c3e50;"); - Button juniorButton = new Button("初中题目"); - juniorButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 14px;"); - juniorButton.setPrefSize(200, 50); + // 间隔 + Region spacer = new Region(); + HBox.setHgrow(spacer, Priority.ALWAYS); - Button seniorButton = new Button("高中题目"); - seniorButton.setStyle("-fx-background-color: #9C27B0; -fx-text-fill: white; -fx-font-size: 14px;"); - seniorButton.setPrefSize(200, 50); + userInfoBar.getChildren().addAll(avatarContainer, usernameLabel, spacer); - Button backButton = new Button("返回"); - backButton.setStyle("-fx-background-color: #757575; -fx-text-fill: white;"); - backButton.setPrefSize(200, 40); + return userInfoBar; + } + + private VBox createSelectionContent() { + VBox selectionContent = new VBox(25); + selectionContent.setPadding(new Insets(30, 20, 20, 20)); + selectionContent.setAlignment(Pos.CENTER); + + Label titleLabel = new Label("选择题目级别"); + titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 26)); + titleLabel.setStyle("-fx-text-fill: #2c3e50;"); + + // 添加副标题 + Label subtitleLabel = new Label("请选择适合您的学习级别"); + subtitleLabel.setFont(Font.font("Arial", 14)); + subtitleLabel.setStyle("-fx-text-fill: #7f8c8d; -fx-padding: 0 0 10 0;"); + + Button primaryButton = createLevelButton("小学题目", "#4CAF50", "#45a049"); + Button juniorButton = createLevelButton("初中题目", "#2196F3", "#1976D2"); + Button seniorButton = createLevelButton("高中题目", "#9C27B0", "#7B1FA2"); + + Button backButton = new Button("返回主菜单"); + backButton.setStyle("-fx-background-color: #95a5a6; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;"); + backButton.setPrefSize(180, 45); + backButton.setOnMouseEntered(e -> backButton.setStyle("-fx-background-color: #7f8c8d; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;")); + backButton.setOnMouseExited(e -> backButton.setStyle("-fx-background-color: #95a5a6; -fx-text-fill: white; -fx-font-size: 14px; -fx-background-radius: 8; -fx-padding: 8 20;")); primaryButton.setOnAction(e -> { String selectedLevel = "小学"; @@ -64,11 +140,48 @@ public class LevelSelectionView { sceneManager.showMainMenuView(); }); - root.getChildren().addAll( - titleLabel, primaryButton, juniorButton, seniorButton, backButton + selectionContent.getChildren().addAll( + titleLabel, subtitleLabel, primaryButton, juniorButton, seniorButton, backButton ); - scene = new Scene(root, 400, 500); + return selectionContent; + } + + private Button createLevelButton(String text, String color, String hoverColor) { + Button button = new Button(text); + button.setStyle(String.format( + "-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " + + "-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: drop shadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);", + color + )); + button.setPrefSize(220, 60); + button.setOnMouseEntered(e -> button.setStyle(String.format( + "-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " + + "-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: drop shadow(gaussian, rgba(0,0,0,0.3), 10, 0.4, 3, 3);", + hoverColor + ))); + button.setOnMouseExited(e -> button.setStyle(String.format( + "-fx-background-color: %s; -fx-text-fill: white; -fx-font-size: 16px; -fx-font-weight: bold; " + + "-fx-background-radius: 12; -fx-padding: 12 30; -fx-effect: drop shadow(gaussian, rgba(0,0,0,0.2), 8, 0.3, 2, 2);", + color + ))); + return button; + } + + private String getFirstLetter() { + return currentUsername != null && !currentUsername.isEmpty() ? + currentUsername.substring(0, 1).toUpperCase() : "U"; + } + + // 添加更新用户名的方法 + public void updateUsername(String username) { + this.currentUsername = username; + if (usernameLabel != null) { + usernameLabel.setText(username != null ? username : "用户"); + } + if (avatarText != null) { + avatarText.setText(getFirstLetter()); + } } public Scene getScene() { diff --git a/src/main/java/com/wsf/mathapp/view/LoginView.java b/src/main/java/com/wsf/mathapp/view/LoginView.java index 3ee5ff1..2e4c088 100644 --- a/src/main/java/com/wsf/mathapp/view/LoginView.java +++ b/src/main/java/com/wsf/mathapp/view/LoginView.java @@ -2,6 +2,8 @@ package com.wsf.mathapp.view; import com.wsf.mathapp.controller.SceneManager; import com.ybw.mathapp.util.Login; +import com.ybw.mathapp.util.LoginFileUtils; +import com.ybw.mathapp.util.Register; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; @@ -29,10 +31,11 @@ public class LoginView { Label subtitleLabel = new Label("用户登录"); subtitleLabel.setFont(Font.font(18)); - TextField emailField = new TextField(); - emailField.setPromptText("请输入邮箱"); - emailField.setMaxWidth(300); - emailField.setPrefHeight(40); + // 修改提示文本 + TextField usernameOrEmailField = new TextField(); + usernameOrEmailField.setPromptText("请输入用户名或邮箱"); + usernameOrEmailField.setMaxWidth(300); + usernameOrEmailField.setPrefHeight(40); PasswordField passwordField = new PasswordField(); passwordField.setPromptText("请输入密码"); @@ -50,20 +53,31 @@ public class LoginView { Label statusLabel = new Label(); loginButton.setOnAction(e -> { - String email = emailField.getText().trim(); + String usernameOrEmail = usernameOrEmailField.getText().trim(); String password = passwordField.getText(); - if (email.isEmpty() || password.isEmpty()) { - showError(statusLabel, "邮箱和密码不能为空!"); + if (usernameOrEmail.isEmpty() || password.isEmpty()) { + showError(statusLabel, "用户名/邮箱和密码不能为空!"); return; } - boolean success = Login.login(email, password); + // 调用后端的登录方法,支持用户名或邮箱登录 + boolean success = Login.login(usernameOrEmail, password); + System.out.println(usernameOrEmail); + System.out.println(password); if (success) { showSuccess(statusLabel); + String username; + if (LoginFileUtils.emailFindName(usernameOrEmail) == null){ + username = usernameOrEmail; + } + else { + username = LoginFileUtils.emailFindName(usernameOrEmail); + } + sceneManager.setCurrentUserName(username); sceneManager.showMainMenuView(); } else { - showError(statusLabel, "邮箱或密码错误!"); + showError(statusLabel, "用户名/邮箱或密码错误!"); } }); @@ -71,8 +85,12 @@ public class LoginView { sceneManager.showRegisterView(); }); + // 添加回车键登录支持 + usernameOrEmailField.setOnAction(e -> loginButton.fire()); + passwordField.setOnAction(e -> loginButton.fire()); + root.getChildren().addAll( - titleLabel, subtitleLabel, emailField, passwordField, + titleLabel, subtitleLabel, usernameOrEmailField, passwordField, loginButton, registerButton, statusLabel ); diff --git a/src/main/java/com/wsf/mathapp/view/MainMenuView.java b/src/main/java/com/wsf/mathapp/view/MainMenuView.java index b63acb0..2734eee 100644 --- a/src/main/java/com/wsf/mathapp/view/MainMenuView.java +++ b/src/main/java/com/wsf/mathapp/view/MainMenuView.java @@ -1,45 +1,134 @@ package com.wsf.mathapp.view; import com.wsf.mathapp.controller.SceneManager; +import com.ybw.mathapp.util.ChangePassword; +import com.ybw.mathapp.util.Login; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; +import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import javafx.scene.shape.Circle; import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; +import javafx.scene.text.Text; public class MainMenuView { private Scene scene; private final SceneManager sceneManager; + private String currentUsername; + + // 添加界面组件引用,用于动态更新 + private Label usernameLabel; + private Text avatarText; + private Label welcomeLabel; public MainMenuView(SceneManager sceneManager) { this.sceneManager = sceneManager; + this.currentUsername = sceneManager.getCurrentUserName(); createScene(); } private void createScene() { - VBox root = new VBox(30); - root.setPadding(new Insets(50)); - root.setAlignment(Pos.CENTER); + // 创建主容器 + VBox mainContainer = new VBox(); + mainContainer.setPadding(new Insets(20)); + + // 创建顶部用户信息栏 + HBox userInfoBar = createUserInfoBar(); + + // 创建主菜单内容区域 + VBox menuContent = createMenuContent(); + + mainContainer.getChildren().addAll(userInfoBar, menuContent); + + scene = new Scene(mainContainer, 450, 550); + } + + private HBox createUserInfoBar() { + HBox userInfoBar = new HBox(15); + userInfoBar.setAlignment(Pos.CENTER_LEFT); + userInfoBar.setPadding(new Insets(0, 0, 30, 0)); + userInfoBar.setStyle("-fx-border-color: #e0e0e0; -fx-border-width: 0 0 1 0; -fx-padding: 0 0 15 0;"); + + // 创建圆形头像容器 + VBox avatarContainer = new VBox(); + avatarContainer.setAlignment(Pos.CENTER); + avatarContainer.setPrefSize(50, 50); + + // 创建圆形头像背景 + Circle avatarCircle = new Circle(22); + avatarCircle.setFill(Color.web("#4CAF50")); + avatarCircle.setStroke(Color.WHITE); + avatarCircle.setStrokeWidth(2); + + // 添加阴影效果 + avatarCircle.setStyle("-fx-effect: drop shadow(gaussian, rgba(0,0,0,0.2), 5, 0.3, 2, 2);"); + + // 添加首字母文本 + avatarText = new Text(getFirstLetter()); + avatarText.setFill(Color.WHITE); + avatarText.setFont(Font.font("Arial", FontWeight.BOLD, 16)); + + // 使用StackPane将文本放在圆形中心 + javafx.scene.layout.StackPane avatarStack = new javafx.scene.layout.StackPane(); + avatarStack.getChildren().addAll(avatarCircle, avatarText); + avatarStack.setPrefSize(44, 44); + avatarStack.setAlignment(Pos.CENTER); + + avatarContainer.getChildren().add(avatarStack); + + // 用户名标签 + usernameLabel = new Label(currentUsername != null ? currentUsername : "用户"); + usernameLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16)); + usernameLabel.setStyle("-fx-text-fill: #2c3e50;"); + + // 间隔 + Region spacer = new Region(); + HBox.setHgrow(spacer, Priority.ALWAYS); + + userInfoBar.getChildren().addAll(avatarContainer, usernameLabel, spacer); + + return userInfoBar; + } + + private VBox createMenuContent() { + VBox menuContent = new VBox(25); + menuContent.setPadding(new Insets(20)); + menuContent.setAlignment(Pos.CENTER); Label titleLabel = new Label("数学学习软件"); titleLabel.setFont(Font.font(28)); + titleLabel.setStyle("-fx-text-fill: #2c3e50;"); - Label welcomeLabel = new Label("欢迎使用数学学习软件"); + // 修改欢迎标签,显示用户名 + welcomeLabel = new Label("欢迎," + (currentUsername != null ? currentUsername : "用户") + "!"); welcomeLabel.setFont(Font.font(18)); + welcomeLabel.setStyle("-fx-text-fill: #7f8c8d;"); Button startButton = new Button("开始练习"); - startButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 16px;"); - startButton.setPrefSize(200, 50); + startButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"); + startButton.setPrefSize(220, 55); + startButton.setOnMouseEntered(e -> startButton.setStyle("-fx-background-color: #45a049; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;")); + startButton.setOnMouseExited(e -> startButton.setStyle("-fx-background-color: #4CAF50; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;")); Button changePasswordButton = new Button("修改密码"); - changePasswordButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 16px;"); - changePasswordButton.setPrefSize(200, 50); + changePasswordButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"); + changePasswordButton.setPrefSize(220, 55); + changePasswordButton.setOnMouseEntered(e -> changePasswordButton.setStyle("-fx-background-color: #1976D2; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;")); + changePasswordButton.setOnMouseExited(e -> changePasswordButton.setStyle("-fx-background-color: #2196F3; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;")); Button logoutButton = new Button("退出登录"); - logoutButton.setStyle("-fx-background-color: #f44336; -fx-text-fill: white; -fx-font-size: 16px;"); - logoutButton.setPrefSize(200, 50); + logoutButton.setStyle("-fx-background-color: #f44336; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;"); + logoutButton.setPrefSize(220, 55); + logoutButton.setOnMouseEntered(e -> logoutButton.setStyle("-fx-background-color: #d32f2f; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;")); + logoutButton.setOnMouseExited(e -> logoutButton.setStyle("-fx-background-color: #f44336; -fx-text-fill: white; -fx-font-size: 16px; -fx-background-radius: 10;")); startButton.setOnAction(e -> { sceneManager.showLevelSelectionView(); @@ -53,12 +142,31 @@ public class MainMenuView { sceneManager.showLoginView(); }); - root.getChildren().addAll( + menuContent.getChildren().addAll( titleLabel, welcomeLabel, startButton, changePasswordButton, logoutButton ); - scene = new Scene(root, 400, 500); + return menuContent; + } + + private String getFirstLetter() { + return currentUsername != null && !currentUsername.isEmpty() ? + currentUsername.substring(0, 1).toUpperCase() : "U"; + } + + // 添加更新用户名的方法 + public void updateUsername(String username) { + this.currentUsername = username; + if (usernameLabel != null) { + usernameLabel.setText(username != null ? username : "用户"); + } + if (avatarText != null) { + avatarText.setText(getFirstLetter()); + } + if (welcomeLabel != null) { + welcomeLabel.setText("欢迎," + (username != null ? username : "用户") + "!"); + } } private void showChangePasswordDialog() { @@ -66,19 +174,25 @@ public class MainMenuView { javafx.scene.control.Dialog dialog = new javafx.scene.control.Dialog<>(); dialog.setTitle("修改密码"); dialog.setHeaderText("请输入密码信息"); + dialog.setGraphic(null); // 移除默认图标 // 创建表单 javafx.scene.layout.GridPane grid = new javafx.scene.layout.GridPane(); - grid.setHgap(10); - grid.setVgap(10); - grid.setPadding(new Insets(20, 150, 10, 10)); + grid.setHgap(15); + grid.setVgap(15); + grid.setPadding(new Insets(20, 30, 10, 30)); javafx.scene.control.PasswordField oldPassword = new javafx.scene.control.PasswordField(); - oldPassword.setPromptText("原密码"); + oldPassword.setPromptText("请输入原密码"); + oldPassword.setPrefWidth(200); + javafx.scene.control.PasswordField newPassword = new javafx.scene.control.PasswordField(); - newPassword.setPromptText("新密码"); + newPassword.setPromptText("请输入新密码"); + newPassword.setPrefWidth(200); + javafx.scene.control.PasswordField confirmPassword = new javafx.scene.control.PasswordField(); - confirmPassword.setPromptText("确认新密码"); + confirmPassword.setPromptText("请确认新密码"); + confirmPassword.setPrefWidth(200); grid.add(new Label("原密码:"), 0, 0); grid.add(oldPassword, 1, 0); @@ -98,7 +212,26 @@ public class MainMenuView { dialog.setResultConverter(dialogButton -> { if (dialogButton == javafx.scene.control.ButtonType.OK) { // 这里可以添加修改密码的逻辑 - System.out.println("修改密码功能待实现"); + String oldPwd = oldPassword.getText(); + String newPwd = newPassword.getText(); + String confirmPwd = confirmPassword.getText(); + + if (oldPwd.isEmpty() || newPwd.isEmpty() || confirmPwd.isEmpty()) { + showAlert("错误", "请填写所有密码字段!"); + return null; + } + if (!Login.login(currentUsername,oldPwd)){ + showAlert("错误", "原密码错误!"); + return null; + } + if (!newPwd.equals(confirmPwd)) { + showAlert("错误", "两次输入的新密码不一致!"); + return null; + } + + // 调用修改密码的后端逻辑 + ChangePassword.changePassword(currentUsername, confirmPwd); + showAlert("成功", "密码修改成功!"); } return null; }); @@ -106,6 +239,14 @@ public class MainMenuView { dialog.showAndWait(); } + private void showAlert(String title, String message) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); + } + public Scene getScene() { return scene; } diff --git a/src/main/java/com/wsf/mathapp/view/RegisterView.java b/src/main/java/com/wsf/mathapp/view/RegisterView.java index 761f19d..f1ed416 100644 --- a/src/main/java/com/wsf/mathapp/view/RegisterView.java +++ b/src/main/java/com/wsf/mathapp/view/RegisterView.java @@ -1,10 +1,9 @@ package com.wsf.mathapp.view; - import com.wsf.mathapp.controller.SceneManager; import com.ybw.mathapp.util.EmailService; -import com.ybw.mathapp.util.Login; import com.ybw.mathapp.util.Register; +import java.util.regex.Pattern; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; @@ -30,6 +29,12 @@ public class RegisterView { Label titleLabel = new Label("用户注册"); titleLabel.setFont(Font.font(20)); + // 添加用户名输入框 + TextField usernameField = new TextField(); + usernameField.setPromptText("请输入用户名(3-20位字母、数字、下划线)"); + usernameField.setMaxWidth(300); + usernameField.setPrefHeight(35); + TextField emailField = new TextField(); emailField.setPromptText("请输入邮箱"); emailField.setMaxWidth(300); @@ -65,7 +70,21 @@ public class RegisterView { Label statusLabel = new Label(); sendCodeButton.setOnAction(e -> { + String username = usernameField.getText().trim(); String email = emailField.getText().trim(); + + // 验证用户名 + if (!isValidUsername(username)) { + showError(statusLabel, "用户名只包含英文字母和数字)"); + return; + } + + // 检查用户名是否已存在 + if (LoginFileUtils.isNameRegistered(username)) { + showError(statusLabel, "用户名已存在,请选择其他用户名!"); + return; + } + if (!EmailService.isValidEmail(email)) { showError(statusLabel, "请输入有效的邮箱地址!"); return; @@ -75,6 +94,7 @@ public class RegisterView { showError(statusLabel, "该邮箱已注册,请直接登录!"); return; } + // 生成并发送验证码 boolean sent = EmailService.sendCode(email); if (sent) { @@ -88,7 +108,24 @@ public class RegisterView { }); registerButton.setOnAction(e -> { + String username = usernameField.getText().trim(); String email = emailField.getText().trim(); + String code = codeField.getText().trim(); + String password = passwordField.getText(); + String confirmPassword = confirmPasswordField.getText(); + + // 验证用户名 + if (!isValidUsername(username)) { + showError(statusLabel, "用户名只包含英文字母和数字"); + return; + } + + // 检查用户名是否已存在 + if (LoginFileUtils.isNameRegistered((username))){ + showError(statusLabel, "用户名已存在,请选择其他用户名!"); + return; + } + if (!EmailService.isValidEmail(email)) { showError(statusLabel, "请输入有效的邮箱地址!"); return; @@ -98,11 +135,8 @@ public class RegisterView { showError(statusLabel, "该邮箱已注册,请直接登录!"); return; } - String code = codeField.getText().trim(); - String password = passwordField.getText(); - String confirmPassword = confirmPasswordField.getText(); - if (email.isEmpty() || code.isEmpty() || password.isEmpty()) { + if (username.isEmpty() || email.isEmpty() || code.isEmpty() || password.isEmpty()) { showError(statusLabel, "请填写所有字段!"); return; } @@ -112,16 +146,19 @@ public class RegisterView { showError(statusLabel, "验证码错误或已过期!"); return; } + if (!Register.isVaildPassword(password)) { showError(statusLabel, "密码要6-10位,包含大,小写字母和数字"); return; } + if (!Register.isEqualPassword(password,confirmPassword)){ showError(statusLabel, "两次密码不一致"); return; } - if (Register.register(email,password)) { - showSuccess(statusLabel, "注册成功!"); + + if (Register.register(username, email, password)) { + showSuccess(statusLabel, "注册成功!用户名: " + username); sceneManager.showLoginView(); } else { showError(statusLabel, "注册失败,请检查信息!"); @@ -133,12 +170,19 @@ public class RegisterView { }); root.getChildren().addAll( - titleLabel, emailField, sendCodeButton, codeField, - passwordField, confirmPasswordField, registerButton, - backButton, statusLabel + titleLabel, + usernameField, // 添加用户名输入框 + emailField, + sendCodeButton, + codeField, + passwordField, + confirmPasswordField, + registerButton, + backButton, + statusLabel ); - scene = new Scene(root, 400, 500); + scene = new Scene(root, 400, 550); // 增加高度以适应新字段 } private void startCountdown(Button button) { @@ -174,4 +218,12 @@ public class RegisterView { public Scene getScene() { return scene; } -} \ No newline at end of file + public static boolean isValidUsername(String username) { + if (username == null || username.trim().isEmpty()) { + return false; + } + // 用户名规则:只能包含英文字母和数字 + String usernameRegex = "^[a-zA-Z0-9]{3,100}$"; + return Pattern.matches(usernameRegex, username.trim()); + } +} diff --git a/src/main/java/com/wsf/mathapp/view/ResultView.java b/src/main/java/com/wsf/mathapp/view/ResultView.java index 1625f60..a1bb0c8 100644 --- a/src/main/java/com/wsf/mathapp/view/ResultView.java +++ b/src/main/java/com/wsf/mathapp/view/ResultView.java @@ -1,11 +1,17 @@ package com.wsf.mathapp.view; import com.wsf.mathapp.controller.SceneManager; +import java.util.Objects; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.text.Font; @@ -13,16 +19,94 @@ public class ResultView { private Scene scene; private final SceneManager sceneManager; private double score; + private String currentUsername; public ResultView(SceneManager sceneManager) { this.sceneManager = sceneManager; + this.currentUsername = "用户"; // 默认用户名 createScene(); } private void createScene() { - VBox root = new VBox(30); - root.setPadding(new Insets(50)); - root.setAlignment(Pos.CENTER); + // 创建主容器 + VBox mainContainer = new VBox(); + mainContainer.setPadding(new Insets(20)); + + // 创建顶部用户信息栏 + HBox userInfoBar = createUserInfoBar(); + + // 创建结果内容区域 + VBox resultContent = createResultContent(); + + mainContainer.getChildren().addAll(userInfoBar, resultContent); + + scene = new Scene(mainContainer, 500, 550); // 增加宽度和高度以适应新布局 + } + + private HBox createUserInfoBar() { + HBox userInfoBar = new HBox(10); + userInfoBar.setAlignment(Pos.CENTER_LEFT); + userInfoBar.setPadding(new Insets(0, 0, 20, 0)); + + // 创建默认头像(使用系统图标或文本) + ImageView avatar = createDefaultAvatar(); + + // 用户名标签 + Label usernameLabel = new Label(currentUsername); + usernameLabel.setFont(Font.font(16)); + usernameLabel.setStyle("-fx-text-fill: #333;"); + + // 添加间隔,让用户信息靠左,其他内容居中 + Region spacer = new Region(); + HBox.setHgrow(spacer, Priority.ALWAYS); + + userInfoBar.getChildren().addAll(avatar, usernameLabel, spacer); + + return userInfoBar; + } + + private ImageView createDefaultAvatar() { + // 尝试加载默认头像图片,如果失败则使用文本头像 + ImageView avatar = new ImageView(); + avatar.setFitWidth(40); + avatar.setFitHeight(40); + + try { + // 尝试加载默认头像图片 + Image defaultAvatar = new Image( + Objects.requireNonNull(getClass().getResourceAsStream("/images/default-avatar.png"))); + avatar.setImage(defaultAvatar); + } catch (Exception e) { + // 如果图片加载失败,创建一个圆形文本头像 + avatar.setImage(createTextAvatar()); + } + + // 设置头像样式 + avatar.setStyle( + "-fx-background-color: #4CAF50; " + + "-fx-background-radius: 20; " + + "-fx-border-radius: 20; " + + "-fx-border-color: #ddd; " + + "-fx-border-width: 2;" + ); + + return avatar; + } + + private Image createTextAvatar() { + // 创建一个简单的文本头像(使用首字母) + String firstLetter = currentUsername.length() > 0 ? + currentUsername.substring(0, 1).toUpperCase() : "U"; + + // 这里可以创建一个包含文本的图像,但为了简单起见,我们使用CSS样式 + // 在实际项目中,你可以使用Canvas绘制或预加载图片 + return null; // 返回null,我们将使用CSS样式 + } + + private VBox createResultContent() { + VBox resultContent = new VBox(30); + resultContent.setPadding(new Insets(20)); + resultContent.setAlignment(Pos.CENTER); Label titleLabel = new Label("答题完成"); titleLabel.setFont(Font.font(24)); @@ -57,12 +141,12 @@ public class ResultView { System.exit(0); }); - root.getChildren().addAll( + resultContent.getChildren().addAll( titleLabel, scoreLabel, messageLabel, restartButton, mainMenuButton, exitButton ); - scene = new Scene(root, 400, 500); + return resultContent; } public void setScore(double score) { @@ -70,11 +154,36 @@ public class ResultView { updateScoreDisplay(); } + public void setCurrentUsername(String username) { + this.currentUsername = username != null ? username : "用户"; + updateUserInfo(); + } + + private void updateUserInfo() { + if (scene != null) { + VBox mainContainer = (VBox) scene.getRoot(); + HBox userInfoBar = (HBox) mainContainer.getChildren().get(0); + + // 更新用户名标签 + Label usernameLabel = (Label) userInfoBar.getChildren().get(1); + usernameLabel.setText(currentUsername); + + // 更新头像(如果需要显示首字母) + updateAvatar(); + } + } + + private void updateAvatar() { + // 如果需要根据用户名更新头像样式,可以在这里实现 + // 例如根据用户名首字母设置不同的背景颜色 + } + private void updateScoreDisplay() { if (scene != null) { - VBox root = (VBox) scene.getRoot(); - Label scoreLabel = (Label) root.getChildren().get(1); - Label messageLabel = (Label) root.getChildren().get(2); + VBox mainContainer = (VBox) scene.getRoot(); + VBox resultContent = (VBox) mainContainer.getChildren().get(1); + Label scoreLabel = (Label) resultContent.getChildren().get(1); + Label messageLabel = (Label) resultContent.getChildren().get(2); int percentage = (int) (score * 100); scoreLabel.setText(percentage + "分"); diff --git a/users.txt b/users.txt index a8bc981..63150c2 100644 --- a/users.txt +++ b/users.txt @@ -1,4 +1,2 @@ -1798231811@qq.com,Ybw1234 -625690134@qq.com,Cfy1234 -3310207578@qq.com,Wsf1234 +wsf,3310207578@qq.com,Wsf1234