feature-branch
lh0923 7 months ago
parent d9548a4fce
commit 03cba69c02

@ -1,13 +1,30 @@
package com.example.demo; package com.example.demo;
import jakarta.annotation.PostConstruct;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
@SpringBootApplication @SpringBootApplication
public class DemoApplication { public class DemoApplication {
@Autowired
private JdbcTemplate jdbcTemplate;
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args); SpringApplication.run(DemoApplication.class, args);
} }
} @PostConstruct
public void testConnection() {
try {
System.out.println("Testing database connection...");
this.jdbcTemplate.queryForObject("SELECT 1", Integer.class);
System.out.println("Database connection successful.");
} catch (Exception e) {
System.err.println("Failed to connect to the database: " + e.getMessage());
e.printStackTrace();
}
}
}

@ -14,38 +14,45 @@ public class User implements UserDetails {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id; // 用户ID
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private AccountType accountType; private AccountType accountType; // 账户类型
private String nickname; // 昵称
private String signature; // 签名或个人简介
private String nickname;
private String signature;
@Column(name = "login_account", unique = true, nullable = false) @Column(name = "login_account", unique = true, nullable = false)
private String loginAccount; private String loginAccount; // 登录账号(通常是用户名或邮箱)
private String password;
private LocalDateTime birthday; // 更改为 LocalDateTime 以便统一时间类型 private String password; // 加密后的密码
private LocalDateTime createdAt;
private LocalDateTime updatedAt; private LocalDateTime birthday; // 生日
private Boolean loginStatus;
private LocalDateTime createdAt; // 创建时间
private LocalDateTime updatedAt; // 更新时间
private Boolean loginStatus; // 登录状态
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private Set<UserSecurityQuestion> securityQuestions = new HashSet<>(); private Set<UserSecurityQuestion> securityQuestions = new HashSet<>(); // 安全问题集合
@ElementCollection(fetch = FetchType.EAGER) @ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "user_authorities", joinColumns = @JoinColumn(name = "user_id")) @CollectionTable(name = "user_authorities", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "authority") @Column(name = "authority")
private Set<String> authorityStrings; // 使用 Set 来避免重复权限 private Set<String> authorityStrings; // 权限字符串集合
public enum AccountType { public enum AccountType {
USER, ADMIN // 英文枚举值更符合国际化标准 USER, ADMIN // 账户类型枚举值
} }
// Default constructor // 默认构造函数
public User() {} public User() {}
// Parameterized constructor for convenience // 参数化构造函数
public User(AccountType accountType, String nickname, String signature, String loginAccount, String password, public User(AccountType accountType, String nickname, String signature, String loginAccount, String password,
LocalDateTime birthday, LocalDateTime createdAt, LocalDateTime updatedAt, Boolean loginStatus, Set<String> authorityStrings) { LocalDateTime birthday, LocalDateTime createdAt, LocalDateTime updatedAt, Boolean loginStatus, Set<String> authorityStrings) {
this.accountType = accountType; this.accountType = accountType;
@ -60,7 +67,7 @@ public class User implements UserDetails {
this.authorityStrings = authorityStrings != null ? authorityStrings : Collections.emptySet(); this.authorityStrings = authorityStrings != null ? authorityStrings : Collections.emptySet();
} }
// Getters and Setters // Getters 和 Setters 方法
/** /**
* *
@ -218,7 +225,8 @@ public class User implements UserDetails {
this.authorityStrings = authorityStrings; this.authorityStrings = authorityStrings;
} }
// Implementing methods of UserDetails interface // 实现 UserDetails 接口的方法
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
return this.getAuthorityStrings().stream() return this.getAuthorityStrings().stream()
@ -265,7 +273,7 @@ public class User implements UserDetails {
this.securityQuestions = securityQuestions; this.securityQuestions = securityQuestions;
} }
// Equals and HashCode methods for better entity comparison // 重写 equals 和 hashCode 方法以更好地进行实体比较
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

@ -77,4 +77,5 @@ public class SecurityConfig {
public AuthenticationManager authenticationManager(AuthenticationProvider authenticationProvider) { public AuthenticationManager authenticationManager(AuthenticationProvider authenticationProvider) {
return new ProviderManager(List.of(authenticationProvider)); return new ProviderManager(List.of(authenticationProvider));
} }
} }

@ -14,6 +14,9 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.Map;
@RestController @RestController
@CrossOrigin(origins = "http://localhost:5137/") // 允许来自前端开发服务器的请求 @CrossOrigin(origins = "http://localhost:5137/") // 允许来自前端开发服务器的请求
@ -48,6 +51,11 @@ public class UserController {
} }
} }
// 设置默认 accountType 如果未指定或无效
if (user.getAccountType() == null || !Arrays.asList(User.AccountType.USER, User.AccountType.ADMIN).contains(user.getAccountType())) {
user.setAccountType(User.AccountType.USER);
}
User registeredUser = userService.registerUser(user); User registeredUser = userService.registerUser(user);
return new ResponseEntity<>(registeredUser, HttpStatus.CREATED); return new ResponseEntity<>(registeredUser, HttpStatus.CREATED);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {

@ -9,4 +9,6 @@ import java.util.Optional;
@Repository @Repository
public interface UserRepository extends JpaRepository<User, Long> { public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByLoginAccount(String loginAccount); Optional<User> findByLoginAccount(String loginAccount);
} }

@ -8,8 +8,10 @@ import com.example.demo.repository.UserSecurityQuestionRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -22,6 +24,9 @@ public class UserService {
private final UserSecurityQuestionRepository userSecurityQuestionRepository; private final UserSecurityQuestionRepository userSecurityQuestionRepository;
private final PasswordEncoder passwordEncoder; private final PasswordEncoder passwordEncoder;
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
@Autowired @Autowired
public UserService(UserRepository userRepository, public UserService(UserRepository userRepository,
ArticleRepository articleRepository, ArticleRepository articleRepository,
@ -31,6 +36,7 @@ public class UserService {
this.articleRepository = articleRepository; this.articleRepository = articleRepository;
this.userSecurityQuestionRepository = userSecurityQuestionRepository; this.userSecurityQuestionRepository = userSecurityQuestionRepository;
this.passwordEncoder = passwordEncoder; this.passwordEncoder = passwordEncoder;
logger.info("UserService dependencies injected successfully.");
} }
/** /**
@ -49,6 +55,11 @@ public class UserService {
throw new IllegalArgumentException("Password cannot be null or empty."); throw new IllegalArgumentException("Password cannot be null or empty.");
} }
// 设置默认 accountType 如果未指定或无效
if (user.getAccountType() == null || !Arrays.asList(User.AccountType.USER, User.AccountType.ADMIN).contains(user.getAccountType())) {
user.setAccountType(User.AccountType.USER);
}
// 初始化 authorityStrings 和 securityQuestions 集合为空集合 // 初始化 authorityStrings 和 securityQuestions 集合为空集合
if (user.getAuthorityStrings() == null) { if (user.getAuthorityStrings() == null) {
user.setAuthorityStrings(Collections.emptySet()); user.setAuthorityStrings(Collections.emptySet());
@ -68,6 +79,17 @@ public class UserService {
return userRepository.save(user); return userRepository.save(user);
} }
/**
*
*
* @param loginAccount
* @param password
* @return Optional
*/
public Optional<User> loginUser(String loginAccount, String password) {
return userRepository.findByLoginAccount(loginAccount)
.filter(user -> passwordEncoder.matches(password, user.getPassword()));
}
/** /**
* *
@ -136,9 +158,9 @@ public class UserService {
/** /**
* *
* *
* @param loginAccount * @param loginAccount
* @param currentPassword * @param currentPassword
* @param newPassword * @param newPassword
*/ */
public void resetPasswordForLoggedInUser(String loginAccount, String currentPassword, String newPassword) { public void resetPasswordForLoggedInUser(String loginAccount, String currentPassword, String newPassword) {
userRepository.findByLoginAccount(loginAccount).ifPresentOrElse( userRepository.findByLoginAccount(loginAccount).ifPresentOrElse(
@ -167,7 +189,7 @@ public class UserService {
/** /**
* *
* *
* @param loginAccount * @param loginAccount
* @param securityQuestions * @param securityQuestions
*/ */
public void addSecurityQuestions(String loginAccount, Set<UserSecurityQuestion> securityQuestions) { public void addSecurityQuestions(String loginAccount, Set<UserSecurityQuestion> securityQuestions) {
@ -192,7 +214,7 @@ public class UserService {
/** /**
* *
* *
* @param loginAccount * @param loginAccount
* @param securityQuestions * @param securityQuestions
*/ */
public void updateSecurityQuestions(String loginAccount, Set<UserSecurityQuestion> securityQuestions) { public void updateSecurityQuestions(String loginAccount, Set<UserSecurityQuestion> securityQuestions) {

@ -1,10 +1,10 @@
-- 插入测试用户 -- 插入测试用户
INSERT INTO Users (account_type, nickname, signature, login_account, password, birthday, created_at, updated_at, login_status) INSERT INTO Users (account_type, nickname, signature, login_account, password, birthday, created_at, updated_at, login_status)
VALUES ('USER', 'testuser', 'Just a test user', 'user@example.com', '123456', '1990-01-01 00:00:00', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, TRUE); VALUES ('USER', 'testuser', 'Just a test user', 'user@example.com', '123456', '1990-01-01 00:00:00', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 1);
-- 插入测试管理员 -- 插入测试管理员
INSERT INTO Users (account_type, nickname, signature, login_account, password, birthday, created_at, updated_at, login_status) INSERT INTO Users (account_type, nickname, signature, login_account, password, birthday, created_at, updated_at, login_status)
VALUES ('ADMIN', 'admin', 'Administrator account', 'admin@example.com', '123456', '1985-05-05 00:00:00', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, TRUE); VALUES ('ADMIN', 'admin', 'Administrator account', 'admin@example.com', '123456', '1985-05-05 00:00:00', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 1);
-- 插入权限信息 -- 插入权限信息
INSERT INTO user_authorities (user_id, authority) VALUES (1, 'ROLE_USER'); INSERT INTO user_authorities (user_id, authority) VALUES (1, 'ROLE_USER');

Loading…
Cancel
Save