feat: implement settings page and config management

This commit is contained in:
Tim
2025-07-07 20:41:52 +08:00
parent fbf0d9fe2f
commit 693d6d5e6b
7 changed files with 244 additions and 4 deletions

View File

@@ -0,0 +1,42 @@
package com.openisle.controller;
import com.openisle.model.PasswordStrength;
import com.openisle.model.PublishMode;
import com.openisle.service.PasswordValidator;
import com.openisle.service.PostService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/admin/config")
@RequiredArgsConstructor
public class AdminConfigController {
private final PostService postService;
private final PasswordValidator passwordValidator;
@GetMapping
public ConfigDto getConfig() {
ConfigDto dto = new ConfigDto();
dto.setPublishMode(postService.getPublishMode());
dto.setPasswordStrength(passwordValidator.getStrength());
return dto;
}
@PostMapping
public ConfigDto updateConfig(@RequestBody ConfigDto dto) {
if (dto.getPublishMode() != null) {
postService.setPublishMode(dto.getPublishMode());
}
if (dto.getPasswordStrength() != null) {
passwordValidator.setStrength(dto.getPasswordStrength());
}
return getConfig();
}
@Data
public static class ConfigDto {
private PublishMode publishMode;
private PasswordStrength passwordStrength;
}
}

View File

@@ -64,6 +64,13 @@ public class UserController {
return ResponseEntity.ok(Map.of("url", url));
}
@PutMapping("/me")
public ResponseEntity<UserDto> updateProfile(@RequestBody UpdateProfileDto dto,
Authentication auth) {
User user = userService.updateProfile(auth.getName(), dto.getUsername(), dto.getIntroduction());
return ResponseEntity.ok(toDto(user));
}
@GetMapping("/{username}")
public ResponseEntity<UserDto> getUser(@PathVariable String username) {
User user = userService.findByUsername(username).orElseThrow();
@@ -128,6 +135,8 @@ public class UserController {
dto.setUsername(user.getUsername());
dto.setEmail(user.getEmail());
dto.setAvatar(user.getAvatar());
dto.setRole(user.getRole().name());
dto.setIntroduction(user.getIntroduction());
dto.setFollowers(subscriptionService.countSubscribers(user.getUsername()));
dto.setFollowing(subscriptionService.countSubscribed(user.getUsername()));
return dto;
@@ -158,6 +167,8 @@ public class UserController {
private String username;
private String email;
private String avatar;
private String role;
private String introduction;
private long followers;
private long following;
}
@@ -179,6 +190,12 @@ public class UserController {
private Long postId;
}
@Data
private static class UpdateProfileDto {
private String username;
private String introduction;
}
@Data
private static class UserAggregateDto {
private UserDto user;

View File

@@ -37,6 +37,9 @@ public class User {
private String avatar;
@Column(length = 1000)
private String introduction;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Role role = Role.USER;

View File

@@ -7,12 +7,20 @@ import org.springframework.stereotype.Service;
@Service
public class PasswordValidator {
private final PasswordStrength strength;
private PasswordStrength strength;
public PasswordValidator(@Value("${app.password.strength:LOW}") PasswordStrength strength) {
this.strength = strength;
}
public PasswordStrength getStrength() {
return strength;
}
public void setStrength(PasswordStrength strength) {
this.strength = strength;
}
public void validate(String password) {
if (password == null || password.isEmpty()) {
throw new FieldException("password", "Password cannot be empty");

View File

@@ -24,7 +24,7 @@ public class PostService {
private final UserRepository userRepository;
private final CategoryRepository categoryRepository;
private final TagRepository tagRepository;
private final PublishMode publishMode;
private PublishMode publishMode;
private final NotificationService notificationService;
private final SubscriptionService subscriptionService;
@@ -45,6 +45,14 @@ public class PostService {
this.publishMode = publishMode;
}
public PublishMode getPublishMode() {
return publishMode;
}
public void setPublishMode(PublishMode publishMode) {
this.publishMode = publishMode;
}
public Post createPost(String username,
Long categoryId,
String title,

View File

@@ -94,4 +94,19 @@ public class UserService {
user.setAvatar(avatarUrl);
return userRepository.save(user);
}
public User updateProfile(String currentUsername, String newUsername, String introduction) {
User user = userRepository.findByUsername(currentUsername)
.orElseThrow(() -> new IllegalArgumentException("User not found"));
if (newUsername != null && !newUsername.equals(currentUsername)) {
userRepository.findByUsername(newUsername).ifPresent(u -> {
throw new FieldException("username", "User name already exists");
});
user.setUsername(newUsername);
}
if (introduction != null) {
user.setIntroduction(introduction);
}
return userRepository.save(user);
}
}