解决合并后出现的问题,为swagger提供禁用选项,暂时移除wiki
This commit is contained in:
@@ -34,11 +34,11 @@ type SetUserRoleRequest struct {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body SetUserRoleRequest true "设置角色请求"
|
||||
// @Success 200 {object} model.Response
|
||||
// @Failure 400 {object} model.Response
|
||||
// @Failure 403 {object} model.Response
|
||||
// @Success 200 {object} model.Response{data=map[string]interface{}} "更新成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
||||
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/users/role [put]
|
||||
// @Router /api/v1/admin/users/role [put]
|
||||
func (h *AdminHandler) SetUserRole(c *gin.Context) {
|
||||
var req SetUserRoleRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -99,10 +99,10 @@ func (h *AdminHandler) SetUserRole(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param page query int false "页码" default(1)
|
||||
// @Param page_size query int false "每页数量" default(20)
|
||||
// @Success 200 {object} model.Response
|
||||
// @Failure 403 {object} model.Response
|
||||
// @Success 200 {object} model.Response{data=map[string]interface{}} "获取成功"
|
||||
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/users [get]
|
||||
// @Router /api/v1/admin/users [get]
|
||||
func (h *AdminHandler) GetUserList(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||
@@ -152,10 +152,10 @@ func (h *AdminHandler) GetUserList(c *gin.Context) {
|
||||
// @Tags Admin
|
||||
// @Produce json
|
||||
// @Param id path int true "用户ID"
|
||||
// @Success 200 {object} model.Response
|
||||
// @Failure 404 {object} model.Response
|
||||
// @Success 200 {object} model.Response{data=map[string]interface{}} "获取成功"
|
||||
// @Failure 404 {object} model.ErrorResponse "用户不存在"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/users/{id} [get]
|
||||
// @Router /api/v1/admin/users/{id} [get]
|
||||
func (h *AdminHandler) GetUserDetail(c *gin.Context) {
|
||||
userID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -201,10 +201,10 @@ type SetUserStatusRequest struct {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body SetUserStatusRequest true "设置状态请求"
|
||||
// @Success 200 {object} model.Response
|
||||
// @Failure 400 {object} model.Response
|
||||
// @Success 200 {object} model.Response{data=map[string]interface{}} "更新成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/users/status [put]
|
||||
// @Router /api/v1/admin/users/status [put]
|
||||
func (h *AdminHandler) SetUserStatus(c *gin.Context) {
|
||||
var req SetUserStatusRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -266,10 +266,10 @@ func (h *AdminHandler) SetUserStatus(c *gin.Context) {
|
||||
// @Tags Admin
|
||||
// @Produce json
|
||||
// @Param id path int true "材质ID"
|
||||
// @Success 200 {object} model.Response
|
||||
// @Failure 404 {object} model.Response
|
||||
// @Success 200 {object} model.Response{data=map[string]interface{}} "删除成功"
|
||||
// @Failure 404 {object} model.ErrorResponse "材质不存在"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/textures/{id} [delete]
|
||||
// @Router /api/v1/admin/textures/{id} [delete]
|
||||
func (h *AdminHandler) DeleteTexture(c *gin.Context) {
|
||||
textureID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -316,9 +316,9 @@ func (h *AdminHandler) DeleteTexture(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param page query int false "页码" default(1)
|
||||
// @Param page_size query int false "每页数量" default(20)
|
||||
// @Success 200 {object} model.Response
|
||||
// @Success 200 {object} model.Response{data=map[string]interface{}} "获取成功"
|
||||
// @Security BearerAuth
|
||||
// @Router /admin/textures [get]
|
||||
// @Router /api/v1/admin/textures [get]
|
||||
func (h *AdminHandler) GetTextureList(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||
@@ -364,3 +364,19 @@ func (h *AdminHandler) GetTextureList(c *gin.Context) {
|
||||
"page_size": pageSize,
|
||||
}))
|
||||
}
|
||||
|
||||
// GetPermissions 获取权限列表
|
||||
// @Summary 获取权限列表
|
||||
// @Description 管理员获取所有Casbin权限规则
|
||||
// @Tags Admin
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.Response{data=map[string]interface{}} "获取成功"
|
||||
// @Security BearerAuth
|
||||
// @Router /api/v1/admin/permissions [get]
|
||||
func (h *AdminHandler) GetPermissions(c *gin.Context) {
|
||||
// 获取所有权限规则
|
||||
policies, _ := h.container.Casbin.GetEnforcer().GetPolicy()
|
||||
c.JSON(http.StatusOK, model.NewSuccessResponse(gin.H{
|
||||
"policies": policies,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func NewAuthHandler(c *container.Container) *AuthHandler {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body types.RegisterRequest true "注册信息"
|
||||
// @Success 200 {object} model.Response "注册成功"
|
||||
// @Success 200 {object} model.Response{data=types.LoginResponse} "注册成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求参数错误"
|
||||
// @Router /api/v1/auth/register [post]
|
||||
func (h *AuthHandler) Register(c *gin.Context) {
|
||||
@@ -107,7 +107,7 @@ func (h *AuthHandler) Login(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body types.SendVerificationCodeRequest true "发送验证码请求"
|
||||
// @Success 200 {object} model.Response "发送成功"
|
||||
// @Success 200 {object} model.Response{data=map[string]string} "发送成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求参数错误"
|
||||
// @Router /api/v1/auth/send-code [post]
|
||||
func (h *AuthHandler) SendVerificationCode(c *gin.Context) {
|
||||
@@ -137,7 +137,7 @@ func (h *AuthHandler) SendVerificationCode(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body types.ResetPasswordRequest true "重置密码请求"
|
||||
// @Success 200 {object} model.Response "重置成功"
|
||||
// @Success 200 {object} model.Response{data=map[string]string} "重置成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "请求参数错误"
|
||||
// @Router /api/v1/auth/reset-password [post]
|
||||
func (h *AuthHandler) ResetPassword(c *gin.Context) {
|
||||
|
||||
@@ -34,7 +34,7 @@ type CaptchaVerifyRequest struct {
|
||||
// @Tags captcha
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]interface{} "生成成功"
|
||||
// @Success 200 {object} map[string]interface{} "生成成功 {code: 200, data: {masterImage, tileImage, captchaId, y}}"
|
||||
// @Failure 500 {object} map[string]interface{} "生成失败"
|
||||
// @Router /api/v1/captcha/generate [get]
|
||||
func (h *CaptchaHandler) Generate(c *gin.Context) {
|
||||
@@ -66,7 +66,7 @@ func (h *CaptchaHandler) Generate(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body CaptchaVerifyRequest true "验证请求"
|
||||
// @Success 200 {object} map[string]interface{} "验证结果"
|
||||
// @Success 200 {object} map[string]interface{} "验证结果 {code: 200/400, msg: string}"
|
||||
// @Failure 400 {object} map[string]interface{} "参数错误"
|
||||
// @Router /api/v1/captcha/verify [post]
|
||||
func (h *CaptchaHandler) Verify(c *gin.Context) {
|
||||
|
||||
@@ -35,7 +35,16 @@ type CustomSkinAPIResponse struct {
|
||||
}
|
||||
|
||||
// GetPlayerInfo 获取玩家信息
|
||||
// GET {ROOT}/{USERNAME}.json
|
||||
// @Summary 获取玩家信息
|
||||
// @Description CustomSkinAPI: 获取玩家皮肤配置信息
|
||||
// @Tags CustomSkinAPI
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param username path string true "玩家用户名"
|
||||
// @Success 200 {object} CustomSkinAPIResponse
|
||||
// @Failure 400 {object} map[string]string "用户名不能为空"
|
||||
// @Failure 404 {object} map[string]string "玩家未找到"
|
||||
// @Router /api/v1/csl/{username} [get]
|
||||
func (h *CustomSkinHandler) GetPlayerInfo(c *gin.Context) {
|
||||
username := c.Param("username")
|
||||
if username == "" {
|
||||
@@ -136,7 +145,14 @@ func (h *CustomSkinHandler) GetPlayerInfo(c *gin.Context) {
|
||||
}
|
||||
|
||||
// GetTexture 获取资源文件
|
||||
// GET {ROOT}/textures/{hash}
|
||||
// @Summary 获取资源文件
|
||||
// @Description CustomSkinAPI: 获取材质图片文件
|
||||
// @Tags CustomSkinAPI
|
||||
// @Param hash path string true "材质Hash"
|
||||
// @Success 200 {file} binary
|
||||
// @Failure 400 {object} map[string]string "资源标识符不能为空"
|
||||
// @Failure 404 {object} map[string]string "资源未找到或不可用"
|
||||
// @Router /api/v1/csl/textures/{hash} [get]
|
||||
func (h *CustomSkinHandler) GetTexture(c *gin.Context) {
|
||||
hash := c.Param("hash")
|
||||
if hash == "" {
|
||||
|
||||
@@ -72,7 +72,8 @@ func (h *ProfileHandler) Create(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} model.Response "获取成功"
|
||||
// @Success 200 {object} model.Response{data=[]types.ProfileInfo} "获取成功"
|
||||
// @Failure 500 {object} model.ErrorResponse "服务器错误"
|
||||
// @Router /api/v1/profile [get]
|
||||
func (h *ProfileHandler) List(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
@@ -100,7 +101,7 @@ func (h *ProfileHandler) List(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param uuid path string true "档案UUID"
|
||||
// @Success 200 {object} model.Response "获取成功"
|
||||
// @Success 200 {object} model.Response{data=types.ProfileInfo} "获取成功"
|
||||
// @Failure 404 {object} model.ErrorResponse "档案不存在"
|
||||
// @Router /api/v1/profile/{uuid} [get]
|
||||
func (h *ProfileHandler) Get(c *gin.Context) {
|
||||
@@ -132,7 +133,7 @@ func (h *ProfileHandler) Get(c *gin.Context) {
|
||||
// @Security BearerAuth
|
||||
// @Param uuid path string true "档案UUID"
|
||||
// @Param request body types.UpdateProfileRequest true "更新信息"
|
||||
// @Success 200 {object} model.Response "更新成功"
|
||||
// @Success 200 {object} model.Response{data=types.ProfileInfo} "更新成功"
|
||||
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
||||
// @Router /api/v1/profile/{uuid} [put]
|
||||
func (h *ProfileHandler) Update(c *gin.Context) {
|
||||
@@ -180,7 +181,7 @@ func (h *ProfileHandler) Update(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param uuid path string true "档案UUID"
|
||||
// @Success 200 {object} model.Response "删除成功"
|
||||
// @Success 200 {object} model.Response{data=map[string]string} "删除成功"
|
||||
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
||||
// @Router /api/v1/profile/{uuid} [delete]
|
||||
func (h *ProfileHandler) Delete(c *gin.Context) {
|
||||
|
||||
@@ -3,7 +3,6 @@ package handler
|
||||
import (
|
||||
"carrotskin/internal/container"
|
||||
"carrotskin/internal/middleware"
|
||||
"carrotskin/internal/model"
|
||||
"carrotskin/pkg/auth"
|
||||
"carrotskin/pkg/config"
|
||||
|
||||
@@ -44,7 +43,10 @@ func RegisterRoutesWithDI(router *gin.Engine, c *container.Container) {
|
||||
router.GET("/health", HealthCheck)
|
||||
|
||||
// Swagger文档路由
|
||||
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
cfg, _ := config.GetConfig()
|
||||
if cfg != nil && cfg.Server.SwaggerEnabled {
|
||||
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
}
|
||||
|
||||
// 创建Handler实例
|
||||
h := NewHandlers(c)
|
||||
@@ -70,9 +72,6 @@ func RegisterRoutesWithDI(router *gin.Engine, c *container.Container) {
|
||||
// Yggdrasil API路由组
|
||||
registerYggdrasilRoutesWithDI(v1, h.Yggdrasil)
|
||||
|
||||
// 系统路由
|
||||
registerSystemRoutes(v1, c)
|
||||
|
||||
// CustomSkinAPI 路由
|
||||
registerCustomSkinRoutes(v1, h.CustomSkin)
|
||||
|
||||
@@ -193,24 +192,6 @@ func registerYggdrasilRoutesWithDI(v1 *gin.RouterGroup, h *YggdrasilHandler) {
|
||||
}
|
||||
}
|
||||
|
||||
// registerSystemRoutes 注册系统路由
|
||||
func registerSystemRoutes(v1 *gin.RouterGroup, c *container.Container) {
|
||||
system := v1.Group("/system")
|
||||
{
|
||||
// 公开配置(无需认证)
|
||||
system.GET("/config", func(ctx *gin.Context) {
|
||||
cfg, _ := config.GetConfig()
|
||||
ctx.JSON(200, model.NewSuccessResponse(gin.H{
|
||||
"site_name": cfg.Site.Name,
|
||||
"site_description": cfg.Site.Description,
|
||||
"registration_enabled": cfg.Site.RegistrationEnabled,
|
||||
"max_textures_per_user": cfg.Site.MaxTexturesPerUser,
|
||||
"max_profiles_per_user": cfg.Site.MaxProfilesPerUser,
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// registerAdminRoutes 注册管理员路由
|
||||
func registerAdminRoutes(v1 *gin.RouterGroup, c *container.Container, h *AdminHandler) {
|
||||
admin := v1.Group("/admin")
|
||||
@@ -229,13 +210,7 @@ func registerAdminRoutes(v1 *gin.RouterGroup, c *container.Container, h *AdminHa
|
||||
admin.DELETE("/textures/:id", h.DeleteTexture)
|
||||
|
||||
// 权限管理
|
||||
admin.GET("/permissions", func(ctx *gin.Context) {
|
||||
// 获取所有权限规则
|
||||
policies, _ := c.Casbin.GetEnforcer().GetPolicy()
|
||||
ctx.JSON(200, model.NewSuccessResponse(gin.H{
|
||||
"policies": policies,
|
||||
}))
|
||||
})
|
||||
admin.GET("/permissions", h.GetPermissions)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,16 @@ func NewTextureHandler(c *container.Container) *TextureHandler {
|
||||
}
|
||||
|
||||
// Get 获取材质详情
|
||||
// @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]
|
||||
func (h *TextureHandler) Get(c *gin.Context) {
|
||||
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
@@ -42,6 +52,19 @@ func (h *TextureHandler) Get(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Search 搜索材质
|
||||
// @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]
|
||||
func (h *TextureHandler) Search(c *gin.Context) {
|
||||
keyword := c.Query("keyword")
|
||||
textureTypeStr := c.Query("type")
|
||||
@@ -85,6 +108,18 @@ func (h *TextureHandler) Search(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Update 更新材质
|
||||
// @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]
|
||||
func (h *TextureHandler) Update(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -118,6 +153,17 @@ func (h *TextureHandler) Update(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Delete 删除材质
|
||||
// @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]
|
||||
func (h *TextureHandler) Delete(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -144,6 +190,16 @@ func (h *TextureHandler) Delete(c *gin.Context) {
|
||||
}
|
||||
|
||||
// ToggleFavorite 切换收藏状态
|
||||
// @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]
|
||||
func (h *TextureHandler) ToggleFavorite(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -171,6 +227,17 @@ func (h *TextureHandler) ToggleFavorite(c *gin.Context) {
|
||||
}
|
||||
|
||||
// GetUserTextures 获取用户上传的材质列表
|
||||
// @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]
|
||||
func (h *TextureHandler) GetUserTextures(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -196,6 +263,17 @@ func (h *TextureHandler) GetUserTextures(c *gin.Context) {
|
||||
}
|
||||
|
||||
// GetUserFavorites 获取用户收藏的材质列表
|
||||
// @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]
|
||||
func (h *TextureHandler) GetUserFavorites(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -221,6 +299,21 @@ func (h *TextureHandler) GetUserFavorites(c *gin.Context) {
|
||||
}
|
||||
|
||||
// Upload 直接上传材质文件
|
||||
// @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]
|
||||
func (h *TextureHandler) Upload(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
|
||||
@@ -24,6 +24,15 @@ func NewUserHandler(c *container.Container) *UserHandler {
|
||||
}
|
||||
|
||||
// GetProfile 获取用户信息
|
||||
// @Summary 获取用户信息
|
||||
// @Description 获取当前登录用户的详细信息
|
||||
// @Tags user
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} model.Response{data=types.UserInfo} "获取成功"
|
||||
// @Failure 404 {object} model.ErrorResponse "用户不存在"
|
||||
// @Router /api/v1/user/profile [get]
|
||||
func (h *UserHandler) GetProfile(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -44,6 +53,17 @@ func (h *UserHandler) GetProfile(c *gin.Context) {
|
||||
}
|
||||
|
||||
// UpdateProfile 更新用户信息
|
||||
// @Summary 更新用户信息
|
||||
// @Description 更新用户资料(密码、头像URL),如需上传头像请使用上传接口
|
||||
// @Tags user
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param request body types.UpdateUserRequest true "更新信息"
|
||||
// @Success 200 {object} model.Response{data=types.UserInfo} "更新成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
||||
// @Failure 404 {object} model.ErrorResponse "用户不存在"
|
||||
// @Router /api/v1/user/profile [put]
|
||||
func (h *UserHandler) UpdateProfile(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -103,6 +123,17 @@ func (h *UserHandler) UpdateProfile(c *gin.Context) {
|
||||
}
|
||||
|
||||
// UploadAvatar 直接上传头像文件
|
||||
// @Summary 上传头像
|
||||
// @Description 上传图片文件作为用户头像
|
||||
// @Tags user
|
||||
// @Accept multipart/form-data
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param file formData file true "头像文件"
|
||||
// @Success 200 {object} model.Response{data=map[string]interface{}} "上传成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
||||
// @Failure 404 {object} model.ErrorResponse "用户不存在"
|
||||
// @Router /api/v1/user/avatar/upload [post]
|
||||
func (h *UserHandler) UploadAvatar(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -162,6 +193,17 @@ func (h *UserHandler) UploadAvatar(c *gin.Context) {
|
||||
}
|
||||
|
||||
// UpdateAvatar 更新头像URL(保留用于外部URL)
|
||||
// @Summary 更新头像URL
|
||||
// @Description 更新用户头像为外部URL
|
||||
// @Tags user
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param avatar_url query string true "头像URL"
|
||||
// @Success 200 {object} model.Response{data=types.UserInfo} "更新成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
||||
// @Failure 404 {object} model.ErrorResponse "用户不存在"
|
||||
// @Router /api/v1/user/avatar [put]
|
||||
func (h *UserHandler) UpdateAvatar(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -199,6 +241,17 @@ func (h *UserHandler) UpdateAvatar(c *gin.Context) {
|
||||
}
|
||||
|
||||
// ChangeEmail 更换邮箱
|
||||
// @Summary 更换邮箱
|
||||
// @Description 更换用户绑定的邮箱,需要验证码
|
||||
// @Tags user
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param request body types.ChangeEmailRequest true "更换邮箱请求"
|
||||
// @Success 200 {object} model.Response{data=types.UserInfo} "更换成功"
|
||||
// @Failure 400 {object} model.ErrorResponse "参数错误"
|
||||
// @Failure 404 {object} model.ErrorResponse "用户不存在"
|
||||
// @Router /api/v1/user/change-email [post]
|
||||
func (h *UserHandler) ChangeEmail(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
@@ -237,6 +290,15 @@ func (h *UserHandler) ChangeEmail(c *gin.Context) {
|
||||
}
|
||||
|
||||
// ResetYggdrasilPassword 重置Yggdrasil密码
|
||||
// @Summary 重置Yggdrasil密码
|
||||
// @Description 重置用户的Yggdrasil API认证密码
|
||||
// @Tags user
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} model.Response{data=map[string]string} "重置成功"
|
||||
// @Failure 500 {object} model.ErrorResponse "服务器错误"
|
||||
// @Router /api/v1/user/yggdrasil-password/reset [post]
|
||||
func (h *UserHandler) ResetYggdrasilPassword(c *gin.Context) {
|
||||
userID, ok := GetUserIDFromContext(c)
|
||||
if !ok {
|
||||
|
||||
@@ -167,6 +167,15 @@ func NewYggdrasilHandler(c *container.Container) *YggdrasilHandler {
|
||||
}
|
||||
|
||||
// Authenticate 用户认证
|
||||
// @Summary Yggdrasil认证
|
||||
// @Description Yggdrasil协议: 用户登录认证
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body AuthenticateRequest true "认证请求"
|
||||
// @Success 200 {object} AuthenticateResponse
|
||||
// @Failure 403 {object} map[string]string "认证失败"
|
||||
// @Router /api/v1/yggdrasil/authserver/authenticate [post]
|
||||
func (h *YggdrasilHandler) Authenticate(c *gin.Context) {
|
||||
rawData, err := io.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
@@ -248,6 +257,15 @@ func (h *YggdrasilHandler) Authenticate(c *gin.Context) {
|
||||
}
|
||||
|
||||
// ValidToken 验证令牌
|
||||
// @Summary Yggdrasil验证令牌
|
||||
// @Description Yggdrasil协议: 验证AccessToken是否有效
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body ValidTokenRequest true "验证请求"
|
||||
// @Success 204 "令牌有效"
|
||||
// @Failure 403 {object} map[string]bool "令牌无效"
|
||||
// @Router /api/v1/yggdrasil/authserver/validate [post]
|
||||
func (h *YggdrasilHandler) ValidToken(c *gin.Context) {
|
||||
var request ValidTokenRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
@@ -266,6 +284,15 @@ func (h *YggdrasilHandler) ValidToken(c *gin.Context) {
|
||||
}
|
||||
|
||||
// RefreshToken 刷新令牌
|
||||
// @Summary Yggdrasil刷新令牌
|
||||
// @Description Yggdrasil协议: 刷新AccessToken
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body RefreshRequest true "刷新请求"
|
||||
// @Success 200 {object} RefreshResponse
|
||||
// @Failure 400 {object} map[string]string "刷新失败"
|
||||
// @Router /api/v1/yggdrasil/authserver/refresh [post]
|
||||
func (h *YggdrasilHandler) RefreshToken(c *gin.Context) {
|
||||
var request RefreshRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
@@ -350,6 +377,14 @@ func (h *YggdrasilHandler) RefreshToken(c *gin.Context) {
|
||||
}
|
||||
|
||||
// InvalidToken 使令牌失效
|
||||
// @Summary Yggdrasil注销令牌
|
||||
// @Description Yggdrasil协议: 使AccessToken失效
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body ValidTokenRequest true "失效请求"
|
||||
// @Success 204 "操作成功"
|
||||
// @Router /api/v1/yggdrasil/authserver/invalidate [post]
|
||||
func (h *YggdrasilHandler) InvalidToken(c *gin.Context) {
|
||||
var request ValidTokenRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
@@ -364,6 +399,15 @@ func (h *YggdrasilHandler) InvalidToken(c *gin.Context) {
|
||||
}
|
||||
|
||||
// SignOut 用户登出
|
||||
// @Summary Yggdrasil登出
|
||||
// @Description Yggdrasil协议: 用户登出,使所有令牌失效
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body SignOutRequest true "登出请求"
|
||||
// @Success 204 "操作成功"
|
||||
// @Failure 400 {object} map[string]string "参数错误"
|
||||
// @Router /api/v1/yggdrasil/authserver/signout [post]
|
||||
func (h *YggdrasilHandler) SignOut(c *gin.Context) {
|
||||
var request SignOutRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
@@ -397,6 +441,15 @@ func (h *YggdrasilHandler) SignOut(c *gin.Context) {
|
||||
}
|
||||
|
||||
// GetProfileByUUID 根据UUID获取档案
|
||||
// @Summary Yggdrasil获取档案
|
||||
// @Description Yggdrasil协议: 根据UUID获取用户档案信息
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param uuid path string true "用户UUID"
|
||||
// @Success 200 {object} map[string]interface{} "档案信息"
|
||||
// @Failure 500 {object} APIResponse "服务器错误"
|
||||
// @Router /api/v1/yggdrasil/sessionserver/session/minecraft/profile/{uuid} [get]
|
||||
func (h *YggdrasilHandler) GetProfileByUUID(c *gin.Context) {
|
||||
uuid := utils.FormatUUID(c.Param("uuid"))
|
||||
h.logger.Info("获取配置文件请求", zap.String("uuid", uuid))
|
||||
@@ -413,6 +466,16 @@ func (h *YggdrasilHandler) GetProfileByUUID(c *gin.Context) {
|
||||
}
|
||||
|
||||
// JoinServer 加入服务器
|
||||
// @Summary Yggdrasil加入服务器
|
||||
// @Description Yggdrasil协议: 客户端加入服务器
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body JoinServerRequest true "加入请求"
|
||||
// @Success 204 "加入成功"
|
||||
// @Failure 400 {object} APIResponse "参数错误"
|
||||
// @Failure 500 {object} APIResponse "服务器错误"
|
||||
// @Router /api/v1/yggdrasil/sessionserver/session/minecraft/join [post]
|
||||
func (h *YggdrasilHandler) JoinServer(c *gin.Context) {
|
||||
var request JoinServerRequest
|
||||
clientIP := c.ClientIP()
|
||||
@@ -449,6 +512,17 @@ func (h *YggdrasilHandler) JoinServer(c *gin.Context) {
|
||||
}
|
||||
|
||||
// HasJoinedServer 验证玩家是否已加入服务器
|
||||
// @Summary Yggdrasil验证加入
|
||||
// @Description Yggdrasil协议: 服务端验证客户端是否已加入
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param username query string true "用户名"
|
||||
// @Param serverId query string true "服务器ID"
|
||||
// @Param ip query string false "客户端IP"
|
||||
// @Success 200 {object} map[string]interface{} "验证成功,返回档案"
|
||||
// @Failure 204 "验证失败"
|
||||
// @Router /api/v1/yggdrasil/sessionserver/session/minecraft/hasJoined [get]
|
||||
func (h *YggdrasilHandler) HasJoinedServer(c *gin.Context) {
|
||||
clientIP, _ := c.GetQuery("ip")
|
||||
|
||||
@@ -499,6 +573,15 @@ func (h *YggdrasilHandler) HasJoinedServer(c *gin.Context) {
|
||||
}
|
||||
|
||||
// GetProfilesByName 批量获取配置文件
|
||||
// @Summary Yggdrasil批量获取档案
|
||||
// @Description Yggdrasil协议: 根据名称批量获取用户档案
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body []string true "用户名列表"
|
||||
// @Success 200 {array} model.Profile "档案列表"
|
||||
// @Failure 400 {object} APIResponse "参数错误"
|
||||
// @Router /api/v1/yggdrasil/api/profiles/minecraft [post]
|
||||
func (h *YggdrasilHandler) GetProfilesByName(c *gin.Context) {
|
||||
var names []string
|
||||
|
||||
@@ -520,6 +603,14 @@ func (h *YggdrasilHandler) GetProfilesByName(c *gin.Context) {
|
||||
}
|
||||
|
||||
// GetMetaData 获取Yggdrasil元数据
|
||||
// @Summary Yggdrasil元数据
|
||||
// @Description Yggdrasil协议: 获取服务器元数据
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]interface{} "元数据"
|
||||
// @Failure 500 {object} APIResponse "服务器错误"
|
||||
// @Router /api/v1/yggdrasil [get]
|
||||
func (h *YggdrasilHandler) GetMetaData(c *gin.Context) {
|
||||
meta := gin.H{
|
||||
"implementationName": "CellAuth",
|
||||
@@ -550,6 +641,16 @@ func (h *YggdrasilHandler) GetMetaData(c *gin.Context) {
|
||||
}
|
||||
|
||||
// GetPlayerCertificates 获取玩家证书
|
||||
// @Summary Yggdrasil获取证书
|
||||
// @Description Yggdrasil协议: 获取玩家证书
|
||||
// @Tags Yggdrasil
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param Authorization header string true "Bearer {token}"
|
||||
// @Success 200 {object} map[string]interface{} "证书信息"
|
||||
// @Failure 401 {object} map[string]string "未授权"
|
||||
// @Failure 500 {object} APIResponse "服务器错误"
|
||||
// @Router /api/v1/yggdrasil/minecraftservices/player/certificates [post]
|
||||
func (h *YggdrasilHandler) GetPlayerCertificates(c *gin.Context) {
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
|
||||
Reference in New Issue
Block a user