You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
two_project/src/main/java/com/mathgenerator/service/UserService.java

155 lines
5.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.mathgenerator.service;
import com.google.gson.Gson;
import java.util.Objects;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.mathgenerator.model.User;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Pattern;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
public class UserService {
private static final Path USER_FILE_PATH = Paths.get("users.json");
// 密码策略: 6-10位, 必须包含大小写字母和数字
private static final Pattern PASSWORD_PATTERN =
Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{6,10}$");
private Map<String, User> userDatabase;
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
public UserService() {
this.userDatabase = loadUsersFromFile();
}
private Map<String, User> loadUsersFromFile() {
try {
if (Files.exists(USER_FILE_PATH) && Files.size(USER_FILE_PATH) > 0) {
try (FileReader reader = new FileReader(USER_FILE_PATH.toFile())) {
Type type = new TypeToken<Map<String, User>>() {}.getType();
Map<String, User> loadedUsers = gson.fromJson(reader, type);
return loadedUsers != null ? new ConcurrentHashMap<>(loadedUsers) : new ConcurrentHashMap<>();
}
}
} catch (IOException e) {
System.err.println("错误:加载用户文件失败 - " + e.getMessage());
}
return new ConcurrentHashMap<>();
}
private void saveUsers() {
try (FileWriter writer = new FileWriter(USER_FILE_PATH.toFile())) {
gson.toJson(this.userDatabase, writer);
} catch (IOException e) {
System.err.println("错误:保存用户文件失败 - " + e.getMessage());
}
}
public Optional<User> findUserByUsername(String username) {
return Optional.ofNullable(this.userDatabase.get(username));
}
public Optional<User> login(String username, String password) {
return findUserByUsername(username)
.filter(user -> user.password().equals(password));
}
/**
* (已更新) 发送真实的邮件验证码。
* @param email 用户的邮箱
* @return 成功发送则返回生成的6位验证码, 失败则返回null
*/
public String sendVerificationCode(String email) {
String code = String.format("%06d", ThreadLocalRandom.current().nextInt(100000, 1000000));
try {
Email mail = new SimpleEmail();
// 1. 设置SMTP服务器信息
mail.setHostName(EmailConfig.getHost());
mail.setSmtpPort(EmailConfig.getPort());
mail.setAuthentication(EmailConfig.getUsername(), EmailConfig.getPassword());
mail.setSSLOnConnect(true); // 开启SSL加密
// 2. 设置邮件内容
mail.setFrom(EmailConfig.getUsername()); // 发件人
mail.setSubject("【数学学习软件】您的注册验证码"); // 邮件主题
mail.setMsg("您好!\n\n感谢您注册数学学习软件。您的验证码是" + code + "\n\n请在5分钟内使用。"); // 邮件正文
mail.addTo(email); // 收件人
// 3. 发送邮件
mail.send();
System.out.println("验证码邮件已成功发送至: " + email);
return code;
} catch (EmailException e) {
System.err.println("错误:发送验证码邮件失败!请检查您的 config.properties 配置或网络连接。");
e.printStackTrace();
return null; // 发送失败
}
}
/**
* 注册新用户。
* @return 成功返回true, 否则返回false
*/
public boolean register(String username, String email, String password) {
// 1. 基础校验:防止 null 或空白输入
if (username == null || email == null || password == null ||
username.trim().isEmpty() || email.trim().isEmpty() || password.trim().isEmpty()) {
return false;
}
// 2. 检查用户名或邮箱是否已存在(使用 Objects.equals 安全比较)
boolean usernameExists = userDatabase.containsKey(username);
boolean emailExists = userDatabase.values().stream()
.anyMatch(u -> Objects.equals(u.email(), email));
if (usernameExists || emailExists) {
return false; // 用户名或邮箱已存在
}
// 3. 创建新用户并保存
User newUser = new User(username, email, password);
userDatabase.put(username, newUser);
saveUsers();
return true;
}
/**
* 验证密码是否符合复杂度要求。
* @param password 待验证的密码
* @return true如果符合要求
*/
public static boolean isPasswordValid(String password) {
return password != null && PASSWORD_PATTERN.matcher(password).matches();
}
/**
* 修改密码。
* @return 成功返回true
*/
public boolean changePassword(String username, String oldPassword, String newPassword) {
return findUserByUsername(username)
.filter(user -> user.password().equals(oldPassword))
.map(user -> {
User updatedUser = new User(user.username(), user.email(), newPassword);
userDatabase.put(username, updatedUser);
saveUsers();
return true;
}).orElse(false);
}
}