diff --git a/backend/assetService b/backend/assetService new file mode 100755 index 0000000..bd56e75 Binary files /dev/null and b/backend/assetService differ diff --git a/backend/galleryService b/backend/galleryService new file mode 100755 index 0000000..48720ab Binary files /dev/null and b/backend/galleryService differ diff --git a/backend/gateway/dto/gallery_converter.go b/backend/gateway/dto/gallery_converter.go index 08c109d..f5c5c8b 100644 --- a/backend/gateway/dto/gallery_converter.go +++ b/backend/gateway/dto/gallery_converter.go @@ -171,6 +171,8 @@ func ConvertInspirationFlowData(pbData *pbGallery.InspirationFlowData) *GetInspi CoverURL: item.CoverUrl, LikeCount: item.LikeCount, OwnerNickname: item.OwnerNickname, + Span: item.Span, + MaterialType: item.MaterialType, }) } diff --git a/backend/gateway/dto/gallery_dto.go b/backend/gateway/dto/gallery_dto.go index 040df3c..1f414b6 100644 --- a/backend/gateway/dto/gallery_dto.go +++ b/backend/gateway/dto/gallery_dto.go @@ -96,10 +96,12 @@ type GetMyExhibitedAssetsResponseDTO struct { // 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"` // 点赞数 + Name string `json:"name"` // 藏品名称 + CoverURL string `json:"cover_url"` // 封面图URL + LikeCount int32 `json:"like_count"` // 点赞数 OwnerNickname string `json:"owner_nickname"` // 展出者昵称 + Span int32 `json:"span"` // 卡片大小: 0-30→1, 31-100→2, 101-200→3, 200+→4 + MaterialType string `json:"material_type"` // 素材类型: hot(人气王者), potential(潜力之星), new(新鲜上架) } // GetInspirationFlowResponseDTO 获取灵感瀑布藏品列表响应 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 deleted file mode 100644 index d3d77de..0000000 --- a/backend/github.com/topfans/backend/pkg/proto/gallery/gallery.triple.go +++ /dev/null @@ -1,284 +0,0 @@ -// 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 deleted file mode 100644 index 3bbe0e5..0000000 --- a/backend/github.com/topfans/backend/pkg/proto/social/social.triple.go +++ /dev/null @@ -1,554 +0,0 @@ -// 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 28ae39f..6984dbc 100644 --- a/backend/pkg/proto/gallery/gallery.pb.go +++ b/backend/pkg/proto/gallery/gallery.pb.go @@ -1422,6 +1422,8 @@ type InspirationFlowItem struct { 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"` // 展出者昵称 + Span int32 `protobuf:"varint,6,opt,name=span,proto3" json:"span,omitempty"` // 卡片大小: 0-30→1, 31-100→2, 101-200→3, 200+→4 + MaterialType string `protobuf:"bytes,7,opt,name=material_type,json=materialType,proto3" json:"material_type,omitempty"` // 素材类型: hot(人气王者), potential(潜力之星), new(新鲜上架) unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1491,6 +1493,20 @@ func (x *InspirationFlowItem) GetOwnerNickname() string { return "" } +func (x *InspirationFlowItem) GetSpan() int32 { + if x != nil { + return x.Span + } + return 0 +} + +func (x *InspirationFlowItem) GetMaterialType() string { + if x != nil { + return x.MaterialType + } + return "" +} + var File_gallery_proto protoreflect.FileDescriptor const file_gallery_proto_rawDesc = "" + @@ -1602,14 +1618,16 @@ const file_gallery_proto_rawDesc = "" + "\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" + + "session_id\x18\x04 \x01(\tR\tsessionId\"\xe0\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" + + "\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" + "\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" + diff --git a/backend/proto/gallery.proto b/backend/proto/gallery.proto index d948278..4153076 100644 --- a/backend/proto/gallery.proto +++ b/backend/proto/gallery.proto @@ -219,6 +219,8 @@ message InspirationFlowItem { int64 asset_id = 1; // 资产ID string name = 2; // 藏品名称 string cover_url = 3; // 封面图URL - int32 like_count = 4; // 点赞数 + int32 like_count = 4; // 点赞数 string owner_nickname = 5; // 展出者昵称 + int32 span = 6; // 卡片大小: 0-30→1, 31-100→2, 101-200→3, 200+→4 + string material_type = 7; // 素材类型: hot(人气王者), potential(潜力之星), new(新鲜上架) } diff --git a/backend/scripts/migrate_add_material_type_to_assets.sql b/backend/scripts/migrate_add_material_type_to_assets.sql new file mode 100644 index 0000000..0355a87 --- /dev/null +++ b/backend/scripts/migrate_add_material_type_to_assets.sql @@ -0,0 +1,4 @@ +-- migrate_add_material_type_to_assets.sql +-- 为 assets 表添加 material_type 字段 + +ALTER TABLE assets ADD COLUMN IF NOT EXISTS material_type VARCHAR(50); \ No newline at end of file diff --git a/backend/scripts/migrate_fix_asset_likes_unique_constraint.sql b/backend/scripts/migrate_fix_asset_likes_unique_constraint.sql new file mode 100644 index 0000000..ca23500 --- /dev/null +++ b/backend/scripts/migrate_fix_asset_likes_unique_constraint.sql @@ -0,0 +1,9 @@ +-- 修复 asset_likes 表唯一约束,添加 star_id +-- 原约束: (user_id, asset_id) +-- 新约束: (user_id, asset_id, star_id) + +-- 删除旧约束 +ALTER TABLE asset_likes DROP CONSTRAINT IF EXISTS uk_asset_likes_user_asset; + +-- 添加新约束(包含 star_id) +ALTER TABLE asset_likes ADD CONSTRAINT uk_asset_likes_user_asset_star UNIQUE (user_id, asset_id, star_id); \ No newline at end of file diff --git a/backend/services/assetService/repository/asset_repository.go b/backend/services/assetService/repository/asset_repository.go index e3e93f6..dbba299 100644 --- a/backend/services/assetService/repository/asset_repository.go +++ b/backend/services/assetService/repository/asset_repository.go @@ -45,6 +45,9 @@ type AssetRepository interface { // DecrementLikeCount 减少点赞数 DecrementLikeCount(assetID int64) error + // UpdateMaterialTypeByLikes 根据点赞数和创建时间更新素材类型 + UpdateMaterialTypeByLikes(assetID int64, likes int32, createdAt int64) error + // IsExhibiting 检查资产是否正在展出中 IsExhibiting(assetID int64) (bool, error) } @@ -295,7 +298,26 @@ func (r *assetRepository) DecrementLikeCount(assetID int64) error { UpdateColumn("like_count", gorm.Expr("like_count - ?", 1)).Error } -// IsExhibiting 检查资产是否正在展出中 +// UpdateMaterialTypeByLikes 根据点赞数和创建时间更新素材类型 +func (r *assetRepository) UpdateMaterialTypeByLikes(assetID int64, likes int32, createdAt int64) error { + if assetID <= 0 { + return errors.New("asset_id must be greater than 0") + } + + now := time.Now().UnixMilli() + var materialType string + if likes > 20 { + materialType = "hot" + } else if createdAt > 0 && now-createdAt < 3600*1000 && likes >= 10 { + materialType = "potential" + } else { + materialType = "new" + } + + return r.db.Model(&models.Asset{}). + Where("id = ?", assetID). + UpdateColumn("material_type", materialType).Error +} // 通过关联 exhibitions 表,查询未过期的展出记录 func (r *assetRepository) IsExhibiting(assetID int64) (bool, error) { if assetID <= 0 { diff --git a/backend/services/galleryService/repository/gallery_repository.go b/backend/services/galleryService/repository/gallery_repository.go index 210bc96..7df261e 100644 --- a/backend/services/galleryService/repository/gallery_repository.go +++ b/backend/services/galleryService/repository/gallery_repository.go @@ -65,6 +65,9 @@ type InspirationFlowItem struct { CoverURL string LikeCount int32 OwnerNickname string + Span int32 // 卡片大小: 0-30→1, 31-100→2, 101-200→3, 200+→4 + MaterialType string // 素材类型: hot(人气王者), potential(潜力之星), new(新鲜上架) + CreatedAt int64 // 创建时间(用于判断是否为潜力之星) } // ExhibitedAssetInfo 我展出的作品信息 @@ -308,9 +311,9 @@ func (r *galleryRepository) CountValidExhibitions(starID int64, materialType str now := time.Now().UnixMilli() query := r.db.Model(&models.Exhibition{}). - Where("occupier_star_id = ? AND expire_at > ? AND deleted_at IS NULL", starID, now) + Where("exhibitions.occupier_star_id = ? AND exhibitions.expire_at > ? AND exhibitions.deleted_at IS NULL", starID, now) - if materialType != "" && materialType != "all" { + if materialType != "" && materialType != "all" && materialType != "random" { query = query.Joins("JOIN assets a ON a.id = exhibitions.asset_id"). Where("a.material_type = ?", materialType) } @@ -328,7 +331,7 @@ func (r *galleryRepository) GetRandomExhibitions(starID int64, materialType stri 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" { + if materialType != "" && materialType != "all" && materialType != "random" { baseQuery = baseQuery.Joins("JOIN assets a ON a.id = exhibitions.asset_id"). Where("a.material_type = ?", materialType) } @@ -339,23 +342,80 @@ func (r *galleryRepository) GetRandomExhibitions(starID int64, materialType stri } // 执行随机排序查询 - 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 + var err error + if materialType == "" || materialType == "all" || materialType == "random" { + err = baseQuery. + Select(`exhibitions.asset_id, a.name, a.cover_url, a.like_count, fp.nickname as owner_nickname, a.material_type, a.created_at`). + 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 + } else { + // baseQuery 已经包含了 assets JOIN,不需要重复添加 + err = baseQuery. + Select(`exhibitions.asset_id, a.name, a.cover_url, a.like_count, fp.nickname as owner_nickname, a.material_type, a.created_at`). + 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 } + // Read-repair: 检查并修正 material_type(查询时自动修正数据不一致) + for _, item := range items { + item.Span = calcSpanByLikes(item.LikeCount) + correctType := calcMaterialType(item.LikeCount, item.CreatedAt) + if item.MaterialType != correctType { + // 异步修正,不阻塞返回(使用 goroutine 避免影响响应时间) + go func(assetID int64, correct string) { + r.db.Model(&models.Asset{}). + Where("id = ?", assetID). + Update("material_type", correct) + }(item.AssetID, correctType) + // 同时修正当前对象的值,保证返回给前端的是正确的 + item.MaterialType = correctType + } + } + return items, nil } +// calcMaterialType 根据点赞数计算素材类型 +func calcMaterialType(likes int32, createdAt int64) string { + now := time.Now().UnixMilli() + isWithin1Hour := createdAt > 0 && now-createdAt < 3600*1000 + + if likes > 20 { + return "hot" + } + // 上架1小时内且点赞>=10为潜力之星 + if isWithin1Hour && likes >= 10 { + return "potential" + } + return "new" +} + +// calcSpanByLikes 根据点赞数计算卡片大小 +// 0-30 → span 1, 31-100 → span 2, 101-200 → span 3, 200+ → span 4 +func calcSpanByLikes(likes int32) int32 { + if likes <= 30 { + return 1 + } else if likes <= 100 { + return 2 + } else if likes <= 200 { + return 3 + } + return 4 +} + // ==================== 辅助函数 ==================== // generateHostProfileID 生成 host_profile_id