feat: Add texture rendering endpoints and service methods
- Introduced new API endpoints for rendering textures, avatars, capes, and previews, enhancing the texture handling capabilities. - Implemented corresponding service methods in the TextureHandler to process rendering requests and return appropriate responses. - Updated the TextureRenderService interface to include methods for rendering textures, avatars, and capes, along with their respective parameters. - Enhanced error handling for invalid texture IDs and added support for different rendering types and formats. - Updated go.mod to include the webp library for image processing.
This commit is contained in:
@@ -108,6 +108,10 @@ func registerTextureRoutes(v1 *gin.RouterGroup, h *TextureHandler, jwtService *a
|
||||
// 公开路由(无需认证)
|
||||
textureGroup.GET("", h.Search)
|
||||
textureGroup.GET("/:id", h.Get)
|
||||
textureGroup.GET("/:id/render", h.RenderTexture) // type/front/back/full/head/isometric
|
||||
textureGroup.GET("/:id/avatar", h.RenderAvatar) // mode=2d/3d
|
||||
textureGroup.GET("/:id/cape", h.RenderCape)
|
||||
textureGroup.GET("/:id/preview", h.RenderPreview) // 自动根据类型预览
|
||||
|
||||
// 需要认证的路由
|
||||
textureAuth := textureGroup.Group("")
|
||||
|
||||
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"carrotskin/internal/container"
|
||||
"carrotskin/internal/model"
|
||||
"carrotskin/internal/service"
|
||||
"carrotskin/internal/types"
|
||||
"strconv"
|
||||
|
||||
@@ -171,6 +172,98 @@ func (h *TextureHandler) Search(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// RenderTexture 渲染皮肤/披风预览
|
||||
func (h *TextureHandler) RenderTexture(c *gin.Context) {
|
||||
textureID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
RespondBadRequest(c, "无效的材质ID", err)
|
||||
return
|
||||
}
|
||||
renderType := service.RenderType(c.DefaultQuery("type", string(service.RenderTypeIsometric)))
|
||||
size := parseIntWithDefault(c.DefaultQuery("size", "256"), 256)
|
||||
format := service.ImageFormat(c.DefaultQuery("format", string(service.ImageFormatPNG)))
|
||||
|
||||
result, err := h.container.TextureRenderService.RenderTexture(c.Request.Context(), textureID, renderType, size, format)
|
||||
if err != nil {
|
||||
RespondBadRequest(c, err.Error(), err)
|
||||
return
|
||||
}
|
||||
RespondSuccess(c, toRenderResponse(result))
|
||||
}
|
||||
|
||||
// RenderAvatar 渲染头像(2D/3D)
|
||||
func (h *TextureHandler) RenderAvatar(c *gin.Context) {
|
||||
textureID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
RespondBadRequest(c, "无效的材质ID", err)
|
||||
return
|
||||
}
|
||||
mode := service.AvatarMode(c.DefaultQuery("mode", string(service.AvatarMode2D)))
|
||||
size := parseIntWithDefault(c.DefaultQuery("size", "256"), 256)
|
||||
format := service.ImageFormat(c.DefaultQuery("format", string(service.ImageFormatPNG)))
|
||||
|
||||
result, err := h.container.TextureRenderService.RenderAvatar(c.Request.Context(), textureID, size, mode, format)
|
||||
if err != nil {
|
||||
RespondBadRequest(c, err.Error(), err)
|
||||
return
|
||||
}
|
||||
RespondSuccess(c, toRenderResponse(result))
|
||||
}
|
||||
|
||||
// RenderCape 渲染披风
|
||||
func (h *TextureHandler) RenderCape(c *gin.Context) {
|
||||
textureID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
RespondBadRequest(c, "无效的材质ID", err)
|
||||
return
|
||||
}
|
||||
size := parseIntWithDefault(c.DefaultQuery("size", "256"), 256)
|
||||
format := service.ImageFormat(c.DefaultQuery("format", string(service.ImageFormatPNG)))
|
||||
|
||||
result, err := h.container.TextureRenderService.RenderCape(c.Request.Context(), textureID, size, format)
|
||||
if err != nil {
|
||||
RespondBadRequest(c, err.Error(), err)
|
||||
return
|
||||
}
|
||||
RespondSuccess(c, toRenderResponse(result))
|
||||
}
|
||||
|
||||
// RenderPreview 自动选择预览(皮肤走等距,披风走披风渲染)
|
||||
func (h *TextureHandler) RenderPreview(c *gin.Context) {
|
||||
textureID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
RespondBadRequest(c, "无效的材质ID", err)
|
||||
return
|
||||
}
|
||||
size := parseIntWithDefault(c.DefaultQuery("size", "256"), 256)
|
||||
format := service.ImageFormat(c.DefaultQuery("format", string(service.ImageFormatPNG)))
|
||||
|
||||
result, err := h.container.TextureRenderService.RenderPreview(c.Request.Context(), textureID, size, format)
|
||||
if err != nil {
|
||||
RespondBadRequest(c, err.Error(), err)
|
||||
return
|
||||
}
|
||||
RespondSuccess(c, toRenderResponse(result))
|
||||
}
|
||||
|
||||
// toRenderResponse 转换为API响应
|
||||
func toRenderResponse(r *service.RenderResult) *types.RenderResponse {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
resp := &types.RenderResponse{
|
||||
URL: r.URL,
|
||||
ContentType: r.ContentType,
|
||||
ETag: r.ETag,
|
||||
Size: r.Size,
|
||||
}
|
||||
if !r.LastModified.IsZero() {
|
||||
t := r.LastModified
|
||||
resp.LastModified = &t
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// Update 更新材质
|
||||
func (h *TextureHandler) Update(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
|
||||
Reference in New Issue
Block a user