第四次合并 #4
Merged
hnu202326010321
merged 6 commits from wuronghai_branch into chenchenghuan_branch 4 months ago
@ -0,0 +1,21 @@
|
||||
import controller.NavigationController;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public class MathLearningApp {
|
||||
public static void main(String[] args) {
|
||||
// Set system look and feel
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Start the application
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// 获取 NavigationController 实例并显示登录界面
|
||||
NavigationController navigationController = NavigationController.getInstance();
|
||||
navigationController.showLoginView();
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,127 @@
|
||||
package controller;
|
||||
|
||||
import model.User;
|
||||
import view.LoginView;
|
||||
import view.RegisterView;
|
||||
import view.MainView;
|
||||
import view.ExamView;
|
||||
import view.ResultView;
|
||||
|
||||
public class NavigationController extends BaseController implements NavigationService {
|
||||
private static NavigationController instance;
|
||||
private LoginView loginView;
|
||||
private RegisterView registerView;
|
||||
private MainView mainView;
|
||||
private ExamView examView;
|
||||
private ResultView resultView;
|
||||
private User currentUser;
|
||||
|
||||
// 单例模式
|
||||
public static NavigationController getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new NavigationController();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private NavigationController() {
|
||||
// 私有构造函数
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLoginView() {
|
||||
if (loginView == null) {
|
||||
loginView = new LoginView();
|
||||
}
|
||||
loginView.setVisible(true);
|
||||
hideAllExcept(loginView);
|
||||
logInfo("显示登录界面");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRegisterView() {
|
||||
if (registerView == null) {
|
||||
registerView = new RegisterView();
|
||||
}
|
||||
registerView.setVisible(true);
|
||||
hideAllExcept(registerView);
|
||||
logInfo("显示注册界面");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMainView(User user) {
|
||||
setCurrentUser(user);
|
||||
if (mainView != null) {
|
||||
mainView.dispose();
|
||||
}
|
||||
mainView = new MainView(user);
|
||||
mainView.setVisible(true);
|
||||
hideAllExcept(mainView);
|
||||
logInfo("显示主界面 - 用户: " + user.getUsername());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMainView() {
|
||||
if (currentUser != null) {
|
||||
showMainView(currentUser);
|
||||
} else {
|
||||
showLoginView();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showExamView(String difficulty, int questionCount) {
|
||||
try {
|
||||
validateStringNotEmpty(difficulty, "难度");
|
||||
if (questionCount <= 0) {
|
||||
throw new IllegalArgumentException("题目数量必须大于0");
|
||||
}
|
||||
|
||||
if (examView == null) {
|
||||
examView = new ExamView();
|
||||
}
|
||||
examView.startNewExam(difficulty, questionCount);
|
||||
examView.setVisible(true);
|
||||
hideAllExcept(examView);
|
||||
logInfo("显示考试界面 - " + difficulty + "难度, " + questionCount + "道题");
|
||||
} catch (Exception e) {
|
||||
logError("显示考试界面异常: " + e.getMessage());
|
||||
showError("无法开始考试: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showResultView(int score, int total, double percentage) {
|
||||
try {
|
||||
if (resultView == null) {
|
||||
resultView = new ResultView();
|
||||
}
|
||||
resultView.setResults(score, total, percentage);
|
||||
resultView.setVisible(true);
|
||||
hideAllExcept(resultView);
|
||||
logInfo("显示成绩界面 - 得分: " + score + "/" + total);
|
||||
} catch (Exception e) {
|
||||
logError("显示成绩界面异常: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentUser(User user) {
|
||||
this.currentUser = user;
|
||||
logInfo("设置当前用户: " + (user != null ? user.getUsername() : "null"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getCurrentUser() {
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
private void hideAllExcept(javax.swing.JFrame visibleFrame) {
|
||||
javax.swing.JFrame[] frames = {loginView, registerView, mainView, examView, resultView};
|
||||
for (javax.swing.JFrame frame : frames) {
|
||||
if (frame != null && frame != visibleFrame) {
|
||||
frame.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package controller;
|
||||
|
||||
import model.User;
|
||||
|
||||
public interface NavigationService {
|
||||
void showLoginView();
|
||||
void showRegisterView();
|
||||
void showMainView(User user);
|
||||
void showMainView();
|
||||
void showExamView(String difficulty, int questionCount);
|
||||
void showResultView(int score, int total, double percentage);
|
||||
void setCurrentUser(User user);
|
||||
User getCurrentUser();
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
package controller;
|
||||
|
||||
import model.Question;
|
||||
import model.QuestionGenerator;
|
||||
import utils.FileUtil;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class QuestionController extends BaseController implements QuestionService {
|
||||
private QuestionGenerator generator = new QuestionGenerator();
|
||||
private List<Question> currentQuestions;
|
||||
private int currentQuestionIndex = 0;
|
||||
private int score = 0;
|
||||
private int[] userAnswers;
|
||||
private String currentDifficulty;
|
||||
private int currentQuestionCount;
|
||||
|
||||
@Override
|
||||
public void startNewExam(String difficulty, int questionCount) {
|
||||
try {
|
||||
validateStringNotEmpty(difficulty, "难度");
|
||||
if (questionCount <= 0 || questionCount > 100) {
|
||||
throw new IllegalArgumentException("题目数量必须在1-100之间");
|
||||
}
|
||||
|
||||
currentQuestions = generator.generateQuestions(questionCount, difficulty);
|
||||
currentQuestionIndex = 0;
|
||||
score = 0;
|
||||
userAnswers = new int[questionCount];
|
||||
Arrays.fill(userAnswers, -1);
|
||||
currentDifficulty = difficulty;
|
||||
currentQuestionCount = questionCount;
|
||||
|
||||
FileUtil.saveCurrentExam(currentQuestions, difficulty, questionCount);
|
||||
logInfo("生成新试卷: " + difficulty + " 难度, " + questionCount + " 道题");
|
||||
} catch (Exception e) {
|
||||
logError("开始新考试异常: " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentExamInfo() {
|
||||
if (currentDifficulty != null && currentQuestionCount > 0) {
|
||||
return currentDifficulty + "难度 - " + currentQuestionCount + "道题";
|
||||
}
|
||||
return "暂无试卷";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Question getCurrentQuestion() {
|
||||
if (currentQuestions == null || currentQuestionIndex >= currentQuestions.size()) {
|
||||
return null;
|
||||
}
|
||||
return currentQuestions.get(currentQuestionIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitAnswer(int answer) {
|
||||
if (currentQuestionIndex < userAnswers.length) {
|
||||
userAnswers[currentQuestionIndex] = answer;
|
||||
logInfo("提交答案: 第" + getCurrentQuestionNumber() + "题, 答案: " + answer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextQuestion() {
|
||||
currentQuestionIndex++;
|
||||
boolean hasNext = currentQuestionIndex < currentQuestions.size();
|
||||
logInfo("下一题: " + (hasNext ? "有" : "无"));
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean previousQuestion() {
|
||||
if (currentQuestionIndex > 0) {
|
||||
currentQuestionIndex--;
|
||||
logInfo("上一题: 第" + getCurrentQuestionNumber() + "题");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculateScore() {
|
||||
score = 0;
|
||||
for (int i = 0; i < currentQuestions.size(); i++) {
|
||||
if (userAnswers[i] != -1 && currentQuestions.get(i).isCorrect(userAnswers[i])) {
|
||||
score++;
|
||||
}
|
||||
}
|
||||
logInfo("计算得分: " + score + "/" + currentQuestions.size());
|
||||
return score;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getPercentage() {
|
||||
double percentage = (double) score / currentQuestions.size() * 100;
|
||||
logInfo("正确率: " + String.format("%.1f%%", percentage));
|
||||
return percentage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentQuestionNumber() {
|
||||
return currentQuestionIndex + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalQuestions() {
|
||||
return currentQuestions != null ? currentQuestions.size() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUserAnswerForCurrentQuestion() {
|
||||
return userAnswers[currentQuestionIndex];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package controller;
|
||||
|
||||
import model.Question;
|
||||
|
||||
public interface QuestionService {
|
||||
void startNewExam(String difficulty, int questionCount);
|
||||
Question getCurrentQuestion();
|
||||
void submitAnswer(int answer);
|
||||
boolean nextQuestion();
|
||||
boolean previousQuestion();
|
||||
int calculateScore();
|
||||
double getPercentage();
|
||||
int getCurrentQuestionNumber();
|
||||
int getTotalQuestions();
|
||||
int getUserAnswerForCurrentQuestion();
|
||||
String getCurrentExamInfo();
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package controller;
|
||||
|
||||
import model.User;
|
||||
|
||||
public interface UserService {
|
||||
String registerUser(String username, String email);
|
||||
String completeRegistration(String username, String code, String password, String confirmPassword);
|
||||
User login(String loginId, String password);
|
||||
String changePassword(User user, String oldPassword, String newPassword, String confirmPassword);
|
||||
void cleanupUnregisteredUsers();
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Question implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String question;
|
||||
private String[] options;
|
||||
private int correctAnswer;
|
||||
private String difficulty;
|
||||
|
||||
public Question(String question, String[] options, int correctAnswer, String difficulty) {
|
||||
this.question = question;
|
||||
this.options = options;
|
||||
this.correctAnswer = correctAnswer;
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
// Getters
|
||||
public String getQuestion() { return question; }
|
||||
public String[] getOptions() { return options; }
|
||||
|
||||
|
||||
public boolean isCorrect(int selectedAnswer) {
|
||||
return selectedAnswer == correctAnswer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Question{" +
|
||||
"question='" + question + '\'' +
|
||||
", difficulty='" + difficulty + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package model;
|
||||
|
||||
public class User {
|
||||
private String username; // 新增:用户名
|
||||
private String email;
|
||||
private String password;
|
||||
private String registrationCode;
|
||||
private boolean isRegistered;
|
||||
|
||||
public User(String username, String email, String registrationCode) {
|
||||
this.username = username;
|
||||
this.email = email;
|
||||
this.registrationCode = registrationCode;
|
||||
this.isRegistered = false;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
|
||||
public String getEmail() { return email; }
|
||||
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
|
||||
public String getRegistrationCode() { return registrationCode; }
|
||||
|
||||
public boolean isRegistered() { return isRegistered; }
|
||||
public void setRegistered(boolean registered) { isRegistered = registered; }
|
||||
}
|
||||
Loading…
Reference in new issue