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, "用户名或邮箱已存在,请换一个用户名");