刘欣睿 20251011 1921 #1

Merged
hnu202326010225 merged 2 commits from liuxinrui_branch into develop 5 months ago

@ -1,5 +1,7 @@
package mathlearning.model;
import com.fasterxml.jackson.databind.BeanProperty;
import java.time.LocalDateTime;
public class User {
@ -9,6 +11,7 @@ public class User {
private LocalDateTime registrationDate;
private String verificationCode;
private boolean verified;
private String type;
public User() {}
@ -18,6 +21,7 @@ public class User {
this.verificationCode = verificationCode;
this.verified = false;
this.registrationDate = LocalDateTime.now();
this.type = null;
}
// Getters and setters
@ -38,4 +42,7 @@ public class User {
public String getUsername() { return username; }
public void setUsername(String username) {this.username = username; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
}

@ -19,7 +19,7 @@ public class EmailService {
this.auth = auth;
}
public boolean sendVerificationCode(String toEmail, String verificationCode) {
public boolean sendVerificationCode(String toEmail, String verificationCode, int flag) {
try {
Properties props = new Properties();
props.put("mail.smtp.host", host);
@ -38,12 +38,11 @@ public class EmailService {
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
message.setSubject("数学学习软件 - 注册验证码");
String emailContent="";
if (flag == 1) emailContent = registerContent(verificationCode);
else if (flag == 2) emailContent = resetPasswordContent(verificationCode);
String emailContent = "尊敬的用户:\n\n" +
"您的注册验证码是:" + verificationCode + "\n\n" +
"该验证码有效期为10分钟。\n\n" +
"如果您没有注册本软件,请忽略此邮件。\n\n" +
"数学学习软件团队";
message.setText(emailContent);
@ -54,4 +53,20 @@ public class EmailService {
return false;
}
}
public String registerContent(String verificationCode) {
return "尊敬的用户:\n\n" +
"您的注册验证码是:" + verificationCode + "\n\n" +
"该验证码有效期为10分钟。\n\n" +
"如果您没有注册本软件,请忽略此邮件。\n\n" +
"数学学习软件团队";
}
public String resetPasswordContent(String verificationCode) {
return "尊敬的用户:\n\n" +
"您的重置验证码是:" + verificationCode + "\n\n" +
"该验证码有效期为10分钟。\n\n" +
"如果您没有重置密码,请忽略此邮件。\n\n" +
"数学学习软件团队";
}
}

@ -0,0 +1,190 @@
package mathlearning.service.MultipleChoiceGenerator;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class ComputingUnit {
String expression;
Stack <String> numbers = new Stack<>();
Stack <String> operators = new Stack<>();
ComputingUnit(String Question){
expression = Question;
}
private void SplitAndChange(){
String[] split = expression.split(" ");
split = separateParentheses(split);
for(int i = 0 ; i < split.length ; i++){
if (split[i].charAt(0) == '√') {
String StrNum = split[i].substring(1);
double num = Math.sqrt(Double.parseDouble(StrNum));
split[i] = String.valueOf(num);
} else if (split[i].charAt(split[i].length()-1) == '²') {
String StrNum = split[i].substring(0, split[i].length()-1);
double result = Math.pow(Double.parseDouble(StrNum), 2);
split[i] = String.valueOf(result);
} else if ((split[i].charAt(0) == 's' || split[i].charAt(0) == 'c'
|| split[i].charAt(0) == 't' )) {
int index = split[i].indexOf(')');
int index2 = split[i].indexOf('(');
String StrNum = split[i].substring(index2 + 1, index);
double num = Double.parseDouble(SquOrRoot(StrNum));
double result = getFunc(split[i].charAt(0), num);
split[i] = String.valueOf(result);
}
}
this.expression = String.join(" ", split);
}
public String[] separateParentheses(String[] originalArray) {
List<String> result = new ArrayList<>();
for (String item : originalArray) {
if (item.startsWith("(") && item.length() > 1) {
// 如果字符串以(开头且长度大于1分离出(
result.add("(");
result.add(item.substring(1).trim());
} else if (item.endsWith(")") && item.length() > 1 &&
(item.charAt(0) != 's' && item.charAt(0) != 'c' && item.charAt(0) != 't')) {
// 如果字符串以)结尾且长度大于1分离出)
result.add(item.substring(0, item.length() - 1).trim());
result.add(")");
} else if ((item.charAt(0) == 's' || item.charAt(0) == 'c' || item.charAt(0) == 't') &&
(item.endsWith(")") && item.charAt(item.length()-2) == ')')) {
result.add(item.substring(0, item.length() - 1).trim());
result.add(")");
} else {
// 其他情况保持不变
result.add(item);
}
}
return result.toArray(new String[0]);
}
private String SquOrRoot(String StrNum){
if(StrNum.charAt(0) == '√'){
return String.valueOf(Math.sqrt(Double.parseDouble(StrNum.substring(1))));
} else if (StrNum.charAt(StrNum.length()-1) == '²') {
return String.valueOf(Math.pow(Double.parseDouble(StrNum.substring(0, StrNum.length()-1)), 2));
}else {
return StrNum;
}
}
private double getFunc(char func, double num){
switch (func) {
case 's':
return Math.sin(num);
case 'c':
return Math.cos(num);
case 't':
return Math.tan(num);
default:
return 0;
}
}
private void priority(String operator){
if(operators.isEmpty() || operators.peek().equals("(")){
operators.push(operator);
}else{
if((operators.peek().equals("+")|| operators.peek().equals("-")) &&
(operator.equals("×") || operator.equals("÷"))){
operators.push(operator);
}else{
CulAndPushOperator(operator);
}
}
}
private void CulAndPushOperator(String operator){
String num1 = numbers.pop();
String num2 = numbers.pop();
String operator1 = operators.pop();
operators.push(operator);
String result = SingleCul(num2, operator1, num1);
numbers.push(result);
}
private String Compute(){
String[] spilt = expression.split(" ");
for (int i = 0; i < spilt.length; i++){
if(spilt[i].equals("+") || spilt[i].equals("-") ||
spilt[i].equals("×") || spilt[i].equals("÷") ||
spilt[i].equals("(") ){//处理运算符
if( spilt[i].equals("(")){
operators.push(spilt[i]);
}else{
priority(spilt[i]);
}
}else if(spilt[i].equals(")")){
String tempResult = numbers.pop();
while (!operators.peek().equals("(")){
String operator = operators.pop();
String num1 = numbers.pop();
tempResult = SingleCul(num1, operator, tempResult);
}
if(operators.peek().equals("(")){
operators.pop();
}
numbers.push(tempResult);
} else {
numbers.push(spilt[i]);
}
}
return CulWithoutPriority();
}
private String CulWithoutPriority(){
if(numbers.isEmpty()){
return "0";
}
String result = numbers.pop();
while (!operators.isEmpty() && !numbers.isEmpty()){
String num1 = numbers.pop();
String operator = operators.pop();
result = SingleCul(num1, operator, result);
}
return result;
}
public String getAnswer(){
SplitAndChange();
return Compute();
}
private String SingleCul(String nowResult, String operator, String num){
// 使用 trim() 去除首尾空格
// 使用 split("\\s+") 按空格分割,只取第一个元素(数字)
String cleanNowResult = nowResult.trim().split("\\s+")[0];
String cleanNum = num.trim().split("\\s+")[0];
// 现在可以安全地解析数字了
Double result = Double.parseDouble(cleanNowResult);
switch (operator) {
case "+":
result += Double.parseDouble(cleanNum);
break;
case "-":
result -= Double.parseDouble(cleanNum);
break;
case "×":
result *= Double.parseDouble(cleanNum);
break;
case "÷":
result /= Double.parseDouble(cleanNum);
break;
}
return String.valueOf(result);
}
}

@ -0,0 +1,92 @@
package mathlearning.service.MultipleChoiceGenerator;
import mathlearning.model.User;
import mathlearning.service.QuestionGenerator.*;
import java.util.*;
public class MultipleChoiceGenerator {
private static QuestionGenerator QuestionGenerator = new PrimaryGenerator();
String[] QuestionList ;
String[] AnswerList ;
String[] ChoiceList ;
MultipleChoiceGenerator(int count, User nowUser){// 如此声明MultipleChoiceGenerator实例,再调用下面三个接口
this.QuestionList = new String[count];
this.ChoiceList = new String[count];
this.QuestionList = SetQuestionList(count, nowUser);
SetChoiceList();
}
public String[] GetQuestionList(){
return this.QuestionList;
}
public String[] GetChoiceList(){
return this.ChoiceList;
}
public String[] GetAnswerList(){
return this.AnswerList;
}
private void SetChoiceList(){
for(int i = 0 ; i < this.AnswerList.length ; i++){
Random random = new Random();
String[] choiceNo = {"A.","B.","C.","D."};
String[] choices = new String[4];
double correctChoice = Double.parseDouble(this.AnswerList[i]);
int position = random.nextInt(4);
choices[position] = choiceNo[position] + String.format("%.2f", correctChoice);
for(int j = 0 ; j < 4 ; j++){
if(j != position){
double choice = correctChoice;
double offset = random.nextInt(41) - 20;
choice += offset;
choices[j] =choiceNo[j] + String.format("%.2f", choice);
}
}
this.ChoiceList[i] = String.join("\n", choices);
}
}
private String[] SetQuestionList(int count, User nowUser){
String[] Questions= new String[count];
if(nowUser.getType().equals("小学") ) {
QuestionGenerator = new PrimaryGenerator();
}
else if( nowUser.getType().equals("初中") ) {
QuestionGenerator = new middleGenerator();
}
else if( nowUser.getType().equals("高中") ) {
QuestionGenerator = new highGenerator();
}
List<String> questions = new ArrayList<>();
Set<String> generatedQuestions = new HashSet<>();
for (int i = 0; i < count; i++) {
String question;
do {
question = QuestionGenerator.generateQuestion();
} while ( generatedQuestions.contains(question ));
generatedQuestions.add(question);
questions.add(question);
}
for(int i = 0 ; i< count ; i++){
Questions[i] = questions.get(i);
}
this.AnswerList = new String[count];
for(int i = 0 ; i< count ; i++){
ComputingUnit computingUnit = new ComputingUnit(Questions[i]);
this.AnswerList[i] = computingUnit.getAnswer();
}
return Questions;
}
}

@ -0,0 +1,37 @@
package mathlearning.service.MultipleChoiceGenerator;
import mathlearning.model.User;
public class MultipleChoiceGeneratorTest {
public static void main(String[] args) {
// 创建一个模拟用户
User testUser = new User();
testUser.setType("小学"); // 可以分别测试"小学"、"初中"、"高中"
// 测试生成10道题目
int questionCount = 10;
MultipleChoiceGenerator generator = new MultipleChoiceGenerator(questionCount, testUser);
// 获取生成的题目、答案和选项
String[] questions = generator.GetQuestionList();
String[] answers = generator.GetAnswerList();
String[] choices = generator.GetChoiceList();
// 输出测试结果
System.out.println("=== 数学题目生成测试 ===");
System.out.println("用户类型: " + testUser.getType());
System.out.println("生成题目数量: " + questionCount);
System.out.println();
for (int i = 0; i < questions.length; i++) {
System.out.println("题目 " + (i + 1) + ": " + questions[i]);
System.out.println("答案: " + answers[i]);
System.out.println("选项:");
String[] choiceArray = choices[i].split("\n");
for (int j = 0; j < choiceArray.length; j++) {
System.out.println(" " + (char)('A' + j) + ". " + choiceArray[j]);
}
System.out.println("----------------------------------------");
}
}
}

@ -0,0 +1,22 @@
package mathlearning.service.QuestionGenerator;
public class PrimaryGenerator extends QuestionGenerator{
public PrimaryGenerator() {
super("小学");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int[operandCount];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper(operands);
return addParen(question);
}
}

@ -0,0 +1,142 @@
package mathlearning.service.QuestionGenerator;
import java.util.Random;
public abstract class QuestionGenerator{
protected Random random = new Random();
public abstract String generateQuestion() ;
protected String type;
public String getType() {
return type;
}
QuestionGenerator() {
type = "无";
}
QuestionGenerator(String Type) {
type = Type;
}
protected String preForOper(int[] operands) {
StringBuilder question = new StringBuilder();
String[] operators = {"+", "-", "×", "÷"};
question.append(operands[0]);
for (int i = 1; i < operands.length; i++) {
String op = operators[ random.nextInt (operators.length)];
question.append(" ").append(op).append(" ").append(operands[i]);
}
return question.toString();
}
protected boolean Check_num(String expression) {
if(!(expression.equals("+") || expression.equals("-") || expression.equals("×") || expression.equals("÷"))) {
return true;
}
else{
return false;
}
}
protected String addParen(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
boolean r_paren_needed = false;
for (int i = 0; i < parts.length; i++) {
if(Check_num ( parts [i]) ) {
if( !r_paren_needed ) {
if(i <= parts.length -3 )
{
if( random.nextBoolean() )
{ result.append("(");r_paren_needed = true;}
}
result.append(parts[i]);
} else {
result.append( parts [i]);
if( !random.nextBoolean()) {
result.append(")");r_paren_needed = false;
}
}
} else {
result.append( parts [i] );
}
if( i < parts.length -1 ) {
result.append(" ");
}
}
if( r_paren_needed ){
result.append(")");r_paren_needed = false;
}
return result.toString();
}
protected String add_squs(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
boolean has_squs = false;
for (int i = 0; i < parts.length; i++) {
if( Check_num( parts [i] )) {
double Thres = 0.3;
if( !has_squs){
Thres = 0.7;
}
if ( random.nextDouble() < Thres ||(i == parts.length -1 && !has_squs)) {
if ( random.nextBoolean() ) {
result.append(parts[i]);
result.append("²");
has_squs = true;
} else {
result.append("√");
result.append(parts[i]);
has_squs = true;
}
} else {
result.append(parts[i]);
}
} else {
result.append(parts[i]);
}
if( i < parts.length -1 ) {
result.append(" ");
}
}
return result.toString();
}
protected String add_sins(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
String[] functions = {"sin", "cos", "tan"};
boolean has_func = false;
for (int i = 0; i < parts.length; i++) {
double Thres = 0.4;
if(!has_func){Thres = 0.8;}
if(Check_num(parts[i]))
{
if ( random.nextDouble() < Thres ||(i == parts.length-1 && !has_func) ) {
String func = functions[random.nextInt(functions.length)];
result.append(func).append("(").append(parts[i]).append(")");
} else {
result.append(parts[i]);
}
} else {
result.append(parts[i]);
}
if( i < parts.length-1 ) {
result.append(" ");
}
}
return result.toString();
}
}

@ -0,0 +1,24 @@
package mathlearning.service.QuestionGenerator;
public class highGenerator extends QuestionGenerator{
public highGenerator() {
super("高中");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int[ operandCount ];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper( operands );
question = add_squs( question );
question = add_sins( question );
return addParen( question );
}
}

@ -0,0 +1,23 @@
package mathlearning.service.QuestionGenerator;
public class middleGenerator extends QuestionGenerator{
public middleGenerator() {
super("初中");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int [ operandCount ];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper(operands);
question = add_squs(question);
return addParen(question);
}
}

@ -147,6 +147,58 @@ public class UserService {
return true;
}
public boolean setPasswordResetCode(String email, String verificationCode) {
User user = users.get(email);
if (user == null) {
return false; // 用户不存在
}
user.setVerificationCode(verificationCode);
verificationCodeTimestamps.put(email, LocalDateTime.now());
saveUsers();
return true;
}
public boolean resetPasswordWithCode(String email, String verificationCode, String newPassword) {
User user = users.get(email);
if (user == null) {
return false;
}
// 验证验证码
if (!user.getVerificationCode().equals(verificationCode)) {
return false;
}
// 检查验证码是否过期
LocalDateTime codeTime = verificationCodeTimestamps.get(email);
if (codeTime == null || codeTime.plusMinutes(VERIFICATION_CODE_EXPIRY_MINUTES).isBefore(LocalDateTime.now())) {
return false;
}
// 验证新密码格式
if (!validatePassword(newPassword)) {
return false;
}
// 更新密码
String newPasswordHash = BCrypt.withDefaults().hashToString(12, newPassword.toCharArray());
user.setPasswordHash(newPasswordHash);
verificationCodeTimestamps.remove(email); // 清除验证码
saveUsers();
return true;
}
public boolean updateUserType(String email, String type) {
User user = users.get(email);
if (user == null) {
return false;
}
user.setType(type);
saveUsers();
return true;
}
public boolean validatePassword(String password) {
if (password.length() < 6 || password.length() > 10) {
return false;
@ -169,7 +221,17 @@ public class UserService {
return users.containsKey(email);
}
public boolean isUserExistsAndVerified(String email) {
User user = users.get(email);
return user != null && user.isVerified();
}
public boolean isValidEmail(String email) {
return email.matches("^[A-Za-z0-9+_.-]+@(.+)$");
}
public User getUser(String email ) {
User user = users.get(email);
return user;
}
}

@ -0,0 +1,221 @@
package mathlearning.ui;
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, 2);
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();
}
}

@ -63,8 +63,13 @@ public class LoginFrame extends JFrame{
registerButton.setFont(new Font("微软雅黑", Font.PLAIN, 14));
registerButton.addActionListener(e -> openRegisterFrame());
JButton changeCodeButton = new JButton("忘记密码?");
changeCodeButton.setFont(new Font("微软雅黑", Font.PLAIN, 14));
changeCodeButton.addActionListener(e -> openChangeCodeFrame());
buttonPanel.add(loginButton);
buttonPanel.add(registerButton);
buttonPanel.add(changeCodeButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
@ -101,11 +106,57 @@ public class LoginFrame extends JFrame{
this.setVisible(false);
}
private void openChangeCodeFrame() {
ChangeCodeFrame changeCodeFrame = new ChangeCodeFrame(userService, this);
changeCodeFrame.setVisible(true);
this.setVisible(false);
}
private void openMainFrame(String email) {
User user = userService.getUser(email);
// 如果用户类型为空,让用户选择类型
if (user.getType() == null || user.getType().isEmpty()) {
String[] types = {"小学", "初中", "高中"};
String selectedType = (String) JOptionPane.showInputDialog(
this,
"欢迎 " + user.getUsername() + "!\n请选择您的教育阶段",
"选择教育阶段",
JOptionPane.QUESTION_MESSAGE,
null,
types,
types[0] // 默认选择第一个
);
// 如果用户选择了类型(没有点击取消)
if (selectedType != null) {
// 更新用户类型
boolean updated = userService.updateUserType(email, selectedType);
if (updated) {
// 更新本地user对象
user.setType(selectedType);
JOptionPane.showMessageDialog(this,
"登录成功!\n教育阶段" + selectedType,
"登录成功", JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(this,
"登录成功!\n但教育阶段设置失败",
"登录成功", JOptionPane.WARNING_MESSAGE);
}
} else {
// 如果用户取消选择,可以设置默认类型或者保持为空
userService.updateUserType(email, "小学");
user.setType("小学");
JOptionPane.showMessageDialog(this,
"登录成功!\n已为您选择默认教育阶段小学",
"登录成功", JOptionPane.INFORMATION_MESSAGE);
}
} else {
// 如果已经有类型,直接显示欢迎信息
JOptionPane.showMessageDialog(this,
"欢迎 " + user.getUsername() + "!\n登录成功。\n教育阶段" + user.getType(),
"登录成功", JOptionPane.INFORMATION_MESSAGE);
}
// 这里先简单显示一个消息,后续可以扩展为主界面
JOptionPane.showMessageDialog(this,
"欢迎 " + email + "!\n登录成功主界面功能待实现。",
"登录成功", JOptionPane.INFORMATION_MESSAGE);
// openMainApplicationWindow(user);
}
}

@ -0,0 +1,53 @@
package mathlearning.ui;
import mathlearning.model.User;
import mathlearning.service.UserService;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MainFrame extends JFrame {
private User currentUser;
private UserService userService;
private JLabel welcomeLabel;
public MainFrame(User user, UserService userService) {
this.currentUser = user;
this.userService = userService;
InitializeUI();
}
private void InitializeUI() {
setTitle("数学学习软件 - 菜单");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 400);
setLocationRelativeTo(null);
setResizable(false);
// 主面板
JPanel titlePanel = new JPanel(new BorderLayout());
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// 欢迎用户与type信息
welcomeLabel = new JLabel("欢迎"+currentUser.getUsername()+"!", JLabel.CENTER);
welcomeLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
JLabel typeLabel = new JLabel("当前选择的测试题为" + currentUser.getType() + "难度", JLabel.CENTER);
typeLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));
typeLabel.setForeground(Color.BLUE);
titlePanel.add(welcomeLabel, BorderLayout.NORTH);
titlePanel.add(typeLabel, BorderLayout.CENTER);
mainPanel.add(titlePanel, BorderLayout.NORTH);
// 功能按钮区域
JPanel centerButtonPanel = new JPanel(new GridLayout(2, 1, 15, 15));
centerButtonPanel.setBorder(BorderFactory.createEmptyBorder(30, 50, 30, 50));
}
}

@ -145,7 +145,7 @@ public class RegisterFrame extends JFrame{
verificationCode = String.valueOf((int)((Math.random() * 9 + 1) * 100000));
// 发送验证码邮件
boolean sent = emailService.sendVerificationCode(email, verificationCode);
boolean sent = emailService.sendVerificationCode(email, verificationCode, 1);
if (sent) {
JOptionPane.showMessageDialog(RegisterFrame.this,

Loading…
Cancel
Save