From 852b02f014472b4052a014dd5bf5451c3cc3d002 Mon Sep 17 00:00:00 2001 From: zerosaturation Date: Fri, 8 May 2026 17:08:21 +0800 Subject: [PATCH] =?UTF-8?q?feat=20:=E6=96=B0=E5=A2=9E=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E4=BB=96=E4=BA=BA=E7=9A=84=E5=9C=A8=E5=B1=95=E4=BD=9C=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gateway/controller/gallery_controller.go | 106 ++++ .../gateway/controller/social_controller.go | 198 ++++++ backend/gateway/router/router.go | 5 + backend/pkg/proto/gallery/gallery.pb.go | 238 +++++-- backend/pkg/proto/gallery/gallery.triple.go | 29 +- backend/pkg/proto/social/social.pb.go | 250 ++++++-- backend/pkg/proto/social/social.triple.go | 77 ++- backend/proto/gallery.proto | 22 + backend/proto/social.proto | 20 + .../provider/gallery_provider.go | 25 + .../repository/gallery_repository.go | 47 ++ .../socialService/provider/social_provider.go | 72 +++ .../repository/social_repository.go | 163 +++++ frontend/pages.json | 9 + frontend/pages/components/AssetSelector.vue | 4 +- frontend/pages/components/BannerTop3.vue | 8 +- frontend/pages/components/RankingModal.vue | 8 +- frontend/pages/components/StarbookContent.vue | 4 +- frontend/pages/exhibition/exhibition.vue | 32 +- frontend/pages/profile/hisWorks.vue | 600 ++++++++++++++++++ frontend/pages/profile/myWorks.vue | 84 ++- frontend/pages/square/square.vue | 14 +- frontend/utils/api.js | 46 +- 23 files changed, 1891 insertions(+), 170 deletions(-) create mode 100644 frontend/pages/profile/hisWorks.vue diff --git a/backend/gateway/controller/gallery_controller.go b/backend/gateway/controller/gallery_controller.go index d619354..dfca85f 100644 --- a/backend/gateway/controller/gallery_controller.go +++ b/backend/gateway/controller/gallery_controller.go @@ -716,4 +716,110 @@ func (ctrl *GalleryController) GetInspirationFlow(c *gin.Context) { ) response.Success(c, flowDTO) +} + +// GetUserExhibitedAssets 获取他人展出的作品列表 +// @Summary 获取他人展出的作品列表 +// @Description 获取指定用户正在展出的作品列表 +// @Tags galleries +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param user_id path int true "用户ID" +// @Param page query int false "页码" default(1) +// @Param page_size query int false "每页数量" default(20) +// @Success 200 {object} response.Response{data=dto.GetMyExhibitedAssetsResponseDTO} +// @Router /api/v1/users/{user_id}/exhibited-assets [get] +func (ctrl *GalleryController) GetUserExhibitedAssets(c *gin.Context) { + userIDStr := c.Param("user_id") + targetUserID, err := strconv.ParseInt(userIDStr, 10, 64) + if err != nil { + response.Error(c, http.StatusBadRequest, "无效的用户ID") + return + } + + callerUserID, exists := c.Get("user_id") + if !exists { + response.Error(c, http.StatusUnauthorized, "用户未认证") + return + } + + callerStarID, exists := c.Get("star_id") + if !exists { + response.Error(c, http.StatusUnauthorized, "明星身份未设置") + return + } + + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) + if page <= 0 { + page = 1 + } + if pageSize <= 0 { + pageSize = 20 + } + if pageSize > 100 { + pageSize = 100 + } + + ctx := context.WithValue(context.Background(), constant.AttachmentKey, map[string]interface{}{ + "user_id": strconv.FormatInt(callerUserID.(int64), 10), + "star_id": strconv.FormatInt(callerStarID.(int64), 10), + }) + + resp, err := ctrl.galleryService.GetUserExhibitedAssets(ctx, &pbGallery.GetUserExhibitedAssetsRequest{ + UserId: targetUserID, + Page: int32(page), + PageSize: int32(pageSize), + }) + if err != nil { + logger.Logger.Error("GetUserExhibitedAssets RPC failed", + zap.Any("caller_user_id", callerUserID), + zap.Any("star_id", callerStarID), + zap.Int64("target_user_id", targetUserID), + 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 + } + + items := make([]*dto.ExhibitedAssetItemDTO, 0, len(resp.Data.Items)) + for _, item := range resp.Data.Items { + items = append(items, &dto.ExhibitedAssetItemDTO{ + AssetID: item.AssetId, + Name: item.Name, + CoverURL: item.CoverUrl, + LikeCount: item.LikeCount, + ExhibitedAt: item.ExhibitedAt, + ExpireAt: item.ExpireAt, + Earnings: item.Earnings, + }) + } + + result := &dto.GetMyExhibitedAssetsResponseDTO{ + Items: items, + Page: resp.Data.Page, + PageSize: resp.Data.PageSize, + Total: resp.Data.Total, + HasMore: resp.Data.HasMore, + } + + logger.Logger.Info("GetUserExhibitedAssets success", + zap.Any("caller_user_id", callerUserID), + zap.Any("star_id", callerStarID), + zap.Int64("target_user_id", targetUserID), + zap.Int32("count", int32(len(items))), + ) + + response.Success(c, result) } \ No newline at end of file diff --git a/backend/gateway/controller/social_controller.go b/backend/gateway/controller/social_controller.go index 5034155..552fe7f 100644 --- a/backend/gateway/controller/social_controller.go +++ b/backend/gateway/controller/social_controller.go @@ -947,3 +947,201 @@ func (ctrl *SocialController) GetMyLikedAssets(c *gin.Context) { "has_more": resp.Data.HasMore, }) } + +// GetMyTodayLikedAssets 获取我今日点赞的作品列表 +// @Summary 获取我今日点赞的作品列表 +// @Description 获取当前用户今日点赞过的作品列表(只返回展出中且未过期的) +// @Tags social +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param page query int false "页码,默认1" +// @Param page_size query int false "每页数量,默认20,最大100" +// @Success 200 {object} response.Response +// @Router /api/v1/me/today-liked-assets [get] +func (ctrl *SocialController) GetMyTodayLikedAssets(c *gin.Context) { + userID, _ := c.Get("user_id") + starID, _ := c.Get("star_id") + + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{ + "user_id": strconv.FormatInt(userID.(int64), 10), + "star_id": strconv.FormatInt(starID.(int64), 10), + }) + + resp, err := ctrl.socialService.GetMyTodayLikedAssets(ctx, &pbSocial.GetMyTodayLikedAssetsRequest{ + Page: int32(page), + PageSize: int32(pageSize), + }) + + if err != nil { + logger.Logger.Error("GetMyTodayLikedAssets RPC failed", zap.Error(err)) + response.Error(c, http.StatusInternalServerError, "服务调用失败") + return + } + + if resp.Base.Code != pbCommon.StatusCode_STATUS_OK { + response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message) + return + } + + items := make([]map[string]interface{}, 0, len(resp.Data.Items)) + for _, item := range resp.Data.Items { + items = append(items, map[string]interface{}{ + "asset_id": item.AssetId, + "name": item.Name, + "cover_url": item.CoverUrl, + "like_count": item.LikeCount, + "liked_at": item.LikedAt, + "earnings": item.Earnings, + }) + } + + response.Success(c, gin.H{ + "items": items, + "total": resp.Data.Total, + "page": resp.Data.Page, + "page_size": resp.Data.PageSize, + "has_more": resp.Data.HasMore, + }) +} + +// GetMyWeekLikedAssets 获取我本周点赞的作品列表 +// @Summary 获取我本周点赞的作品列表 +// @Description 获取当前用户本周点赞过的作品列表(只返回展出中且未过期的) +// @Tags social +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param page query int false "页码,默认1" +// @Param page_size query int false "每页数量,默认20,最大100" +// @Success 200 {object} response.Response +// @Router /api/v1/me/week-liked-assets [get] +func (ctrl *SocialController) GetMyWeekLikedAssets(c *gin.Context) { + userID, _ := c.Get("user_id") + starID, _ := c.Get("star_id") + + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{ + "user_id": strconv.FormatInt(userID.(int64), 10), + "star_id": strconv.FormatInt(starID.(int64), 10), + }) + + resp, err := ctrl.socialService.GetMyWeekLikedAssets(ctx, &pbSocial.GetMyWeekLikedAssetsRequest{ + Page: int32(page), + PageSize: int32(pageSize), + }) + + if err != nil { + logger.Logger.Error("GetMyWeekLikedAssets RPC failed", zap.Error(err)) + response.Error(c, http.StatusInternalServerError, "服务调用失败") + return + } + + if resp.Base.Code != pbCommon.StatusCode_STATUS_OK { + response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message) + return + } + + items := make([]map[string]interface{}, 0, len(resp.Data.Items)) + for _, item := range resp.Data.Items { + items = append(items, map[string]interface{}{ + "asset_id": item.AssetId, + "name": item.Name, + "cover_url": item.CoverUrl, + "like_count": item.LikeCount, + "liked_at": item.LikedAt, + "earnings": item.Earnings, + }) + } + + response.Success(c, gin.H{ + "items": items, + "total": resp.Data.Total, + "page": resp.Data.Page, + "page_size": resp.Data.PageSize, + "has_more": resp.Data.HasMore, + }) +} + +// GetUserLikedAssets 获取他人点赞的作品列表 +// @Summary 获取他人点赞的作品列表 +// @Description 获取指定用户点赞过的作品列表(只返回展出中且未过期的) +// @Tags social +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param user_id path int true "用户ID" +// @Param page query int false "页码,默认1" +// @Param page_size query int false "每页数量,默认20,最大100" +// @Success 200 {object} response.Response +// @Router /api/v1/users/{user_id}/liked-assets [get] +func (ctrl *SocialController) GetUserLikedAssets(c *gin.Context) { + userIDStr := c.Param("user_id") + targetUserID, err := strconv.ParseInt(userIDStr, 10, 64) + if err != nil { + response.Error(c, http.StatusBadRequest, "无效的用户ID") + return + } + + callerUserID, _ := c.Get("user_id") + callerStarID, _ := c.Get("star_id") + + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) + pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{ + "user_id": strconv.FormatInt(callerUserID.(int64), 10), + "star_id": strconv.FormatInt(callerStarID.(int64), 10), + }) + + resp, err := ctrl.socialService.GetUserLikedAssets(ctx, &pbSocial.GetUserLikedAssetsRequest{ + UserId: targetUserID, + Page: int32(page), + PageSize: int32(pageSize), + }) + + if err != nil { + logger.Logger.Error("GetUserLikedAssets RPC failed", zap.Error(err)) + response.Error(c, http.StatusInternalServerError, "服务调用失败") + return + } + + if resp.Base.Code != pbCommon.StatusCode_STATUS_OK { + response.ErrorWithCode(c, int(resp.Base.Code), resp.Base.Message) + return + } + + items := make([]map[string]interface{}, 0, len(resp.Data.Items)) + for _, item := range resp.Data.Items { + items = append(items, map[string]interface{}{ + "asset_id": item.AssetId, + "name": item.Name, + "cover_url": item.CoverUrl, + "like_count": item.LikeCount, + "liked_at": item.LikedAt, + "earnings": item.Earnings, + }) + } + + response.Success(c, gin.H{ + "items": items, + "total": resp.Data.Total, + "page": resp.Data.Page, + "page_size": resp.Data.PageSize, + "has_more": resp.Data.HasMore, + }) +} diff --git a/backend/gateway/router/router.go b/backend/gateway/router/router.go index d1d5401..5c76e8a 100644 --- a/backend/gateway/router/router.go +++ b/backend/gateway/router/router.go @@ -100,8 +100,11 @@ func SetupRouter(userClient *client.Client, socialClient *client.Client, assetCl // 用户相关路由(公开) users := v1.Group("/users") + users.Use(middleware.AuthMiddleware()) { users.GET("/:user_id", userCtrl.GetUser) // 获取指定用户信息 + users.GET("/:user_id/liked-assets", socialCtrl.GetUserLikedAssets) // 获取他人点赞的作品列表 + users.GET("/:user_id/exhibited-assets", galleryCtrl.GetUserExhibitedAssets) // 获取他人展出的作品列表 } // 粉丝档案相关路由(公开) @@ -124,6 +127,8 @@ func SetupRouter(userClient *client.Client, socialClient *client.Client, assetCl me.PUT("/nickname", userCtrl.UpdateNickname) // 更新昵称 me.PUT("/avatar", userCtrl.UpdateAvatar) // 更新头像 me.GET("/liked-assets", socialCtrl.GetMyLikedAssets) // 获取我点赞的作品列表 + me.GET("/today-liked-assets", socialCtrl.GetMyTodayLikedAssets) // 获取我今日点赞的作品列表 + me.GET("/week-liked-assets", socialCtrl.GetMyWeekLikedAssets) // 获取我本周点赞的作品列表 me.GET("/exhibited-assets", galleryCtrl.GetMyExhibitedAssets) // 获取我展出的作品列表 } diff --git a/backend/pkg/proto/gallery/gallery.pb.go b/backend/pkg/proto/gallery/gallery.pb.go index 6984dbc..2a2370a 100644 --- a/backend/pkg/proto/gallery/gallery.pb.go +++ b/backend/pkg/proto/gallery/gallery.pb.go @@ -1507,6 +1507,120 @@ func (x *InspirationFlowItem) GetMaterialType() string { return "" } +// 获取他人展出的作品列表请求(暂不实现) +type GetUserExhibitedAssetsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 他人用户ID + Page int32 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"` // 页码(默认1) + PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // 每页数量(默认20,最大100) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserExhibitedAssetsRequest) Reset() { + *x = GetUserExhibitedAssetsRequest{} + mi := &file_gallery_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserExhibitedAssetsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserExhibitedAssetsRequest) ProtoMessage() {} + +func (x *GetUserExhibitedAssetsRequest) ProtoReflect() protoreflect.Message { + mi := &file_gallery_proto_msgTypes[24] + 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 GetUserExhibitedAssetsRequest.ProtoReflect.Descriptor instead. +func (*GetUserExhibitedAssetsRequest) Descriptor() ([]byte, []int) { + return file_gallery_proto_rawDescGZIP(), []int{24} +} + +func (x *GetUserExhibitedAssetsRequest) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *GetUserExhibitedAssetsRequest) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *GetUserExhibitedAssetsRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +// 获取他人展出的作品列表响应(暂不实现) +type GetUserExhibitedAssetsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Base *common.BaseResponse `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"` + Data *ExhibitedAssetsData `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserExhibitedAssetsResponse) Reset() { + *x = GetUserExhibitedAssetsResponse{} + mi := &file_gallery_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserExhibitedAssetsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserExhibitedAssetsResponse) ProtoMessage() {} + +func (x *GetUserExhibitedAssetsResponse) ProtoReflect() protoreflect.Message { + mi := &file_gallery_proto_msgTypes[25] + 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 GetUserExhibitedAssetsResponse.ProtoReflect.Descriptor instead. +func (*GetUserExhibitedAssetsResponse) Descriptor() ([]byte, []int) { + return file_gallery_proto_rawDescGZIP(), []int{25} +} + +func (x *GetUserExhibitedAssetsResponse) GetBase() *common.BaseResponse { + if x != nil { + return x.Base + } + return nil +} + +func (x *GetUserExhibitedAssetsResponse) GetData() *ExhibitedAssetsData { + if x != nil { + return x.Data + } + return nil +} + var File_gallery_proto protoreflect.FileDescriptor const file_gallery_proto_rawDesc = "" + @@ -1627,7 +1741,14 @@ const file_gallery_proto_rawDesc = "" + "like_count\x18\x04 \x01(\x05R\tlikeCount\x12%\n" + "\x0eowner_nickname\x18\x05 \x01(\tR\rownerNickname\x12\x12\n" + "\x04span\x18\x06 \x01(\x05R\x04span\x12#\n" + - "\rmaterial_type\x18\a \x01(\tR\fmaterialType2\xc6\a\n" + + "\rmaterial_type\x18\a \x01(\tR\fmaterialType\"i\n" + + "\x1dGetUserExhibitedAssetsRequest\x12\x17\n" + + "\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x12\n" + + "\x04page\x18\x02 \x01(\x05R\x04page\x12\x1b\n" + + "\tpage_size\x18\x03 \x01(\x05R\bpageSize\"\x8c\x01\n" + + "\x1eGetUserExhibitedAssetsResponse\x120\n" + + "\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x128\n" + + "\x04data\x18\x02 \x01(\v2$.topfans.gallery.ExhibitedAssetsDataR\x04data2\xf4\b\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" + @@ -1637,7 +1758,8 @@ const file_gallery_proto_rawDesc = "" + "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-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" + "\x12GetInspirationFlow\x12*.topfans.gallery.GetInspirationFlowRequest\x1a+.topfans.gallery.GetInspirationFlowResponse\" \x82\xd3\xe4\x93\x02\x1a\x12\x18/api/v1/inspiration-flow\x12\xab\x01\n" + + "\x16GetUserExhibitedAssets\x12..topfans.gallery.GetUserExhibitedAssetsRequest\x1a/.topfans.gallery.GetUserExhibitedAssetsResponse\"0\x82\xd3\xe4\x93\x02*\x12(/api/v1/users/{user_id}/exhibited-assetsB6Z4github.com/topfans/backend/pkg/proto/gallery;galleryb\x06proto3" var ( file_gallery_proto_rawDescOnce sync.Once @@ -1651,72 +1773,78 @@ func file_gallery_proto_rawDescGZIP() []byte { return file_gallery_proto_rawDescData } -var file_gallery_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_gallery_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_gallery_proto_goTypes = []any{ - (*GetMyGalleryRequest)(nil), // 0: topfans.gallery.GetMyGalleryRequest - (*GetMyGalleryResponse)(nil), // 1: topfans.gallery.GetMyGalleryResponse - (*GetUserGalleryRequest)(nil), // 2: topfans.gallery.GetUserGalleryRequest - (*GetUserGalleryResponse)(nil), // 3: topfans.gallery.GetUserGalleryResponse - (*PlaceAssetRequest)(nil), // 4: topfans.gallery.PlaceAssetRequest - (*PlaceAssetResponse)(nil), // 5: topfans.gallery.PlaceAssetResponse - (*UnlockSlotRequest)(nil), // 6: topfans.gallery.UnlockSlotRequest - (*UnlockSlotResponse)(nil), // 7: topfans.gallery.UnlockSlotResponse - (*GalleryData)(nil), // 8: topfans.gallery.GalleryData - (*SlotInfo)(nil), // 9: topfans.gallery.SlotInfo - (*AssetInfo)(nil), // 10: topfans.gallery.AssetInfo - (*UnlockCondition)(nil), // 11: topfans.gallery.UnlockCondition - (*PlaceAssetData)(nil), // 12: topfans.gallery.PlaceAssetData - (*UnlockSlotData)(nil), // 13: topfans.gallery.UnlockSlotData - (*RemoveFromSlotRequest)(nil), // 14: topfans.gallery.RemoveFromSlotRequest - (*RemoveFromSlotResponse)(nil), // 15: topfans.gallery.RemoveFromSlotResponse - (*GetMyExhibitedAssetsRequest)(nil), // 16: topfans.gallery.GetMyExhibitedAssetsRequest - (*GetMyExhibitedAssetsResponse)(nil), // 17: topfans.gallery.GetMyExhibitedAssetsResponse - (*ExhibitedAssetsData)(nil), // 18: topfans.gallery.ExhibitedAssetsData - (*ExhibitedAssetItem)(nil), // 19: topfans.gallery.ExhibitedAssetItem - (*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 + (*GetMyGalleryRequest)(nil), // 0: topfans.gallery.GetMyGalleryRequest + (*GetMyGalleryResponse)(nil), // 1: topfans.gallery.GetMyGalleryResponse + (*GetUserGalleryRequest)(nil), // 2: topfans.gallery.GetUserGalleryRequest + (*GetUserGalleryResponse)(nil), // 3: topfans.gallery.GetUserGalleryResponse + (*PlaceAssetRequest)(nil), // 4: topfans.gallery.PlaceAssetRequest + (*PlaceAssetResponse)(nil), // 5: topfans.gallery.PlaceAssetResponse + (*UnlockSlotRequest)(nil), // 6: topfans.gallery.UnlockSlotRequest + (*UnlockSlotResponse)(nil), // 7: topfans.gallery.UnlockSlotResponse + (*GalleryData)(nil), // 8: topfans.gallery.GalleryData + (*SlotInfo)(nil), // 9: topfans.gallery.SlotInfo + (*AssetInfo)(nil), // 10: topfans.gallery.AssetInfo + (*UnlockCondition)(nil), // 11: topfans.gallery.UnlockCondition + (*PlaceAssetData)(nil), // 12: topfans.gallery.PlaceAssetData + (*UnlockSlotData)(nil), // 13: topfans.gallery.UnlockSlotData + (*RemoveFromSlotRequest)(nil), // 14: topfans.gallery.RemoveFromSlotRequest + (*RemoveFromSlotResponse)(nil), // 15: topfans.gallery.RemoveFromSlotResponse + (*GetMyExhibitedAssetsRequest)(nil), // 16: topfans.gallery.GetMyExhibitedAssetsRequest + (*GetMyExhibitedAssetsResponse)(nil), // 17: topfans.gallery.GetMyExhibitedAssetsResponse + (*ExhibitedAssetsData)(nil), // 18: topfans.gallery.ExhibitedAssetsData + (*ExhibitedAssetItem)(nil), // 19: topfans.gallery.ExhibitedAssetItem + (*GetInspirationFlowRequest)(nil), // 20: topfans.gallery.GetInspirationFlowRequest + (*GetInspirationFlowResponse)(nil), // 21: topfans.gallery.GetInspirationFlowResponse + (*InspirationFlowData)(nil), // 22: topfans.gallery.InspirationFlowData + (*InspirationFlowItem)(nil), // 23: topfans.gallery.InspirationFlowItem + (*GetUserExhibitedAssetsRequest)(nil), // 24: topfans.gallery.GetUserExhibitedAssetsRequest + (*GetUserExhibitedAssetsResponse)(nil), // 25: topfans.gallery.GetUserExhibitedAssetsResponse + (*common.BaseResponse)(nil), // 26: topfans.common.BaseResponse } var file_gallery_proto_depIdxs = []int32{ - 24, // 0: topfans.gallery.GetMyGalleryResponse.base:type_name -> topfans.common.BaseResponse + 26, // 0: topfans.gallery.GetMyGalleryResponse.base:type_name -> topfans.common.BaseResponse 8, // 1: topfans.gallery.GetMyGalleryResponse.data:type_name -> topfans.gallery.GalleryData - 24, // 2: topfans.gallery.GetUserGalleryResponse.base:type_name -> topfans.common.BaseResponse + 26, // 2: topfans.gallery.GetUserGalleryResponse.base:type_name -> topfans.common.BaseResponse 8, // 3: topfans.gallery.GetUserGalleryResponse.data:type_name -> topfans.gallery.GalleryData - 24, // 4: topfans.gallery.PlaceAssetResponse.base:type_name -> topfans.common.BaseResponse + 26, // 4: topfans.gallery.PlaceAssetResponse.base:type_name -> topfans.common.BaseResponse 12, // 5: topfans.gallery.PlaceAssetResponse.data:type_name -> topfans.gallery.PlaceAssetData - 24, // 6: topfans.gallery.UnlockSlotResponse.base:type_name -> topfans.common.BaseResponse + 26, // 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 - 24, // 11: topfans.gallery.RemoveFromSlotResponse.base:type_name -> topfans.common.BaseResponse - 24, // 12: topfans.gallery.GetMyExhibitedAssetsResponse.base:type_name -> topfans.common.BaseResponse + 26, // 11: topfans.gallery.RemoveFromSlotResponse.base:type_name -> topfans.common.BaseResponse + 26, // 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 - 24, // 15: topfans.gallery.GetInspirationFlowResponse.base:type_name -> topfans.common.BaseResponse + 26, // 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 + 26, // 18: topfans.gallery.GetUserExhibitedAssetsResponse.base:type_name -> topfans.common.BaseResponse + 18, // 19: topfans.gallery.GetUserExhibitedAssetsResponse.data:type_name -> topfans.gallery.ExhibitedAssetsData + 0, // 20: topfans.gallery.GalleryService.GetMyGallery:input_type -> topfans.gallery.GetMyGalleryRequest + 2, // 21: topfans.gallery.GalleryService.GetUserGallery:input_type -> topfans.gallery.GetUserGalleryRequest + 4, // 22: topfans.gallery.GalleryService.PlaceAsset:input_type -> topfans.gallery.PlaceAssetRequest + 6, // 23: topfans.gallery.GalleryService.UnlockSlot:input_type -> topfans.gallery.UnlockSlotRequest + 14, // 24: topfans.gallery.GalleryService.RemoveFromSlot:input_type -> topfans.gallery.RemoveFromSlotRequest + 16, // 25: topfans.gallery.GalleryService.GetMyExhibitedAssets:input_type -> topfans.gallery.GetMyExhibitedAssetsRequest + 20, // 26: topfans.gallery.GalleryService.GetInspirationFlow:input_type -> topfans.gallery.GetInspirationFlowRequest + 24, // 27: topfans.gallery.GalleryService.GetUserExhibitedAssets:input_type -> topfans.gallery.GetUserExhibitedAssetsRequest + 1, // 28: topfans.gallery.GalleryService.GetMyGallery:output_type -> topfans.gallery.GetMyGalleryResponse + 3, // 29: topfans.gallery.GalleryService.GetUserGallery:output_type -> topfans.gallery.GetUserGalleryResponse + 5, // 30: topfans.gallery.GalleryService.PlaceAsset:output_type -> topfans.gallery.PlaceAssetResponse + 7, // 31: topfans.gallery.GalleryService.UnlockSlot:output_type -> topfans.gallery.UnlockSlotResponse + 15, // 32: topfans.gallery.GalleryService.RemoveFromSlot:output_type -> topfans.gallery.RemoveFromSlotResponse + 17, // 33: topfans.gallery.GalleryService.GetMyExhibitedAssets:output_type -> topfans.gallery.GetMyExhibitedAssetsResponse + 21, // 34: topfans.gallery.GalleryService.GetInspirationFlow:output_type -> topfans.gallery.GetInspirationFlowResponse + 25, // 35: topfans.gallery.GalleryService.GetUserExhibitedAssets:output_type -> topfans.gallery.GetUserExhibitedAssetsResponse + 28, // [28:36] is the sub-list for method output_type + 20, // [20:28] is the sub-list for method input_type + 20, // [20:20] is the sub-list for extension type_name + 20, // [20:20] is the sub-list for extension extendee + 0, // [0:20] is the sub-list for field type_name } func init() { file_gallery_proto_init() } @@ -1730,7 +1858,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: 24, + NumMessages: 26, NumExtensions: 0, NumServices: 1, }, diff --git a/backend/pkg/proto/gallery/gallery.triple.go b/backend/pkg/proto/gallery/gallery.triple.go index 4a991a4..0f0358f 100644 --- a/backend/pkg/proto/gallery/gallery.triple.go +++ b/backend/pkg/proto/gallery/gallery.triple.go @@ -50,6 +50,8 @@ const ( GalleryServiceGetMyExhibitedAssetsProcedure = "/topfans.gallery.GalleryService/GetMyExhibitedAssets" // GalleryServiceGetInspirationFlowProcedure is the fully-qualified name of the GalleryService's GetInspirationFlow RPC. GalleryServiceGetInspirationFlowProcedure = "/topfans.gallery.GalleryService/GetInspirationFlow" + // GalleryServiceGetUserExhibitedAssetsProcedure is the fully-qualified name of the GalleryService's GetUserExhibitedAssets RPC. + GalleryServiceGetUserExhibitedAssetsProcedure = "/topfans.gallery.GalleryService/GetUserExhibitedAssets" ) var ( @@ -65,6 +67,7 @@ type GalleryService interface { 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) + GetUserExhibitedAssets(ctx context.Context, req *GetUserExhibitedAssetsRequest, opts ...client.CallOption) (*GetUserExhibitedAssetsResponse, error) } // NewGalleryService constructs a client for the gallery.GalleryService service. @@ -143,9 +146,17 @@ func (c *GalleryServiceImpl) GetInspirationFlow(ctx context.Context, req *GetIns return resp, nil } +func (c *GalleryServiceImpl) GetUserExhibitedAssets(ctx context.Context, req *GetUserExhibitedAssetsRequest, opts ...client.CallOption) (*GetUserExhibitedAssetsResponse, error) { + resp := new(GetUserExhibitedAssetsResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetUserExhibitedAssets", 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"}, + MethodNames: []string{"GetMyGallery", "GetUserGallery", "PlaceAsset", "UnlockSlot", "RemoveFromSlot", "GetMyExhibitedAssets", "GetInspirationFlow", "GetUserExhibitedAssets"}, ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) { dubboCli := dubboCliRaw.(*GalleryServiceImpl) dubboCli.conn = conn @@ -161,6 +172,7 @@ type GalleryServiceHandler interface { RemoveFromSlot(context.Context, *RemoveFromSlotRequest) (*RemoveFromSlotResponse, error) GetMyExhibitedAssets(context.Context, *GetMyExhibitedAssetsRequest) (*GetMyExhibitedAssetsResponse, error) GetInspirationFlow(context.Context, *GetInspirationFlowRequest) (*GetInspirationFlowResponse, error) + GetUserExhibitedAssets(context.Context, *GetUserExhibitedAssetsRequest) (*GetUserExhibitedAssetsResponse, error) } func RegisterGalleryServiceHandler(srv *server.Server, hdlr GalleryServiceHandler, opts ...server.ServiceOption) error { @@ -280,5 +292,20 @@ var GalleryService_ServiceInfo = server.ServiceInfo{ return triple_protocol.NewResponse(res), nil }, }, + { + Name: "GetUserExhibitedAssets", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetUserExhibitedAssetsRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetUserExhibitedAssetsRequest) + res, err := handler.(GalleryServiceHandler).GetUserExhibitedAssets(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, }, } diff --git a/backend/pkg/proto/social/social.pb.go b/backend/pkg/proto/social/social.pb.go index d96f5ff..cd7d297 100644 --- a/backend/pkg/proto/social/social.pb.go +++ b/backend/pkg/proto/social/social.pb.go @@ -2628,6 +2628,120 @@ func (x *GetMyWeekLikedAssetsResponse) GetData() *LikedAssetsData { return nil } +// 获取他人点赞的作品列表请求(暂不实现) +type GetUserLikedAssetsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 他人用户ID + Page int32 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"` // 页码(默认1) + PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // 每页数量(默认20,最大100) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserLikedAssetsRequest) Reset() { + *x = GetUserLikedAssetsRequest{} + mi := &file_social_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserLikedAssetsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserLikedAssetsRequest) ProtoMessage() {} + +func (x *GetUserLikedAssetsRequest) ProtoReflect() protoreflect.Message { + mi := &file_social_proto_msgTypes[41] + 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 GetUserLikedAssetsRequest.ProtoReflect.Descriptor instead. +func (*GetUserLikedAssetsRequest) Descriptor() ([]byte, []int) { + return file_social_proto_rawDescGZIP(), []int{41} +} + +func (x *GetUserLikedAssetsRequest) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *GetUserLikedAssetsRequest) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *GetUserLikedAssetsRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +// 获取他人点赞的作品列表响应(暂不实现) +type GetUserLikedAssetsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Base *common.BaseResponse `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"` + Data *LikedAssetsData `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserLikedAssetsResponse) Reset() { + *x = GetUserLikedAssetsResponse{} + mi := &file_social_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserLikedAssetsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserLikedAssetsResponse) ProtoMessage() {} + +func (x *GetUserLikedAssetsResponse) ProtoReflect() protoreflect.Message { + mi := &file_social_proto_msgTypes[42] + 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 GetUserLikedAssetsResponse.ProtoReflect.Descriptor instead. +func (*GetUserLikedAssetsResponse) Descriptor() ([]byte, []int) { + return file_social_proto_rawDescGZIP(), []int{42} +} + +func (x *GetUserLikedAssetsResponse) GetBase() *common.BaseResponse { + if x != nil { + return x.Base + } + return nil +} + +func (x *GetUserLikedAssetsResponse) GetData() *LikedAssetsData { + if x != nil { + return x.Data + } + return nil +} + var File_social_proto protoreflect.FileDescriptor const file_social_proto_rawDesc = "" + @@ -2825,7 +2939,14 @@ const file_social_proto_rawDesc = "" + "\tpage_size\x18\x02 \x01(\x05R\bpageSize\"\x85\x01\n" + "\x1cGetMyWeekLikedAssetsResponse\x120\n" + "\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x123\n" + - "\x04data\x18\x02 \x01(\v2\x1f.topfans.social.LikedAssetsDataR\x04data2\xf8\x12\n" + + "\x04data\x18\x02 \x01(\v2\x1f.topfans.social.LikedAssetsDataR\x04data\"e\n" + + "\x19GetUserLikedAssetsRequest\x12\x17\n" + + "\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x12\n" + + "\x04page\x18\x02 \x01(\x05R\x04page\x12\x1b\n" + + "\tpage_size\x18\x03 \x01(\x05R\bpageSize\"\x83\x01\n" + + "\x1aGetUserLikedAssetsResponse\x120\n" + + "\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x123\n" + + "\x04data\x18\x02 \x01(\v2\x1f.topfans.social.LikedAssetsDataR\x04data2\x94\x14\n" + "\rSocialService\x12\x8d\x01\n" + "\x11SendFriendRequest\x12(.topfans.social.SendFriendRequestRequest\x1a).topfans.social.SendFriendRequestResponse\"#\x82\xd3\xe4\x93\x02\x1d:\x01*\"\x18/api/v1/friends/requests\x12\x8a\x01\n" + "\x11GetFriendRequests\x12(.topfans.social.GetFriendRequestsRequest\x1a).topfans.social.GetFriendRequestsResponse\" \x82\xd3\xe4\x93\x02\x1a\x12\x18/api/v1/friends/requests\x12\xa7\x01\n" + @@ -2843,7 +2964,8 @@ const file_social_proto_rawDesc = "" + "\x0eCheckAssetLike\x12%.topfans.social.CheckAssetLikeRequest\x1a&.topfans.social.CheckAssetLikeResponse\"-\x82\xd3\xe4\x93\x02'\x12%/api/v1/social/assets/{asset_id}/like\x12\x86\x01\n" + "\x10GetMyLikedAssets\x12'.topfans.social.GetMyLikedAssetsRequest\x1a(.topfans.social.GetMyLikedAssetsResponse\"\x1f\x82\xd3\xe4\x93\x02\x19\x12\x17/api/v1/me/liked-assets\x12\x9b\x01\n" + "\x15GetMyTodayLikedAssets\x12,.topfans.social.GetMyTodayLikedAssetsRequest\x1a-.topfans.social.GetMyTodayLikedAssetsResponse\"%\x82\xd3\xe4\x93\x02\x1f\x12\x1d/api/v1/me/today-liked-assets\x12\x97\x01\n" + - "\x14GetMyWeekLikedAssets\x12+.topfans.social.GetMyWeekLikedAssetsRequest\x1a,.topfans.social.GetMyWeekLikedAssetsResponse\"$\x82\xd3\xe4\x93\x02\x1e\x12\x1c/api/v1/me/week-liked-assetsB4Z2github.com/topfans/backend/pkg/proto/social;socialb\x06proto3" + "\x14GetMyWeekLikedAssets\x12+.topfans.social.GetMyWeekLikedAssetsRequest\x1a,.topfans.social.GetMyWeekLikedAssetsResponse\"$\x82\xd3\xe4\x93\x02\x1e\x12\x1c/api/v1/me/week-liked-assets\x12\x99\x01\n" + + "\x12GetUserLikedAssets\x12).topfans.social.GetUserLikedAssetsRequest\x1a*.topfans.social.GetUserLikedAssetsResponse\",\x82\xd3\xe4\x93\x02&\x12$/api/v1/users/{user_id}/liked-assetsB4Z2github.com/topfans/backend/pkg/proto/social;socialb\x06proto3" var ( file_social_proto_rawDescOnce sync.Once @@ -2857,7 +2979,7 @@ func file_social_proto_rawDescGZIP() []byte { return file_social_proto_rawDescData } -var file_social_proto_msgTypes = make([]protoimpl.MessageInfo, 41) +var file_social_proto_msgTypes = make([]protoimpl.MessageInfo, 43) var file_social_proto_goTypes = []any{ (*FriendRequest)(nil), // 0: topfans.social.FriendRequest (*Friendship)(nil), // 1: topfans.social.Friendship @@ -2900,75 +3022,81 @@ var file_social_proto_goTypes = []any{ (*GetMyTodayLikedAssetsResponse)(nil), // 38: topfans.social.GetMyTodayLikedAssetsResponse (*GetMyWeekLikedAssetsRequest)(nil), // 39: topfans.social.GetMyWeekLikedAssetsRequest (*GetMyWeekLikedAssetsResponse)(nil), // 40: topfans.social.GetMyWeekLikedAssetsResponse - (*common.BaseResponse)(nil), // 41: topfans.common.BaseResponse + (*GetUserLikedAssetsRequest)(nil), // 41: topfans.social.GetUserLikedAssetsRequest + (*GetUserLikedAssetsResponse)(nil), // 42: topfans.social.GetUserLikedAssetsResponse + (*common.BaseResponse)(nil), // 43: topfans.common.BaseResponse } var file_social_proto_depIdxs = []int32{ - 41, // 0: topfans.social.SendFriendRequestResponse.base:type_name -> topfans.common.BaseResponse + 43, // 0: topfans.social.SendFriendRequestResponse.base:type_name -> topfans.common.BaseResponse 20, // 1: topfans.social.SendFriendRequestResponse.matched_users:type_name -> topfans.social.FanProfileSearchResult - 41, // 2: topfans.social.GetFriendRequestsResponse.base:type_name -> topfans.common.BaseResponse + 43, // 2: topfans.social.GetFriendRequestsResponse.base:type_name -> topfans.common.BaseResponse 0, // 3: topfans.social.GetFriendRequestsResponse.items:type_name -> topfans.social.FriendRequest - 41, // 4: topfans.social.HandleFriendRequestResponse.base:type_name -> topfans.common.BaseResponse - 41, // 5: topfans.social.GetFriendListResponse.base:type_name -> topfans.common.BaseResponse + 43, // 4: topfans.social.HandleFriendRequestResponse.base:type_name -> topfans.common.BaseResponse + 43, // 5: topfans.social.GetFriendListResponse.base:type_name -> topfans.common.BaseResponse 1, // 6: topfans.social.GetFriendListResponse.items:type_name -> topfans.social.Friendship - 41, // 7: topfans.social.DeleteFriendResponse.base:type_name -> topfans.common.BaseResponse - 41, // 8: topfans.social.SetFriendRemarkResponse.base:type_name -> topfans.common.BaseResponse - 41, // 9: topfans.social.CheckFriendshipResponse.base:type_name -> topfans.common.BaseResponse - 41, // 10: topfans.social.GetFriendCountResponse.base:type_name -> topfans.common.BaseResponse - 41, // 11: topfans.social.SearchUserForFriendResponse.base:type_name -> topfans.common.BaseResponse + 43, // 7: topfans.social.DeleteFriendResponse.base:type_name -> topfans.common.BaseResponse + 43, // 8: topfans.social.SetFriendRemarkResponse.base:type_name -> topfans.common.BaseResponse + 43, // 9: topfans.social.CheckFriendshipResponse.base:type_name -> topfans.common.BaseResponse + 43, // 10: topfans.social.GetFriendCountResponse.base:type_name -> topfans.common.BaseResponse + 43, // 11: topfans.social.SearchUserForFriendResponse.base:type_name -> topfans.common.BaseResponse 20, // 12: topfans.social.SearchUserForFriendResponse.user:type_name -> topfans.social.FanProfileSearchResult - 41, // 13: topfans.social.GetRandomUsersResponse.base:type_name -> topfans.common.BaseResponse + 43, // 13: topfans.social.GetRandomUsersResponse.base:type_name -> topfans.common.BaseResponse 21, // 14: topfans.social.GetRandomUsersResponse.users:type_name -> topfans.social.RandomUser - 41, // 15: topfans.social.GetUsersPagedResponse.base:type_name -> topfans.common.BaseResponse + 43, // 15: topfans.social.GetUsersPagedResponse.base:type_name -> topfans.common.BaseResponse 24, // 16: topfans.social.GetUsersPagedResponse.users:type_name -> topfans.social.PagedUser - 41, // 17: topfans.social.LikeAssetResponse.base:type_name -> topfans.common.BaseResponse - 41, // 18: topfans.social.UnlikeAssetResponse.base:type_name -> topfans.common.BaseResponse - 41, // 19: topfans.social.CheckAssetLikeResponse.base:type_name -> topfans.common.BaseResponse - 41, // 20: topfans.social.GetMyLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse + 43, // 17: topfans.social.LikeAssetResponse.base:type_name -> topfans.common.BaseResponse + 43, // 18: topfans.social.UnlikeAssetResponse.base:type_name -> topfans.common.BaseResponse + 43, // 19: topfans.social.CheckAssetLikeResponse.base:type_name -> topfans.common.BaseResponse + 43, // 20: topfans.social.GetMyLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse 35, // 21: topfans.social.GetMyLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData 36, // 22: topfans.social.LikedAssetsData.items:type_name -> topfans.social.LikedAssetItem - 41, // 23: topfans.social.GetMyTodayLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse + 43, // 23: topfans.social.GetMyTodayLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse 35, // 24: topfans.social.GetMyTodayLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData - 41, // 25: topfans.social.GetMyWeekLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse + 43, // 25: topfans.social.GetMyWeekLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse 35, // 26: topfans.social.GetMyWeekLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData - 2, // 27: topfans.social.SocialService.SendFriendRequest:input_type -> topfans.social.SendFriendRequestRequest - 4, // 28: topfans.social.SocialService.GetFriendRequests:input_type -> topfans.social.GetFriendRequestsRequest - 6, // 29: topfans.social.SocialService.HandleFriendRequest:input_type -> topfans.social.HandleFriendRequestRequest - 8, // 30: topfans.social.SocialService.GetFriendList:input_type -> topfans.social.GetFriendListRequest - 10, // 31: topfans.social.SocialService.DeleteFriend:input_type -> topfans.social.DeleteFriendRequest - 12, // 32: topfans.social.SocialService.SetFriendRemark:input_type -> topfans.social.SetFriendRemarkRequest - 14, // 33: topfans.social.SocialService.CheckFriendship:input_type -> topfans.social.CheckFriendshipRequest - 16, // 34: topfans.social.SocialService.GetFriendCount:input_type -> topfans.social.GetFriendCountRequest - 18, // 35: topfans.social.SocialService.SearchUserForFriend:input_type -> topfans.social.SearchUserForFriendRequest - 22, // 36: topfans.social.SocialService.GetRandomUsers:input_type -> topfans.social.GetRandomUsersRequest - 25, // 37: topfans.social.SocialService.GetUsersPaged:input_type -> topfans.social.GetUsersPagedRequest - 27, // 38: topfans.social.SocialService.LikeAsset:input_type -> topfans.social.LikeAssetRequest - 29, // 39: topfans.social.SocialService.UnlikeAsset:input_type -> topfans.social.UnlikeAssetRequest - 31, // 40: topfans.social.SocialService.CheckAssetLike:input_type -> topfans.social.CheckAssetLikeRequest - 33, // 41: topfans.social.SocialService.GetMyLikedAssets:input_type -> topfans.social.GetMyLikedAssetsRequest - 37, // 42: topfans.social.SocialService.GetMyTodayLikedAssets:input_type -> topfans.social.GetMyTodayLikedAssetsRequest - 39, // 43: topfans.social.SocialService.GetMyWeekLikedAssets:input_type -> topfans.social.GetMyWeekLikedAssetsRequest - 3, // 44: topfans.social.SocialService.SendFriendRequest:output_type -> topfans.social.SendFriendRequestResponse - 5, // 45: topfans.social.SocialService.GetFriendRequests:output_type -> topfans.social.GetFriendRequestsResponse - 7, // 46: topfans.social.SocialService.HandleFriendRequest:output_type -> topfans.social.HandleFriendRequestResponse - 9, // 47: topfans.social.SocialService.GetFriendList:output_type -> topfans.social.GetFriendListResponse - 11, // 48: topfans.social.SocialService.DeleteFriend:output_type -> topfans.social.DeleteFriendResponse - 13, // 49: topfans.social.SocialService.SetFriendRemark:output_type -> topfans.social.SetFriendRemarkResponse - 15, // 50: topfans.social.SocialService.CheckFriendship:output_type -> topfans.social.CheckFriendshipResponse - 17, // 51: topfans.social.SocialService.GetFriendCount:output_type -> topfans.social.GetFriendCountResponse - 19, // 52: topfans.social.SocialService.SearchUserForFriend:output_type -> topfans.social.SearchUserForFriendResponse - 23, // 53: topfans.social.SocialService.GetRandomUsers:output_type -> topfans.social.GetRandomUsersResponse - 26, // 54: topfans.social.SocialService.GetUsersPaged:output_type -> topfans.social.GetUsersPagedResponse - 28, // 55: topfans.social.SocialService.LikeAsset:output_type -> topfans.social.LikeAssetResponse - 30, // 56: topfans.social.SocialService.UnlikeAsset:output_type -> topfans.social.UnlikeAssetResponse - 32, // 57: topfans.social.SocialService.CheckAssetLike:output_type -> topfans.social.CheckAssetLikeResponse - 34, // 58: topfans.social.SocialService.GetMyLikedAssets:output_type -> topfans.social.GetMyLikedAssetsResponse - 38, // 59: topfans.social.SocialService.GetMyTodayLikedAssets:output_type -> topfans.social.GetMyTodayLikedAssetsResponse - 40, // 60: topfans.social.SocialService.GetMyWeekLikedAssets:output_type -> topfans.social.GetMyWeekLikedAssetsResponse - 44, // [44:61] is the sub-list for method output_type - 27, // [27:44] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 43, // 27: topfans.social.GetUserLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse + 35, // 28: topfans.social.GetUserLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData + 2, // 29: topfans.social.SocialService.SendFriendRequest:input_type -> topfans.social.SendFriendRequestRequest + 4, // 30: topfans.social.SocialService.GetFriendRequests:input_type -> topfans.social.GetFriendRequestsRequest + 6, // 31: topfans.social.SocialService.HandleFriendRequest:input_type -> topfans.social.HandleFriendRequestRequest + 8, // 32: topfans.social.SocialService.GetFriendList:input_type -> topfans.social.GetFriendListRequest + 10, // 33: topfans.social.SocialService.DeleteFriend:input_type -> topfans.social.DeleteFriendRequest + 12, // 34: topfans.social.SocialService.SetFriendRemark:input_type -> topfans.social.SetFriendRemarkRequest + 14, // 35: topfans.social.SocialService.CheckFriendship:input_type -> topfans.social.CheckFriendshipRequest + 16, // 36: topfans.social.SocialService.GetFriendCount:input_type -> topfans.social.GetFriendCountRequest + 18, // 37: topfans.social.SocialService.SearchUserForFriend:input_type -> topfans.social.SearchUserForFriendRequest + 22, // 38: topfans.social.SocialService.GetRandomUsers:input_type -> topfans.social.GetRandomUsersRequest + 25, // 39: topfans.social.SocialService.GetUsersPaged:input_type -> topfans.social.GetUsersPagedRequest + 27, // 40: topfans.social.SocialService.LikeAsset:input_type -> topfans.social.LikeAssetRequest + 29, // 41: topfans.social.SocialService.UnlikeAsset:input_type -> topfans.social.UnlikeAssetRequest + 31, // 42: topfans.social.SocialService.CheckAssetLike:input_type -> topfans.social.CheckAssetLikeRequest + 33, // 43: topfans.social.SocialService.GetMyLikedAssets:input_type -> topfans.social.GetMyLikedAssetsRequest + 37, // 44: topfans.social.SocialService.GetMyTodayLikedAssets:input_type -> topfans.social.GetMyTodayLikedAssetsRequest + 39, // 45: topfans.social.SocialService.GetMyWeekLikedAssets:input_type -> topfans.social.GetMyWeekLikedAssetsRequest + 41, // 46: topfans.social.SocialService.GetUserLikedAssets:input_type -> topfans.social.GetUserLikedAssetsRequest + 3, // 47: topfans.social.SocialService.SendFriendRequest:output_type -> topfans.social.SendFriendRequestResponse + 5, // 48: topfans.social.SocialService.GetFriendRequests:output_type -> topfans.social.GetFriendRequestsResponse + 7, // 49: topfans.social.SocialService.HandleFriendRequest:output_type -> topfans.social.HandleFriendRequestResponse + 9, // 50: topfans.social.SocialService.GetFriendList:output_type -> topfans.social.GetFriendListResponse + 11, // 51: topfans.social.SocialService.DeleteFriend:output_type -> topfans.social.DeleteFriendResponse + 13, // 52: topfans.social.SocialService.SetFriendRemark:output_type -> topfans.social.SetFriendRemarkResponse + 15, // 53: topfans.social.SocialService.CheckFriendship:output_type -> topfans.social.CheckFriendshipResponse + 17, // 54: topfans.social.SocialService.GetFriendCount:output_type -> topfans.social.GetFriendCountResponse + 19, // 55: topfans.social.SocialService.SearchUserForFriend:output_type -> topfans.social.SearchUserForFriendResponse + 23, // 56: topfans.social.SocialService.GetRandomUsers:output_type -> topfans.social.GetRandomUsersResponse + 26, // 57: topfans.social.SocialService.GetUsersPaged:output_type -> topfans.social.GetUsersPagedResponse + 28, // 58: topfans.social.SocialService.LikeAsset:output_type -> topfans.social.LikeAssetResponse + 30, // 59: topfans.social.SocialService.UnlikeAsset:output_type -> topfans.social.UnlikeAssetResponse + 32, // 60: topfans.social.SocialService.CheckAssetLike:output_type -> topfans.social.CheckAssetLikeResponse + 34, // 61: topfans.social.SocialService.GetMyLikedAssets:output_type -> topfans.social.GetMyLikedAssetsResponse + 38, // 62: topfans.social.SocialService.GetMyTodayLikedAssets:output_type -> topfans.social.GetMyTodayLikedAssetsResponse + 40, // 63: topfans.social.SocialService.GetMyWeekLikedAssets:output_type -> topfans.social.GetMyWeekLikedAssetsResponse + 42, // 64: topfans.social.SocialService.GetUserLikedAssets:output_type -> topfans.social.GetUserLikedAssetsResponse + 47, // [47:65] is the sub-list for method output_type + 29, // [29:47] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_social_proto_init() } @@ -2982,7 +3110,7 @@ func file_social_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_social_proto_rawDesc), len(file_social_proto_rawDesc)), NumEnums: 0, - NumMessages: 41, + NumMessages: 43, NumExtensions: 0, NumServices: 1, }, diff --git a/backend/pkg/proto/social/social.triple.go b/backend/pkg/proto/social/social.triple.go index bcb87dc..d133947 100644 --- a/backend/pkg/proto/social/social.triple.go +++ b/backend/pkg/proto/social/social.triple.go @@ -89,6 +89,9 @@ type SocialService interface { 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) + GetUserLikedAssets(ctx context.Context, req *GetUserLikedAssetsRequest, opts ...client.CallOption) (*GetUserLikedAssetsResponse, error) } // NewSocialService constructs a client for the social.SocialService service. @@ -231,9 +234,33 @@ func (c *SocialServiceImpl) GetMyLikedAssets(ctx context.Context, req *GetMyLike 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 +} + +func (c *SocialServiceImpl) GetUserLikedAssets(ctx context.Context, req *GetUserLikedAssetsRequest, opts ...client.CallOption) (*GetUserLikedAssetsResponse, error) { + resp := new(GetUserLikedAssetsResponse) + if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetUserLikedAssets", 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"}, + MethodNames: []string{"SendFriendRequest", "GetFriendRequests", "HandleFriendRequest", "GetFriendList", "DeleteFriend", "SetFriendRemark", "CheckFriendship", "GetFriendCount", "SearchUserForFriend", "GetRandomUsers", "GetUsersPaged", "LikeAsset", "UnlikeAsset", "CheckAssetLike", "GetMyLikedAssets", "GetMyTodayLikedAssets", "GetMyWeekLikedAssets", "GetUserLikedAssets"}, ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) { dubboCli := dubboCliRaw.(*SocialServiceImpl) dubboCli.conn = conn @@ -257,6 +284,9 @@ type SocialServiceHandler interface { 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) + GetUserLikedAssets(context.Context, *GetUserLikedAssetsRequest) (*GetUserLikedAssetsResponse, error) } func RegisterSocialServiceHandler(srv *server.Server, hdlr SocialServiceHandler, opts ...server.ServiceOption) error { @@ -496,5 +526,50 @@ var SocialService_ServiceInfo = server.ServiceInfo{ 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 + }, + }, + { + Name: "GetUserLikedAssets", + Type: constant.CallUnary, + ReqInitFunc: func() interface{} { + return new(GetUserLikedAssetsRequest) + }, + MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) { + req := args[0].(*GetUserLikedAssetsRequest) + res, err := handler.(SocialServiceHandler).GetUserLikedAssets(ctx, req) + if err != nil { + return nil, err + } + return triple_protocol.NewResponse(res), nil + }, + }, }, } diff --git a/backend/proto/gallery.proto b/backend/proto/gallery.proto index 4153076..01831d7 100644 --- a/backend/proto/gallery.proto +++ b/backend/proto/gallery.proto @@ -61,6 +61,13 @@ service GalleryService { get: "/api/v1/inspiration-flow" }; } + + // 获取他人展出的作品列表(暂不实现) + rpc GetUserExhibitedAssets(GetUserExhibitedAssetsRequest) returns (GetUserExhibitedAssetsResponse) { + option (google.api.http) = { + get: "/api/v1/users/{user_id}/exhibited-assets" + }; + } } // 请求和响应消息定义 @@ -224,3 +231,18 @@ message InspirationFlowItem { int32 span = 6; // 卡片大小: 0-30→1, 31-100→2, 101-200→3, 200+→4 string material_type = 7; // 素材类型: hot(人气王者), potential(潜力之星), new(新鲜上架) } + +// ==================== 他人作品相关消息(暂不实现)==================== + +// 获取他人展出的作品列表请求(暂不实现) +message GetUserExhibitedAssetsRequest { + int64 user_id = 1; // 他人用户ID + int32 page = 2; // 页码(默认1) + int32 page_size = 3; // 每页数量(默认20,最大100) +} + +// 获取他人展出的作品列表响应(暂不实现) +message GetUserExhibitedAssetsResponse { + topfans.common.BaseResponse base = 1; + ExhibitedAssetsData data = 2; +} diff --git a/backend/proto/social.proto b/backend/proto/social.proto index 3946343..40a8d47 100644 --- a/backend/proto/social.proto +++ b/backend/proto/social.proto @@ -317,6 +317,19 @@ message GetMyWeekLikedAssetsResponse { LikedAssetsData data = 2; } +// 获取他人点赞的作品列表请求(暂不实现) +message GetUserLikedAssetsRequest { + int64 user_id = 1; // 他人用户ID + int32 page = 2; // 页码(默认1) + int32 page_size = 3; // 每页数量(默认20,最大100) +} + +// 获取他人点赞的作品列表响应(暂不实现) +message GetUserLikedAssetsResponse { + topfans.common.BaseResponse base = 1; + LikedAssetsData data = 2; +} + // ==================== 社交服务(包含好友等功能)==================== service SocialService { @@ -451,5 +464,12 @@ service SocialService { get: "/api/v1/me/week-liked-assets" }; } + + // 获取他人点赞的作品列表(暂不实现) + rpc GetUserLikedAssets(GetUserLikedAssetsRequest) returns (GetUserLikedAssetsResponse) { + option (google.api.http) = { + get: "/api/v1/users/{user_id}/liked-assets" + }; + } } diff --git a/backend/services/galleryService/provider/gallery_provider.go b/backend/services/galleryService/provider/gallery_provider.go index 14bbe98..b1c8fae 100644 --- a/backend/services/galleryService/provider/gallery_provider.go +++ b/backend/services/galleryService/provider/gallery_provider.go @@ -396,6 +396,31 @@ func (p *GalleryProvider) GetInspirationFlow(ctx context.Context, req *pb.GetIns }, nil } +// GetUserExhibitedAssets 获取他人展出的作品列表 +func (p *GalleryProvider) GetUserExhibitedAssets(ctx context.Context, req *pb.GetUserExhibitedAssetsRequest) (*pb.GetUserExhibitedAssetsResponse, error) { + logger.Logger.Info("Received GetUserExhibitedAssets request", + zap.Int64("target_user_id", req.UserId), + ) + + // 从 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.GetUserExhibitedAssetsResponse{ + Base: &pbCommon.BaseResponse{ + Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED, + Message: "user authentication required", + Timestamp: 0, + }, + }, err + } + + // 调用Service层 + return p.exhibitionService.GetUserExhibitedAssets(ctx, userID, starID, req) +} + // ==================== 辅助函数 ==================== // extractUserInfoFromDubboAttachments 从Dubbo attachments提取用户信息 diff --git a/backend/services/galleryService/repository/gallery_repository.go b/backend/services/galleryService/repository/gallery_repository.go index 1e71784..efe8f07 100644 --- a/backend/services/galleryService/repository/gallery_repository.go +++ b/backend/services/galleryService/repository/gallery_repository.go @@ -42,6 +42,14 @@ type GalleryRepository interface { // 返回: 作品列表、总数量 GetMyExhibitedAssets(userID, starID int64, page, pageSize int) ([]*ExhibitedAssetInfo, int64, error) + // GetUserExhibitedAssets 获取他人展出的作品列表(只返回展出中且未过期的) + // userID: 他人用户ID + // starID: 明星ID + // page: 页码(从1开始) + // pageSize: 每页数量 + // 返回: 作品列表、总数量 + GetUserExhibitedAssets(userID, starID int64, page, pageSize int) ([]*ExhibitedAssetInfo, int64, error) + // ========== 灵感瀑布相关 ========== // CountValidExhibitions 统计有效展品数量 @@ -315,6 +323,45 @@ func (r *galleryRepository) GetMyExhibitedAssets(userID, starID int64, page, pag return items, total, nil } +// GetUserExhibitedAssets 获取他人展出的作品列表(只返回展出中且未过期的) +func (r *galleryRepository) GetUserExhibitedAssets(userID, starID int64, page, pageSize int) ([]*ExhibitedAssetInfo, int64, error) { + var items []*ExhibitedAssetInfo + var total int64 + + now := time.Now().UnixMilli() + + // 计数查询 + err := r.db.Model(&models.Exhibition{}). + Where("occupier_uid = ? AND occupier_star_id = ? AND deleted_at IS NULL AND expire_at > ?", userID, starID, now). + Count(&total).Error + if err != nil { + return nil, 0, err + } + + // 数据查询 + offset := (page - 1) * pageSize + err = r.db.Model(&models.Exhibition{}). + Raw(` + SELECT exhibitions.asset_id, a.name, a.cover_url, a.like_count, + exhibitions.start_time as exhibited_at, exhibitions.expire_at, + 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 + } + + return items, total, nil +} + // ========== 灵感瀑布相关实现 ========== // CountValidExhibitions 统计有效展品数量 diff --git a/backend/services/socialService/provider/social_provider.go b/backend/services/socialService/provider/social_provider.go index e079dbb..e78d3af 100644 --- a/backend/services/socialService/provider/social_provider.go +++ b/backend/services/socialService/provider/social_provider.go @@ -400,6 +400,78 @@ func (p *SocialProvider) GetMyLikedAssets(ctx context.Context, req *pb.GetMyLike return p.assetLikeService.GetMyLikedAssets(ctx, req, userID, starID) } +// GetMyTodayLikedAssets 获取我今日点赞的作品列表 +func (p *SocialProvider) GetMyTodayLikedAssets(ctx context.Context, req *pb.GetMyTodayLikedAssetsRequest) (*pb.GetMyTodayLikedAssetsResponse, error) { + userID, starID, err := extractUserInfo(ctx) + if err != nil { + logger.Logger.Warn("Failed to extract user info from context", zap.Error(err)) + return &pb.GetMyTodayLikedAssetsResponse{ + Base: &common.BaseResponse{ + Code: common.StatusCode_STATUS_UNAUTHORIZED, + Message: "Unauthorized: " + err.Error(), + Timestamp: time.Now().UnixMilli(), + }, + }, nil + } + + logger.Logger.Debug("GetMyTodayLikedAssets called", + zap.Int64("user_id", userID), + zap.Int64("star_id", starID), + zap.Int32("page", req.Page), + zap.Int32("page_size", req.PageSize), + ) + + return p.assetLikeService.GetMyTodayLikedAssets(ctx, req, userID, starID) +} + +// GetMyWeekLikedAssets 获取我本周点赞的作品列表 +func (p *SocialProvider) GetMyWeekLikedAssets(ctx context.Context, req *pb.GetMyWeekLikedAssetsRequest) (*pb.GetMyWeekLikedAssetsResponse, error) { + userID, starID, err := extractUserInfo(ctx) + if err != nil { + logger.Logger.Warn("Failed to extract user info from context", zap.Error(err)) + return &pb.GetMyWeekLikedAssetsResponse{ + Base: &common.BaseResponse{ + Code: common.StatusCode_STATUS_UNAUTHORIZED, + Message: "Unauthorized: " + err.Error(), + Timestamp: time.Now().UnixMilli(), + }, + }, nil + } + + logger.Logger.Debug("GetMyWeekLikedAssets called", + zap.Int64("user_id", userID), + zap.Int64("star_id", starID), + zap.Int32("page", req.Page), + zap.Int32("page_size", req.PageSize), + ) + + return p.assetLikeService.GetMyWeekLikedAssets(ctx, req, userID, starID) +} + +// GetUserLikedAssets 获取他人点赞的作品列表 +func (p *SocialProvider) GetUserLikedAssets(ctx context.Context, req *pb.GetUserLikedAssetsRequest) (*pb.GetUserLikedAssetsResponse, error) { + userID, starID, err := extractUserInfo(ctx) + if err != nil { + logger.Logger.Warn("Failed to extract user info from context", zap.Error(err)) + return &pb.GetUserLikedAssetsResponse{ + Base: &common.BaseResponse{ + Code: common.StatusCode_STATUS_UNAUTHORIZED, + Message: "Unauthorized: " + err.Error(), + Timestamp: time.Now().UnixMilli(), + }, + }, nil + } + + logger.Logger.Debug("GetUserLikedAssets called", + zap.Int64("user_id", userID), + zap.Int64("star_id", starID), + zap.Int32("page", req.Page), + zap.Int32("page_size", req.PageSize), + ) + + return p.assetLikeService.GetUserLikedAssets(ctx, req, userID, starID) +} + // extractUserInfo 从 Dubbo attachments 中提取用户信息 // 网关调用:网关已验证 Token 并将 user_id 和 star_id 通过 attachments 传递 func extractUserInfo(ctx context.Context) (int64, int64, error) { diff --git a/backend/services/socialService/repository/social_repository.go b/backend/services/socialService/repository/social_repository.go index ce8cfba..9b2df7b 100644 --- a/backend/services/socialService/repository/social_repository.go +++ b/backend/services/socialService/repository/social_repository.go @@ -111,6 +111,30 @@ type SocialRepository interface { // pageSize: 每页数量 // 返回: 作品列表、总数量 GetMyLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) + + // GetMyTodayLikedAssets 获取我今日点赞的作品列表(只返回展出中且未过期的) + // userID: 用户ID + // starID: 明星ID + // page: 页码(从1开始) + // pageSize: 每页数量 + // 返回: 作品列表、总数量 + GetMyTodayLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) + + // GetMyWeekLikedAssets 获取我本周点赞的作品列表(只返回展出中且未过期的) + // userID: 用户ID + // starID: 明星ID + // page: 页码(从1开始) + // pageSize: 每页数量 + // 返回: 作品列表、总数量 + GetMyWeekLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) + + // GetUserLikedAssets 获取他人点赞的作品列表(只返回展出中且未过期的) + // userID: 他人用户ID + // starID: 明星ID + // page: 页码(从1开始) + // pageSize: 每页数量 + // 返回: 作品列表、总数量 + GetUserLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) } // LikedAssetInfo 我点赞的作品信息 @@ -593,3 +617,142 @@ func (r *socialRepositoryImpl) GetMyLikedAssets(userID, starID int64, page, page return items, total, nil } + +// GetMyTodayLikedAssets 获取我今日点赞的作品列表(只返回展出中且未过期的) +func (r *socialRepositoryImpl) GetMyTodayLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) { + now := time.Now() + startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).UnixMilli() + + var items []*LikedAssetInfo + var total int64 + + countQuery := r.db.Model(&models.AssetLike{}). + Joins("JOIN assets a ON a.id = asset_likes.asset_id"). + Joins("JOIN exhibitions e ON e.asset_id = a.id"). + Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID). + Where("asset_likes.created_at >= ?", startOfDay). + Where("a.deleted_at IS NULL AND a.is_active = ?", true). + Where("e.deleted_at IS NULL AND e.expire_at > ?", now.UnixMilli()) + + if err := countQuery.Distinct("asset_likes.asset_id").Count(&total).Error; err != nil { + return nil, 0, err + } + + offset := (page - 1) * pageSize + err := r.db.Model(&models.AssetLike{}). + Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count, + asset_likes.created_at as liked_at, + COALESCE(SUM(err.crystal_amount), 0) as earnings`). + Joins("JOIN assets a ON a.id = asset_likes.asset_id"). + Joins("JOIN exhibitions e ON e.asset_id = a.id"). + Joins("LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'"). + Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID). + Where("asset_likes.created_at >= ?", startOfDay). + Where("a.deleted_at IS NULL AND a.is_active = ?", true). + Where("e.deleted_at IS NULL AND e.expire_at > ?", now.UnixMilli()). + Group("asset_likes.asset_id, a.name, a.cover_url, a.like_count, asset_likes.created_at"). + Order("asset_likes.created_at DESC"). + Limit(pageSize). + Offset(offset). + Scan(&items).Error + + if err != nil { + return nil, 0, err + } + + return items, total, nil +} + +// GetMyWeekLikedAssets 获取我本周点赞的作品列表(只返回展出中且未过期的) +func (r *socialRepositoryImpl) GetMyWeekLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) { + now := time.Now() + // 本周开始于周一 + weekday := int(now.Weekday()) + if weekday == 0 { + weekday = 7 + } + startOfWeek := now.AddDate(0, 0, -weekday+1) + startOfWeek = time.Date(startOfWeek.Year(), startOfWeek.Month(), startOfWeek.Day(), 0, 0, 0, 0, now.Location()) + startOfWeekMillis := startOfWeek.UnixMilli() + + var items []*LikedAssetInfo + var total int64 + + countQuery := r.db.Model(&models.AssetLike{}). + Joins("JOIN assets a ON a.id = asset_likes.asset_id"). + Joins("JOIN exhibitions e ON e.asset_id = a.id"). + Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID). + Where("asset_likes.created_at >= ?", startOfWeekMillis). + Where("a.deleted_at IS NULL AND a.is_active = ?", true). + Where("e.deleted_at IS NULL AND e.expire_at > ?", now.UnixMilli()) + + if err := countQuery.Distinct("asset_likes.asset_id").Count(&total).Error; err != nil { + return nil, 0, err + } + + offset := (page - 1) * pageSize + err := r.db.Model(&models.AssetLike{}). + Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count, + asset_likes.created_at as liked_at, + COALESCE(SUM(err.crystal_amount), 0) as earnings`). + Joins("JOIN assets a ON a.id = asset_likes.asset_id"). + Joins("JOIN exhibitions e ON e.asset_id = a.id"). + Joins("LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'"). + Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID). + Where("asset_likes.created_at >= ?", startOfWeekMillis). + Where("a.deleted_at IS NULL AND a.is_active = ?", true). + Where("e.deleted_at IS NULL AND e.expire_at > ?", now.UnixMilli()). + Group("asset_likes.asset_id, a.name, a.cover_url, a.like_count, asset_likes.created_at"). + Order("asset_likes.created_at DESC"). + Limit(pageSize). + Offset(offset). + Scan(&items).Error + + if err != nil { + return nil, 0, err + } + + return items, total, nil +} + +// GetUserLikedAssets 获取他人点赞的作品列表(只返回展出中且未过期的) +func (r *socialRepositoryImpl) GetUserLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) { + var items []*LikedAssetInfo + var total int64 + + now := time.Now().UnixMilli() + + countQuery := r.db.Model(&models.AssetLike{}). + Joins("JOIN assets a ON a.id = asset_likes.asset_id"). + Joins("JOIN exhibitions e ON e.asset_id = a.id"). + Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID). + Where("a.deleted_at IS NULL AND a.is_active = ?", true). + Where("e.deleted_at IS NULL AND e.expire_at > ?", now) + + if err := countQuery.Distinct("asset_likes.asset_id").Count(&total).Error; err != nil { + return nil, 0, err + } + + offset := (page - 1) * pageSize + err := r.db.Model(&models.AssetLike{}). + Select(`asset_likes.asset_id, a.name, a.cover_url, a.like_count, + asset_likes.created_at as liked_at, + COALESCE(SUM(err.crystal_amount), 0) as earnings`). + Joins("JOIN assets a ON a.id = asset_likes.asset_id"). + Joins("JOIN exhibitions e ON e.asset_id = a.id"). + Joins("LEFT JOIN exhibition_revenue_records err ON err.asset_id = a.id AND err.status = 'claimable'"). + Where("asset_likes.user_id = ? AND asset_likes.star_id = ?", userID, starID). + Where("a.deleted_at IS NULL AND a.is_active = ?", true). + Where("e.deleted_at IS NULL AND e.expire_at > ?", now). + Group("asset_likes.asset_id, a.name, a.cover_url, a.like_count, asset_likes.created_at"). + Order("asset_likes.created_at DESC"). + Limit(pageSize). + Offset(offset). + Scan(&items).Error + + if err != nil { + return nil, 0, err + } + + return items, total, nil +} diff --git a/frontend/pages.json b/frontend/pages.json index 0b00eb9..af54d8c 100644 --- a/frontend/pages.json +++ b/frontend/pages.json @@ -101,6 +101,15 @@ } } }, + { + "path": "pages/profile/hisWorks", + "style": { + "navigationStyle": "custom", + "app-plus": { + "bounce": "none" + } + } + }, { "path": "pages/exhibition/exhibition", "style": { diff --git a/frontend/pages/components/AssetSelector.vue b/frontend/pages/components/AssetSelector.vue index 6ad2b49..2c8253d 100644 --- a/frontend/pages/components/AssetSelector.vue +++ b/frontend/pages/components/AssetSelector.vue @@ -18,7 +18,7 @@ - + diff --git a/frontend/pages/components/BannerTop3.vue b/frontend/pages/components/BannerTop3.vue index 541f68a..4106a2d 100644 --- a/frontend/pages/components/BannerTop3.vue +++ b/frontend/pages/components/BannerTop3.vue @@ -1,6 +1,6 @@ @@ -32,9 +32,9 @@ const loadTop3 = async () => { } }; -const onBannerTap = () => { - uni.navigateTo({ url: '/pages/rank/rank' }); -}; +// const onBannerTap = () => { +// uni.navigateTo({ url: '/pages/profile/hisWorks?userId=1&nickname=用户' }); +// }; onMounted(loadTop3); defineExpose({ reload: loadTop3 }); diff --git a/frontend/pages/components/RankingModal.vue b/frontend/pages/components/RankingModal.vue index 73067e7..1e002bb 100644 --- a/frontend/pages/components/RankingModal.vue +++ b/frontend/pages/components/RankingModal.vue @@ -59,7 +59,7 @@ @@ -76,7 +76,7 @@ :userId="item.userId" :avatar="item.avatar" :nickname="item.nickname" :popularityScore="item.popularityScore" :artworkImage="item.artworkImage" :artworkId="item.artworkId" :showVisitButton="!isCurrentUser(item.userId)" - :isCurrentUser="isCurrentUser(item.userId)" @visit="handleVisit(item.userId)" + :isCurrentUser="isCurrentUser(item.userId)" @visit="handleVisit(item.userId, item.nickname)" @view-profile="handleViewProfile" @artwork-click="handleArtworkClick" /> @@ -970,8 +970,8 @@ const getCurrentTabInfo = () => { }; // 处理拜访按钮点击 -const handleVisit = (userId) => { - emit('visit', userId); +const handleVisit = (userId, nickname) => { + emit('visit', { userId, nickname }); }; // 处理查看个人信息 diff --git a/frontend/pages/components/StarbookContent.vue b/frontend/pages/components/StarbookContent.vue index 4b7ec62..b829763 100644 --- a/frontend/pages/components/StarbookContent.vue +++ b/frontend/pages/components/StarbookContent.vue @@ -6,7 +6,7 @@ - + diff --git a/frontend/pages/exhibition/exhibition.vue b/frontend/pages/exhibition/exhibition.vue index 7a9bd29..e58dacd 100644 --- a/frontend/pages/exhibition/exhibition.vue +++ b/frontend/pages/exhibition/exhibition.vue @@ -11,6 +11,9 @@ {{ isViewingOthers ? (galleryOwnerNickname ? galleryOwnerNickname + '的展馆' : 'TA的展馆') : '我的展馆' }} + + 查看TA的作品 + @@ -808,7 +811,15 @@ export default { url: '/pages/castlove/mall' }); }; - + + // 跳转到查看TA的作品页面 + const goToHisWorks = () => { + if (!galleryOwnerId.value || !galleryOwnerNickname.value) return; + uni.navigateTo({ + url: `/pages/profile/hisWorks?userId=${galleryOwnerId.value}&nickname=${encodeURIComponent(galleryOwnerNickname.value)}` + }); + }; + // 处理底部按钮点击 const handleBottomButtonClick = async () => { if (isMyGallery.value) { @@ -1644,7 +1655,10 @@ export default { width: 100%; z-index: 99; text-align: center; - pointer-events: none; + display: flex; + flex-direction: column; + align-items: center; + gap: 16rpx; } .gallery-owner-title-text { @@ -1655,6 +1669,20 @@ export default { letter-spacing: 4rpx; } +.view-works-btn { + pointer-events: auto; + background: linear-gradient(135deg, #F0E4B1 0%, #F08399 50%, #B94E73 100%); + border-radius: 24rpx; + padding: 12rpx 28rpx; + box-shadow: 0 4rpx 12rpx rgba(185, 78, 115, 0.4); +} + +.view-works-btn-text { + font-size: 24rpx; + color: #fff; + font-weight: 600; +} + /* 展览板容器 */ .exhibition-boards { position: relative; diff --git a/frontend/pages/profile/hisWorks.vue b/frontend/pages/profile/hisWorks.vue new file mode 100644 index 0000000..2a2f080 --- /dev/null +++ b/frontend/pages/profile/hisWorks.vue @@ -0,0 +1,600 @@ + + + + + diff --git a/frontend/pages/profile/myWorks.vue b/frontend/pages/profile/myWorks.vue index b447fa5..3d38687 100644 --- a/frontend/pages/profile/myWorks.vue +++ b/frontend/pages/profile/myWorks.vue @@ -1,7 +1,7 @@