main
commit
a47385a1b6
@ -0,0 +1,186 @@
|
||||
package com.example.mathsystemtogether;
|
||||
|
||||
import jakarta.mail.*;
|
||||
import jakarta.mail.internet.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 邮件服务类
|
||||
* 负责发送验证码邮件
|
||||
*/
|
||||
public class EmailService {
|
||||
|
||||
private String smtpHost;
|
||||
private String smtpPort;
|
||||
private String fromEmail;
|
||||
private String fromPassword;
|
||||
private Session session;
|
||||
private boolean isConfigured = false;
|
||||
|
||||
public EmailService() {
|
||||
loadConfiguration();
|
||||
if (isConfigured) {
|
||||
initializeSession();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从配置文件加载邮件配置
|
||||
*/
|
||||
private void loadConfiguration() {
|
||||
try (InputStream input = getClass().getClassLoader().getResourceAsStream("mail.properties")) {
|
||||
if (input == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Properties props = new Properties();
|
||||
props.load(input);
|
||||
|
||||
smtpHost = props.getProperty("mail.smtp.host");
|
||||
smtpPort = props.getProperty("mail.smtp.port");
|
||||
fromEmail = props.getProperty("mail.from.email");
|
||||
fromPassword = props.getProperty("mail.from.password");
|
||||
|
||||
// 检查配置是否完整
|
||||
if (smtpHost != null && smtpPort != null && fromEmail != null && fromPassword != null) {
|
||||
isConfigured = true;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
// 配置加载失败,静默处理
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化邮件会话
|
||||
*/
|
||||
private void initializeSession() {
|
||||
if (!isConfigured) {
|
||||
return;
|
||||
}
|
||||
|
||||
Properties props = new Properties();
|
||||
props.put("mail.smtp.host", smtpHost);
|
||||
props.put("mail.smtp.port", smtpPort);
|
||||
props.put("mail.smtp.auth", "true");
|
||||
props.put("mail.smtp.starttls.enable", "true");
|
||||
props.put("mail.smtp.ssl.trust", smtpHost);
|
||||
|
||||
// 创建认证器
|
||||
Authenticator authenticator = new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(fromEmail, fromPassword);
|
||||
}
|
||||
};
|
||||
|
||||
session = Session.getInstance(props, authenticator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成6位数字验证码
|
||||
*/
|
||||
public String generateVerificationCode() {
|
||||
Random random = new Random();
|
||||
return String.format("%06d", random.nextInt(1000000));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送验证码邮件
|
||||
* @param toEmail 接收方邮箱
|
||||
* @param verificationCode 验证码
|
||||
* @return 发送是否成功
|
||||
*/
|
||||
public boolean sendVerificationCode(String toEmail, String verificationCode) {
|
||||
if (!isConfigured) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Message message = new MimeMessage(session);
|
||||
message.setFrom(new InternetAddress(fromEmail));
|
||||
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
|
||||
message.setSubject("数学考试系统 - 邮箱验证码");
|
||||
|
||||
// 创建邮件内容
|
||||
String htmlContent = createEmailContent(verificationCode);
|
||||
message.setContent(htmlContent, "text/html; charset=UTF-8");
|
||||
|
||||
// 发送邮件
|
||||
Transport.send(message);
|
||||
return true;
|
||||
|
||||
} catch (MessagingException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建邮件HTML内容
|
||||
*/
|
||||
private String createEmailContent(String verificationCode) {
|
||||
StringBuilder html = new StringBuilder();
|
||||
html.append("<!DOCTYPE html>");
|
||||
html.append("<html>");
|
||||
html.append("<head>");
|
||||
html.append("<meta charset=\"UTF-8\">");
|
||||
html.append("<title>邮箱验证码</title>");
|
||||
html.append("<style>");
|
||||
html.append("body { font-family: Arial, sans-serif; background-color: #f5f5f5; margin: 0; padding: 20px; }");
|
||||
html.append(".container { max-width: 600px; margin: 0 auto; background-color: white; border-radius: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); overflow: hidden; }");
|
||||
html.append(".header { background: linear-gradient(135deg, #8A2BE2, #9932CC); color: white; padding: 30px; text-align: center; }");
|
||||
html.append(".header h1 { margin: 0; font-size: 24px; }");
|
||||
html.append(".content { padding: 30px; }");
|
||||
html.append(".verification-code { background-color: #f8f9fa; border: 2px solid #8A2BE2; border-radius: 8px; padding: 20px; text-align: center; margin: 20px 0; }");
|
||||
html.append(".code { font-size: 32px; font-weight: bold; color: #8A2BE2; letter-spacing: 5px; margin: 10px 0; }");
|
||||
html.append(".footer { background-color: #f8f9fa; padding: 20px; text-align: center; color: #666; font-size: 14px; }");
|
||||
html.append(".warning { background-color: #fff3cd; border: 1px solid #ffeaa7; border-radius: 5px; padding: 15px; margin: 20px 0; color: #856404; }");
|
||||
html.append("</style>");
|
||||
html.append("</head>");
|
||||
html.append("<body>");
|
||||
html.append("<div class=\"container\">");
|
||||
html.append("<div class=\"header\">");
|
||||
html.append("<h1>数学考试系统</h1>");
|
||||
html.append("<p>邮箱验证码</p>");
|
||||
html.append("</div>");
|
||||
html.append("<div class=\"content\">");
|
||||
html.append("<h2>您好!</h2>");
|
||||
html.append("<p>您正在注册数学考试系统,请使用以下验证码完成注册:</p>");
|
||||
html.append("<div class=\"verification-code\">");
|
||||
html.append("<p><strong>验证码:</strong></p>");
|
||||
html.append("<div class=\"code\">").append(verificationCode).append("</div>");
|
||||
html.append("</div>");
|
||||
html.append("<div class=\"warning\">");
|
||||
html.append("<p><strong>重要提示:</strong></p>");
|
||||
html.append("<ul>");
|
||||
html.append("<li>验证码有效期为 <strong>5分钟</strong></li>");
|
||||
html.append("<li>请勿将验证码泄露给他人</li>");
|
||||
html.append("<li>如非本人操作,请忽略此邮件</li>");
|
||||
html.append("</ul>");
|
||||
html.append("</div>");
|
||||
html.append("<p>如果您没有注册数学考试系统,请忽略此邮件。</p>");
|
||||
html.append("<p>祝您使用愉快!</p>");
|
||||
html.append("<p><strong>数学考试系统团队</strong></p>");
|
||||
html.append("</div>");
|
||||
html.append("<div class=\"footer\">");
|
||||
html.append("<p>此邮件由系统自动发送,请勿回复</p>");
|
||||
html.append("<p>2024 数学考试系统. All rights reserved.</p>");
|
||||
html.append("</div>");
|
||||
html.append("</div>");
|
||||
html.append("</body>");
|
||||
html.append("</html>");
|
||||
|
||||
return html.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查邮件服务是否可用
|
||||
*/
|
||||
public boolean isAvailable() {
|
||||
return isConfigured && session != null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.effect.DropShadow?>
|
||||
<?import javafx.scene.paint.LinearGradient?>
|
||||
<?import javafx.scene.paint.Stop?>
|
||||
|
||||
<BorderPane xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.mathsystemtogether.RegisterController" style="-fx-background-color: linear-gradient(to bottom, #6A0DAD, #4B0082, #2E0854);">
|
||||
<top>
|
||||
<VBox spacing="15.0" style="-fx-background-color: linear-gradient(to right, #8A2BE2, #9932CC, #8B008B); -fx-background-radius: 15; -fx-padding: 20;">
|
||||
<padding>
|
||||
<Insets bottom="15.0" left="20.0" right="20.0" top="20.0"/>
|
||||
</padding>
|
||||
<Label text="🎓 用户注册" textFill="white" textAlignment="CENTER" style="-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.5), 10, 0, 0, 2);">
|
||||
<font>
|
||||
<Font name="System Bold" size="28.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<Label text="✨ 创建新账户 · 邮箱验证 · 安全可靠" textFill="#E6E6FA" textAlignment="CENTER">
|
||||
<font>
|
||||
<Font name="System" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
</VBox>
|
||||
</top>
|
||||
<center>
|
||||
<VBox spacing="10.0">
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="15.0" right="15.0" top="10.0"/>
|
||||
</padding>
|
||||
|
||||
<!-- 注册区域 -->
|
||||
<VBox spacing="15.0" style="-fx-background-color: linear-gradient(to bottom, #E6E6FA, #D8BFD8, #DDA0DD); -fx-padding: 20; -fx-background-radius: 15; -fx-effect: dropshadow(gaussian, rgba(139,0,139,0.3), 15, 0, 0, 5);">
|
||||
<Label text="📝 填写注册信息" textFill="#4B0082" textAlignment="CENTER">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
|
||||
<!-- 用户名输入 -->
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="👤 用户名:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<TextField fx:id="usernameField" promptText="请输入用户名" prefWidth="200.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 密码输入 -->
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="🔑 密码:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<PasswordField fx:id="passwordField" promptText="请输入密码" prefWidth="200.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 确认密码输入 -->
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="🔒 确认密码:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<PasswordField fx:id="confirmPasswordField" promptText="请再次输入密码" prefWidth="200.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 邮箱输入 -->
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="📧 邮箱:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<TextField fx:id="emailField" promptText="请输入邮箱地址" prefWidth="200.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 验证码输入 -->
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="🔢 验证码:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<TextField fx:id="verificationCodeField" promptText="请输入验证码" prefWidth="120.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2; -fx-padding: 8;"/>
|
||||
<Button fx:id="sendCodeButton" text="📤 发送验证码" onAction="#handleSendCode" style="-fx-background-color: linear-gradient(to right, #32CD32, #228B22); -fx-text-fill: white; -fx-background-radius: 8; -fx-padding: 8 15; -fx-font-size: 12; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 3, 0, 0, 1);"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 难度级别选择 -->
|
||||
<HBox spacing="15.0" alignment="CENTER_LEFT">
|
||||
<Label text="📚 难度级别:" minWidth="100.0" textFill="#6A0DAD">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<ComboBox fx:id="levelComboBox" prefWidth="140.0" style="-fx-background-color: white; -fx-background-radius: 8; -fx-border-color: #8A2BE2; -fx-border-radius: 8; -fx-border-width: 2;"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<HBox spacing="15.0" alignment="CENTER">
|
||||
<Button fx:id="registerButton" text="🚀 注册" onAction="#handleRegister" style="-fx-background-color: linear-gradient(to right, #8A2BE2, #9932CC); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 12 25; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
<Button fx:id="backToLoginButton" text="🔙 返回登录" onAction="#handleBackToLogin" style="-fx-background-color: linear-gradient(to right, #DC143C, #B22222); -fx-text-fill: white; -fx-background-radius: 10; -fx-padding: 12 25; -fx-font-size: 14; -fx-font-weight: bold; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2);"/>
|
||||
</HBox>
|
||||
|
||||
<!-- 状态标签 -->
|
||||
<Label fx:id="statusLabel" textFill="#8B0000" style="-fx-font-weight: bold; -fx-font-size: 14;" textAlignment="CENTER"/>
|
||||
</VBox>
|
||||
|
||||
<!-- 注册说明 -->
|
||||
<VBox spacing="15.0" style="-fx-background-color: linear-gradient(to bottom, #F8F0FF, #E6E6FA, #D8BFD8); -fx-padding: 20; -fx-background-radius: 15; -fx-effect: dropshadow(gaussian, rgba(139,0,139,0.2), 10, 0, 0, 3);">
|
||||
<Label text="📖 注册说明" textFill="#4B0082" textAlignment="CENTER">
|
||||
<font>
|
||||
<Font name="System Bold" size="16.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<VBox spacing="8.0" style="-fx-padding: 10; -fx-background-color: rgba(255,255,255,0.8); -fx-background-radius: 10; -fx-effect: dropshadow(gaussian, rgba(139,0,139,0.1), 5, 0, 0, 2);">
|
||||
<Label text="① 填写用户名、密码和邮箱信息" textFill="#6A0DAD" style="-fx-font-weight: bold;"/>
|
||||
<Label text="② 点击'发送验证码'获取邮箱验证码" textFill="#6A0DAD" style="-fx-font-weight: bold;"/>
|
||||
<Label text="③ 输入收到的验证码完成验证" textFill="#6A0DAD" style="-fx-font-weight: bold;"/>
|
||||
<Label text="④ 选择适合的难度级别" textFill="#6A0DAD" style="-fx-font-weight: bold;"/>
|
||||
<Label text="⑤ 点击'注册'完成账户创建" textFill="#6A0DAD" style="-fx-font-weight: bold;"/>
|
||||
</VBox>
|
||||
</VBox>
|
||||
</VBox>
|
||||
</center>
|
||||
</BorderPane>
|
||||
@ -0,0 +1,43 @@
|
||||
# 邮件服务配置
|
||||
# QQ邮箱配置
|
||||
|
||||
# QQ邮箱SMTP配置
|
||||
mail.smtp.host=smtp.qq.com
|
||||
mail.smtp.port=587
|
||||
mail.smtp.auth=true
|
||||
mail.smtp.starttls.enable=true
|
||||
mail.smtp.ssl.trust=smtp.qq.com
|
||||
|
||||
# 发送方邮箱配置
|
||||
mail.from.email=1961004835@qq.com
|
||||
mail.from.password=nixyzbpbcrekhgfe
|
||||
|
||||
# 其他邮箱服务商配置示例:
|
||||
|
||||
# Gmail配置
|
||||
# mail.smtp.host=smtp.gmail.com
|
||||
# mail.smtp.port=587
|
||||
# mail.smtp.auth=true
|
||||
# mail.smtp.starttls.enable=true
|
||||
# mail.smtp.ssl.trust=smtp.gmail.com
|
||||
|
||||
# 163邮箱配置
|
||||
# mail.smtp.host=smtp.163.com
|
||||
# mail.smtp.port=587
|
||||
# mail.smtp.auth=true
|
||||
# mail.smtp.starttls.enable=true
|
||||
# mail.smtp.ssl.trust=smtp.163.com
|
||||
|
||||
# 126邮箱配置
|
||||
# mail.smtp.host=smtp.126.com
|
||||
# mail.smtp.port=587
|
||||
# mail.smtp.auth=true
|
||||
# mail.smtp.starttls.enable=true
|
||||
# mail.smtp.ssl.trust=smtp.126.com
|
||||
|
||||
# 企业邮箱配置示例
|
||||
# mail.smtp.host=smtp.exmail.qq.com
|
||||
# mail.smtp.port=587
|
||||
# mail.smtp.auth=true
|
||||
# mail.smtp.starttls.enable=true
|
||||
# mail.smtp.ssl.trust=smtp.exmail.qq.com
|
||||
@ -0,0 +1 @@
|
||||
wgll|123456|ymhlovesLQX@163.com|小学|1760162416490
|
||||
Loading…
Reference in new issue