|
|
|
|
@ -8,35 +8,22 @@ import javafx.scene.layout.VBox;
|
|
|
|
|
import javafx.stage.Stage;
|
|
|
|
|
import javafx.collections.FXCollections;
|
|
|
|
|
import javafx.collections.ObservableList;
|
|
|
|
|
import java.time.Instant;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.nio.file.Files;
|
|
|
|
|
import java.nio.file.Paths;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 考试系统控制器
|
|
|
|
|
*/
|
|
|
|
|
public class ExamController {
|
|
|
|
|
@FXML private VBox registerPanel;
|
|
|
|
|
@FXML private TextField registerUsernameField;
|
|
|
|
|
@FXML private PasswordField registerPasswordField;
|
|
|
|
|
@FXML private TextField registerEmailField;
|
|
|
|
|
@FXML private TextField registerCodeField;
|
|
|
|
|
@FXML private Button sendRegisterCodeButton;
|
|
|
|
|
@FXML private Button verifyRegisterCodeButton;
|
|
|
|
|
@FXML private Label registerStatusLabel;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 登录界面控件
|
|
|
|
|
@FXML private TextField usernameField;
|
|
|
|
|
@FXML private PasswordField passwordField;
|
|
|
|
|
@FXML private Button loginButton;
|
|
|
|
|
@FXML private TextField emailField;
|
|
|
|
|
@FXML private TextField emailCodeField;
|
|
|
|
|
@FXML private Button sendCodeButton;
|
|
|
|
|
@FXML private Button verifyCodeButton;
|
|
|
|
|
@FXML private Label emailStatusLabel;
|
|
|
|
|
@FXML private Label loginStatusLabel;
|
|
|
|
|
@FXML private Button registerButton;
|
|
|
|
|
|
|
|
|
|
@FXML private Label loginStatusLabel;
|
|
|
|
|
|
|
|
|
|
// 考试设置界面控件
|
|
|
|
|
@FXML private VBox examSetupPanel;
|
|
|
|
|
@ -47,36 +34,12 @@ 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;
|
|
|
|
|
private int currentQuestionIndex = 0;
|
|
|
|
|
private Map<Integer, String> userAnswers = new HashMap<>();
|
|
|
|
|
private ChoiceQuestionGenerator questionGenerator;
|
|
|
|
|
private final Map<String, Account> userMap = new HashMap<>();
|
|
|
|
|
private final EmailCodeService emailCodeService = new EmailCodeService();
|
|
|
|
|
private boolean emailVerified = false;
|
|
|
|
|
private final Map<String, RegisterInfo> pendingRegistrations = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final String USER_DATA_FILE = "user_data.txt";
|
|
|
|
|
|
|
|
|
|
// 常量定义
|
|
|
|
|
private static final int MIN_QUESTIONS = 5;
|
|
|
|
|
@ -85,344 +48,12 @@ public class ExamController {
|
|
|
|
|
@FXML
|
|
|
|
|
public void initialize() {
|
|
|
|
|
initAccounts();
|
|
|
|
|
loadUserDataFromFile();
|
|
|
|
|
setupLevelComboBox();
|
|
|
|
|
examSetupPanel.setVisible(false);
|
|
|
|
|
questionCountField.setText("10");
|
|
|
|
|
|
|
|
|
|
if (registerPanel != null) {
|
|
|
|
|
registerPanel.setVisible(false);
|
|
|
|
|
}
|
|
|
|
|
if (setPasswordPanel != null) {
|
|
|
|
|
setPasswordPanel.setVisible(false);
|
|
|
|
|
}
|
|
|
|
|
if (changePasswordPanel != null) {
|
|
|
|
|
changePasswordPanel.setVisible(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 添加内部类用于存储注册信息
|
|
|
|
|
static class RegisterInfo {
|
|
|
|
|
final String username;
|
|
|
|
|
String password;
|
|
|
|
|
final String email;
|
|
|
|
|
final String registerCode;
|
|
|
|
|
final Instant expireTime;
|
|
|
|
|
boolean codeVerified;
|
|
|
|
|
|
|
|
|
|
RegisterInfo(String username, String password, String email, String registerCode) {
|
|
|
|
|
this.username = username;
|
|
|
|
|
this.password = password;
|
|
|
|
|
this.email = email;
|
|
|
|
|
this.registerCode = registerCode;
|
|
|
|
|
this.expireTime = Instant.now().plusSeconds(300); // 5分钟有效期
|
|
|
|
|
this.codeVerified = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isExpired() {
|
|
|
|
|
return Instant.now().isAfter(expireTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private void handleVerifyRegisterCode() {
|
|
|
|
|
String email = registerEmailField.getText().trim();
|
|
|
|
|
String code = registerCodeField.getText().trim();
|
|
|
|
|
|
|
|
|
|
if (email.isEmpty() || code.isEmpty()) {
|
|
|
|
|
registerStatusLabel.setText("请填写邮箱和验证码");
|
|
|
|
|
registerStatusLabel.setStyle("-fx-text-fill: red;");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用邮箱验证码服务验证
|
|
|
|
|
boolean isValid = emailCodeService.verifyCode(email, code);
|
|
|
|
|
|
|
|
|
|
if (isValid) {
|
|
|
|
|
// 检查是否有待处理的注册信息
|
|
|
|
|
RegisterInfo registerInfo = pendingRegistrations.get(email);
|
|
|
|
|
if (registerInfo != null) {
|
|
|
|
|
registerInfo.codeVerified = true;
|
|
|
|
|
registerStatusLabel.setText("验证码验证成功,请设置密码");
|
|
|
|
|
registerStatusLabel.setStyle("-fx-text-fill: green;");
|
|
|
|
|
|
|
|
|
|
// 显示设置密码面板
|
|
|
|
|
if (setPasswordPanel != null) {
|
|
|
|
|
setPasswordPanel.setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
registerStatusLabel.setText("注册信息丢失,请重新注册");
|
|
|
|
|
registerStatusLabel.setStyle("-fx-text-fill: red;");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
registerStatusLabel.setText("验证码错误或已过期");
|
|
|
|
|
registerStatusLabel.setStyle("-fx-text-fill: red;");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private void showRegisterPanel() {
|
|
|
|
|
if (registerPanel != null) {
|
|
|
|
|
registerPanel.setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@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() {
|
|
|
|
|
// 小学三个账号
|
|
|
|
|
userMap.put("张三1", new Account("张三1", "123", Level.小学));
|
|
|
|
|
@ -444,6 +75,34 @@ private void handleRegisterUser() {
|
|
|
|
|
levelComboBox.setValue("小学");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void loadUserDataFromFile() {
|
|
|
|
|
try {
|
|
|
|
|
if (!Files.exists(Paths.get(USER_DATA_FILE))) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<String> lines = Files.readAllLines(Paths.get(USER_DATA_FILE));
|
|
|
|
|
for (String line : lines) {
|
|
|
|
|
String[] parts = line.split("\\|");
|
|
|
|
|
if (parts.length >= 4) {
|
|
|
|
|
String username = parts[0];
|
|
|
|
|
String password = parts[1];
|
|
|
|
|
String levelStr = parts[3];
|
|
|
|
|
|
|
|
|
|
Level level;
|
|
|
|
|
try {
|
|
|
|
|
level = Level.valueOf(levelStr);
|
|
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
|
|
level = Level.小学; // 默认级别
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userMap.put(username, new Account(username, password, level));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// 加载用户数据失败,静默处理
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private void handleLogin() {
|
|
|
|
|
@ -464,28 +123,39 @@ private void handleRegisterUser() {
|
|
|
|
|
examSetupPanel.setVisible(true);
|
|
|
|
|
loginStatusLabel.setText("登录成功!");
|
|
|
|
|
loginStatusLabel.setStyle("-fx-text-fill: green;");
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
loginStatusLabel.setText("用户名或密码错误");
|
|
|
|
|
loginStatusLabel.setStyle("-fx-text-fill: red;");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private void handleRegister() {
|
|
|
|
|
try {
|
|
|
|
|
// 打开注册界面
|
|
|
|
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("register-view.fxml"));
|
|
|
|
|
Scene scene = new Scene(loader.load(), 800, 800);
|
|
|
|
|
Stage registerStage = new Stage();
|
|
|
|
|
registerStage.setTitle("数学考试系统 - 用户注册");
|
|
|
|
|
registerStage.setScene(scene);
|
|
|
|
|
registerStage.setResizable(false);
|
|
|
|
|
registerStage.show();
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
loginStatusLabel.setText("打开注册界面失败:" + e.getMessage());
|
|
|
|
|
loginStatusLabel.setStyle("-fx-text-fill: red;");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
private void handleLogout() {
|
|
|
|
|
currentAccount = null;
|
|
|
|
|
examQuestions = null;
|
|
|
|
|
currentQuestionIndex = 0;
|
|
|
|
|
userAnswers.clear();
|
|
|
|
|
examSetupPanel.setVisible(false);
|
|
|
|
|
usernameField.clear();
|
|
|
|
|
passwordField.clear();
|
|
|
|
|
loginStatusLabel.setText("");
|
|
|
|
|
statusLabel.setText("");
|
|
|
|
|
emailVerified = false;
|
|
|
|
|
if (emailField != null) emailField.clear();
|
|
|
|
|
if (emailCodeField != null) emailCodeField.clear();
|
|
|
|
|
if (emailStatusLabel != null) emailStatusLabel.setText("");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@FXML
|
|
|
|
|
@ -508,8 +178,6 @@ private void handleRegisterUser() {
|
|
|
|
|
String selectedLevel = levelComboBox.getValue();
|
|
|
|
|
ChoiceQuestionGenerator.Level level = ChoiceQuestionGenerator.Level.valueOf(selectedLevel);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 生成考试题目
|
|
|
|
|
questionGenerator = new ChoiceQuestionGenerator();
|
|
|
|
|
examQuestions = questionGenerator.generateQuestions(level, count);
|
|
|
|
|
@ -529,10 +197,6 @@ private void handleRegisterUser() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void startExam() {
|
|
|
|
|
try {
|
|
|
|
|
// 打开专门的考试界面
|
|
|
|
|
@ -560,7 +224,6 @@ private void handleRegisterUser() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 内部类
|
|
|
|
|
static class Account {
|
|
|
|
|
final String username;
|
|
|
|
|
@ -577,4 +240,4 @@ private void handleRegisterUser() {
|
|
|
|
|
enum Level {
|
|
|
|
|
小学, 初中, 高中
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|