2025-11-28 23:30:49 +08:00
|
|
|
package handler
|
|
|
|
|
|
|
|
|
|
import (
|
2025-12-02 19:43:39 +08:00
|
|
|
"carrotskin/internal/container"
|
2025-11-28 23:30:49 +08:00
|
|
|
"carrotskin/internal/model"
|
|
|
|
|
"carrotskin/internal/types"
|
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-02 19:43:39 +08:00
|
|
|
// TextureHandler 材质处理器(依赖注入版本)
|
|
|
|
|
type TextureHandler struct {
|
|
|
|
|
container *container.Container
|
|
|
|
|
logger *zap.Logger
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewTextureHandler 创建TextureHandler实例
|
|
|
|
|
func NewTextureHandler(c *container.Container) *TextureHandler {
|
|
|
|
|
return &TextureHandler{
|
|
|
|
|
container: c,
|
|
|
|
|
logger: c.Logger,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get 获取材质详情
|
2025-12-26 01:15:17 +08:00
|
|
|
// @Summary 获取材质详情
|
|
|
|
|
// @Description 获取指定ID的材质详细信息
|
|
|
|
|
// @Tags texture
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Param id path int true "材质ID"
|
|
|
|
|
// @Success 200 {object} model.Response{data=types.TextureInfo} "获取成功"
|
|
|
|
|
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
|
|
|
|
// @Failure 404 {object} model.ErrorResponse "材质不存在"
|
|
|
|
|
// @Router /api/v1/texture/{id} [get]
|
2025-12-02 19:43:39 +08:00
|
|
|
func (h *TextureHandler) Get(c *gin.Context) {
|
2025-12-02 10:33:19 +08:00
|
|
|
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondBadRequest(c, "无效的材质ID", err)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 22:52:33 +08:00
|
|
|
texture, err := h.container.TextureService.GetByID(c.Request.Context(), id)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondNotFound(c, err.Error())
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondSuccess(c, TextureToTextureInfo(texture))
|
2025-11-28 23:30:49 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-02 19:43:39 +08:00
|
|
|
// Search 搜索材质
|
2025-12-26 01:15:17 +08:00
|
|
|
// @Summary 搜索材质
|
|
|
|
|
// @Description 搜索材质列表,支持关键词、类型、公开性筛选和分页
|
|
|
|
|
// @Tags texture
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Param keyword query string false "关键词"
|
|
|
|
|
// @Param type query string false "材质类型 (SKIN/CAPE)"
|
|
|
|
|
// @Param public_only query boolean false "仅显示公开材质"
|
|
|
|
|
// @Param page query int false "页码" default(1)
|
|
|
|
|
// @Param page_size query int false "每页数量" default(20)
|
|
|
|
|
// @Success 200 {object} model.Response{data=map[string]interface{}} "获取成功"
|
|
|
|
|
// @Failure 500 {object} model.ErrorResponse "服务器错误"
|
|
|
|
|
// @Router /api/v1/texture [get]
|
2025-12-02 19:43:39 +08:00
|
|
|
func (h *TextureHandler) Search(c *gin.Context) {
|
2025-11-28 23:30:49 +08:00
|
|
|
keyword := c.Query("keyword")
|
|
|
|
|
textureTypeStr := c.Query("type")
|
|
|
|
|
publicOnly := c.Query("public_only") == "true"
|
|
|
|
|
|
2025-12-02 17:40:39 +08:00
|
|
|
page := parseIntWithDefault(c.DefaultQuery("page", "1"), 1)
|
|
|
|
|
pageSize := parseIntWithDefault(c.DefaultQuery("page_size", "20"), 20)
|
2025-11-28 23:30:49 +08:00
|
|
|
|
|
|
|
|
var textureType model.TextureType
|
|
|
|
|
switch textureTypeStr {
|
|
|
|
|
case "SKIN":
|
|
|
|
|
textureType = model.TextureTypeSkin
|
|
|
|
|
case "CAPE":
|
|
|
|
|
textureType = model.TextureTypeCape
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 22:52:33 +08:00
|
|
|
textures, total, err := h.container.TextureService.Search(c.Request.Context(), keyword, textureType, publicOnly, page, pageSize)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 19:43:39 +08:00
|
|
|
h.logger.Error("搜索材质失败", zap.String("keyword", keyword), zap.Error(err))
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondServerError(c, "搜索材质失败", err)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-04 20:07:30 +08:00
|
|
|
// 返回格式:
|
|
|
|
|
// {
|
|
|
|
|
// "code": 200,
|
|
|
|
|
// "message": "操作成功",
|
|
|
|
|
// "data": {
|
|
|
|
|
// "list": [...],
|
|
|
|
|
// "total": 1,
|
|
|
|
|
// "page": 1,
|
|
|
|
|
// "per_page": 5
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
RespondSuccess(c, gin.H{
|
|
|
|
|
"list": TexturesToTextureInfos(textures),
|
|
|
|
|
"total": total,
|
|
|
|
|
"page": page,
|
|
|
|
|
"per_page": pageSize,
|
|
|
|
|
})
|
2025-11-28 23:30:49 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-02 19:43:39 +08:00
|
|
|
// Update 更新材质
|
2025-12-26 01:15:17 +08:00
|
|
|
// @Summary 更新材质
|
|
|
|
|
// @Description 更新材质信息(名称、描述、公开性)
|
|
|
|
|
// @Tags texture
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Security BearerAuth
|
|
|
|
|
// @Param id path int true "材质ID"
|
|
|
|
|
// @Param request body types.UpdateTextureRequest true "更新信息"
|
|
|
|
|
// @Success 200 {object} model.Response{data=types.TextureInfo} "更新成功"
|
|
|
|
|
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
|
|
|
|
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
|
|
|
|
// @Router /api/v1/texture/{id} [put]
|
2025-12-02 19:43:39 +08:00
|
|
|
func (h *TextureHandler) Update(c *gin.Context) {
|
2025-12-02 10:33:19 +08:00
|
|
|
userID, ok := GetUserIDFromContext(c)
|
|
|
|
|
if !ok {
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 10:33:19 +08:00
|
|
|
textureID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondBadRequest(c, "无效的材质ID", err)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var req types.UpdateTextureRequest
|
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondBadRequest(c, "请求参数错误", err)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 22:52:33 +08:00
|
|
|
texture, err := h.container.TextureService.Update(c.Request.Context(), textureID, userID, req.Name, req.Description, req.IsPublic)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 19:43:39 +08:00
|
|
|
h.logger.Error("更新材质失败",
|
2025-12-02 10:33:19 +08:00
|
|
|
zap.Int64("user_id", userID),
|
2025-11-28 23:30:49 +08:00
|
|
|
zap.Int64("texture_id", textureID),
|
|
|
|
|
zap.Error(err),
|
|
|
|
|
)
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondForbidden(c, err.Error())
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondSuccess(c, TextureToTextureInfo(texture))
|
2025-11-28 23:30:49 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-02 19:43:39 +08:00
|
|
|
// Delete 删除材质
|
2025-12-26 01:15:17 +08:00
|
|
|
// @Summary 删除材质
|
|
|
|
|
// @Description 删除指定ID的材质
|
|
|
|
|
// @Tags texture
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Security BearerAuth
|
|
|
|
|
// @Param id path int true "材质ID"
|
|
|
|
|
// @Success 200 {object} model.Response "删除成功"
|
|
|
|
|
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
|
|
|
|
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
|
|
|
|
// @Router /api/v1/texture/{id} [delete]
|
2025-12-02 19:43:39 +08:00
|
|
|
func (h *TextureHandler) Delete(c *gin.Context) {
|
2025-12-02 10:33:19 +08:00
|
|
|
userID, ok := GetUserIDFromContext(c)
|
|
|
|
|
if !ok {
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 10:33:19 +08:00
|
|
|
textureID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondBadRequest(c, "无效的材质ID", err)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 22:52:33 +08:00
|
|
|
if err := h.container.TextureService.Delete(c.Request.Context(), textureID, userID); err != nil {
|
2025-12-02 19:43:39 +08:00
|
|
|
h.logger.Error("删除材质失败",
|
2025-12-02 10:33:19 +08:00
|
|
|
zap.Int64("user_id", userID),
|
2025-11-28 23:30:49 +08:00
|
|
|
zap.Int64("texture_id", textureID),
|
|
|
|
|
zap.Error(err),
|
|
|
|
|
)
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondForbidden(c, err.Error())
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondSuccess(c, nil)
|
2025-11-28 23:30:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ToggleFavorite 切换收藏状态
|
2025-12-26 01:15:17 +08:00
|
|
|
// @Summary 切换收藏状态
|
|
|
|
|
// @Description 收藏或取消收藏指定材质
|
|
|
|
|
// @Tags texture
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Security BearerAuth
|
|
|
|
|
// @Param id path int true "材质ID"
|
|
|
|
|
// @Success 200 {object} model.Response{data=map[string]bool} "操作成功"
|
|
|
|
|
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
|
|
|
|
// @Router /api/v1/texture/{id} [post]
|
2025-12-02 19:43:39 +08:00
|
|
|
func (h *TextureHandler) ToggleFavorite(c *gin.Context) {
|
2025-12-02 10:33:19 +08:00
|
|
|
userID, ok := GetUserIDFromContext(c)
|
|
|
|
|
if !ok {
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 10:33:19 +08:00
|
|
|
textureID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondBadRequest(c, "无效的材质ID", err)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 22:52:33 +08:00
|
|
|
isFavorited, err := h.container.TextureService.ToggleFavorite(c.Request.Context(), userID, textureID)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 19:43:39 +08:00
|
|
|
h.logger.Error("切换收藏状态失败",
|
2025-12-02 10:33:19 +08:00
|
|
|
zap.Int64("user_id", userID),
|
2025-11-28 23:30:49 +08:00
|
|
|
zap.Int64("texture_id", textureID),
|
|
|
|
|
zap.Error(err),
|
|
|
|
|
)
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondBadRequest(c, err.Error(), nil)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondSuccess(c, map[string]bool{"is_favorited": isFavorited})
|
2025-11-28 23:30:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetUserTextures 获取用户上传的材质列表
|
2025-12-26 01:15:17 +08:00
|
|
|
// @Summary 获取我的材质
|
|
|
|
|
// @Description 获取当前登录用户上传的材质列表
|
|
|
|
|
// @Tags texture
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Security BearerAuth
|
|
|
|
|
// @Param page query int false "页码" default(1)
|
|
|
|
|
// @Param page_size query int false "每页数量" default(20)
|
|
|
|
|
// @Success 200 {object} model.Response{data=map[string]interface{}} "获取成功"
|
|
|
|
|
// @Failure 500 {object} model.ErrorResponse "服务器错误"
|
|
|
|
|
// @Router /api/v1/texture/my [get]
|
2025-12-02 19:43:39 +08:00
|
|
|
func (h *TextureHandler) GetUserTextures(c *gin.Context) {
|
2025-12-02 10:33:19 +08:00
|
|
|
userID, ok := GetUserIDFromContext(c)
|
|
|
|
|
if !ok {
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 17:40:39 +08:00
|
|
|
page := parseIntWithDefault(c.DefaultQuery("page", "1"), 1)
|
|
|
|
|
pageSize := parseIntWithDefault(c.DefaultQuery("page_size", "20"), 20)
|
2025-11-28 23:30:49 +08:00
|
|
|
|
2025-12-02 22:52:33 +08:00
|
|
|
textures, total, err := h.container.TextureService.GetByUserID(c.Request.Context(), userID, page, pageSize)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 19:43:39 +08:00
|
|
|
h.logger.Error("获取用户材质列表失败", zap.Int64("user_id", userID), zap.Error(err))
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondServerError(c, "获取材质列表失败", err)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-04 20:07:30 +08:00
|
|
|
RespondSuccess(c, gin.H{
|
|
|
|
|
"list": TexturesToTextureInfos(textures),
|
|
|
|
|
"total": total,
|
|
|
|
|
"page": page,
|
|
|
|
|
"per_page": pageSize,
|
|
|
|
|
})
|
2025-11-28 23:30:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetUserFavorites 获取用户收藏的材质列表
|
2025-12-26 01:15:17 +08:00
|
|
|
// @Summary 获取我的收藏
|
|
|
|
|
// @Description 获取当前登录用户收藏的材质列表
|
|
|
|
|
// @Tags texture
|
|
|
|
|
// @Accept json
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Security BearerAuth
|
|
|
|
|
// @Param page query int false "页码" default(1)
|
|
|
|
|
// @Param page_size query int false "每页数量" default(20)
|
|
|
|
|
// @Success 200 {object} model.Response{data=map[string]interface{}} "获取成功"
|
|
|
|
|
// @Failure 500 {object} model.ErrorResponse "服务器错误"
|
|
|
|
|
// @Router /api/v1/texture/favorites [get]
|
2025-12-02 19:43:39 +08:00
|
|
|
func (h *TextureHandler) GetUserFavorites(c *gin.Context) {
|
2025-12-02 10:33:19 +08:00
|
|
|
userID, ok := GetUserIDFromContext(c)
|
|
|
|
|
if !ok {
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 17:40:39 +08:00
|
|
|
page := parseIntWithDefault(c.DefaultQuery("page", "1"), 1)
|
|
|
|
|
pageSize := parseIntWithDefault(c.DefaultQuery("page_size", "20"), 20)
|
2025-11-28 23:30:49 +08:00
|
|
|
|
2025-12-02 22:52:33 +08:00
|
|
|
textures, total, err := h.container.TextureService.GetUserFavorites(c.Request.Context(), userID, page, pageSize)
|
2025-11-28 23:30:49 +08:00
|
|
|
if err != nil {
|
2025-12-02 19:43:39 +08:00
|
|
|
h.logger.Error("获取用户收藏列表失败", zap.Int64("user_id", userID), zap.Error(err))
|
2025-12-02 10:33:19 +08:00
|
|
|
RespondServerError(c, "获取收藏列表失败", err)
|
2025-11-28 23:30:49 +08:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-04 20:07:30 +08:00
|
|
|
RespondSuccess(c, gin.H{
|
|
|
|
|
"list": TexturesToTextureInfos(textures),
|
|
|
|
|
"total": total,
|
|
|
|
|
"page": page,
|
|
|
|
|
"per_page": pageSize,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Upload 直接上传材质文件
|
2025-12-26 01:15:17 +08:00
|
|
|
// @Summary 上传材质
|
|
|
|
|
// @Description 上传图片文件创建新材质
|
|
|
|
|
// @Tags texture
|
|
|
|
|
// @Accept multipart/form-data
|
|
|
|
|
// @Produce json
|
|
|
|
|
// @Security BearerAuth
|
|
|
|
|
// @Param file formData file true "材质文件 (PNG)"
|
|
|
|
|
// @Param name formData string true "材质名称"
|
|
|
|
|
// @Param description formData string false "材质描述"
|
|
|
|
|
// @Param type formData string false "材质类型 (SKIN/CAPE)" default(SKIN)
|
|
|
|
|
// @Param is_public formData boolean false "是否公开" default(false)
|
|
|
|
|
// @Param is_slim formData boolean false "是否为纤细模型 (仅SKIN有效)" default(false)
|
|
|
|
|
// @Success 200 {object} model.Response{data=types.TextureInfo} "上传成功"
|
|
|
|
|
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
|
|
|
|
// @Router /api/v1/texture/upload [post]
|
2025-12-04 20:07:30 +08:00
|
|
|
func (h *TextureHandler) Upload(c *gin.Context) {
|
|
|
|
|
userID, ok := GetUserIDFromContext(c)
|
|
|
|
|
if !ok {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 解析multipart表单
|
|
|
|
|
if err := c.Request.ParseMultipartForm(32 << 20); err != nil { // 32MB
|
|
|
|
|
RespondBadRequest(c, "解析表单失败", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取文件
|
|
|
|
|
file, err := c.FormFile("file")
|
|
|
|
|
if err != nil {
|
|
|
|
|
RespondBadRequest(c, "获取文件失败", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 读取文件内容
|
|
|
|
|
src, err := file.Open()
|
|
|
|
|
if err != nil {
|
|
|
|
|
RespondBadRequest(c, "打开文件失败", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
defer src.Close()
|
|
|
|
|
|
|
|
|
|
fileData := make([]byte, file.Size)
|
|
|
|
|
if _, err := src.Read(fileData); err != nil {
|
|
|
|
|
RespondBadRequest(c, "读取文件失败", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取表单字段
|
|
|
|
|
name := c.PostForm("name")
|
|
|
|
|
if name == "" {
|
|
|
|
|
RespondBadRequest(c, "名称不能为空", nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
description := c.PostForm("description")
|
|
|
|
|
textureType := c.PostForm("type")
|
|
|
|
|
if textureType == "" {
|
|
|
|
|
textureType = "SKIN" // 默认值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isPublic := c.PostForm("is_public") == "true"
|
|
|
|
|
isSlim := c.PostForm("is_slim") == "true"
|
|
|
|
|
|
|
|
|
|
// 检查上传限制
|
|
|
|
|
maxTextures := h.container.UserService.GetMaxTexturesPerUser()
|
|
|
|
|
if err := h.container.TextureService.CheckUploadLimit(c.Request.Context(), userID, maxTextures); err != nil {
|
|
|
|
|
RespondBadRequest(c, err.Error(), nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 调用服务上传
|
|
|
|
|
texture, err := h.container.TextureService.UploadTexture(
|
|
|
|
|
c.Request.Context(),
|
|
|
|
|
userID,
|
|
|
|
|
name,
|
|
|
|
|
description,
|
|
|
|
|
textureType,
|
|
|
|
|
fileData,
|
|
|
|
|
file.Filename,
|
|
|
|
|
isPublic,
|
|
|
|
|
isSlim,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
h.logger.Error("上传材质失败",
|
|
|
|
|
zap.Int64("user_id", userID),
|
|
|
|
|
zap.String("file_name", file.Filename),
|
|
|
|
|
zap.Error(err),
|
|
|
|
|
)
|
|
|
|
|
RespondBadRequest(c, err.Error(), nil)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RespondSuccess(c, TextureToTextureInfo(texture))
|
2025-11-28 23:30:49 +08:00
|
|
|
}
|