diff --git a/README.md b/README.md index f21bc7bd9..5a40441bc 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ OpenIsle 是一个使用 Spring Boot 和 Vue 3 构建的全栈开源社区平台 - 集成 OpenAI 提供的 Markdown 格式化功能 - 通过环境变量可调整密码强度、登录方式、保护码等多种配置 - 支持图片上传,默认使用腾讯云 COS 扩展 +- 默认头像使用 DiceBear Avatars,可通过 `AVATAR_STYLE` 和 `AVATAR_SIZE` 环境变量自定义主题和大小 - 浏览器推送通知,离开网站也能及时收到提醒 ## 🌟 项目优势 diff --git a/src/main/java/com/openisle/service/AvatarGenerator.java b/src/main/java/com/openisle/service/AvatarGenerator.java new file mode 100644 index 000000000..92895dae4 --- /dev/null +++ b/src/main/java/com/openisle/service/AvatarGenerator.java @@ -0,0 +1,25 @@ +package com.openisle.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +@Service +public class AvatarGenerator { + + @Value("${app.avatar.base-url:https://api.dicebear.com/6.x}") + private String baseUrl; + + @Value("${app.avatar.style:identicon}") + private String style; + + @Value("${app.avatar.size:64}") + private int size; + + public String generate(String seed) { + String encoded = URLEncoder.encode(seed, StandardCharsets.UTF_8); + return String.format("%s/%s/png?seed=%s&size=%d", baseUrl, style, encoded, size); + } +} diff --git a/src/main/java/com/openisle/service/GithubAuthService.java b/src/main/java/com/openisle/service/GithubAuthService.java index 52e010c3c..739770944 100644 --- a/src/main/java/com/openisle/service/GithubAuthService.java +++ b/src/main/java/com/openisle/service/GithubAuthService.java @@ -10,6 +10,7 @@ import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import org.springframework.web.client.HttpClientErrorException; +import com.openisle.service.AvatarGenerator; import java.util.Collections; import java.util.Map; @@ -21,6 +22,7 @@ import java.util.Optional; public class GithubAuthService { private final UserRepository userRepository; private final RestTemplate restTemplate = new RestTemplate(); + private final AvatarGenerator avatarGenerator; @Value("${github.client-id:}") private String clientId; @@ -117,7 +119,7 @@ public class GithubAuthService { if (avatar != null) { user.setAvatar(avatar); } else { - user.setAvatar("https://github.com/" + finalUsername + ".png"); + user.setAvatar(avatarGenerator.generate(finalUsername)); } return userRepository.save(user); } diff --git a/src/main/java/com/openisle/service/GoogleAuthService.java b/src/main/java/com/openisle/service/GoogleAuthService.java index 56b0778ec..89cee5951 100644 --- a/src/main/java/com/openisle/service/GoogleAuthService.java +++ b/src/main/java/com/openisle/service/GoogleAuthService.java @@ -10,6 +10,7 @@ import com.openisle.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import com.openisle.service.AvatarGenerator; import java.util.Collections; import java.util.Optional; @@ -19,6 +20,7 @@ import java.util.Optional; public class GoogleAuthService { private final UserRepository userRepository; + private final AvatarGenerator avatarGenerator; @Value("${google.client-id:}") private String clientId; @@ -70,7 +72,7 @@ public class GoogleAuthService { if (avatar != null) { user.setAvatar(avatar); } else { - user.setAvatar("https://github.com/identicons/" + username + ".png"); + user.setAvatar(avatarGenerator.generate(username)); } return userRepository.save(user); } diff --git a/src/main/java/com/openisle/service/UserService.java b/src/main/java/com/openisle/service/UserService.java index 05d2029e4..5872791c8 100644 --- a/src/main/java/com/openisle/service/UserService.java +++ b/src/main/java/com/openisle/service/UserService.java @@ -4,6 +4,7 @@ import com.openisle.model.User; import com.openisle.model.Role; import com.openisle.service.PasswordValidator; import com.openisle.service.UsernameValidator; +import com.openisle.service.AvatarGenerator; import com.openisle.exception.FieldException; import com.openisle.repository.UserRepository; import lombok.RequiredArgsConstructor; @@ -22,6 +23,7 @@ public class UserService { private final UsernameValidator usernameValidator; private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); private final ImageUploader imageUploader; + private final AvatarGenerator avatarGenerator; public User register(String username, String email, String password, String reason, com.openisle.model.RegisterMode mode) { usernameValidator.validate(username); @@ -66,7 +68,7 @@ public class UserService { user.setRole(Role.USER); user.setVerified(false); user.setVerificationCode(genCode()); - user.setAvatar("https://github.com/identicons/" + username + ".png"); + user.setAvatar(avatarGenerator.generate(username)); user.setRegisterReason(reason); user.setApproved(mode == com.openisle.model.RegisterMode.DIRECT); return userRepository.save(user); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f1e2b2b30..01af18f2c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -24,6 +24,11 @@ app.register.mode=${REGISTER_MODE:WHITELIST} app.upload.check-type=${UPLOAD_CHECK_TYPE:true} app.upload.max-size=${UPLOAD_MAX_SIZE:5242880} +# Default avatar generator configuration +app.avatar.style=${AVATAR_STYLE:identicon} +app.avatar.size=${AVATAR_SIZE:64} +app.avatar.base-url=${AVATAR_BASE_URL:https://api.dicebear.com/6.x} + # Default list size for user posts and replies app.user.posts-limit=${USER_POSTS_LIMIT:10} app.user.replies-limit=${USER_REPLIES_LIMIT:50}