diff --git a/src/model/Login.java b/src/model/Login.java
index 54192f2..10712a5 100644
--- a/src/model/Login.java
+++ b/src/model/Login.java
@@ -64,6 +64,19 @@ public class Login {
return null;
}
+ public static boolean isEmailExists(String email){
+ if(email == null || email.trim().isEmpty()){
+ return false;
+ }
+ for(Account acc:accounts.values()){
+ if(acc.email != null && acc.email.equalsIgnoreCase(email.trim())){
+ return true;
+ }
+ }
+ return false;
+ }
+
+
// 注册(GUI 调用),若用户名已存在返回 false
// 注册(GUI 调用),若用户名或邮箱已存在返回 false
public static synchronized boolean register(String username, String password, Level level,
@@ -73,6 +86,10 @@ public class Login {
return false;
}
+ if(isEmailExists(email)){
+ return false;
+ }
+
// 检查邮箱是否重复
for (Account existing : accounts.values()) {
if (existing.email != null && existing.email.equalsIgnoreCase(email)) {
diff --git a/src/view/ExamFrame.java b/src/view/ExamFrame.java
new file mode 100644
index 0000000..eda873e
--- /dev/null
+++ b/src/view/ExamFrame.java
@@ -0,0 +1,172 @@
+package view;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.ButtonGroup;
+import javax.swing.BorderFactory;
+import javax.swing.SwingConstants;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+
+import model.Paper;
+import model.Login;
+
+/**
+ * 答题界面(选择题,四选一)
+ */
+public class ExamFrame extends JFrame {
+
+ private Paper paper;
+ private Login.Account user;
+ private int index = 0;
+ private int score = 0;
+
+ private JLabel qLabel;
+ private JRadioButton[] radioBtns = new JRadioButton[4];
+ private ButtonGroup group;
+ private JButton submitBtn;
+ private JButton quitBtn;
+
+ private JPanel centerPanel;
+ private JPanel bottomPanel;
+
+ public ExamFrame(Paper paper, Login.Account user) {
+ this.paper = paper;
+ this.user = user;
+
+ setTitle("答题 - " + user.username);
+ setSize(700, 400);
+ setLocationRelativeTo(null);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ qLabel = new JLabel("", SwingConstants.LEFT);
+ qLabel.setFont(new Font("Serif", Font.PLAIN, 16));
+ JPanel top = new JPanel(new BorderLayout());
+ top.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ top.add(qLabel, BorderLayout.CENTER);
+
+ centerPanel = new JPanel(new GridLayout(4, 1, 6, 6));
+ group = new ButtonGroup();
+ for (int i = 0; i < 4; i++) {
+ radioBtns[i] = new JRadioButton();
+ group.add(radioBtns[i]);
+ centerPanel.add(radioBtns[i]);
+ }
+
+ bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ submitBtn = new JButton("提交当前题");
+ quitBtn = new JButton("结束并查看成绩");
+ bottomPanel.add(quitBtn);
+ bottomPanel.add(submitBtn);
+
+ add(top, BorderLayout.NORTH);
+ add(centerPanel, BorderLayout.CENTER);
+ add(bottomPanel, BorderLayout.SOUTH);
+
+ submitBtn.addActionListener(e -> submitAnswer());
+ quitBtn.addActionListener(e -> finishExam());
+
+ showQuestion();
+ setVisible(true);
+ }
+
+ /**
+ * 显示一道题
+ */
+ private void showQuestion() {
+ if (index >= paper.size()) {
+ showSubmitPage();
+ return;
+ }
+ String q = paper.questions.get(index);
+ qLabel.setText("第 " + (index + 1) + " 题: " + q + "");
+ String[] opts = paper.options.get(index);
+
+ for (int i = 0; i < 4; i++) {
+ radioBtns[i].setText(opts[i]);
+ }
+ // 清除上一次选择
+ group.clearSelection();
+ }
+
+ /**
+ * 提交当前题
+ */
+ private void submitAnswer() {
+ int selected = -1;
+ for (int i = 0; i < 4; i++) {
+ if (radioBtns[i].isSelected()) {
+ selected = i;
+ }
+ }
+ if (selected == -1) {
+ JOptionPane.showMessageDialog(this, "请选择一个选项后再提交");
+ return;
+ }
+ // 判断对错
+ if (selected == paper.correctIndex[index]) {
+ score++;
+ }
+
+ index++;
+ if (index < paper.size()) {
+ showQuestion();
+ } else {
+ // 做完所有题 → 显示提交确认页面
+ showSubmitPage();
+ }
+ }
+
+ /**
+ * 做完所有题目后显示确认提交界面
+ */
+ private void showSubmitPage() {
+ // 移除中间题目区域和按钮
+ getContentPane().remove(centerPanel);
+ getContentPane().remove(bottomPanel);
+
+ JLabel finishLabel = new JLabel("已完成所有题目,是否确认提交?", SwingConstants.CENTER);
+ finishLabel.setFont(new Font("Serif", Font.BOLD, 18));
+ add(finishLabel, BorderLayout.CENTER);
+
+ JPanel confirmPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ JButton confirmBtn = new JButton("确认提交");
+ JButton cancelBtn = new JButton("返回最后一题");
+ confirmPanel.add(cancelBtn);
+ confirmPanel.add(confirmBtn);
+ add(confirmPanel, BorderLayout.SOUTH);
+
+ confirmBtn.addActionListener(e -> finishExam());
+ cancelBtn.addActionListener(e -> {
+ // 返回最后一题继续查看/修改
+ getContentPane().remove(finishLabel);
+ getContentPane().remove(confirmPanel);
+ add(centerPanel, BorderLayout.CENTER);
+ add(bottomPanel, BorderLayout.SOUTH);
+ index = paper.size() - 1;
+ showQuestion();
+ revalidate();
+ repaint();
+ });
+
+ revalidate();
+ repaint();
+ }
+
+ /**
+ * 完成考试 → 进入成绩界面
+ */
+ private void finishExam() {
+ int total = paper.size();
+ double percent = total == 0 ? 0 : (100.0 * score / total);
+ dispose();
+ new ResultFrame(user, score, total, percent);
+ }
+}
diff --git a/src/view/RegisterFrame.java b/src/view/RegisterFrame.java
index a08c1a6..ffb3c13 100644
--- a/src/view/RegisterFrame.java
+++ b/src/view/RegisterFrame.java
@@ -1,6 +1,6 @@
package view;
-import java.awt.GridLayout;
+import java.awt.*;
import java.util.Properties;
import java.util.Random;
@@ -25,7 +25,6 @@ import jakarta.mail.internet.MimeMessage;
import model.Login;
import model.LanguageSwitch;
-
/**
* 注册界面(使用 QQ 邮箱发送验证码)
*/
@@ -33,19 +32,21 @@ public class RegisterFrame extends JDialog {
private JTextField usernameField;
private JTextField emailField;
- private JComboBox levelBox;
private JPasswordField pwdField;
private JPasswordField pwdField2;
private JTextField codeField;
private String lastCode;
+ private boolean isValidEmail(String email){
+ String emailRegex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
+ return email.matches(emailRegex);
+ }
// QQ 邮箱配置
private static final String FROM_EMAIL = "songqifeng.sqf@qq.com";
private static final String AUTH_CODE = "gcyschltjgxedgjd"; // ⚠️ 在 QQ 邮箱里申请的授权码
-
public RegisterFrame(JFrame owner) {
super(owner, "注册新用户", true);
- setSize(420, 320);
+ setSize(420, 300);
setLocationRelativeTo(owner);
JPanel p = new JPanel(new GridLayout(7, 2, 6, 6));
@@ -58,11 +59,7 @@ public class RegisterFrame extends JDialog {
emailField = new JTextField();
p.add(emailField);
- p.add(new JLabel("年级:"));
- levelBox = new JComboBox<>(new String[]{"小学", "初中", "高中"});
- p.add(levelBox);
-
- p.add(new JLabel("密码 (6-10位,含大小写与数字):"));
+ p.add(new JLabel("密码 (6-10位,需含大小写与数字):"));
pwdField = new JPasswordField();
p.add(pwdField);
@@ -70,11 +67,15 @@ public class RegisterFrame extends JDialog {
pwdField2 = new JPasswordField();
p.add(pwdField2);
- JButton sendCodeBtn = new JButton("发送注册码");
- p.add(sendCodeBtn);
+ p.add(new JLabel("请输入注册码:"));
codeField = new JTextField();
p.add(codeField);
+ JButton sendCodeBtn = new JButton("发送注册码");
+ p.add(sendCodeBtn);
+
+ p.add(new JLabel());
+
JButton regBtn = new JButton("注册");
p.add(regBtn);
JButton cancelBtn = new JButton("取消");
@@ -84,10 +85,16 @@ public class RegisterFrame extends JDialog {
sendCodeBtn.addActionListener(e -> {
String email = emailField.getText().trim();
- if (email.isEmpty() || !email.contains("@")) {
+ if (email.isEmpty() || !isValidEmail(email)) {
JOptionPane.showMessageDialog(this, "请输入有效邮箱");
return;
}
+
+ if(Login.isEmailExists(email)){
+ JOptionPane.showMessageDialog(this,"该邮箱已经被注册,请使用其他邮箱");
+ return;
+ }
+
lastCode = String.format("%04d", new Random().nextInt(10000));
boolean sent = sendEmail(email, lastCode);
if (sent) {
@@ -108,6 +115,10 @@ public class RegisterFrame extends JDialog {
JOptionPane.showMessageDialog(this, "请填写完整信息并输入注册码");
return;
}
+ if(Login.isEmailExists(email)){
+ JOptionPane.showMessageDialog(this,"该邮箱已被注册,请使用其他邮箱");
+ return;
+ }
if (!code.equals(lastCode)) {
JOptionPane.showMessageDialog(this, "注册码错误,请重新输入");
return;
@@ -120,8 +131,9 @@ public class RegisterFrame extends JDialog {
JOptionPane.showMessageDialog(this, "密码不满足要求:6-10位且包含大写、小写和数字");
return;
}
- String levelStr = (String) levelBox.getSelectedItem();
- Login.Level lv = LanguageSwitch.chineseToLevel(levelStr);
+
+ Login.Level lv = Login.Level.PRIMARY;
+
boolean ok = Login.register(u, pwd, lv, email);
if (!ok) {
JOptionPane.showMessageDialog(this, "用户名或邮箱已存在,请换一个用户名");