mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-22 22:21:09 +08:00
Introduce pluggable email and image upload
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package com.openisle.controller;
|
||||
|
||||
import com.openisle.model.User;
|
||||
import com.openisle.service.EmailService;
|
||||
import com.openisle.service.EmailSender;
|
||||
import com.openisle.service.JwtService;
|
||||
import com.openisle.service.UserService;
|
||||
import lombok.Data;
|
||||
@@ -42,7 +42,7 @@ curl -X POST http://localhost:8080/api/auth/login \
|
||||
public class AuthController {
|
||||
private final UserService userService;
|
||||
private final JwtService jwtService;
|
||||
private final EmailService emailService;
|
||||
private final EmailSender emailService;
|
||||
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<?> register(@RequestBody RegisterRequest req) {
|
||||
|
||||
53
src/main/java/com/openisle/controller/UserController.java
Normal file
53
src/main/java/com/openisle/controller/UserController.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package com.openisle.controller;
|
||||
|
||||
import com.openisle.model.User;
|
||||
import com.openisle.service.ImageUploader;
|
||||
import com.openisle.service.UserService;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
private final UserService userService;
|
||||
private final ImageUploader imageUploader;
|
||||
|
||||
@GetMapping("/me")
|
||||
public ResponseEntity<UserDto> me(Authentication auth) {
|
||||
User user = userService.findByUsername(auth.getName()).orElseThrow();
|
||||
return ResponseEntity.ok(toDto(user));
|
||||
}
|
||||
|
||||
@PostMapping("/me/avatar")
|
||||
public ResponseEntity<?> uploadAvatar(@RequestParam("file") MultipartFile file,
|
||||
Authentication auth) throws IOException {
|
||||
String url = imageUploader.upload(file.getBytes(), file.getOriginalFilename());
|
||||
userService.updateAvatar(auth.getName(), url);
|
||||
return ResponseEntity.ok(Map.of("url", url));
|
||||
}
|
||||
|
||||
private UserDto toDto(User user) {
|
||||
UserDto dto = new UserDto();
|
||||
dto.setId(user.getId());
|
||||
dto.setUsername(user.getUsername());
|
||||
dto.setEmail(user.getEmail());
|
||||
dto.setAvatar(user.getAvatar());
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class UserDto {
|
||||
private Long id;
|
||||
private String username;
|
||||
private String email;
|
||||
private String avatar;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,8 @@ public class User {
|
||||
|
||||
private String verificationCode;
|
||||
|
||||
private String avatar;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false)
|
||||
private Role role = Role.USER;
|
||||
|
||||
24
src/main/java/com/openisle/service/CosImageUploader.java
Normal file
24
src/main/java/com/openisle/service/CosImageUploader.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.openisle.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* ImageUploader implementation using Tencent Cloud COS.
|
||||
* For simplicity this demo just returns a URL composed of the base URL and file name.
|
||||
*/
|
||||
@Service
|
||||
public class CosImageUploader extends ImageUploader {
|
||||
|
||||
private final String baseUrl;
|
||||
|
||||
public CosImageUploader(@Value("${cos.base-url:https://example.com}") String baseUrl) {
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(byte[] data, String filename) {
|
||||
// In a real implementation you would call COS SDK here
|
||||
return baseUrl + "/" + filename;
|
||||
}
|
||||
}
|
||||
14
src/main/java/com/openisle/service/EmailSender.java
Normal file
14
src/main/java/com/openisle/service/EmailSender.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package com.openisle.service;
|
||||
|
||||
/**
|
||||
* Abstract email sender used to deliver emails.
|
||||
*/
|
||||
public abstract class EmailSender {
|
||||
/**
|
||||
* Send an email to a recipient.
|
||||
* @param to recipient email address
|
||||
* @param subject email subject
|
||||
* @param text email body
|
||||
*/
|
||||
public abstract void sendEmail(String to, String subject, String text);
|
||||
}
|
||||
14
src/main/java/com/openisle/service/ImageUploader.java
Normal file
14
src/main/java/com/openisle/service/ImageUploader.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package com.openisle.service;
|
||||
|
||||
/**
|
||||
* Abstract service for uploading images.
|
||||
*/
|
||||
public abstract class ImageUploader {
|
||||
/**
|
||||
* Upload an image and return its accessible URL.
|
||||
* @param data image binary data
|
||||
* @param filename name of the file
|
||||
* @return accessible URL of the uploaded file
|
||||
*/
|
||||
public abstract String upload(byte[] data, String filename);
|
||||
}
|
||||
@@ -12,13 +12,14 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class EmailService {
|
||||
public class ResendEmailSender extends EmailSender {
|
||||
|
||||
@Value("${resend.api.key}")
|
||||
private String apiKey;
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Override
|
||||
public void sendEmail(String to, String subject, String text) {
|
||||
String url = "https://api.resend.com/emails"; // hypothetical endpoint
|
||||
|
||||
@@ -78,4 +78,15 @@ public class UserService {
|
||||
.filter(User::isVerified)
|
||||
.filter(user -> passwordEncoder.matches(password, user.getPassword()));
|
||||
}
|
||||
|
||||
public Optional<User> findByUsername(String username) {
|
||||
return userRepository.findByUsername(username);
|
||||
}
|
||||
|
||||
public User updateAvatar(String username, String avatarUrl) {
|
||||
User user = userRepository.findByUsername(username)
|
||||
.orElseThrow(() -> new IllegalArgumentException("User not found"));
|
||||
user.setAvatar(avatarUrl);
|
||||
return userRepository.save(user);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user