diff --git a/backend/gateway/controller/gallery_controller.go b/backend/gateway/controller/gallery_controller.go index c8cb49f..d619354 100644 --- a/backend/gateway/controller/gallery_controller.go +++ b/backend/gateway/controller/gallery_controller.go @@ -633,4 +633,87 @@ result := &dto.GetMyExhibitedAssetsResponseDTO{ ) response.Success(c, result) +} + +// GetInspirationFlow 获取灵感瀑布藏品列表 +// @Summary 获取灵感瀑布藏品列表 +// @Description 获取灵感瀑布藏品列表,支持随机展示和双向滚动 +// @Tags galleries +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param cursor query string false "游标" +// @Param direction query string false "滚动方向:right(加载新数据)/ left(加载历史)" default(right) +// @Param limit query int false "每页数量" default(10) +// @Param type query string false "过滤类型:badge/poster/original/all" default(all) +// @Param session_id query string false "会话ID" +// @Success 200 {object} response.Response{data=dto.GetInspirationFlowResponseDTO} +// @Router /api/v1/inspiration-flow [get] +func (ctrl *GalleryController) GetInspirationFlow(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 + } + + // 解析请求参数 + cursor := c.Query("cursor") + direction := c.DefaultQuery("direction", "right") + limitStr := c.DefaultQuery("limit", "10") + limit, _ := strconv.Atoi(limitStr) + materialType := c.DefaultQuery("type", "all") + sessionID := c.Query("session_id") + + // 创建带有附加信息的context(Triple协议要求attachments值为string类型) + ctx := context.WithValue(context.Background(), constant.AttachmentKey, map[string]interface{}{ + "user_id": strconv.FormatInt(userID.(int64), 10), + "star_id": strconv.FormatInt(starID.(int64), 10), + }) + + // 调用RPC服务 + resp, err := ctrl.galleryService.GetInspirationFlow(ctx, &pbGallery.GetInspirationFlowRequest{ + Cursor: cursor, + Direction: direction, + Limit: int32(limit), + Type: materialType, + SessionId: sessionID, + }) + if err != nil { + logger.Logger.Error("GetInspirationFlow RPC failed", + zap.Any("user_id", userID), + zap.Any("star_id", starID), + zap.Error(err), + ) + _, msg := parseRPCError(err) + errorMsg := "获取灵感瀑布列表失败" + if msg != "" { + errorMsg += "," + msg + } + response.Error(c, http.StatusInternalServerError, errorMsg) + return + } + + // 检查业务错误 + if resp.Base.Code != pbCommon.StatusCode_STATUS_OK { + response.Error(c, http.StatusBadRequest, resp.Base.Message) + return + } + + // 转换为DTO + flowDTO := dto.ConvertInspirationFlowData(resp.Data) + + logger.Logger.Info("GetInspirationFlow success", + zap.Any("user_id", userID), + zap.Any("star_id", starID), + zap.Int("count", len(flowDTO.Items)), + ) + + response.Success(c, flowDTO) } \ No newline at end of file diff --git a/backend/gateway/dto/gallery_converter.go b/backend/gateway/dto/gallery_converter.go index 37b9e4b..08c109d 100644 --- a/backend/gateway/dto/gallery_converter.go +++ b/backend/gateway/dto/gallery_converter.go @@ -150,3 +150,29 @@ func ConvertPlaceAssetRequest(dto *PlaceAssetRequestDTO) *pbGallery.PlaceAssetRe SlotId: dto.SlotID, } } + +// ConvertInspirationFlowData 转换灵感瀑布数据 +func ConvertInspirationFlowData(pbData *pbGallery.InspirationFlowData) *GetInspirationFlowResponseDTO { + if pbData == nil { + return nil + } + + dto := &GetInspirationFlowResponseDTO{ + Cursor: pbData.Cursor, + HasMore: pbData.HasMore, + SessionID: pbData.SessionId, + Items: make([]*InspirationFlowItemDTO, 0, len(pbData.Items)), + } + + for _, item := range pbData.Items { + dto.Items = append(dto.Items, &InspirationFlowItemDTO{ + AssetID: item.AssetId, + Name: item.Name, + CoverURL: item.CoverUrl, + LikeCount: item.LikeCount, + OwnerNickname: item.OwnerNickname, + }) + } + + return dto +} diff --git a/backend/gateway/dto/gallery_dto.go b/backend/gateway/dto/gallery_dto.go index 18f729d..040df3c 100644 --- a/backend/gateway/dto/gallery_dto.go +++ b/backend/gateway/dto/gallery_dto.go @@ -90,3 +90,22 @@ type GetMyExhibitedAssetsResponseDTO struct { Total int64 `json:"total"` // 总数量 HasMore bool `json:"has_more"` // 是否有更多 } + +// ========== 灵感瀑布相关 ========== + +// InspirationFlowItemDTO 灵感瀑布藏品项 +type InspirationFlowItemDTO struct { + AssetID int64 `json:"asset_id"` // 资产ID + Name string `json:"name"` // 藏品名称 + CoverURL string `json:"cover_url"` // 封面图URL + LikeCount int32 `json:"like_count"` // 点赞数 + OwnerNickname string `json:"owner_nickname"` // 展出者昵称 +} + +// GetInspirationFlowResponseDTO 获取灵感瀑布藏品列表响应 +type GetInspirationFlowResponseDTO struct { + Items []*InspirationFlowItemDTO `json:"items"` // 藏品列表 + Cursor string `json:"cursor"` // 下次请求的游标 + HasMore bool `json:"has_more"` // 是否有更多 + SessionID string `json:"session_id"` // 会话ID +} diff --git a/backend/gateway/router/router.go b/backend/gateway/router/router.go index c81de4d..d1d5401 100644 --- a/backend/gateway/router/router.go +++ b/backend/gateway/router/router.go @@ -203,6 +203,13 @@ func SetupRouter(userClient *client.Client, socialClient *client.Client, assetCl galleries.POST("/slots_unlock", galleryCtrl.UnlockSlot) // 解锁/购买新展位 } + // 灵感瀑布相关路由(需要认证) + inspirationFlow := v1.Group("/inspiration-flow") + inspirationFlow.Use(middleware.AuthMiddleware()) + { + inspirationFlow.GET("", galleryCtrl.GetInspirationFlow) // 获取灵感瀑布藏品列表 + } + // 我的展馆路由(需要认证) mygalleries := v1.Group("/mygalleries") mygalleries.Use(middleware.AuthMiddleware()) diff --git a/backend/github.com/topfans/backend/pkg/proto/gallery/gallery.triple.go b/backend/github.com/topfans/backend/pkg/proto/gallery/gallery.triple.go new file mode 100644 index 0000000..d3d77de --- /dev/null +++ b/backend/github.com/topfans/backend/pkg/proto/gallery/gallery.triple.go @@ -0,0 +1,284 @@ +// Code generated by protoc-gen-triple. DO NOT EDIT. +// +// Source: gallery.proto +package gallery + +import ( + "context" +) + +import ( + "dubbo.apache.org/dubbo-go/v3" + "dubbo.apache.org/dubbo-go/v3/client" + "dubbo.apache.org/dubbo-go/v3/common" + "dubbo.apache.org/dubbo-go/v3/common/constant" + "dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol" + "dubbo.apache.org/dubbo-go/v3/server" +) + +// This is a compile-time assertion to ensure that this generated file and the Triple package +// are compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of Triple newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of Triple or updating the Triple +// version compiled into your binary. +const _ = triple_protocol.IsAtLeastVersion0_1_0 + +const ( + // GalleryServiceName is the fully-qualified name of the GalleryService service. + GalleryServiceName = "topfans.gallery.GalleryService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // GalleryServiceGetMyGalleryProcedure is the fully-qualified name of the GalleryService's GetMyGallery RPC. + GalleryServiceGetMyGalleryProcedure = "/topfans.gallery.GalleryService/GetMyGallery" + // GalleryServiceGetUserGalleryProcedure is the fully-qualified name of the GalleryService's GetUserGallery RPC. + GalleryServiceGetUserGalleryProcedure = "/topfans.gallery.GalleryService/GetUserGallery" + // GalleryServicePlaceAssetProcedure is the fully-qualified name of the GalleryService's PlaceAsset RPC. + GalleryServicePlaceAssetProcedure = "/topfans.gallery.GalleryService/PlaceAsset" + // GalleryServiceUnlockSlotProcedure is the fully-qualified name of the GalleryService's UnlockSlot RPC. + GalleryServiceUnlockSlotProcedure = "/topfans.gallery.GalleryService/UnlockSlot" + // GalleryServiceRemoveFromSlotProcedure is the fully-qualified name of the GalleryService's RemoveFromSlot RPC. + GalleryServiceRemoveFromSlotProcedure = "/topfans.gallery.GalleryService/RemoveFromSlot" + // GalleryServiceGetMyExhibitedAssetsProcedure is the fully-qualified name of the GalleryService's GetMyExhibitedAssets RPC. + GalleryServiceGetMyExhibitedAssetsProcedure = "/topfans.gallery.GalleryService/GetMyExhibitedAssets" + // GalleryServiceGetInspirationFlowProcedure is the fully-qualified name of the GalleryService's GetInspirationFlow RPC. + GalleryServiceGetInspirationFlowProcedure = "/topfans.gallery.GalleryService/GetInspirationFlow" +) + +var ( + _ GalleryService = (*GalleryServiceImpl)(nil) +) + +// GalleryService is a client for the topfans.gallery.GalleryService service. +type GalleryService interface { + GetMyGallery(ctx context.Context, req *GetMyGalleryRequest, opts ...client.CallOption) (*GetMyGalleryResponse, error) + GetUserGallery(ctx context.Context, req *GetUserGalleryRequest, opts ...client.CallOption) (*GetUserGalleryResponse, error) + PlaceAsset(ctx context.Context, req *PlaceAssetRequest, opts ...client.CallOption) (*PlaceAssetResponse, error) + UnlockSlot(ctx context.Context, req *UnlockSlotRequest, opts ...client.CallOption) (*UnlockSlotResponse, error) + RemoveFromSlot(ctx context.Context, req *RemoveFromSlotRequest, opts ...client.CallOption) (*RemoveFromSlotResponse, error) + GetMyExhibitedAssets(ctx context.Context, req *GetMyExhibitedAssetsRequest, opts ...client.CallOption) (*GetMyExhibitedAssetsResponse, error) + GetInspirationFlow(ctx context.Context, req *GetInspirationFlowRequest, opts ...client.CallOption) (*GetInspirationFlowResponse, error) +} + +// NewGalleryService constructs a client for the gallery.GalleryService service. +func NewGalleryService(cli *client.Client, opts ...client.ReferenceOption) (GalleryService, error) { + conn, err := cli.DialWithInfo("topfans.gallery.GalleryService", &GalleryService_ClientInfo, opts...) + if err != nil { + return nil, err + } + return &GalleryServiceImpl{ + conn: conn, + }, nil +} + +func SetConsumerGalleryService(srv common.RPCService) { + dubbo.SetConsumerServiceWithInfo(srv, &GalleryService_ClientInfo) +} + +// GalleryServiceImpl implements GalleryService. +type GalleryServiceImpl struct { + conn *client.Connection +} + +func (c *GalleryServiceImpl) GetMyGallery(ctx context.Context, req *GetMyGalleryRequest, opts ...client.CallOption) (*GetMyGalleryResponse, error) { + resp := new(GetMyGalleryResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyGallery", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *GalleryServiceImpl) GetUserGallery(ctx context.Context, req *GetUserGalleryRequest, opts ...client.CallOption) (*GetUserGalleryResponse, error) { + resp := new(GetUserGalleryResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetUserGallery", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *GalleryServiceImpl) PlaceAsset(ctx context.Context, req *PlaceAssetRequest, opts ...client.CallOption) (*PlaceAssetResponse, error) { + resp := new(PlaceAssetResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "PlaceAsset", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *GalleryServiceImpl) UnlockSlot(ctx context.Context, req *UnlockSlotRequest, opts ...client.CallOption) (*UnlockSlotResponse, error) { + resp := new(UnlockSlotResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "UnlockSlot", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *GalleryServiceImpl) RemoveFromSlot(ctx context.Context, req *RemoveFromSlotRequest, opts ...client.CallOption) (*RemoveFromSlotResponse, error) { + resp := new(RemoveFromSlotResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "RemoveFromSlot", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *GalleryServiceImpl) GetMyExhibitedAssets(ctx context.Context, req *GetMyExhibitedAssetsRequest, opts ...client.CallOption) (*GetMyExhibitedAssetsResponse, error) { + resp := new(GetMyExhibitedAssetsResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyExhibitedAssets", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *GalleryServiceImpl) GetInspirationFlow(ctx context.Context, req *GetInspirationFlowRequest, opts ...client.CallOption) (*GetInspirationFlowResponse, error) { + resp := new(GetInspirationFlowResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetInspirationFlow", opts...); err != nil { + return nil, err + } + return resp, nil +} + +var GalleryService_ClientInfo = client.ClientInfo{ + InterfaceName: "topfans.gallery.GalleryService", + MethodNames: []string{"GetMyGallery", "GetUserGallery", "PlaceAsset", "UnlockSlot", "RemoveFromSlot", "GetMyExhibitedAssets", "GetInspirationFlow"}, + ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) { + dubboCli := dubboCliRaw.(*GalleryServiceImpl) + dubboCli.conn = conn + }, +} + +// GalleryServiceHandler is an implementation of the topfans.gallery.GalleryService service. +type GalleryServiceHandler interface { + GetMyGallery(context.Context, *GetMyGalleryRequest) (*GetMyGalleryResponse, error) + GetUserGallery(context.Context, *GetUserGalleryRequest) (*GetUserGalleryResponse, error) + PlaceAsset(context.Context, *PlaceAssetRequest) (*PlaceAssetResponse, error) + UnlockSlot(context.Context, *UnlockSlotRequest) (*UnlockSlotResponse, error) + RemoveFromSlot(context.Context, *RemoveFromSlotRequest) (*RemoveFromSlotResponse, error) + GetMyExhibitedAssets(context.Context, *GetMyExhibitedAssetsRequest) (*GetMyExhibitedAssetsResponse, error) + GetInspirationFlow(context.Context, *GetInspirationFlowRequest) (*GetInspirationFlowResponse, error) +} + +func RegisterGalleryServiceHandler(srv *server.Server, hdlr GalleryServiceHandler, opts ...server.ServiceOption) error { + return srv.Register(hdlr, &GalleryService_ServiceInfo, opts...) +} + +func SetProviderGalleryService(srv common.RPCService) { + dubbo.SetProviderServiceWithInfo(srv, &GalleryService_ServiceInfo) +} + +var GalleryService_ServiceInfo = server.ServiceInfo{ + InterfaceName: "topfans.gallery.GalleryService", + ServiceType: (*GalleryServiceHandler)(nil), + Methods: []server.MethodInfo{ + { + Name: "GetMyGallery", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetMyGalleryRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetMyGalleryRequest) + res, err := handler.(GalleryServiceHandler).GetMyGallery(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetUserGallery", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetUserGalleryRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetUserGalleryRequest) + res, err := handler.(GalleryServiceHandler).GetUserGallery(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "PlaceAsset", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(PlaceAssetRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*PlaceAssetRequest) + res, err := handler.(GalleryServiceHandler).PlaceAsset(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "UnlockSlot", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(UnlockSlotRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*UnlockSlotRequest) + res, err := handler.(GalleryServiceHandler).UnlockSlot(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "RemoveFromSlot", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(RemoveFromSlotRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*RemoveFromSlotRequest) + res, err := handler.(GalleryServiceHandler).RemoveFromSlot(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetMyExhibitedAssets", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetMyExhibitedAssetsRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetMyExhibitedAssetsRequest) + res, err := handler.(GalleryServiceHandler).GetMyExhibitedAssets(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetInspirationFlow", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetInspirationFlowRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetInspirationFlowRequest) + res, err := handler.(GalleryServiceHandler).GetInspirationFlow(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + }, +} diff --git a/backend/github.com/topfans/backend/pkg/proto/social/social.triple.go b/backend/github.com/topfans/backend/pkg/proto/social/social.triple.go new file mode 100644 index 0000000..3bbe0e5 --- /dev/null +++ b/backend/github.com/topfans/backend/pkg/proto/social/social.triple.go @@ -0,0 +1,554 @@ +// Code generated by protoc-gen-triple. DO NOT EDIT. +// +// Source: social.proto +package social + +import ( + "context" +) + +import ( + "dubbo.apache.org/dubbo-go/v3" + "dubbo.apache.org/dubbo-go/v3/client" + "dubbo.apache.org/dubbo-go/v3/common" + "dubbo.apache.org/dubbo-go/v3/common/constant" + "dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol" + "dubbo.apache.org/dubbo-go/v3/server" +) + +// This is a compile-time assertion to ensure that this generated file and the Triple package +// are compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of Triple newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of Triple or updating the Triple +// version compiled into your binary. +const _ = triple_protocol.IsAtLeastVersion0_1_0 + +const ( + // SocialServiceName is the fully-qualified name of the SocialService service. + SocialServiceName = "topfans.social.SocialService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // SocialServiceSendFriendRequestProcedure is the fully-qualified name of the SocialService's SendFriendRequest RPC. + SocialServiceSendFriendRequestProcedure = "/topfans.social.SocialService/SendFriendRequest" + // SocialServiceGetFriendRequestsProcedure is the fully-qualified name of the SocialService's GetFriendRequests RPC. + SocialServiceGetFriendRequestsProcedure = "/topfans.social.SocialService/GetFriendRequests" + // SocialServiceHandleFriendRequestProcedure is the fully-qualified name of the SocialService's HandleFriendRequest RPC. + SocialServiceHandleFriendRequestProcedure = "/topfans.social.SocialService/HandleFriendRequest" + // SocialServiceGetFriendListProcedure is the fully-qualified name of the SocialService's GetFriendList RPC. + SocialServiceGetFriendListProcedure = "/topfans.social.SocialService/GetFriendList" + // SocialServiceDeleteFriendProcedure is the fully-qualified name of the SocialService's DeleteFriend RPC. + SocialServiceDeleteFriendProcedure = "/topfans.social.SocialService/DeleteFriend" + // SocialServiceSetFriendRemarkProcedure is the fully-qualified name of the SocialService's SetFriendRemark RPC. + SocialServiceSetFriendRemarkProcedure = "/topfans.social.SocialService/SetFriendRemark" + // SocialServiceCheckFriendshipProcedure is the fully-qualified name of the SocialService's CheckFriendship RPC. + SocialServiceCheckFriendshipProcedure = "/topfans.social.SocialService/CheckFriendship" + // SocialServiceGetFriendCountProcedure is the fully-qualified name of the SocialService's GetFriendCount RPC. + SocialServiceGetFriendCountProcedure = "/topfans.social.SocialService/GetFriendCount" + // SocialServiceSearchUserForFriendProcedure is the fully-qualified name of the SocialService's SearchUserForFriend RPC. + SocialServiceSearchUserForFriendProcedure = "/topfans.social.SocialService/SearchUserForFriend" + // SocialServiceGetRandomUsersProcedure is the fully-qualified name of the SocialService's GetRandomUsers RPC. + SocialServiceGetRandomUsersProcedure = "/topfans.social.SocialService/GetRandomUsers" + // SocialServiceGetUsersPagedProcedure is the fully-qualified name of the SocialService's GetUsersPaged RPC. + SocialServiceGetUsersPagedProcedure = "/topfans.social.SocialService/GetUsersPaged" + // SocialServiceLikeAssetProcedure is the fully-qualified name of the SocialService's LikeAsset RPC. + SocialServiceLikeAssetProcedure = "/topfans.social.SocialService/LikeAsset" + // SocialServiceUnlikeAssetProcedure is the fully-qualified name of the SocialService's UnlikeAsset RPC. + SocialServiceUnlikeAssetProcedure = "/topfans.social.SocialService/UnlikeAsset" + // SocialServiceCheckAssetLikeProcedure is the fully-qualified name of the SocialService's CheckAssetLike RPC. + SocialServiceCheckAssetLikeProcedure = "/topfans.social.SocialService/CheckAssetLike" + // SocialServiceGetMyLikedAssetsProcedure is the fully-qualified name of the SocialService's GetMyLikedAssets RPC. + SocialServiceGetMyLikedAssetsProcedure = "/topfans.social.SocialService/GetMyLikedAssets" + // SocialServiceGetMyTodayLikedAssetsProcedure is the fully-qualified name of the SocialService's GetMyTodayLikedAssets RPC. + SocialServiceGetMyTodayLikedAssetsProcedure = "/topfans.social.SocialService/GetMyTodayLikedAssets" + // SocialServiceGetMyWeekLikedAssetsProcedure is the fully-qualified name of the SocialService's GetMyWeekLikedAssets RPC. + SocialServiceGetMyWeekLikedAssetsProcedure = "/topfans.social.SocialService/GetMyWeekLikedAssets" +) + +var ( + _ SocialService = (*SocialServiceImpl)(nil) +) + +// SocialService is a client for the topfans.social.SocialService service. +type SocialService interface { + SendFriendRequest(ctx context.Context, req *SendFriendRequestRequest, opts ...client.CallOption) (*SendFriendRequestResponse, error) + GetFriendRequests(ctx context.Context, req *GetFriendRequestsRequest, opts ...client.CallOption) (*GetFriendRequestsResponse, error) + HandleFriendRequest(ctx context.Context, req *HandleFriendRequestRequest, opts ...client.CallOption) (*HandleFriendRequestResponse, error) + GetFriendList(ctx context.Context, req *GetFriendListRequest, opts ...client.CallOption) (*GetFriendListResponse, error) + DeleteFriend(ctx context.Context, req *DeleteFriendRequest, opts ...client.CallOption) (*DeleteFriendResponse, error) + SetFriendRemark(ctx context.Context, req *SetFriendRemarkRequest, opts ...client.CallOption) (*SetFriendRemarkResponse, error) + CheckFriendship(ctx context.Context, req *CheckFriendshipRequest, opts ...client.CallOption) (*CheckFriendshipResponse, error) + GetFriendCount(ctx context.Context, req *GetFriendCountRequest, opts ...client.CallOption) (*GetFriendCountResponse, error) + SearchUserForFriend(ctx context.Context, req *SearchUserForFriendRequest, opts ...client.CallOption) (*SearchUserForFriendResponse, error) + GetRandomUsers(ctx context.Context, req *GetRandomUsersRequest, opts ...client.CallOption) (*GetRandomUsersResponse, error) + GetUsersPaged(ctx context.Context, req *GetUsersPagedRequest, opts ...client.CallOption) (*GetUsersPagedResponse, error) + LikeAsset(ctx context.Context, req *LikeAssetRequest, opts ...client.CallOption) (*LikeAssetResponse, error) + UnlikeAsset(ctx context.Context, req *UnlikeAssetRequest, opts ...client.CallOption) (*UnlikeAssetResponse, error) + CheckAssetLike(ctx context.Context, req *CheckAssetLikeRequest, opts ...client.CallOption) (*CheckAssetLikeResponse, error) + GetMyLikedAssets(ctx context.Context, req *GetMyLikedAssetsRequest, opts ...client.CallOption) (*GetMyLikedAssetsResponse, error) + GetMyTodayLikedAssets(ctx context.Context, req *GetMyTodayLikedAssetsRequest, opts ...client.CallOption) (*GetMyTodayLikedAssetsResponse, error) + GetMyWeekLikedAssets(ctx context.Context, req *GetMyWeekLikedAssetsRequest, opts ...client.CallOption) (*GetMyWeekLikedAssetsResponse, error) +} + +// NewSocialService constructs a client for the social.SocialService service. +func NewSocialService(cli *client.Client, opts ...client.ReferenceOption) (SocialService, error) { + conn, err := cli.DialWithInfo("topfans.social.SocialService", &SocialService_ClientInfo, opts...) + if err != nil { + return nil, err + } + return &SocialServiceImpl{ + conn: conn, + }, nil +} + +func SetConsumerSocialService(srv common.RPCService) { + dubbo.SetConsumerServiceWithInfo(srv, &SocialService_ClientInfo) +} + +// SocialServiceImpl implements SocialService. +type SocialServiceImpl struct { + conn *client.Connection +} + +func (c *SocialServiceImpl) SendFriendRequest(ctx context.Context, req *SendFriendRequestRequest, opts ...client.CallOption) (*SendFriendRequestResponse, error) { + resp := new(SendFriendRequestResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "SendFriendRequest", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) GetFriendRequests(ctx context.Context, req *GetFriendRequestsRequest, opts ...client.CallOption) (*GetFriendRequestsResponse, error) { + resp := new(GetFriendRequestsResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetFriendRequests", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) HandleFriendRequest(ctx context.Context, req *HandleFriendRequestRequest, opts ...client.CallOption) (*HandleFriendRequestResponse, error) { + resp := new(HandleFriendRequestResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "HandleFriendRequest", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) GetFriendList(ctx context.Context, req *GetFriendListRequest, opts ...client.CallOption) (*GetFriendListResponse, error) { + resp := new(GetFriendListResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetFriendList", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) DeleteFriend(ctx context.Context, req *DeleteFriendRequest, opts ...client.CallOption) (*DeleteFriendResponse, error) { + resp := new(DeleteFriendResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "DeleteFriend", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) SetFriendRemark(ctx context.Context, req *SetFriendRemarkRequest, opts ...client.CallOption) (*SetFriendRemarkResponse, error) { + resp := new(SetFriendRemarkResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "SetFriendRemark", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) CheckFriendship(ctx context.Context, req *CheckFriendshipRequest, opts ...client.CallOption) (*CheckFriendshipResponse, error) { + resp := new(CheckFriendshipResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "CheckFriendship", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) GetFriendCount(ctx context.Context, req *GetFriendCountRequest, opts ...client.CallOption) (*GetFriendCountResponse, error) { + resp := new(GetFriendCountResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetFriendCount", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) SearchUserForFriend(ctx context.Context, req *SearchUserForFriendRequest, opts ...client.CallOption) (*SearchUserForFriendResponse, error) { + resp := new(SearchUserForFriendResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "SearchUserForFriend", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) GetRandomUsers(ctx context.Context, req *GetRandomUsersRequest, opts ...client.CallOption) (*GetRandomUsersResponse, error) { + resp := new(GetRandomUsersResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetRandomUsers", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) GetUsersPaged(ctx context.Context, req *GetUsersPagedRequest, opts ...client.CallOption) (*GetUsersPagedResponse, error) { + resp := new(GetUsersPagedResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetUsersPaged", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) LikeAsset(ctx context.Context, req *LikeAssetRequest, opts ...client.CallOption) (*LikeAssetResponse, error) { + resp := new(LikeAssetResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "LikeAsset", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) UnlikeAsset(ctx context.Context, req *UnlikeAssetRequest, opts ...client.CallOption) (*UnlikeAssetResponse, error) { + resp := new(UnlikeAssetResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "UnlikeAsset", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) CheckAssetLike(ctx context.Context, req *CheckAssetLikeRequest, opts ...client.CallOption) (*CheckAssetLikeResponse, error) { + resp := new(CheckAssetLikeResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "CheckAssetLike", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) GetMyLikedAssets(ctx context.Context, req *GetMyLikedAssetsRequest, opts ...client.CallOption) (*GetMyLikedAssetsResponse, error) { + resp := new(GetMyLikedAssetsResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyLikedAssets", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) GetMyTodayLikedAssets(ctx context.Context, req *GetMyTodayLikedAssetsRequest, opts ...client.CallOption) (*GetMyTodayLikedAssetsResponse, error) { + resp := new(GetMyTodayLikedAssetsResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyTodayLikedAssets", opts...); err != nil { + return nil, err + } + return resp, nil +} + +func (c *SocialServiceImpl) GetMyWeekLikedAssets(ctx context.Context, req *GetMyWeekLikedAssetsRequest, opts ...client.CallOption) (*GetMyWeekLikedAssetsResponse, error) { + resp := new(GetMyWeekLikedAssetsResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyWeekLikedAssets", opts...); err != nil { + return nil, err + } + return resp, nil +} + +var SocialService_ClientInfo = client.ClientInfo{ + InterfaceName: "topfans.social.SocialService", + MethodNames: []string{"SendFriendRequest", "GetFriendRequests", "HandleFriendRequest", "GetFriendList", "DeleteFriend", "SetFriendRemark", "CheckFriendship", "GetFriendCount", "SearchUserForFriend", "GetRandomUsers", "GetUsersPaged", "LikeAsset", "UnlikeAsset", "CheckAssetLike", "GetMyLikedAssets", "GetMyTodayLikedAssets", "GetMyWeekLikedAssets"}, + ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) { + dubboCli := dubboCliRaw.(*SocialServiceImpl) + dubboCli.conn = conn + }, +} + +// SocialServiceHandler is an implementation of the topfans.social.SocialService service. +type SocialServiceHandler interface { + SendFriendRequest(context.Context, *SendFriendRequestRequest) (*SendFriendRequestResponse, error) + GetFriendRequests(context.Context, *GetFriendRequestsRequest) (*GetFriendRequestsResponse, error) + HandleFriendRequest(context.Context, *HandleFriendRequestRequest) (*HandleFriendRequestResponse, error) + GetFriendList(context.Context, *GetFriendListRequest) (*GetFriendListResponse, error) + DeleteFriend(context.Context, *DeleteFriendRequest) (*DeleteFriendResponse, error) + SetFriendRemark(context.Context, *SetFriendRemarkRequest) (*SetFriendRemarkResponse, error) + CheckFriendship(context.Context, *CheckFriendshipRequest) (*CheckFriendshipResponse, error) + GetFriendCount(context.Context, *GetFriendCountRequest) (*GetFriendCountResponse, error) + SearchUserForFriend(context.Context, *SearchUserForFriendRequest) (*SearchUserForFriendResponse, error) + GetRandomUsers(context.Context, *GetRandomUsersRequest) (*GetRandomUsersResponse, error) + GetUsersPaged(context.Context, *GetUsersPagedRequest) (*GetUsersPagedResponse, error) + LikeAsset(context.Context, *LikeAssetRequest) (*LikeAssetResponse, error) + UnlikeAsset(context.Context, *UnlikeAssetRequest) (*UnlikeAssetResponse, error) + CheckAssetLike(context.Context, *CheckAssetLikeRequest) (*CheckAssetLikeResponse, error) + GetMyLikedAssets(context.Context, *GetMyLikedAssetsRequest) (*GetMyLikedAssetsResponse, error) + GetMyTodayLikedAssets(context.Context, *GetMyTodayLikedAssetsRequest) (*GetMyTodayLikedAssetsResponse, error) + GetMyWeekLikedAssets(context.Context, *GetMyWeekLikedAssetsRequest) (*GetMyWeekLikedAssetsResponse, error) +} + +func RegisterSocialServiceHandler(srv *server.Server, hdlr SocialServiceHandler, opts ...server.ServiceOption) error { + return srv.Register(hdlr, &SocialService_ServiceInfo, opts...) +} + +func SetProviderSocialService(srv common.RPCService) { + dubbo.SetProviderServiceWithInfo(srv, &SocialService_ServiceInfo) +} + +var SocialService_ServiceInfo = server.ServiceInfo{ + InterfaceName: "topfans.social.SocialService", + ServiceType: (*SocialServiceHandler)(nil), + Methods: []server.MethodInfo{ + { + Name: "SendFriendRequest", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(SendFriendRequestRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*SendFriendRequestRequest) + res, err := handler.(SocialServiceHandler).SendFriendRequest(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetFriendRequests", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetFriendRequestsRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetFriendRequestsRequest) + res, err := handler.(SocialServiceHandler).GetFriendRequests(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "HandleFriendRequest", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(HandleFriendRequestRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*HandleFriendRequestRequest) + res, err := handler.(SocialServiceHandler).HandleFriendRequest(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetFriendList", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetFriendListRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetFriendListRequest) + res, err := handler.(SocialServiceHandler).GetFriendList(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "DeleteFriend", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(DeleteFriendRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*DeleteFriendRequest) + res, err := handler.(SocialServiceHandler).DeleteFriend(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "SetFriendRemark", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(SetFriendRemarkRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*SetFriendRemarkRequest) + res, err := handler.(SocialServiceHandler).SetFriendRemark(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "CheckFriendship", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(CheckFriendshipRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*CheckFriendshipRequest) + res, err := handler.(SocialServiceHandler).CheckFriendship(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetFriendCount", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetFriendCountRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetFriendCountRequest) + res, err := handler.(SocialServiceHandler).GetFriendCount(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "SearchUserForFriend", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(SearchUserForFriendRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*SearchUserForFriendRequest) + res, err := handler.(SocialServiceHandler).SearchUserForFriend(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetRandomUsers", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetRandomUsersRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetRandomUsersRequest) + res, err := handler.(SocialServiceHandler).GetRandomUsers(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetUsersPaged", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetUsersPagedRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetUsersPagedRequest) + res, err := handler.(SocialServiceHandler).GetUsersPaged(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "LikeAsset", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(LikeAssetRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*LikeAssetRequest) + res, err := handler.(SocialServiceHandler).LikeAsset(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "UnlikeAsset", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(UnlikeAssetRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*UnlikeAssetRequest) + res, err := handler.(SocialServiceHandler).UnlikeAsset(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "CheckAssetLike", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(CheckAssetLikeRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*CheckAssetLikeRequest) + res, err := handler.(SocialServiceHandler).CheckAssetLike(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetMyLikedAssets", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetMyLikedAssetsRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetMyLikedAssetsRequest) + res, err := handler.(SocialServiceHandler).GetMyLikedAssets(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetMyTodayLikedAssets", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetMyTodayLikedAssetsRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetMyTodayLikedAssetsRequest) + res, err := handler.(SocialServiceHandler).GetMyTodayLikedAssets(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + { + Name: "GetMyWeekLikedAssets", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetMyWeekLikedAssetsRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetMyWeekLikedAssetsRequest) + res, err := handler.(SocialServiceHandler).GetMyWeekLikedAssets(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, + }, +} diff --git a/backend/pkg/proto/gallery/gallery.pb.go b/backend/pkg/proto/gallery/gallery.pb.go index 27a730e..28ae39f 100644 --- a/backend/pkg/proto/gallery/gallery.pb.go +++ b/backend/pkg/proto/gallery/gallery.pb.go @@ -1215,6 +1215,282 @@ func (x *ExhibitedAssetItem) GetEarnings() int64 { return 0 } +// 获取灵感瀑布藏品列表请求 +type GetInspirationFlowRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Cursor string `protobuf:"bytes,1,opt,name=cursor,proto3" json:"cursor,omitempty"` // 游标(首次请求为空) + Direction string `protobuf:"bytes,2,opt,name=direction,proto3" json:"direction,omitempty"` // 滚动方向:right(加载新数据)/ left(加载历史) + Limit int32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` // 每页数量(默认10,最大20) + Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` // 过滤类型:badge/poster/original/all(默认all) + SessionId string `protobuf:"bytes,5,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` // 会话ID(首次请求时为空,后端返回新的session_id) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetInspirationFlowRequest) Reset() { + *x = GetInspirationFlowRequest{} + mi := &file_gallery_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetInspirationFlowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInspirationFlowRequest) ProtoMessage() {} + +func (x *GetInspirationFlowRequest) ProtoReflect() protoreflect.Message { + mi := &file_gallery_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInspirationFlowRequest.ProtoReflect.Descriptor instead. +func (*GetInspirationFlowRequest) Descriptor() ([]byte, []int) { + return file_gallery_proto_rawDescGZIP(), []int{20} +} + +func (x *GetInspirationFlowRequest) GetCursor() string { + if x != nil { + return x.Cursor + } + return "" +} + +func (x *GetInspirationFlowRequest) GetDirection() string { + if x != nil { + return x.Direction + } + return "" +} + +func (x *GetInspirationFlowRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *GetInspirationFlowRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *GetInspirationFlowRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +// 获取灵感瀑布藏品列表响应 +type GetInspirationFlowResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Base *common.BaseResponse `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"` + Data *InspirationFlowData `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetInspirationFlowResponse) Reset() { + *x = GetInspirationFlowResponse{} + mi := &file_gallery_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetInspirationFlowResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetInspirationFlowResponse) ProtoMessage() {} + +func (x *GetInspirationFlowResponse) ProtoReflect() protoreflect.Message { + mi := &file_gallery_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetInspirationFlowResponse.ProtoReflect.Descriptor instead. +func (*GetInspirationFlowResponse) Descriptor() ([]byte, []int) { + return file_gallery_proto_rawDescGZIP(), []int{21} +} + +func (x *GetInspirationFlowResponse) GetBase() *common.BaseResponse { + if x != nil { + return x.Base + } + return nil +} + +func (x *GetInspirationFlowResponse) GetData() *InspirationFlowData { + if x != nil { + return x.Data + } + return nil +} + +// 灵感瀑布数据 +type InspirationFlowData struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*InspirationFlowItem `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` // 藏品列表 + Cursor string `protobuf:"bytes,2,opt,name=cursor,proto3" json:"cursor,omitempty"` // 下次请求的游标 + HasMore bool `protobuf:"varint,3,opt,name=has_more,json=hasMore,proto3" json:"has_more,omitempty"` // 是否有更多 + SessionId string `protobuf:"bytes,4,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` // 会话ID(首次请求时返回) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InspirationFlowData) Reset() { + *x = InspirationFlowData{} + mi := &file_gallery_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InspirationFlowData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InspirationFlowData) ProtoMessage() {} + +func (x *InspirationFlowData) ProtoReflect() protoreflect.Message { + mi := &file_gallery_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InspirationFlowData.ProtoReflect.Descriptor instead. +func (*InspirationFlowData) Descriptor() ([]byte, []int) { + return file_gallery_proto_rawDescGZIP(), []int{22} +} + +func (x *InspirationFlowData) GetItems() []*InspirationFlowItem { + if x != nil { + return x.Items + } + return nil +} + +func (x *InspirationFlowData) GetCursor() string { + if x != nil { + return x.Cursor + } + return "" +} + +func (x *InspirationFlowData) GetHasMore() bool { + if x != nil { + return x.HasMore + } + return false +} + +func (x *InspirationFlowData) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +// 灵感瀑布藏品项 +type InspirationFlowItem struct { + state protoimpl.MessageState `protogen:"open.v1"` + AssetId int64 `protobuf:"varint,1,opt,name=asset_id,json=assetId,proto3" json:"asset_id,omitempty"` // 资产ID + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // 藏品名称 + CoverUrl string `protobuf:"bytes,3,opt,name=cover_url,json=coverUrl,proto3" json:"cover_url,omitempty"` // 封面图URL + LikeCount int32 `protobuf:"varint,4,opt,name=like_count,json=likeCount,proto3" json:"like_count,omitempty"` // 点赞数 + OwnerNickname string `protobuf:"bytes,5,opt,name=owner_nickname,json=ownerNickname,proto3" json:"owner_nickname,omitempty"` // 展出者昵称 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InspirationFlowItem) Reset() { + *x = InspirationFlowItem{} + mi := &file_gallery_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InspirationFlowItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InspirationFlowItem) ProtoMessage() {} + +func (x *InspirationFlowItem) ProtoReflect() protoreflect.Message { + mi := &file_gallery_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InspirationFlowItem.ProtoReflect.Descriptor instead. +func (*InspirationFlowItem) Descriptor() ([]byte, []int) { + return file_gallery_proto_rawDescGZIP(), []int{23} +} + +func (x *InspirationFlowItem) GetAssetId() int64 { + if x != nil { + return x.AssetId + } + return 0 +} + +func (x *InspirationFlowItem) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *InspirationFlowItem) GetCoverUrl() string { + if x != nil { + return x.CoverUrl + } + return "" +} + +func (x *InspirationFlowItem) GetLikeCount() int32 { + if x != nil { + return x.LikeCount + } + return 0 +} + +func (x *InspirationFlowItem) GetOwnerNickname() string { + if x != nil { + return x.OwnerNickname + } + return "" +} + var File_gallery_proto protoreflect.FileDescriptor const file_gallery_proto_rawDesc = "" + @@ -1310,7 +1586,30 @@ const file_gallery_proto_rawDesc = "" + "like_count\x18\x04 \x01(\x05R\tlikeCount\x12!\n" + "\fexhibited_at\x18\x05 \x01(\x03R\vexhibitedAt\x12\x1b\n" + "\texpire_at\x18\x06 \x01(\x03R\bexpireAt\x12\x1a\n" + - "\bearnings\x18\a \x01(\x03R\bearnings2\xb4\x06\n" + + "\bearnings\x18\a \x01(\x03R\bearnings\"\x9a\x01\n" + + "\x19GetInspirationFlowRequest\x12\x16\n" + + "\x06cursor\x18\x01 \x01(\tR\x06cursor\x12\x1c\n" + + "\tdirection\x18\x02 \x01(\tR\tdirection\x12\x14\n" + + "\x05limit\x18\x03 \x01(\x05R\x05limit\x12\x12\n" + + "\x04type\x18\x04 \x01(\tR\x04type\x12\x1d\n" + + "\n" + + "session_id\x18\x05 \x01(\tR\tsessionId\"\x88\x01\n" + + "\x1aGetInspirationFlowResponse\x120\n" + + "\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x128\n" + + "\x04data\x18\x02 \x01(\v2$.topfans.gallery.InspirationFlowDataR\x04data\"\xa3\x01\n" + + "\x13InspirationFlowData\x12:\n" + + "\x05items\x18\x01 \x03(\v2$.topfans.gallery.InspirationFlowItemR\x05items\x12\x16\n" + + "\x06cursor\x18\x02 \x01(\tR\x06cursor\x12\x19\n" + + "\bhas_more\x18\x03 \x01(\bR\ahasMore\x12\x1d\n" + + "\n" + + "session_id\x18\x04 \x01(\tR\tsessionId\"\xa7\x01\n" + + "\x13InspirationFlowItem\x12\x19\n" + + "\basset_id\x18\x01 \x01(\x03R\aassetId\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x1b\n" + + "\tcover_url\x18\x03 \x01(\tR\bcoverUrl\x12\x1d\n" + + "\n" + + "like_count\x18\x04 \x01(\x05R\tlikeCount\x12%\n" + + "\x0eowner_nickname\x18\x05 \x01(\tR\rownerNickname2\xc6\a\n" + "\x0eGalleryService\x12u\n" + "\fGetMyGallery\x12$.topfans.gallery.GetMyGalleryRequest\x1a%.topfans.gallery.GetMyGalleryResponse\"\x18\x82\xd3\xe4\x93\x02\x12\x12\x10/api/mygalleries\x12\x86\x01\n" + "\x0eGetUserGallery\x12&.topfans.gallery.GetUserGalleryRequest\x1a'.topfans.gallery.GetUserGalleryResponse\"#\x82\xd3\xe4\x93\x02\x1d\x12\x1b/api/galleries/{target_uid}\x12v\n" + @@ -1319,7 +1618,8 @@ const file_gallery_proto_rawDesc = "" + "\n" + "UnlockSlot\x12\".topfans.gallery.UnlockSlotRequest\x1a#.topfans.gallery.UnlockSlotResponse\"&\x82\xd3\xe4\x93\x02 :\x01*\"\x1b/api/galleries/slots_unlock\x12\x8f\x01\n" + "\x0eRemoveFromSlot\x12&.topfans.gallery.RemoveFromSlotRequest\x1a'.topfans.gallery.RemoveFromSlotResponse\",\x82\xd3\xe4\x93\x02&*$/api/galleries/slots/{slot_id}/asset\x12\x98\x01\n" + - "\x14GetMyExhibitedAssets\x12,.topfans.gallery.GetMyExhibitedAssetsRequest\x1a-.topfans.gallery.GetMyExhibitedAssetsResponse\"#\x82\xd3\xe4\x93\x02\x1d\x12\x1b/api/v1/me/exhibited-assetsB6Z4github.com/topfans/backend/pkg/proto/gallery;galleryb\x06proto3" + "\x14GetMyExhibitedAssets\x12,.topfans.gallery.GetMyExhibitedAssetsRequest\x1a-.topfans.gallery.GetMyExhibitedAssetsResponse\"#\x82\xd3\xe4\x93\x02\x1d\x12\x1b/api/v1/me/exhibited-assets\x12\x8f\x01\n" + + "\x12GetInspirationFlow\x12*.topfans.gallery.GetInspirationFlowRequest\x1a+.topfans.gallery.GetInspirationFlowResponse\" \x82\xd3\xe4\x93\x02\x1a\x12\x18/api/v1/inspiration-flowB6Z4github.com/topfans/backend/pkg/proto/gallery;galleryb\x06proto3" var ( file_gallery_proto_rawDescOnce sync.Once @@ -1333,7 +1633,7 @@ func file_gallery_proto_rawDescGZIP() []byte { return file_gallery_proto_rawDescData } -var file_gallery_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_gallery_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_gallery_proto_goTypes = []any{ (*GetMyGalleryRequest)(nil), // 0: topfans.gallery.GetMyGalleryRequest (*GetMyGalleryResponse)(nil), // 1: topfans.gallery.GetMyGalleryResponse @@ -1355,41 +1655,50 @@ var file_gallery_proto_goTypes = []any{ (*GetMyExhibitedAssetsResponse)(nil), // 17: topfans.gallery.GetMyExhibitedAssetsResponse (*ExhibitedAssetsData)(nil), // 18: topfans.gallery.ExhibitedAssetsData (*ExhibitedAssetItem)(nil), // 19: topfans.gallery.ExhibitedAssetItem - (*common.BaseResponse)(nil), // 20: topfans.common.BaseResponse + (*GetInspirationFlowRequest)(nil), // 20: topfans.gallery.GetInspirationFlowRequest + (*GetInspirationFlowResponse)(nil), // 21: topfans.gallery.GetInspirationFlowResponse + (*InspirationFlowData)(nil), // 22: topfans.gallery.InspirationFlowData + (*InspirationFlowItem)(nil), // 23: topfans.gallery.InspirationFlowItem + (*common.BaseResponse)(nil), // 24: topfans.common.BaseResponse } var file_gallery_proto_depIdxs = []int32{ - 20, // 0: topfans.gallery.GetMyGalleryResponse.base:type_name -> topfans.common.BaseResponse + 24, // 0: topfans.gallery.GetMyGalleryResponse.base:type_name -> topfans.common.BaseResponse 8, // 1: topfans.gallery.GetMyGalleryResponse.data:type_name -> topfans.gallery.GalleryData - 20, // 2: topfans.gallery.GetUserGalleryResponse.base:type_name -> topfans.common.BaseResponse + 24, // 2: topfans.gallery.GetUserGalleryResponse.base:type_name -> topfans.common.BaseResponse 8, // 3: topfans.gallery.GetUserGalleryResponse.data:type_name -> topfans.gallery.GalleryData - 20, // 4: topfans.gallery.PlaceAssetResponse.base:type_name -> topfans.common.BaseResponse + 24, // 4: topfans.gallery.PlaceAssetResponse.base:type_name -> topfans.common.BaseResponse 12, // 5: topfans.gallery.PlaceAssetResponse.data:type_name -> topfans.gallery.PlaceAssetData - 20, // 6: topfans.gallery.UnlockSlotResponse.base:type_name -> topfans.common.BaseResponse + 24, // 6: topfans.gallery.UnlockSlotResponse.base:type_name -> topfans.common.BaseResponse 13, // 7: topfans.gallery.UnlockSlotResponse.data:type_name -> topfans.gallery.UnlockSlotData 9, // 8: topfans.gallery.GalleryData.slots:type_name -> topfans.gallery.SlotInfo 10, // 9: topfans.gallery.SlotInfo.asset:type_name -> topfans.gallery.AssetInfo 11, // 10: topfans.gallery.SlotInfo.unlock_condition:type_name -> topfans.gallery.UnlockCondition - 20, // 11: topfans.gallery.RemoveFromSlotResponse.base:type_name -> topfans.common.BaseResponse - 20, // 12: topfans.gallery.GetMyExhibitedAssetsResponse.base:type_name -> topfans.common.BaseResponse + 24, // 11: topfans.gallery.RemoveFromSlotResponse.base:type_name -> topfans.common.BaseResponse + 24, // 12: topfans.gallery.GetMyExhibitedAssetsResponse.base:type_name -> topfans.common.BaseResponse 18, // 13: topfans.gallery.GetMyExhibitedAssetsResponse.data:type_name -> topfans.gallery.ExhibitedAssetsData 19, // 14: topfans.gallery.ExhibitedAssetsData.items:type_name -> topfans.gallery.ExhibitedAssetItem - 0, // 15: topfans.gallery.GalleryService.GetMyGallery:input_type -> topfans.gallery.GetMyGalleryRequest - 2, // 16: topfans.gallery.GalleryService.GetUserGallery:input_type -> topfans.gallery.GetUserGalleryRequest - 4, // 17: topfans.gallery.GalleryService.PlaceAsset:input_type -> topfans.gallery.PlaceAssetRequest - 6, // 18: topfans.gallery.GalleryService.UnlockSlot:input_type -> topfans.gallery.UnlockSlotRequest - 14, // 19: topfans.gallery.GalleryService.RemoveFromSlot:input_type -> topfans.gallery.RemoveFromSlotRequest - 16, // 20: topfans.gallery.GalleryService.GetMyExhibitedAssets:input_type -> topfans.gallery.GetMyExhibitedAssetsRequest - 1, // 21: topfans.gallery.GalleryService.GetMyGallery:output_type -> topfans.gallery.GetMyGalleryResponse - 3, // 22: topfans.gallery.GalleryService.GetUserGallery:output_type -> topfans.gallery.GetUserGalleryResponse - 5, // 23: topfans.gallery.GalleryService.PlaceAsset:output_type -> topfans.gallery.PlaceAssetResponse - 7, // 24: topfans.gallery.GalleryService.UnlockSlot:output_type -> topfans.gallery.UnlockSlotResponse - 15, // 25: topfans.gallery.GalleryService.RemoveFromSlot:output_type -> topfans.gallery.RemoveFromSlotResponse - 17, // 26: topfans.gallery.GalleryService.GetMyExhibitedAssets:output_type -> topfans.gallery.GetMyExhibitedAssetsResponse - 21, // [21:27] is the sub-list for method output_type - 15, // [15:21] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 24, // 15: topfans.gallery.GetInspirationFlowResponse.base:type_name -> topfans.common.BaseResponse + 22, // 16: topfans.gallery.GetInspirationFlowResponse.data:type_name -> topfans.gallery.InspirationFlowData + 23, // 17: topfans.gallery.InspirationFlowData.items:type_name -> topfans.gallery.InspirationFlowItem + 0, // 18: topfans.gallery.GalleryService.GetMyGallery:input_type -> topfans.gallery.GetMyGalleryRequest + 2, // 19: topfans.gallery.GalleryService.GetUserGallery:input_type -> topfans.gallery.GetUserGalleryRequest + 4, // 20: topfans.gallery.GalleryService.PlaceAsset:input_type -> topfans.gallery.PlaceAssetRequest + 6, // 21: topfans.gallery.GalleryService.UnlockSlot:input_type -> topfans.gallery.UnlockSlotRequest + 14, // 22: topfans.gallery.GalleryService.RemoveFromSlot:input_type -> topfans.gallery.RemoveFromSlotRequest + 16, // 23: topfans.gallery.GalleryService.GetMyExhibitedAssets:input_type -> topfans.gallery.GetMyExhibitedAssetsRequest + 20, // 24: topfans.gallery.GalleryService.GetInspirationFlow:input_type -> topfans.gallery.GetInspirationFlowRequest + 1, // 25: topfans.gallery.GalleryService.GetMyGallery:output_type -> topfans.gallery.GetMyGalleryResponse + 3, // 26: topfans.gallery.GalleryService.GetUserGallery:output_type -> topfans.gallery.GetUserGalleryResponse + 5, // 27: topfans.gallery.GalleryService.PlaceAsset:output_type -> topfans.gallery.PlaceAssetResponse + 7, // 28: topfans.gallery.GalleryService.UnlockSlot:output_type -> topfans.gallery.UnlockSlotResponse + 15, // 29: topfans.gallery.GalleryService.RemoveFromSlot:output_type -> topfans.gallery.RemoveFromSlotResponse + 17, // 30: topfans.gallery.GalleryService.GetMyExhibitedAssets:output_type -> topfans.gallery.GetMyExhibitedAssetsResponse + 21, // 31: topfans.gallery.GalleryService.GetInspirationFlow:output_type -> topfans.gallery.GetInspirationFlowResponse + 25, // [25:32] is the sub-list for method output_type + 18, // [18:25] is the sub-list for method input_type + 18, // [18:18] is the sub-list for extension type_name + 18, // [18:18] is the sub-list for extension extendee + 0, // [0:18] is the sub-list for field type_name } func init() { file_gallery_proto_init() } @@ -1403,7 +1712,7 @@ func file_gallery_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_gallery_proto_rawDesc), len(file_gallery_proto_rawDesc)), NumEnums: 0, - NumMessages: 20, + NumMessages: 24, NumExtensions: 0, NumServices: 1, }, diff --git a/backend/pkg/proto/gallery/gallery.triple.go b/backend/pkg/proto/gallery/gallery.triple.go index 18b0bd9..4a991a4 100644 --- a/backend/pkg/proto/gallery/gallery.triple.go +++ b/backend/pkg/proto/gallery/gallery.triple.go @@ -48,6 +48,8 @@ const ( GalleryServiceRemoveFromSlotProcedure = "/topfans.gallery.GalleryService/RemoveFromSlot" // GalleryServiceGetMyExhibitedAssetsProcedure is the fully-qualified name of the GalleryService's GetMyExhibitedAssets RPC. GalleryServiceGetMyExhibitedAssetsProcedure = "/topfans.gallery.GalleryService/GetMyExhibitedAssets" + // GalleryServiceGetInspirationFlowProcedure is the fully-qualified name of the GalleryService's GetInspirationFlow RPC. + GalleryServiceGetInspirationFlowProcedure = "/topfans.gallery.GalleryService/GetInspirationFlow" ) var ( @@ -62,6 +64,7 @@ type GalleryService interface { UnlockSlot(ctx context.Context, req *UnlockSlotRequest, opts ...client.CallOption) (*UnlockSlotResponse, error) RemoveFromSlot(ctx context.Context, req *RemoveFromSlotRequest, opts ...client.CallOption) (*RemoveFromSlotResponse, error) GetMyExhibitedAssets(ctx context.Context, req *GetMyExhibitedAssetsRequest, opts ...client.CallOption) (*GetMyExhibitedAssetsResponse, error) + GetInspirationFlow(ctx context.Context, req *GetInspirationFlowRequest, opts ...client.CallOption) (*GetInspirationFlowResponse, error) } // NewGalleryService constructs a client for the gallery.GalleryService service. @@ -132,9 +135,17 @@ func (c *GalleryServiceImpl) GetMyExhibitedAssets(ctx context.Context, req *GetM return resp, nil } +func (c *GalleryServiceImpl) GetInspirationFlow(ctx context.Context, req *GetInspirationFlowRequest, opts ...client.CallOption) (*GetInspirationFlowResponse, error) { + resp := new(GetInspirationFlowResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetInspirationFlow", opts...); err != nil { + return nil, err + } + return resp, nil +} + var GalleryService_ClientInfo = client.ClientInfo{ InterfaceName: "topfans.gallery.GalleryService", - MethodNames: []string{"GetMyGallery", "GetUserGallery", "PlaceAsset", "UnlockSlot", "RemoveFromSlot", "GetMyExhibitedAssets"}, + MethodNames: []string{"GetMyGallery", "GetUserGallery", "PlaceAsset", "UnlockSlot", "RemoveFromSlot", "GetMyExhibitedAssets", "GetInspirationFlow"}, ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) { dubboCli := dubboCliRaw.(*GalleryServiceImpl) dubboCli.conn = conn @@ -149,6 +160,7 @@ type GalleryServiceHandler interface { UnlockSlot(context.Context, *UnlockSlotRequest) (*UnlockSlotResponse, error) RemoveFromSlot(context.Context, *RemoveFromSlotRequest) (*RemoveFromSlotResponse, error) GetMyExhibitedAssets(context.Context, *GetMyExhibitedAssetsRequest) (*GetMyExhibitedAssetsResponse, error) + GetInspirationFlow(context.Context, *GetInspirationFlowRequest) (*GetInspirationFlowResponse, error) } func RegisterGalleryServiceHandler(srv *server.Server, hdlr GalleryServiceHandler, opts ...server.ServiceOption) error { @@ -253,5 +265,20 @@ var GalleryService_ServiceInfo = server.ServiceInfo{ return triple_protocol.NewResponse(res), nil }, }, + { + Name: "GetInspirationFlow", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetInspirationFlowRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetInspirationFlowRequest) + res, err := handler.(GalleryServiceHandler).GetInspirationFlow(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, }, } diff --git a/backend/pkg/proto/task/task.pb.go b/backend/pkg/proto/task/task.pb.go index ed997ca..77ff955 100644 --- a/backend/pkg/proto/task/task.pb.go +++ b/backend/pkg/proto/task/task.pb.go @@ -605,6 +605,7 @@ type OnboardingStage struct { Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"` // pending/completed/in_progress IsCurrent bool `protobuf:"varint,7,opt,name=is_current,json=isCurrent,proto3" json:"is_current,omitempty"` AllTasksCompleted bool `protobuf:"varint,8,opt,name=all_tasks_completed,json=allTasksCompleted,proto3" json:"all_tasks_completed,omitempty"` // 该阶段所有任务是否完成 + IsRewardClaimed bool `protobuf:"varint,9,opt,name=is_reward_claimed,json=isRewardClaimed,proto3" json:"is_reward_claimed,omitempty"` // 该阶段奖励是否已领取 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -695,6 +696,13 @@ func (x *OnboardingStage) GetAllTasksCompleted() bool { return false } +func (x *OnboardingStage) GetIsRewardClaimed() bool { + if x != nil { + return x.IsRewardClaimed + } + return false +} + type CompleteGuideRequest struct { state protoimpl.MessageState `protogen:"open.v1"` TaskKey string `protobuf:"bytes,1,opt,name=task_key,json=taskKey,proto3" json:"task_key,omitempty"` @@ -1942,7 +1950,7 @@ const file_task_proto_rawDesc = "" + "\n" + "experience\x18\x04 \x01(\x03R\n" + "experience\x12*\n" + - "\x11claimed_task_keys\x18\x05 \x03(\tR\x0fclaimedTaskKeys\"\x96\x02\n" + + "\x11claimed_task_keys\x18\x05 \x03(\tR\x0fclaimedTaskKeys\"\xc2\x02\n" + "\x0fOnboardingStage\x12\x14\n" + "\x05stage\x18\x01 \x01(\x05R\x05stage\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12,\n" + @@ -1953,7 +1961,8 @@ const file_task_proto_rawDesc = "" + "\x06status\x18\x06 \x01(\tR\x06status\x12\x1d\n" + "\n" + "is_current\x18\a \x01(\bR\tisCurrent\x12.\n" + - "\x13all_tasks_completed\x18\b \x01(\bR\x11allTasksCompleted\"h\n" + + "\x13all_tasks_completed\x18\b \x01(\bR\x11allTasksCompleted\x12*\n" + + "\x11is_reward_claimed\x18\t \x01(\bR\x0fisRewardClaimed\"h\n" + "\x14CompleteGuideRequest\x12\x19\n" + "\btask_key\x18\x01 \x01(\tR\ataskKey\x125\n" + "\x06stages\x18\x02 \x03(\v2\x1d.topfans.task.OnboardingStageR\x06stages\"\xd6\x01\n" + diff --git a/backend/proto/gallery.proto b/backend/proto/gallery.proto index e93626a..d948278 100644 --- a/backend/proto/gallery.proto +++ b/backend/proto/gallery.proto @@ -54,6 +54,13 @@ service GalleryService { get: "/api/v1/me/exhibited-assets" }; } + + // 获取灵感瀑布藏品列表 + rpc GetInspirationFlow(GetInspirationFlowRequest) returns (GetInspirationFlowResponse) { + option (google.api.http) = { + get: "/api/v1/inspiration-flow" + }; + } } // 请求和响应消息定义 @@ -181,3 +188,37 @@ message ExhibitedAssetItem { int64 expire_at = 6; // 展出过期时间(毫秒时间戳) int64 earnings = 7; // 当前可领取收益 } + +// ==================== 灵感瀑布相关消息 ==================== + +// 获取灵感瀑布藏品列表请求 +message GetInspirationFlowRequest { + string cursor = 1; // 游标(首次请求为空) + string direction = 2; // 滚动方向:right(加载新数据)/ left(加载历史) + int32 limit = 3; // 每页数量(默认10,最大20) + string type = 4; // 过滤类型:badge/poster/original/all(默认all) + string session_id = 5; // 会话ID(首次请求时为空,后端返回新的session_id) +} + +// 获取灵感瀑布藏品列表响应 +message GetInspirationFlowResponse { + topfans.common.BaseResponse base = 1; + InspirationFlowData data = 2; +} + +// 灵感瀑布数据 +message InspirationFlowData { + repeated InspirationFlowItem items = 1; // 藏品列表 + string cursor = 2; // 下次请求的游标 + bool has_more = 3; // 是否有更多 + string session_id = 4; // 会话ID(首次请求时返回) +} + +// 灵感瀑布藏品项 +message InspirationFlowItem { + int64 asset_id = 1; // 资产ID + string name = 2; // 藏品名称 + string cover_url = 3; // 封面图URL + int32 like_count = 4; // 点赞数 + string owner_nickname = 5; // 展出者昵称 +} diff --git a/backend/services/galleryService/provider/gallery_provider.go b/backend/services/galleryService/provider/gallery_provider.go index 762c647..14bbe98 100644 --- a/backend/services/galleryService/provider/gallery_provider.go +++ b/backend/services/galleryService/provider/gallery_provider.go @@ -338,6 +338,64 @@ func (p *GalleryProvider) GetMyExhibitedAssets(ctx context.Context, req *pb.GetM return p.exhibitionService.GetMyExhibitedAssets(ctx, userID, starID, req) } +// GetInspirationFlow 获取灵感瀑布藏品列表 +func (p *GalleryProvider) GetInspirationFlow(ctx context.Context, req *pb.GetInspirationFlowRequest) (*pb.GetInspirationFlowResponse, error) { + logger.Logger.Info("Received GetInspirationFlow request", + zap.String("cursor", req.Cursor), + zap.String("direction", req.Direction), + zap.Int32("limit", req.Limit), + zap.String("type", req.Type), + ) + + // 从 Dubbo attachments 获取用户信息(网关已验证并传递) + userID, starID, err := extractUserInfoFromDubboAttachments(ctx) + if err != nil { + logger.Logger.Error("Failed to extract user info from attachments", + zap.Error(err), + ) + return &pb.GetInspirationFlowResponse{ + Base: &pbCommon.BaseResponse{ + Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED, + Message: "user authentication required", + Timestamp: 0, + }, + }, err + } + + // 调用Service层 + data, _, err := p.galleryService.GetInspirationFlow(userID, starID, req.Cursor, req.Direction, req.Limit, req.Type, req.SessionId) + if err != nil { + logger.Logger.Error("GetInspirationFlow failed", + zap.Int64("user_id", userID), + zap.Int64("star_id", starID), + zap.String("direction", req.Direction), + zap.Error(err), + ) + return &pb.GetInspirationFlowResponse{ + Base: &pbCommon.BaseResponse{ + Code: appErrors.ToStatusCode(err), + Message: err.Error(), + Timestamp: 0, + }, + }, err + } + + logger.Logger.Info("GetInspirationFlow successful", + zap.Int64("user_id", userID), + zap.Int64("star_id", starID), + zap.Int("item_count", len(data.Items)), + ) + + return &pb.GetInspirationFlowResponse{ + Base: &pbCommon.BaseResponse{ + Code: pbCommon.StatusCode_STATUS_OK, + Message: "success", + Timestamp: 0, + }, + Data: data, + }, nil +} + // ==================== 辅助函数 ==================== // extractUserInfoFromDubboAttachments 从Dubbo attachments提取用户信息 diff --git a/backend/services/galleryService/repository/gallery_repository.go b/backend/services/galleryService/repository/gallery_repository.go index b618929..210bc96 100644 --- a/backend/services/galleryService/repository/gallery_repository.go +++ b/backend/services/galleryService/repository/gallery_repository.go @@ -41,6 +41,30 @@ type GalleryRepository interface { // pageSize: 每页数量 // 返回: 作品列表、总数量 GetMyExhibitedAssets(userID, starID int64, page, pageSize int) ([]*ExhibitedAssetInfo, int64, error) + + // ========== 灵感瀑布相关 ========== + + // CountValidExhibitions 统计有效展品数量 + // starID: 明星ID + // materialType: 素材类型过滤(空字符串表示不过滤) + CountValidExhibitions(starID int64, materialType string) (int64, error) + + // GetRandomExhibitions 获取随机展品列表 + // starID: 明星ID + // materialType: 素材类型过滤(空字符串表示不过滤) + // excludeIDs: 排除的展品ID列表(用于去重) + // limit: 返回数量 + // offset: 偏移量(随机生成) + GetRandomExhibitions(starID int64, materialType string, excludeIDs []int64, limit, offset int) ([]*InspirationFlowItem, error) +} + +// InspirationFlowItem 灵感瀑布展品项 +type InspirationFlowItem struct { + AssetID int64 + Name string + CoverURL string + LikeCount int32 + OwnerNickname string } // ExhibitedAssetInfo 我展出的作品信息 @@ -255,18 +279,19 @@ func (r *galleryRepository) GetMyExhibitedAssets(userID, starID int64, page, pag // 数据查询 offset := (page - 1) * pageSize err = r.db.Model(&models.Exhibition{}). - Select(`exhibitions.asset_id, a.name, a.cover_url, a.like_count, + Raw(` + SELECT exhibitions.asset_id, a.name, a.cover_url, a.like_count, exhibitions.start_time as exhibited_at, exhibitions.expire_at, - COALESCE(SUM(err.crystal_amount), 0) as earnings`). - Joins("JOIN assets a ON a.id = exhibitions.asset_id"). - Joins("LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'"). - Where("exhibitions.occupier_uid = ? AND exhibitions.occupier_star_id = ?", userID, starID). - Where("exhibitions.deleted_at IS NULL AND exhibitions.expire_at > ?", now). - Group("exhibitions.asset_id, a.name, a.cover_url, a.like_count, exhibitions.start_time, exhibitions.expire_at"). - Order("exhibitions.start_time DESC"). - Limit(pageSize). - Offset(offset). - Scan(&items).Error + COALESCE(CAST(SUM(err.crystal_amount) / 10 AS bigint), 0) as earnings + FROM exhibitions + JOIN assets a ON a.id = exhibitions.asset_id + LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable' + WHERE exhibitions.occupier_uid = ? AND exhibitions.occupier_star_id = ? + AND exhibitions.deleted_at IS NULL AND exhibitions.expire_at > ? + GROUP BY exhibitions.asset_id, a.name, a.cover_url, a.like_count, exhibitions.start_time, exhibitions.expire_at + ORDER BY exhibitions.start_time DESC + LIMIT ? OFFSET ? + `, userID, starID, now, pageSize, offset).Scan(&items).Error if err != nil { return nil, 0, err @@ -275,6 +300,62 @@ func (r *galleryRepository) GetMyExhibitedAssets(userID, starID int64, page, pag return items, total, nil } +// ========== 灵感瀑布相关实现 ========== + +// CountValidExhibitions 统计有效展品数量 +func (r *galleryRepository) CountValidExhibitions(starID int64, materialType string) (int64, error) { + var count int64 + now := time.Now().UnixMilli() + + query := r.db.Model(&models.Exhibition{}). + Where("occupier_star_id = ? AND expire_at > ? AND deleted_at IS NULL", starID, now) + + if materialType != "" && materialType != "all" { + query = query.Joins("JOIN assets a ON a.id = exhibitions.asset_id"). + Where("a.material_type = ?", materialType) + } + + err := query.Count(&count).Error + return count, err +} + +// GetRandomExhibitions 获取随机展品列表 +func (r *galleryRepository) GetRandomExhibitions(starID int64, materialType string, excludeIDs []int64, limit, offset int) ([]*InspirationFlowItem, error) { + var items []*InspirationFlowItem + now := time.Now().UnixMilli() + + // 构建基础查询 + baseQuery := r.db.Model(&models.Exhibition{}). + Where("exhibitions.occupier_star_id = ? AND exhibitions.expire_at > ? AND exhibitions.deleted_at IS NULL", starID, now) + + if materialType != "" && materialType != "all" { + baseQuery = baseQuery.Joins("JOIN assets a ON a.id = exhibitions.asset_id"). + Where("a.material_type = ?", materialType) + } + + // 排除已展示的ID + if len(excludeIDs) > 0 { + baseQuery = baseQuery.Where("exhibitions.id NOT IN ?", excludeIDs) + } + + // 执行随机排序查询 + err := baseQuery. + Select(`exhibitions.asset_id, a.name, a.cover_url, a.like_count, fp.nickname as owner_nickname`). + Joins("JOIN assets a ON a.id = exhibitions.asset_id"). + Joins("JOIN fan_profiles fp ON exhibitions.occupier_uid = fp.user_id AND exhibitions.occupier_star_id = fp.star_id"). + Where("a.status = 1 AND a.is_active = true"). + Order("RANDOM()"). + Limit(limit). + Offset(offset). + Scan(&items).Error + + if err != nil { + return nil, err + } + + return items, nil +} + // ==================== 辅助函数 ==================== // generateHostProfileID 生成 host_profile_id diff --git a/docs/superpowers/specs/2026-04-27-inspiration-flow-design.md b/docs/superpowers/specs/2026-04-27-inspiration-flow-design.md index 247ca45..77e4649 100644 --- a/docs/superpowers/specs/2026-04-27-inspiration-flow-design.md +++ b/docs/superpowers/specs/2026-04-27-inspiration-flow-design.md @@ -695,3 +695,104 @@ onDataLoaded() { | 2026-04-29 | 改用随机 offset 方案(方案 B),每次请求都是独立随机,数据变化无影响 | | 2026-04-29 | 新增双向滚动支持:向右加载新数据,向左加载历史数据,后端维护会话级缓存 | | 2026-04-29 | 修复:修正重复的 10.4 章节、RangeSamplingStrategy 签名、游标结构说明 | +| 2026-04-29 | 新增 Redis 会话级缓存实现方案:支持双向滚动去重 | + +--- + +## 十三、Redis 会话级缓存实现 + +### 13.1 技术选型 + +- **客户端**: `github.com/redis/go-redis/v9` +- **连接信息**: `localhost:6379`,无密码 +- **TTL**: 30分钟(无操作自动清理) + +### 13.2 缓存结构 + +``` +Key: inspiration_flow:{star_id}:{session_id} +Type: Hash +Fields: + - displayed_ids: ["id1", "id2", ...] # 已展示ID列表(用于去重) + - history: {"id1": json_data1, "id2": json_data2, ...} # 历史数据详情 +TTL: 1800秒(30分钟) +``` + +### 13.3 环境变量配置 + +| 变量名 | 说明 | 默认值 | +|--------|------|--------| +| REDIS_HOST | Redis 主机地址 | 127.0.0.1 | +| REDIS_PORT | Redis 端口 | 6379 | +| REDIS_PASSWORD | Redis 密码 | (空) | +| REDIS_DB | Redis 数据库编号 | 0 | + +### 13.4 核心逻辑 + +| 方向 | 行为 | +|------|------| +| `direction=right` | 随机查询新数据(排除已展示ID),返回并更新缓存 | +| `direction=left` | 从缓存的历史数据中分页返回 | + +### 13.5 实现文件 + +| 文件 | 说明 | +|------|------| +| `backend/pkg/database/redis.go`(新建) | Redis 客户端初始化 | +| `backend/services/socialService/repository/social_repository.go` | 新增 `GetRandomUsersExcludeIDs` | +| `backend/services/socialService/service/friend_service.go` | 修改 `GetRandomUsers` 支持 direction + 缓存 | +| `backend/services/socialService/provider/social_provider.go` | 透传 direction 参数 | +| `backend/gateway/dto/social_converter.go` | 转换 exclude_ids | +| `backend/gateway/config/config.go` | 新增 Redis 配置 | + +### 13.6 session_id 生成 + +- 由后端生成(UUID) +- 首次请求时返回给前端,前端后续请求携带 + +### 13.7 向左滚动实现 + +向左滚动时,后端从 Redis 缓存的 `history` 字段读取已展示数据,按 offset 分页返回。前端在左侧插入展示。 + +### 13.8 预签名 URL 批量获取优化 + +**问题**:前端逐个获取预签名 URL,N 个卡片产生 N 次请求。 + +**解决方案**:新增批量接口,前端一次性获取所有 URL。 + +**接口设计**: +``` +POST /api/v1/assets/oss/batch-presigned-urls +Content-Type: application/json + +Request: +{ + "files": ["path/to/img1.png", "path/to/img2.png", ...], + "expires": 3600, + "type": "asset" +} + +Response: +{ + "code": 200, + "data": { + "urls": { + "path/to/img1.png": "https://xxx?signature=...", + "path/to/img2.png": "https://xxx?signature=..." + } + } +} +``` + +**前端逻辑**: +1. 加载用户数据后,收集所有 `cover_url` +2. 批量调用接口获取全部预签名 URL +3. 存入 Map 缓存,后续直接使用 + +**实现文件**: +| 文件 | 说明 | +|------|------| +| `backend/gateway/controller/asset_controller.go` | 新增 batch presigned urls 路由 | +| `backend/gateway/dto/asset_dto.go` | 新增 BatchPresignedUrlsRequest/Response | +| `frontend/utils/api.js` | 新增 `getBatchOssPresignedUrlsApi` | +| `frontend/pages/square/components/WaterfallGrid.vue` | 使用批量接口替代逐个调用 | diff --git a/frontend/pages/components/Header.vue b/frontend/pages/components/Header.vue index aed5133..f1898b4 100644 --- a/frontend/pages/components/Header.vue +++ b/frontend/pages/components/Header.vue @@ -22,18 +22,18 @@ - - + + 2. 下层:文字背景块 新手引导 - + --> @@ -388,13 +388,13 @@ const handleAvatarClick = () => { if (pages.length > 0) { const currentPage = pages[pages.length - 1]; // 检查当前页面是否是个人信息页面 - if (currentPage.route === 'pages/profile/profile') { + if (currentPage.route === 'pages/profile/myWorks') { // 已经在个人信息页面,不执行跳转 return; } } uni.navigateTo({ - url: '/pages/profile/profile' + url: '/pages/profile/myWorks' }); }; @@ -570,7 +570,7 @@ defineExpose({ } .balance-number { - font-size: 22rpx; + font-size: 24rpx; font-weight: bold; color: #FFB800; font-family: 'ZaoZiGongFangJianHei-1', sans-serif; diff --git a/frontend/pages/profile/myWorks.vue b/frontend/pages/profile/myWorks.vue index bba47fd..d2148bc 100644 --- a/frontend/pages/profile/myWorks.vue +++ b/frontend/pages/profile/myWorks.vue @@ -10,6 +10,9 @@ + + 个人设置 + @@ -22,15 +25,13 @@ - - - + @tap="handleExhibitionCardTap(item, index)"> + + + @@ -39,10 +40,11 @@ - + - {{ item.earnings || 0 }} + {{ item.earnings || 0 }}/时 @@ -50,9 +52,11 @@ - + - + + @@ -60,7 +64,8 @@ - + + @@ -69,34 +74,27 @@ - + - + - + - - + + @@ -104,13 +102,15 @@ {{ item.status_text }} {{ formatScore(item.score) }} - + + - + + +{{ item.reward }} @@ -118,7 +118,7 @@ - 今日暂无点赞作品 + 当前暂无点赞作品 @@ -127,12 +127,8 @@ - + @@ -144,7 +140,24 @@ import { onShow } from '@dcloudio/uni-app'; import { doubleTapLike } from '@/utils/likeHelper.js'; const goBack = () => { - uni.navigateBack(); + // 获取页面栈 + const pages = getCurrentPages(); + if (pages.length > 1) { + // 有上一页,执行返回 + uni.navigateBack(); + } else { + // 没有上一页,跳转到square页面 + uni.reLaunch({ + url: '/pages/square/square' + }); + } +}; + +const goToSettings = () => { + + uni.navigateTo({ + url: '/pages/profile/profile' + }); }; const goToCastlove = () => { @@ -237,7 +250,7 @@ const handleExhibitionCardTap = (item, index) => { if (success) { // 更新在展作品的点赞数 exhibitionWorks.value[index].like_count = (exhibitionWorks.value[index].like_count || 0) + 1; - // 将作品添加到今日点赞列表 + // 将作品添加到当前点赞列表 const likedItem = { id: item.id, cover_url: item.cover_url, @@ -275,7 +288,7 @@ const formatScore = (score) => { // 在展作品列表 const exhibitionWorks = ref([]); -// 今日点赞作品列表 +// 当前点赞作品列表 const likedWorks = ref([]); // 加载我的展出作品 @@ -383,6 +396,28 @@ onShow(() => { width: 64rpx; } +.nav-settings { + height: 64rpx; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(to bottom right, + #F0E4B1 0%, + #F08399 50%, + #B94E73 100%); + border-radius: 24rpx; + padding: 8rpx 20rpx 8rpx 20rpx; + box-shadow: + 0 4rpx 12rpx rgba(255, 143, 158, 0.2), + inset 0 2rpx 4rpx rgba(255, 255, 255, 0.4); +} + +.nav-settings-text { + font-size: 24rpx; + color: #fff; + font-weight: 400; +} + /* 内容区域 */ .scroll-content { position: relative; @@ -492,7 +527,7 @@ onShow(() => { .card-user-text { font-size: 20rpx; color: #fff; - background: rgba(0,0,0,0.45); + background: rgba(0, 0, 0, 0.45); padding: 4rpx 14rpx; border-radius: 20rpx; } @@ -532,11 +567,11 @@ onShow(() => { } .card-income-text-wrap { + width: 64rpx; background: linear-gradient(to bottom right, - #F0E4B1 0%, - #F08399 50%, - #B94E73 100% - ); + #F0E4B1 0%, + #F08399 50%, + #B94E73 100%); border-radius: 999rpx; padding: 8rpx 20rpx 8rpx 40rpx; box-shadow: @@ -553,7 +588,7 @@ onShow(() => { font-weight: 700; text-align: center; } - + .heart-icon { width: 28rpx; @@ -562,15 +597,15 @@ onShow(() => { .card-rate-text-wrap { background: linear-gradient(to bottom right, - #F0E4B1 0%, - #F08399 50%, - #B94E73 100% - ); + #F0E4B1 0%, + #F08399 50%, + #B94E73 100%); border-radius: 999rpx; - padding: 2rpx 12rpx; + padding: 2rpx 16rpx; box-shadow: 0 4rpx 12rpx rgba(255, 143, 158, 0.2), inset 0 2rpx 4rpx rgba(255, 255, 255, 0.4); + display: flex; } .card-rate-text { @@ -643,7 +678,7 @@ onShow(() => { color: #b09cc0; } -/* 今日点赞列表 */ +/* 当前点赞列表 */ .liked-list { max-height: 732rpx; } @@ -686,7 +721,7 @@ onShow(() => { width: 48rpx; height: 48rpx; border-radius: 50%; - background: rgba(180,140,220,0.3); + background: rgba(180, 140, 220, 0.3); display: flex; align-items: center; justify-content: center; @@ -720,8 +755,8 @@ onShow(() => { transform: rotate(-22deg); transform-origin: center center; position: relative; - z-index: 3; - padding: 0.25rem; + z-index: 3; + padding: 0.25rem; } .liked-cover-frame { diff --git a/frontend/pages/square/components/CabinItem.vue b/frontend/pages/square/components/CabinItem.vue deleted file mode 100644 index 292b5f5..0000000 --- a/frontend/pages/square/components/CabinItem.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - - - diff --git a/frontend/pages/square/components/ContentTabs.vue b/frontend/pages/square/components/ContentTabs.vue index 276a0ef..e52dfac 100644 --- a/frontend/pages/square/components/ContentTabs.vue +++ b/frontend/pages/square/components/ContentTabs.vue @@ -39,11 +39,10 @@ defineProps({ defineEmits(['update:modelValue']) const tabs = [ - { key: 'hot', label: '热门作品', emoji: null, icon: '/static/square/rementubiao.png', iconWidth: 104, iconHeight: 104 }, - { key: 'xingka', label: '星卡', emoji: null, icon: '/static/square/xingka.png', iconWidth: 80, iconHeight: 80 }, - { key: 'baji', label: '把爱', emoji: null, icon: '/static/square/baji.png', iconWidth: 80, iconHeight: 80 }, - { key: 'haibao', label: '海报', emoji: null, icon: '/static/square/haibao.png', iconWidth: 96, iconHeight: 96 }, -] + { key: 'hot', label: '人气王者', emoji: null, icon: '/static/square/rementubiao.png', iconWidth: 104, iconHeight: 104 }, + { key: 'xingka', label: '潜力之星', emoji: null, icon: '/static/square/xingka.png', iconWidth: 80, iconHeight: 80 }, + { key: 'baji', label: '新鲜上架', emoji: null, icon: '/static/square/baji.png', iconWidth: 80, iconHeight: 80 }, + { key: 'haibao', label: '随机寻宝', emoji: null, icon: '/static/square/haibao.png', iconWidth: 96, iconHeight: 96 },] diff --git a/frontend/pages/square/square.vue b/frontend/pages/square/square.vue index 8cbfc76..fa15d89 100644 --- a/frontend/pages/square/square.vue +++ b/frontend/pages/square/square.vue @@ -8,6 +8,8 @@ :screenWidth="screenWidth" :screenHeight="screenHeight" :bannerBottom="bannerBottomPx" + :useMockData="USE_MOCK_DATA" + :category="activeContentTab" @cardClick="handleCardClick" class="fall-bg" /> @@ -68,6 +70,7 @@ import WaterfallGrid from './components/WaterfallGrid.vue' import ContentTabs from './components/ContentTabs.vue' import { clearSubStepProgress, shouldShowGuideStartModal } from '@/utils/guideConfig.js' import { useBanner } from './composables/useBanner.js' +import { USE_MOCK_DATA } from './config/mockData.js' // ========== Store & User Info ========== const store = useStore() @@ -78,7 +81,6 @@ const currentStarId = ref(uni.getStorageSync('star_id') || null) const activeContentTab = ref('hot') const navExpanded = ref(false) const showRankingModal = ref(false) -const isDev = ref(false) // 开发模式,显示调试按钮 // ========== Screen Info ========== const screenWidth = ref(375) @@ -143,12 +145,6 @@ const handleTabChange = (newTab) => { } } -const openDebugGrid = () => { - uni.navigateTo({ - url: '/pages/square/debug-grid' - }) -} - // ========== Tile Change Callback ========== const handleTileChange = () => {} @@ -282,25 +278,4 @@ onUnmounted(() => { opacity: 1; } } - -.debug-btn { - position: fixed; - bottom: 200rpx; - right: 20rpx; - width: 100rpx; - height: 100rpx; - background: rgba(255, 0, 0, 0.8); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - z-index: 999; - box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.3); -} - -.debug-text { - font-size: 24rpx; - color: #ffffff; - font-weight: bold; -} diff --git a/frontend/utils/api.js b/frontend/utils/api.js index 37608d5..5863606 100644 --- a/frontend/utils/api.js +++ b/frontend/utils/api.js @@ -1,6 +1,6 @@ // API 基础配置 -const baseURL = 'http://101.132.250.62:8080' -// const baseURL = 'http://192.168.110.60:8080' +// const baseURL = 'http://101.132.250.62:8080' +const baseURL = 'http://192.168.110.60:8080' // const baseURL = 'http://localhost:8080' // 是否使用模拟数据(开发调试时设为 true,后端API准备好后改为 false) @@ -606,4 +606,23 @@ export function getMyLikedAssetsApi(page = 1, pageSize = 20) { url: `/api/v1/me/liked-assets?page=${page}&page_size=${pageSize}`, method: 'GET' }) +} + +// ==================== 灵感瀑布相关接口 ==================== + +// 获取灵感瀑布藏品列表 +export function getInspirationFlowApi(params) { + return request({ + url: '/api/v1/inspiration-flow', + method: 'GET', + data: params + }) +} + +// 批量获取OSS预签名URL(用于读取目录下的图片) +export function getBatchOssPresignedUrlsApi(files, expires = 3600, type = 'asset') { + return request({ + url: `/api/v1/assets/oss/batch-presigned-urls?files=${encodeURIComponent(JSON.stringify(files))}&expires=${expires}&type=${type}`, + method: 'GET' + }) } \ No newline at end of file