package controller import ( "context" "net/http" "strconv" "dubbo.apache.org/dubbo-go/v3/client" "dubbo.apache.org/dubbo-go/v3/common/constant" "github.com/gin-gonic/gin" "github.com/topfans/backend/gateway/pkg/response" "github.com/topfans/backend/pkg/logger" pb "github.com/topfans/backend/pkg/proto/starbook" "go.uber.org/zap" ) // StarbookController 星册控制器 type StarbookController struct { starbookService pb.StarbookService } // NewStarbookController 创建星册控制器 func NewStarbookController(dubboClient *client.Client) (*StarbookController, error) { // 创建 StarbookService 客户端 starbookService, err := pb.NewStarbookService(dubboClient) if err != nil { return nil, err } return &StarbookController{ starbookService: starbookService, }, nil } // GetStarbookHome 获取星册首页 // @Summary 获取星册首页 // @Description 获取当前用户的星册首页数据,按类型和分组展示 // @Tags starbook // @Accept json // @Produce json // @Security BearerAuth // @Success 200 {object} response.Response // @Router /api/v1/starbook/home [get] func (ctrl *StarbookController) GetStarbookHome(c *gin.Context) { // 验证用户是否已登录(通过 AuthMiddleware 设置的上下文) userID, exists := c.Get("user_id") if !exists { response.Error(c, http.StatusUnauthorized, "未授权") return } starID, exists := c.Get("star_id") if !exists { response.Error(c, http.StatusUnauthorized, "未授权") return } // 设置上下文和 Dubbo attachments ctx := context.WithValue(c.Request.Context(), constant.AttachmentKey, map[string]interface{}{ "user_id": strconv.FormatInt(userID.(int64), 10), "star_id": strconv.FormatInt(starID.(int64), 10), }) logger.Logger.Debug("Calling GetStarbookHome", zap.Int64("user_id", userID.(int64)), zap.Int64("star_id", starID.(int64)), ) // 调用星册服务(通过 Dubbo,user/star ID 从 context 的 attachments 中获取) resp, err := ctrl.starbookService.GetStarbookHome(ctx, &pb.GetStarbookHomeRequest{}) if err != nil { logger.Logger.Error("GetStarbookHome RPC failed", zap.Error(err), zap.Int64("user_id", userID.(int64)), zap.Int64("star_id", starID.(int64)), ) response.Error(c, http.StatusInternalServerError, "获取星册首页失败: "+err.Error()) return } response.Success(c, resp) } // GetStarbookItems 获取星册藏品列表 // @Summary 获取星册藏品列表 // @Description 获取指定分组的藏品列表,支持分页 // @Tags starbook // @Accept json // @Produce json // @Security BearerAuth // @Param type query string true "资产类型: regular/collection/activity" // @Param category query string false "子分类,regular 时固定为 castlove" // @Param grade query int false "等级,仅 regular 类型有效" // @Param page query int false "页码,默认1" // @Param page_size query int false "每页数量,默认20" // @Success 200 {object} response.Response // @Router /api/v1/starbook/items [get] func (ctrl *StarbookController) GetStarbookItems(c *gin.Context) { // 验证用户是否已登录 userID, exists := c.Get("user_id") if !exists { response.Error(c, http.StatusUnauthorized, "未授权") return } starID, exists := c.Get("star_id") if !exists { response.Error(c, http.StatusUnauthorized, "未授权") return } // 解析查询参数 assetType := c.Query("type") if assetType == "" { response.Error(c, http.StatusBadRequest, "type 参数不能为空") return } category := c.DefaultQuery("category", "castlove") grade, _ := strconv.Atoi(c.DefaultQuery("grade", "0")) page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) // 设置上下文和 Dubbo attachments ctx := context.WithValue(c.Request.Context(), constant.AttachmentKey, map[string]interface{}{ "user_id": strconv.FormatInt(userID.(int64), 10), "star_id": strconv.FormatInt(starID.(int64), 10), }) // 构建请求 req := &pb.GetStarbookItemsRequest{ Type: assetType, Category: category, Grade: int32(grade), Page: int32(page), PageSize: int32(pageSize), } logger.Logger.Debug("Calling GetStarbookItems", zap.Int64("user_id", userID.(int64)), zap.Int64("star_id", starID.(int64)), zap.String("type", assetType), zap.Int32("page", int32(page)), ) // 调用星册服务 resp, err := ctrl.starbookService.GetStarbookItems(ctx, req) if err != nil { logger.Logger.Error("GetStarbookItems RPC failed", zap.Error(err), zap.Int64("user_id", userID.(int64)), zap.Int64("star_id", starID.(int64)), ) response.Error(c, http.StatusInternalServerError, "获取星册藏品列表失败: "+err.Error()) return } response.Success(c, resp) }