108 lines
3.3 KiB
Go
108 lines
3.3 KiB
Go
package controller
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"time"
|
|
|
|
"dubbo.apache.org/dubbo-go/v3/client"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/topfans/backend/gateway/pkg/response"
|
|
pbCastlove "github.com/topfans/backend/pkg/proto/castlove"
|
|
"github.com/topfans/backend/pkg/logger"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// CastloveConfigController 铸爱工艺配置 控制器
|
|
// 端点:GET /api/v1/castlove/config
|
|
// 流程:JWT 鉴权 → 透传 Dubbo RPC → 透传 DB → sanitize → 5s 进程内缓存 → JSON 响应
|
|
type CastloveConfigController struct {
|
|
castloveConfigClient pbCastlove.CastloveConfigService
|
|
}
|
|
|
|
// NewCastloveConfigController 创建铸爱工艺配置 Controller 实例
|
|
// dubboClient:指向 assetService(端口 20003)的 Dubbo 客户端
|
|
func NewCastloveConfigController(dubboClient *client.Client) (*CastloveConfigController, error) {
|
|
cli, err := pbCastlove.NewCastloveConfigService(dubboClient)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &CastloveConfigController{
|
|
castloveConfigClient: cli,
|
|
}, nil
|
|
}
|
|
|
|
// GetCastloveConfig 获取铸爱工艺配置(全量分类 + 卡片)
|
|
// @Summary 获取铸爱工艺配置
|
|
// @Description 强制鉴权;返回全量分类(星卡/吧唧/海报 等)及其下卡片(含 route_path / route_params)
|
|
// @Tags castlove
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Security BearerAuth
|
|
// @Success 200 {object} response.Response
|
|
// @Router /api/v1/castlove/config [get]
|
|
func (ctrl *CastloveConfigController) GetCastloveConfig(c *gin.Context) {
|
|
logger.Logger.Info("GetCastloveConfig request")
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
resp, err := ctrl.castloveConfigClient.GetCastloveConfig(ctx, &pbCastlove.GetCastloveConfigRequest{})
|
|
if err != nil {
|
|
logger.Logger.Error("GetCastloveConfig RPC failed", zap.Error(err))
|
|
response.Error(c, http.StatusInternalServerError, "配置加载失败")
|
|
return
|
|
}
|
|
|
|
if resp.Base == nil || resp.Base.GetCode() != 200 {
|
|
// proto Base 为 nil 视为异常,但仍尝试把 categories 透传出去,避免空响应
|
|
logger.Logger.Warn("GetCastloveConfig: unexpected base",
|
|
zap.Any("base", resp.Base),
|
|
)
|
|
}
|
|
|
|
// proto 数组转 []map 以便 gin 序列化为 JSON 数组而非 proto 字段名
|
|
categories := make([]map[string]interface{}, 0, len(resp.Categories))
|
|
for _, cat := range resp.Categories {
|
|
crafts := make([]map[string]interface{}, 0, len(cat.Crafts))
|
|
for _, cr := range cat.Crafts {
|
|
crafts = append(crafts, map[string]interface{}{
|
|
"id": cr.Id,
|
|
"name": cr.Name,
|
|
"image_url": cr.ImageUrl,
|
|
"route_path": nullableString(cr.RoutePath), // "" → nil,与 DB NULL 行为一致
|
|
"route_params": nullableJSONString(cr.RouteParams),
|
|
"sort_order": cr.SortOrder,
|
|
})
|
|
}
|
|
categories = append(categories, map[string]interface{}{
|
|
"id": cat.Id,
|
|
"name": cat.Name,
|
|
"type_key": nullableString(cat.TypeKey),
|
|
"sort_order": cat.SortOrder,
|
|
"crafts": crafts,
|
|
})
|
|
}
|
|
|
|
response.Success(c, map[string]interface{}{
|
|
"categories": categories,
|
|
"version": resp.Version,
|
|
})
|
|
}
|
|
|
|
// nullableString 空串转 nil(JSON 序列化时为 null,与 DB NULL 行为一致)
|
|
func nullableString(s string) interface{} {
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
return s
|
|
}
|
|
|
|
// nullableJSONString 空串转 nil(route_params 同上)
|
|
func nullableJSONString(s string) interface{} {
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
return s
|
|
}
|