|
|
|
|
@ -0,0 +1,226 @@
|
|
|
|
|
package mathlearning.ui;
|
|
|
|
|
|
|
|
|
|
import at.favre.lib.crypto.bcrypt.BCrypt;
|
|
|
|
|
import mathlearning.model.User;
|
|
|
|
|
import mathlearning.service.EmailService;
|
|
|
|
|
import mathlearning.service.UserService;
|
|
|
|
|
|
|
|
|
|
import javax.swing.*;
|
|
|
|
|
import java.awt.*;
|
|
|
|
|
import java.awt.event.ActionEvent;
|
|
|
|
|
import java.awt.event.ActionListener;
|
|
|
|
|
|
|
|
|
|
public class ChangeCodeFrame extends JFrame {
|
|
|
|
|
private UserService userService;
|
|
|
|
|
private EmailService emailService;
|
|
|
|
|
private LoginFrame loginFrame;
|
|
|
|
|
|
|
|
|
|
private JTextField emailField;
|
|
|
|
|
private JButton sendCodeButton;
|
|
|
|
|
private JTextField codeField;
|
|
|
|
|
private JPasswordField passwordField;
|
|
|
|
|
private JPasswordField confirmPasswordField;
|
|
|
|
|
private JButton registerButton;
|
|
|
|
|
private JButton backButton;
|
|
|
|
|
|
|
|
|
|
private String verificationCode;
|
|
|
|
|
|
|
|
|
|
public ChangeCodeFrame(UserService userService, LoginFrame loginFrame) {
|
|
|
|
|
this.userService = userService;
|
|
|
|
|
this.loginFrame = loginFrame;
|
|
|
|
|
|
|
|
|
|
// 配置邮箱服务(需要替换为真实的邮箱配置)
|
|
|
|
|
this.emailService = new EmailService(
|
|
|
|
|
"smtp.qq.com",
|
|
|
|
|
"587",
|
|
|
|
|
"2793415226@qq.com", // 替换为你的QQ邮箱
|
|
|
|
|
"rmiomlakglpjddhb", // 替换为你的授权码
|
|
|
|
|
true
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
initializeUI();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initializeUI() {
|
|
|
|
|
setTitle("数学学习软件 - 忘记密码");
|
|
|
|
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
|
|
setSize(450, 400);
|
|
|
|
|
setLocationRelativeTo(null);
|
|
|
|
|
setResizable(false);
|
|
|
|
|
|
|
|
|
|
// 主面板
|
|
|
|
|
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
|
|
|
|
|
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
JLabel titleLabel = new JLabel("重置密码", JLabel.CENTER);
|
|
|
|
|
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
|
|
|
|
|
mainPanel.add(titleLabel, BorderLayout.NORTH);
|
|
|
|
|
|
|
|
|
|
//表单面板
|
|
|
|
|
JPanel formPanel = new JPanel(new GridLayout(5, 2, 10, 10));
|
|
|
|
|
|
|
|
|
|
JLabel emailLabel = new JLabel("邮箱:");
|
|
|
|
|
emailLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
emailField = new JTextField();
|
|
|
|
|
|
|
|
|
|
JLabel codeLabel = new JLabel("验证码:");
|
|
|
|
|
codeLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
|
|
|
|
|
JPanel codePanel = new JPanel(new BorderLayout());
|
|
|
|
|
codeField = new JTextField();
|
|
|
|
|
sendCodeButton = new JButton("发送验证码");
|
|
|
|
|
sendCodeButton.addActionListener(new SendCodeListener());
|
|
|
|
|
|
|
|
|
|
codePanel.add(codeField, BorderLayout.CENTER);
|
|
|
|
|
codePanel.add(sendCodeButton, BorderLayout.EAST);
|
|
|
|
|
|
|
|
|
|
JLabel passwordLabel = new JLabel("新密码:");
|
|
|
|
|
passwordLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
passwordField = new JPasswordField();
|
|
|
|
|
|
|
|
|
|
JLabel confirmPasswordLabel = new JLabel("确认密码:");
|
|
|
|
|
confirmPasswordLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
confirmPasswordField = new JPasswordField();
|
|
|
|
|
|
|
|
|
|
formPanel.add(emailLabel);
|
|
|
|
|
formPanel.add(emailField);
|
|
|
|
|
formPanel.add(codeLabel);
|
|
|
|
|
formPanel.add(codePanel);
|
|
|
|
|
formPanel.add(passwordLabel);
|
|
|
|
|
formPanel.add(passwordField);
|
|
|
|
|
formPanel.add(confirmPasswordLabel);
|
|
|
|
|
formPanel.add(confirmPasswordField);
|
|
|
|
|
|
|
|
|
|
mainPanel.add(formPanel, BorderLayout.CENTER);
|
|
|
|
|
|
|
|
|
|
// 按钮面板
|
|
|
|
|
JPanel buttonPanel = new JPanel(new FlowLayout());
|
|
|
|
|
|
|
|
|
|
registerButton = new JButton("更改密码");
|
|
|
|
|
registerButton.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
registerButton.addActionListener(new ChangeCodeFrame.ChangeCodeButtonListener());
|
|
|
|
|
|
|
|
|
|
backButton = new JButton("返回登录");
|
|
|
|
|
backButton.setFont(new Font("微软雅黑", Font.PLAIN, 14));
|
|
|
|
|
backButton.addActionListener(e -> goBackToLogin());
|
|
|
|
|
|
|
|
|
|
buttonPanel.add(registerButton);
|
|
|
|
|
buttonPanel.add(backButton);
|
|
|
|
|
|
|
|
|
|
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
|
|
|
|
|
|
|
|
|
|
add(mainPanel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class SendCodeListener implements ActionListener {
|
|
|
|
|
@Override
|
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
|
String email = emailField.getText().trim();
|
|
|
|
|
|
|
|
|
|
if (email.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"请输入邮箱地址", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!userService.isValidEmail(email)) {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"邮箱格式不正确", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查用户是否存在且已验证
|
|
|
|
|
if (!userService.isUserExistsAndVerified(email)) {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"该邮箱未注册或未验证", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成6位验证码
|
|
|
|
|
verificationCode = String.valueOf((int)((Math.random() * 9 + 1) * 100000));
|
|
|
|
|
|
|
|
|
|
// 发送验证码邮件
|
|
|
|
|
boolean sent = emailService.sendVerificationCode(email, verificationCode);
|
|
|
|
|
|
|
|
|
|
if (sent) {
|
|
|
|
|
// 在服务中保存验证码
|
|
|
|
|
boolean codeSaved = userService.setPasswordResetCode(email, verificationCode);
|
|
|
|
|
|
|
|
|
|
if (codeSaved) {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"验证码已发送到您的邮箱,请查收", "成功", JOptionPane.INFORMATION_MESSAGE);
|
|
|
|
|
|
|
|
|
|
// 禁用发送按钮60秒
|
|
|
|
|
sendCodeButton.setEnabled(false);
|
|
|
|
|
new Thread(() -> {
|
|
|
|
|
try {
|
|
|
|
|
for (int i = 60; i > 0; i--) {
|
|
|
|
|
final int current = i;
|
|
|
|
|
SwingUtilities.invokeLater(() ->
|
|
|
|
|
sendCodeButton.setText(current + "秒后重发"));
|
|
|
|
|
Thread.sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
SwingUtilities.invokeLater(() -> {
|
|
|
|
|
sendCodeButton.setText("发送验证码");
|
|
|
|
|
sendCodeButton.setEnabled(true);
|
|
|
|
|
});
|
|
|
|
|
} catch (InterruptedException ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}).start();
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"保存验证码失败", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"验证码发送失败,请检查邮箱地址或网络连接", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class ChangeCodeButtonListener implements ActionListener {
|
|
|
|
|
@Override
|
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
|
String email = emailField.getText().trim();
|
|
|
|
|
String code = codeField.getText().trim();
|
|
|
|
|
String password = new String(passwordField.getPassword());
|
|
|
|
|
String confirmPassword = new String(confirmPasswordField.getPassword());
|
|
|
|
|
|
|
|
|
|
// 验证输入
|
|
|
|
|
if (email.isEmpty() || code.isEmpty() || password.isEmpty()) {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"请填写所有字段", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!password.equals(confirmPassword)) {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"两次输入的密码不一致", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!userService.validatePassword(password)) {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"密码必须为6-10位,且包含大小写字母和数字", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用新的重置密码方法
|
|
|
|
|
if (userService.resetPasswordWithCode(email, code, password)) {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"密码重置成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
|
|
|
|
|
goBackToLogin();
|
|
|
|
|
} else {
|
|
|
|
|
JOptionPane.showMessageDialog(ChangeCodeFrame.this,
|
|
|
|
|
"重置失败,请检查验证码是否正确或是否已过期", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void goBackToLogin() {
|
|
|
|
|
loginFrame.setVisible(true);
|
|
|
|
|
this.dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|