Complete core functions #9
2
pom.xml
2
pom.xml
@@ -177,7 +177,7 @@
|
||||
<dependency>
|
||||
<groupId>top.fatweb</groupId>
|
||||
<artifactId>avatar-generator</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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<DefaultBase64Vo> {
|
||||
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<AvatarBase64Vo> {
|
||||
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<AvatarBase64Vo> {
|
||||
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<AvatarBase64Vo> {
|
||||
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<AvatarBase64Vo> {
|
||||
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<AvatarBase64Vo> {
|
||||
return ResponseResult.success(
|
||||
ResponseCode.API_AVATAR_SUCCESS,
|
||||
data = avatarService.githubBase64(avatarGitHubParam)
|
||||
)
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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?
|
||||
)
|
||||
@@ -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"))
|
||||
|
||||
Reference in New Issue
Block a user