注册用户功能修改

pull/5/head
梁晨旭 2 months ago
parent cb77d713d0
commit 97122ce22b

@ -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<Question> 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) {

@ -74,10 +74,12 @@
<Button fx:id="verifyCodeButton" text="验证" onAction="#handleVerifyEmailCode" style="-fx-background-color: linear-gradient(to right, #8A2BE2, #9932CC); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 8 16; -fx-font-size: 12; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
<Label fx:id="emailStatusLabel" textFill="#8B0000" style="-fx-font-weight: bold;"/>
</HBox>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Button fx:id="loginButton" text="🚀 登录" onAction="#handleLogin" style="-fx-background-color: linear-gradient(to right, #8A2BE2, #9932CC); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 10 20; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
<Label fx:id="loginStatusLabel" textFill="#8B0000" style="-fx-font-weight: bold;"/>
</HBox>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Button fx:id="loginButton" text="🚀 登录" onAction="#handleLogin" style="-fx-background-color: linear-gradient(to right, #8A2BE2, #9932CC); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 10 20; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
<Button fx:id="registerButton" text="📝 注册" onAction="#showRegisterPanel" style="-fx-background-color: linear-gradient(to right, #32CD32, #228B22); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 10 20; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
<Label fx:id="loginStatusLabel" textFill="#8B0000" style="-fx-font-weight: bold;"/>
</HBox>
</VBox>
<!-- 考试设置区域 -->
@ -110,7 +112,78 @@
<Label fx:id="statusLabel" textFill="#4B0082" style="-fx-font-weight: bold; -fx-font-size: 14;"/>
</VBox>
<!-- 在考试设置区域下方添加修改密码按钮 -->
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Button fx:id="changePasswordButton" text="🔑 修改密码" onAction="#showChangePasswordPanel" style="-fx-background-color: linear-gradient(to right, #FF8C00, #FFA500); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 10 20; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
</HBox>
<!-- 添加设置密码面板 -->
<VBox fx:id="setPasswordPanel" spacing="15.0" style="-fx-background-color: linear-gradient(to bottom, #F8F0FF, #E6E6FA, #D8BFD8); -fx-padding: 20; -fx-background-radius: 15; -fx-effect: dropshadow(gaussian, rgba(139,0,139,0.3), 15, 0, 0, 5);" visible="false">
<Label text="🔐 设置密码" textFill="#4B0082" textAlignment="CENTER">
<font>
<Font name="System Bold" size="18.0"/>
</font>
</Label>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Label text="🔑 密码:" minWidth="80.0" textFill="#6A0DAD">
<font>
<Font name="System Bold" size="14.0"/>
</font>
</Label>
<PasswordField fx:id="setPasswordField" promptText="6-10位包含大小写字母和数字" prefWidth="180.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
</HBox>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Label text="✅ 确认密码:" minWidth="80.0" textFill="#6A0DAD">
<font>
<Font name="System Bold" size="14.0"/>
</font>
</Label>
<PasswordField fx:id="confirmPasswordField" promptText="请再次输入密码" prefWidth="180.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
</HBox>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Button fx:id="confirmSetPasswordButton" text="✅ 确认设置" onAction="#handleSetPassword" style="-fx-background-color: linear-gradient(to right, #32CD32, #228B22); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 10 20; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
<Button text="❌ 取消" onAction="#hideSetPasswordPanel" style="-fx-background-color: linear-gradient(to right, #DC143C, #B22222); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 10 20; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
<Label fx:id="setPasswordStatusLabel" textFill="#8B0000" style="-fx-font-weight: bold;"/>
</HBox>
</VBox>
<!-- 添加修改密码面板 -->
<VBox fx:id="changePasswordPanel" spacing="15.0" style="-fx-background-color: linear-gradient(to bottom, #F8F0FF, #E6E6FA, #D8BFD8); -fx-padding: 20; -fx-background-radius: 15; -fx-effect: dropshadow(gaussian, rgba(139,0,139,0.3), 15, 0, 0, 5);" visible="false">
<Label text="🔑 修改密码" textFill="#4B0082" textAlignment="CENTER">
<font>
<Font name="System Bold" size="18.0"/>
</font>
</Label>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Label text="🔒 原密码:" minWidth="80.0" textFill="#6A0DAD">
<font>
<Font name="System Bold" size="14.0"/>
</font>
</Label>
<PasswordField fx:id="oldPasswordField" promptText="请输入原密码" prefWidth="180.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
</HBox>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Label text="🆕 新密码:" minWidth="80.0" textFill="#6A0DAD">
<font>
<Font name="System Bold" size="14.0"/>
</font>
</Label>
<PasswordField fx:id="newPasswordField" promptText="6-10位包含大小写字母和数字" prefWidth="180.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
</HBox>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Label text="✅ 确认新密码:" minWidth="80.0" textFill="#6A0DAD">
<font>
<Font name="System Bold" size="14.0"/>
</font>
</Label>
<PasswordField fx:id="confirmNewPasswordField" promptText="请再次输入新密码" prefWidth="180.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
</HBox>
<HBox spacing="15.0" alignment="CENTER_LEFT">
<Button fx:id="confirmChangePasswordButton" text="✅ 确认修改" onAction="#handleChangePassword" style="-fx-background-color: linear-gradient(to right, #32CD32, #228B22); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 10 20; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
<Button fx:id="cancelChangePasswordButton" text="❌ 取消" onAction="#hideChangePasswordPanel" style="-fx-background-color: linear-gradient(to right, #DC143C, #B22222); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 10 20; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
<Label fx:id="changePasswordStatusLabel" textFill="#8B0000" style="-fx-font-weight: bold;"/>
</HBox>
</VBox>
<!-- 使用说明 -->
<VBox spacing="15.0" style="-fx-background-color: linear-gradient(to bottom, #F8F0FF, #E6E6FA, #D8BFD8); -fx-padding: 20; -fx-background-radius: 15; -fx-effect: dropshadow(gaussian, rgba(139,0,139,0.2), 10, 0, 0, 3);">

Loading…
Cancel
Save