feat: use DiceBear for default avatars

This commit is contained in:
Tim
2025-07-30 14:24:49 +08:00
parent b2779759c0
commit 1fcdff6203
6 changed files with 40 additions and 3 deletions

View File

@@ -31,6 +31,7 @@ OpenIsle 是一个使用 Spring Boot 和 Vue 3 构建的全栈开源社区平台
- 集成 OpenAI 提供的 Markdown 格式化功能
- 通过环境变量可调整密码强度、登录方式、保护码等多种配置
- 支持图片上传,默认使用腾讯云 COS 扩展
- 默认头像使用 DiceBear Avatars可通过 `AVATAR_STYLE``AVATAR_SIZE` 环境变量自定义主题和大小
- 浏览器推送通知,离开网站也能及时收到提醒
## 🌟 项目优势

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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}