diff --git a/pom.xml b/pom.xml
index 1dc1ee3..1290dc9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -177,7 +177,7 @@
top.fatweb
avatar-generator
- 1.0.0-SNAPSHOT
+ 1.1.0
diff --git a/src/main/kotlin/top/fatweb/api/config/InitConfig.kt b/src/main/kotlin/top/fatweb/api/config/InitConfig.kt
index 5d3f6ab..3efccb6 100644
--- a/src/main/kotlin/top/fatweb/api/config/InitConfig.kt
+++ b/src/main/kotlin/top/fatweb/api/config/InitConfig.kt
@@ -10,6 +10,7 @@ import org.springframework.stereotype.Component
import top.fatweb.api.entity.permission.User
import top.fatweb.api.entity.permission.UserInfo
import top.fatweb.api.properties.AdminProperties
+import top.fatweb.api.service.api.v1.IAvatarService
import top.fatweb.api.service.permission.IUserInfoService
import top.fatweb.api.service.permission.IUserService
@@ -24,7 +25,8 @@ import top.fatweb.api.service.permission.IUserService
class InitConfig(
private val userService: IUserService,
private val userInfoService: IUserInfoService,
- private val passwordEncoder: PasswordEncoder
+ private val passwordEncoder: PasswordEncoder,
+ private val avatarService: IAvatarService
) {
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
@@ -49,6 +51,7 @@ class InitConfig(
val userInfo = UserInfo().apply {
userId = 0
nickname = AdminProperties.nickname
+ avatar = avatarService.githubBase64(null).base64
email = AdminProperties.email
}
diff --git a/src/main/kotlin/top/fatweb/api/controller/api/v1/AvatarController.kt b/src/main/kotlin/top/fatweb/api/controller/api/v1/AvatarController.kt
index e42f486..bfd2808 100644
--- a/src/main/kotlin/top/fatweb/api/controller/api/v1/AvatarController.kt
+++ b/src/main/kotlin/top/fatweb/api/controller/api/v1/AvatarController.kt
@@ -8,12 +8,12 @@ import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
+import top.fatweb.api.entity.common.ResponseCode
import top.fatweb.api.entity.common.ResponseResult
import top.fatweb.api.param.api.v1.avatar.AvatarBaseParam
-import top.fatweb.api.param.api.v1.avatar.AvatarEightBitParam
import top.fatweb.api.param.api.v1.avatar.AvatarGitHubParam
import top.fatweb.api.service.api.v1.IAvatarService
-import top.fatweb.api.vo.api.v1.avatar.DefaultBase64Vo
+import top.fatweb.api.vo.api.v1.avatar.AvatarBase64Vo
/**
* Avatar controller
@@ -27,10 +27,45 @@ import top.fatweb.api.vo.api.v1.avatar.DefaultBase64Vo
class AvatarController(
private val avatarService: IAvatarService
) {
- @Operation(summary = "获取默认随机头像")
- @GetMapping
- fun getDefault(@PathVariable apiVersion: String): ResponseResult {
- return ResponseResult.success(data = avatarService.getDefault())
+ @Operation(summary = "获取随机头像")
+ @GetMapping(produces = [MediaType.IMAGE_PNG_VALUE])
+ fun getDefault(@PathVariable apiVersion: String, @Valid avatarBaseParam: AvatarBaseParam?): ByteArray {
+ return when ((1..4).random()) {
+ 1 -> avatarService.triangle(avatarBaseParam)
+ 2 -> avatarService.square(avatarBaseParam)
+ 3 -> avatarService.identicon(avatarBaseParam)
+ else -> avatarService.github(AvatarGitHubParam().apply {
+ seed = avatarBaseParam?.seed
+ size = avatarBaseParam?.size
+ margin = avatarBaseParam?.margin
+ padding = avatarBaseParam?.padding
+ colors = avatarBaseParam?.colors
+ background = avatarBaseParam?.background
+ })
+ }
+ }
+
+ @Operation(summary = "获取随机头像 Base64")
+ @GetMapping("base64")
+ fun getDefaultBase64(
+ @PathVariable apiVersion: String,
+ @Valid avatarBaseParam: AvatarBaseParam?
+ ): ResponseResult {
+ return ResponseResult.success(
+ ResponseCode.API_AVATAR_SUCCESS, data = when ((1..4).random()) {
+ 1 -> avatarService.triangleBase64(avatarBaseParam)
+ 2 -> avatarService.squareBase64(avatarBaseParam)
+ 3 -> avatarService.identiconBase64(avatarBaseParam)
+ else -> avatarService.githubBase64(AvatarGitHubParam().apply {
+ seed = avatarBaseParam?.seed
+ size = avatarBaseParam?.size
+ margin = avatarBaseParam?.margin
+ padding = avatarBaseParam?.padding
+ colors = avatarBaseParam?.colors
+ background = avatarBaseParam?.background
+ })
+ }
+ )
}
@Operation(summary = "三角形头像")
@@ -39,29 +74,57 @@ class AvatarController(
return avatarService.triangle(avatarBaseParam)
}
+ @Operation(summary = "三角形头像 Base64")
+ @GetMapping("/triangle/base64")
+ fun triangleBase64(@PathVariable apiVersion: String, @Valid avatarBaseParam: AvatarBaseParam?): ResponseResult {
+ return ResponseResult.success(
+ ResponseCode.API_AVATAR_SUCCESS,
+ data = avatarService.triangleBase64(avatarBaseParam)
+ )
+ }
+
@Operation(summary = "正方形头像")
@GetMapping("/square", produces = [MediaType.IMAGE_PNG_VALUE])
fun square(@PathVariable apiVersion: String, @Valid avatarBaseParam: AvatarBaseParam?): ByteArray {
return avatarService.square(avatarBaseParam)
}
+ @Operation(summary = "正方形头像 Base64")
+ @GetMapping("/square/base64")
+ fun squareBase64(@PathVariable apiVersion: String, @Valid avatarBaseParam: AvatarBaseParam?): ResponseResult {
+ return ResponseResult.success(
+ ResponseCode.API_AVATAR_SUCCESS,
+ data = avatarService.squareBase64(avatarBaseParam)
+ )
+ }
+
@Operation(summary = "Identicon 头像")
@GetMapping("/identicon", produces = [MediaType.IMAGE_PNG_VALUE])
fun identicon(@PathVariable apiVersion: String, @Valid avatarBaseParam: AvatarBaseParam?): ByteArray {
return avatarService.identicon(avatarBaseParam)
}
+ @Operation(summary = "Identicon 头像 Base64")
+ @GetMapping("/identicon/base64")
+ fun identiconBase64(@PathVariable apiVersion: String, @Valid avatarBaseParam: AvatarBaseParam?): ResponseResult {
+ return ResponseResult.success(
+ ResponseCode.API_AVATAR_SUCCESS,
+ data = avatarService.identiconBase64(avatarBaseParam)
+ )
+ }
+
@Operation(summary = "GitHub 头像")
@GetMapping("/github", produces = [MediaType.IMAGE_PNG_VALUE])
fun github(@PathVariable apiVersion: String, @Valid avatarGitHubParam: AvatarGitHubParam?): ByteArray {
return avatarService.github(avatarGitHubParam)
}
-/*
- @Operation(summary = "8 Bit 头像")
- @GetMapping("/8bit", produces = [MediaType.IMAGE_PNG_VALUE])
- fun eightBit(@PathVariable apiVersion: String, @Valid avatarEightBitParam: AvatarEightBitParam): ByteArray {
- return avatarService.eightBit(avatarEightBitParam)
+ @Operation(summary = "GitHub 头像 Base64")
+ @GetMapping("/github/base64")
+ fun githubBase64(@PathVariable apiVersion: String, @Valid avatarGitHubParam: AvatarGitHubParam?): ResponseResult {
+ return ResponseResult.success(
+ ResponseCode.API_AVATAR_SUCCESS,
+ data = avatarService.githubBase64(avatarGitHubParam)
+ )
}
-*/
}
\ No newline at end of file
diff --git a/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt b/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt
index 4a3d09f..e048715 100644
--- a/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt
+++ b/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt
@@ -37,6 +37,7 @@ enum class ResponseCode(val code: Int) {
DATABASE_EXECUTE_ERROR(BusinessCode.DATABASE, 40),
DATABASE_DUPLICATE_KEY(BusinessCode.DATABASE, 45),
+ API_AVATAR_SUCCESS(BusinessCode.API_AVATAR, 0),
API_AVATAR_ERROR(BusinessCode.API_AVATAR, 5);
constructor(businessCode: BusinessCode, code: Int) : this(businessCode.code * 100 + code)
diff --git a/src/main/kotlin/top/fatweb/api/param/api/v1/avatar/AvatarGitHubParam.kt b/src/main/kotlin/top/fatweb/api/param/api/v1/avatar/AvatarGitHubParam.kt
index 9c74c1c..a431151 100644
--- a/src/main/kotlin/top/fatweb/api/param/api/v1/avatar/AvatarGitHubParam.kt
+++ b/src/main/kotlin/top/fatweb/api/param/api/v1/avatar/AvatarGitHubParam.kt
@@ -8,6 +8,6 @@ data class AvatarGitHubParam(
@field:Max(1000, message = "Element size must be less than or equal to 1000")
val elementSize: Int = 400,
- @Schema(description = "精确度", defaultValue = "3")
- val precision: Int = 3
+ @Schema(description = "精确度", defaultValue = "5")
+ val precision: Int = 5
) : AvatarBaseParam()
diff --git a/src/main/kotlin/top/fatweb/api/service/api/v1/AvatarServiceImpl.kt b/src/main/kotlin/top/fatweb/api/service/api/v1/AvatarServiceImpl.kt
index b35fd64..b29e2e3 100644
--- a/src/main/kotlin/top/fatweb/api/service/api/v1/AvatarServiceImpl.kt
+++ b/src/main/kotlin/top/fatweb/api/service/api/v1/AvatarServiceImpl.kt
@@ -4,7 +4,7 @@ import org.springframework.stereotype.Service
import top.fatweb.api.param.api.v1.avatar.AvatarBaseParam
import top.fatweb.api.param.api.v1.avatar.AvatarGitHubParam
import top.fatweb.api.util.NumberUtil
-import top.fatweb.api.vo.api.v1.avatar.DefaultBase64Vo
+import top.fatweb.api.vo.api.v1.avatar.AvatarBase64Vo
import top.fatweb.avatargenerator.GitHubAvatar
import top.fatweb.avatargenerator.IdenticonAvatar
import top.fatweb.avatargenerator.SquareAvatar
@@ -14,14 +14,9 @@ import java.awt.Color
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
+@OptIn(ExperimentalEncodingApi::class)
@Service
class AvatarServiceImpl : IAvatarService {
- @OptIn(ExperimentalEncodingApi::class)
- override fun getDefault(): DefaultBase64Vo {
- val avatar = GitHubAvatar.newAvatarBuilder(396, 5).build()
- val bytes = avatar.createAsPngBytes(1232132134543L)
- return DefaultBase64Vo(Base64.encode(bytes))
- }
override fun triangle(avatarBaseParam: AvatarBaseParam?): ByteArray {
val avatar = (
@@ -40,6 +35,9 @@ class AvatarServiceImpl : IAvatarService {
return avatar.createAsPngBytes(avatarBaseParam?.seed ?: NumberUtil.getRandomLong())
}
+ override fun triangleBase64(avatarBaseParam: AvatarBaseParam?) =
+ AvatarBase64Vo(Base64.encode(triangle(avatarBaseParam)))
+
override fun square(avatarBaseParam: AvatarBaseParam?): ByteArray {
val avatar = (
if (avatarBaseParam == null || avatarBaseParam.colors.isNullOrEmpty())
@@ -57,6 +55,9 @@ class AvatarServiceImpl : IAvatarService {
return avatar.createAsPngBytes(avatarBaseParam?.seed ?: NumberUtil.getRandomLong())
}
+ override fun squareBase64(avatarBaseParam: AvatarBaseParam?) =
+ AvatarBase64Vo(Base64.encode(square(avatarBaseParam)))
+
override fun identicon(avatarBaseParam: AvatarBaseParam?): ByteArray {
val avatar = IdenticonAvatar.newAvatarBuilder().apply {
avatarBaseParam?.size?.let { size(it, it) }
@@ -71,9 +72,12 @@ class AvatarServiceImpl : IAvatarService {
return avatar.createAsPngBytes(avatarBaseParam?.seed ?: NumberUtil.getRandomLong())
}
+ override fun identiconBase64(avatarBaseParam: AvatarBaseParam?) =
+ AvatarBase64Vo(Base64.encode(identicon(avatarBaseParam)))
+
override fun github(avatarGitHubParam: AvatarGitHubParam?): ByteArray {
val avatar = (avatarGitHubParam?.let { GitHubAvatar.newAvatarBuilder(it.elementSize, it.precision) }
- ?: let { GitHubAvatar.newAvatarBuilder() }).apply {
+ ?: let { GitHubAvatar.newAvatarBuilder(400, 5) }).apply {
avatarGitHubParam?.size?.let { size(it, it) }
avatarGitHubParam?.margin?.let { margin(it) }
avatarGitHubParam?.padding?.let { padding(it) }
@@ -86,33 +90,8 @@ class AvatarServiceImpl : IAvatarService {
return avatar.createAsPngBytes(avatarGitHubParam?.seed ?: NumberUtil.getRandomLong())
}
- /*
- override fun eightBit(avatarEightBitParam: AvatarEightBitParam?): ByteArray {
- val avatar = if (avatarEightBitParam?.gender?.equals("female") ?: false) {
- EightBitAvatar.newFemaleAvatarBuilder().apply {
- avatarEightBitParam?.size?.let { size(it, it) }
- avatarEightBitParam?.margin?.let { margin(it) }
- avatarEightBitParam?.padding?.let { padding(it) }
- if (avatarEightBitParam != null && !avatarEightBitParam.colors.isNullOrEmpty()) {
- color(decodeColor(avatarEightBitParam.colors!!.random()))
- }
- avatarEightBitParam?.background?.let { layers(ColorPaintBackgroundLayer(decodeColor(it))) }
- }.build()
- } else {
- EightBitAvatar.newMaleAvatarBuilder().apply {
- avatarEightBitParam?.size?.let { size(it, it) }
- avatarEightBitParam?.margin?.let { margin(it) }
- avatarEightBitParam?.padding?.let { padding(it) }
- if (avatarEightBitParam != null && !avatarEightBitParam.colors.isNullOrEmpty()) {
- color(decodeColor(avatarEightBitParam.colors!!.random()))
- }
- avatarEightBitParam?.background?.let { layers(ColorPaintBackgroundLayer(decodeColor(it))) }
- }.build()
- }
-
- return avatar.createAsPngBytes(avatarEightBitParam?.seed ?: NumberUtil.getRandomLong())
- }
- */
+ override fun githubBase64(avatarGitHubParam: AvatarGitHubParam?) =
+ AvatarBase64Vo(Base64.encode(github(avatarGitHubParam)))
fun decodeColor(nm: String): Color {
return if (Regex("^#[0-9a-fA-F]{6}$").matches(nm)) {
diff --git a/src/main/kotlin/top/fatweb/api/service/api/v1/IAvatarService.kt b/src/main/kotlin/top/fatweb/api/service/api/v1/IAvatarService.kt
index 80cae76..0245fbf 100644
--- a/src/main/kotlin/top/fatweb/api/service/api/v1/IAvatarService.kt
+++ b/src/main/kotlin/top/fatweb/api/service/api/v1/IAvatarService.kt
@@ -1,21 +1,26 @@
package top.fatweb.api.service.api.v1
import top.fatweb.api.param.api.v1.avatar.AvatarBaseParam
-import top.fatweb.api.param.api.v1.avatar.AvatarEightBitParam
import top.fatweb.api.param.api.v1.avatar.AvatarGitHubParam
-import top.fatweb.api.vo.api.v1.avatar.DefaultBase64Vo
+import top.fatweb.api.vo.api.v1.avatar.AvatarBase64Vo
interface IAvatarService {
- fun getDefault(): DefaultBase64Vo
-
fun triangle(avatarBaseParam: AvatarBaseParam?): ByteArray
+ fun triangleBase64(avatarBaseParam: AvatarBaseParam?): AvatarBase64Vo
+
fun square(avatarBaseParam: AvatarBaseParam?): ByteArray
+ fun squareBase64(avatarBaseParam: AvatarBaseParam?): AvatarBase64Vo
+
fun identicon(avatarBaseParam: AvatarBaseParam?): ByteArray
+ fun identiconBase64(avatarBaseParam: AvatarBaseParam?): AvatarBase64Vo
+
fun github(avatarGitHubParam: AvatarGitHubParam?): ByteArray
+ fun githubBase64(avatarGitHubParam: AvatarGitHubParam?): AvatarBase64Vo
+
// fun eightBit(avatarEightBitParam: AvatarEightBitParam?): ByteArray
}
\ No newline at end of file
diff --git a/src/main/kotlin/top/fatweb/api/vo/api/v1/avatar/DefaultBase64Vo.kt b/src/main/kotlin/top/fatweb/api/vo/api/v1/avatar/AvatarBase64Vo.kt
similarity index 64%
rename from src/main/kotlin/top/fatweb/api/vo/api/v1/avatar/DefaultBase64Vo.kt
rename to src/main/kotlin/top/fatweb/api/vo/api/v1/avatar/AvatarBase64Vo.kt
index 4982d96..4560ef1 100644
--- a/src/main/kotlin/top/fatweb/api/vo/api/v1/avatar/DefaultBase64Vo.kt
+++ b/src/main/kotlin/top/fatweb/api/vo/api/v1/avatar/AvatarBase64Vo.kt
@@ -3,13 +3,13 @@ package top.fatweb.api.vo.api.v1.avatar
import io.swagger.v3.oas.annotations.media.Schema
/**
- * Default base64 value object
+ * Avatar base64 value object
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
-@Schema(description = "默认随机头像 Base64 返回参数")
-data class DefaultBase64Vo(
+@Schema(description = "头像 Base64 返回参数")
+data class AvatarBase64Vo(
@Schema(description = "base64")
val base64: String?
)
diff --git a/src/test/kotlin/top/fatweb/api/FatWebApiApplicationTests.kt b/src/test/kotlin/top/fatweb/api/FatWebApiApplicationTests.kt
index 4800eaf..929c673 100644
--- a/src/test/kotlin/top/fatweb/api/FatWebApiApplicationTests.kt
+++ b/src/test/kotlin/top/fatweb/api/FatWebApiApplicationTests.kt
@@ -10,9 +10,6 @@ import top.fatweb.api.properties.SecurityProperties
import top.fatweb.api.util.ByteUtil
import top.fatweb.api.util.JwtUtil
import top.fatweb.api.util.StrUtil
-import top.fatweb.avatargenerator.GitHubAvatar
-import kotlin.io.encoding.Base64
-import kotlin.io.encoding.ExperimentalEncodingApi
@ExtendWith(SpringExtension::class)
@@ -45,14 +42,6 @@ class FatWebApiApplicationTests {
assertEquals("1.5MiB", ByteUtil.formatByteSize(1 * 1024 * 1024 + 512 * 1024))
}
- @OptIn(ExperimentalEncodingApi::class)
- @Test
- fun name() {
- val avatar = GitHubAvatar.newAvatarBuilder(396, 5).build()
- val bytes = avatar.createAsPngBytes(1232132134543L)
- logger.info(Base64.encode(bytes))
- }
-
@Test
fun upperToUnderLetterTest() {
assertEquals("create_time", StrUtil.upperToUnderLetter("createTime"))