feat: 新增历史点赞查询和修改点赞规则

This commit is contained in:
zerosaturation 2026-05-22 18:06:33 +08:00
parent 415d224798
commit 4d42d9a6d0
18 changed files with 928 additions and 168 deletions

View File

@ -885,6 +885,85 @@ func (ctrl *SocialController) UnlikeAsset(c *gin.Context) {
// 注意CheckAssetLike 已被删除 // 注意CheckAssetLike 已被删除
// 检查点赞状态请通过 GET /api/v1/assets/:asset_id 获取,响应中的 is_liked 字段表示当前用户是否已点赞 // 检查点赞状态请通过 GET /api/v1/assets/:asset_id 获取,响应中的 is_liked 字段表示当前用户是否已点赞
// GetAssetLikers 获取资产点赞用户列表
// @Summary 获取资产点赞用户列表
// @Description 获取指定藏品的点赞用户列表(带游标分页)
// @Tags social
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param asset_id path int true "资产ID"
// @Param page_size query int false "每页数量默认20最大100"
// @Param cursor query int false "游标(上一页最后一条的 created_at首次请求传0"
// @Success 200 {object} response.Response
// @Router /api/v1/social/assets/{asset_id}/likers [get]
func (ctrl *SocialController) GetAssetLikers(c *gin.Context) {
// 1. 解析资产ID
assetIDStr := c.Param("asset_id")
assetID, err := strconv.ParseInt(assetIDStr, 10, 64)
if err != nil {
response.Error(c, http.StatusBadRequest, "参数错误: asset_id 必须为数字")
return
}
// 2. 解析查询参数
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
cursorStr := c.DefaultQuery("cursor", "0")
cursor, err := strconv.ParseInt(cursorStr, 10, 64)
if err != nil {
cursor = 0
}
// 3. 设置上下文
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = context.WithValue(ctx, constant.AttachmentKey, map[string]interface{}{
"user_id": "0", // 查询点赞列表不需要 user_id
"star_id": "0",
})
// 4. 调用 RPC
resp, err := ctrl.socialService.GetAssetLikers(ctx, &pbSocial.GetAssetLikersRequest{
AssetId: assetID,
PageSize: int32(pageSize),
Cursor: cursor,
})
if err != nil {
logger.Logger.Error("GetAssetLikers RPC failed",
zap.Int64("asset_id", assetID),
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
}
// 5. 构建响应
users := make([]map[string]interface{}, 0, len(resp.Users))
for _, u := range resp.Users {
users = append(users, map[string]interface{}{
"user_id": u.UserId,
"nickname": u.Nickname,
"avatar": u.Avatar,
"fan_level": u.FanLevel,
"liked_at": u.LikedAt,
})
}
response.Success(c, gin.H{
"users": users,
"total": resp.Total,
"has_more": resp.HasMore,
"next_cursor": resp.NextCursor,
})
}
// GetMyLikedAssets 获取我点赞的作品列表 // GetMyLikedAssets 获取我点赞的作品列表
// @Summary 获取我点赞的作品列表 // @Summary 获取我点赞的作品列表
// @Description 获取当前用户点赞过的作品列表(只返回展出中且未过期的) // @Description 获取当前用户点赞过的作品列表(只返回展出中且未过期的)

View File

@ -174,6 +174,7 @@ func SetupRouter(userClient *client.Client, socialClient *client.Client, assetCl
// 资产点赞操作(保留操作接口,查询状态已集成到资产详情) // 资产点赞操作(保留操作接口,查询状态已集成到资产详情)
social.POST("/assets/:asset_id/like", socialCtrl.LikeAsset) // 点赞资产 social.POST("/assets/:asset_id/like", socialCtrl.LikeAsset) // 点赞资产
social.DELETE("/assets/:asset_id/like", socialCtrl.UnlikeAsset) // 取消点赞 social.DELETE("/assets/:asset_id/like", socialCtrl.UnlikeAsset) // 取消点赞
social.GET("/assets/:asset_id/likers", socialCtrl.GetAssetLikers) // 获取点赞用户列表
// 注意GET /api/v1/assets/:asset_id 会返回 is_liked 字段,无需单独查询 // 注意GET /api/v1/assets/:asset_id 会返回 is_liked 字段,无需单独查询
} }

View File

@ -13,8 +13,26 @@ import (
const ( const (
BlacklistKeyPrefix = "blacklist:token:" BlacklistKeyPrefix = "blacklist:token:"
InspirationFlowKeyPrefix = "inspiration_flow:" InspirationFlowKeyPrefix = "inspiration_flow:"
AssetLikersKeyPrefix = "asset_likers:"
) )
// AssetLikersCache 缓存数据结构
type AssetLikersCache struct {
Users []AssetLikerWithTotal `json:"users"` // 完整用户列表(按 liked_at DESC
Total int64 `json:"total"` // 总数
UpdatedAt int64 `json:"updated_at"` // 缓存更新时间
}
// AssetLikerWithTotal 用户+点赞时间
type AssetLikerWithTotal struct {
UserID int64 `json:"user_id"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
FanLevel int32 `json:"fan_level"`
LikedAt int64 `json:"liked_at"`
StarID int64 `json:"star_id"` // 用于 JOIN fan_profiles缓存时保留
}
// RedisClient Redis 客户端单例 // RedisClient Redis 客户端单例
var RedisClient *redis.Client var RedisClient *redis.Client
@ -249,3 +267,55 @@ func GetHistoryPage(cache *InspirationFlowCache, offset, limit int) []Inspiratio
} }
return items[start:end] return items[start:end]
} }
// AssetLikersKey 生成藏品点赞用户列表缓存 Key
func AssetLikersKey(assetID int64) string {
return fmt.Sprintf("%s%d", AssetLikersKeyPrefix, assetID)
}
// GetAssetLikersCache 获取藏品点赞用户列表缓存
func GetAssetLikersCache(ctx context.Context, assetID int64) (*AssetLikersCache, error) {
if RedisClient == nil {
return nil, fmt.Errorf("redis client is not initialized")
}
key := AssetLikersKey(assetID)
data, err := RedisClient.Get(ctx, key).Result()
if err == redis.Nil {
return nil, nil // 缓存不存在
}
if err != nil {
return nil, err
}
var cache AssetLikersCache
if err := json.Unmarshal([]byte(data), &cache); err != nil {
return nil, err
}
return &cache, nil
}
// SetAssetLikersCache 设置藏品点赞用户列表缓存
func SetAssetLikersCache(ctx context.Context, assetID int64, cache *AssetLikersCache, ttl time.Duration) error {
if RedisClient == nil {
return fmt.Errorf("redis client is not initialized")
}
key := AssetLikersKey(assetID)
data, err := json.Marshal(cache)
if err != nil {
return err
}
return RedisClient.Set(ctx, key, data, ttl).Err()
}
// InvalidateAssetLikersCache 删除藏品点赞用户列表缓存
func InvalidateAssetLikersCache(ctx context.Context, assetID int64) error {
if RedisClient == nil {
return nil // Redis 未初始化时跳过
}
key := AssetLikersKey(assetID)
return RedisClient.Del(ctx, key).Err()
}

View File

@ -2148,6 +2148,221 @@ func (x *CheckAssetLikeResponse) GetIsLiked() bool {
return false return false
} }
// 获取资产点赞用户列表请求
type GetAssetLikersRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
AssetId int64 `protobuf:"varint,1,opt,name=asset_id,json=assetId,proto3" json:"asset_id,omitempty"` // 资产ID
PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // 每页数量默认20最大100
Cursor int64 `protobuf:"varint,3,opt,name=cursor,proto3" json:"cursor,omitempty"` // 游标(上一页最后一条的 created_at首次请求传0
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetAssetLikersRequest) Reset() {
*x = GetAssetLikersRequest{}
mi := &file_social_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetAssetLikersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetAssetLikersRequest) ProtoMessage() {}
func (x *GetAssetLikersRequest) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[33]
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 GetAssetLikersRequest.ProtoReflect.Descriptor instead.
func (*GetAssetLikersRequest) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{33}
}
func (x *GetAssetLikersRequest) GetAssetId() int64 {
if x != nil {
return x.AssetId
}
return 0
}
func (x *GetAssetLikersRequest) GetPageSize() int32 {
if x != nil {
return x.PageSize
}
return 0
}
func (x *GetAssetLikersRequest) GetCursor() int64 {
if x != nil {
return x.Cursor
}
return 0
}
// 获取资产点赞用户列表响应
type GetAssetLikersResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Base *common.BaseResponse `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
Users []*AssetLiker `protobuf:"bytes,2,rep,name=users,proto3" json:"users,omitempty"` // 点赞用户列表
Total int64 `protobuf:"varint,3,opt,name=total,proto3" json:"total,omitempty"` // 总数
HasMore bool `protobuf:"varint,4,opt,name=has_more,json=hasMore,proto3" json:"has_more,omitempty"` // 是否有更多
NextCursor int64 `protobuf:"varint,5,opt,name=next_cursor,json=nextCursor,proto3" json:"next_cursor,omitempty"` // 下一页游标
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetAssetLikersResponse) Reset() {
*x = GetAssetLikersResponse{}
mi := &file_social_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetAssetLikersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetAssetLikersResponse) ProtoMessage() {}
func (x *GetAssetLikersResponse) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[34]
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 GetAssetLikersResponse.ProtoReflect.Descriptor instead.
func (*GetAssetLikersResponse) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{34}
}
func (x *GetAssetLikersResponse) GetBase() *common.BaseResponse {
if x != nil {
return x.Base
}
return nil
}
func (x *GetAssetLikersResponse) GetUsers() []*AssetLiker {
if x != nil {
return x.Users
}
return nil
}
func (x *GetAssetLikersResponse) GetTotal() int64 {
if x != nil {
return x.Total
}
return 0
}
func (x *GetAssetLikersResponse) GetHasMore() bool {
if x != nil {
return x.HasMore
}
return false
}
func (x *GetAssetLikersResponse) GetNextCursor() int64 {
if x != nil {
return x.NextCursor
}
return 0
}
// 点赞用户信息
type AssetLiker struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 用户ID
Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname,omitempty"` // 昵称
Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` // 头像URL
FanLevel int32 `protobuf:"varint,4,opt,name=fan_level,json=fanLevel,proto3" json:"fan_level,omitempty"` // 粉丝等级
LikedAt int64 `protobuf:"varint,5,opt,name=liked_at,json=likedAt,proto3" json:"liked_at,omitempty"` // 点赞时间(毫秒时间戳)
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AssetLiker) Reset() {
*x = AssetLiker{}
mi := &file_social_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AssetLiker) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AssetLiker) ProtoMessage() {}
func (x *AssetLiker) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[35]
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 AssetLiker.ProtoReflect.Descriptor instead.
func (*AssetLiker) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{35}
}
func (x *AssetLiker) GetUserId() int64 {
if x != nil {
return x.UserId
}
return 0
}
func (x *AssetLiker) GetNickname() string {
if x != nil {
return x.Nickname
}
return ""
}
func (x *AssetLiker) GetAvatar() string {
if x != nil {
return x.Avatar
}
return ""
}
func (x *AssetLiker) GetFanLevel() int32 {
if x != nil {
return x.FanLevel
}
return 0
}
func (x *AssetLiker) GetLikedAt() int64 {
if x != nil {
return x.LikedAt
}
return 0
}
// 获取我点赞的作品列表请求 // 获取我点赞的作品列表请求
type GetMyLikedAssetsRequest struct { type GetMyLikedAssetsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
@ -2160,7 +2375,7 @@ type GetMyLikedAssetsRequest struct {
func (x *GetMyLikedAssetsRequest) Reset() { func (x *GetMyLikedAssetsRequest) Reset() {
*x = GetMyLikedAssetsRequest{} *x = GetMyLikedAssetsRequest{}
mi := &file_social_proto_msgTypes[33] mi := &file_social_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2172,7 +2387,7 @@ func (x *GetMyLikedAssetsRequest) String() string {
func (*GetMyLikedAssetsRequest) ProtoMessage() {} func (*GetMyLikedAssetsRequest) ProtoMessage() {}
func (x *GetMyLikedAssetsRequest) ProtoReflect() protoreflect.Message { func (x *GetMyLikedAssetsRequest) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[33] mi := &file_social_proto_msgTypes[36]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2185,7 +2400,7 @@ func (x *GetMyLikedAssetsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyLikedAssetsRequest.ProtoReflect.Descriptor instead. // Deprecated: Use GetMyLikedAssetsRequest.ProtoReflect.Descriptor instead.
func (*GetMyLikedAssetsRequest) Descriptor() ([]byte, []int) { func (*GetMyLikedAssetsRequest) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{33} return file_social_proto_rawDescGZIP(), []int{36}
} }
func (x *GetMyLikedAssetsRequest) GetPage() int32 { func (x *GetMyLikedAssetsRequest) GetPage() int32 {
@ -2220,7 +2435,7 @@ type GetMyLikedAssetsResponse struct {
func (x *GetMyLikedAssetsResponse) Reset() { func (x *GetMyLikedAssetsResponse) Reset() {
*x = GetMyLikedAssetsResponse{} *x = GetMyLikedAssetsResponse{}
mi := &file_social_proto_msgTypes[34] mi := &file_social_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2232,7 +2447,7 @@ func (x *GetMyLikedAssetsResponse) String() string {
func (*GetMyLikedAssetsResponse) ProtoMessage() {} func (*GetMyLikedAssetsResponse) ProtoMessage() {}
func (x *GetMyLikedAssetsResponse) ProtoReflect() protoreflect.Message { func (x *GetMyLikedAssetsResponse) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[34] mi := &file_social_proto_msgTypes[37]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2245,7 +2460,7 @@ func (x *GetMyLikedAssetsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyLikedAssetsResponse.ProtoReflect.Descriptor instead. // Deprecated: Use GetMyLikedAssetsResponse.ProtoReflect.Descriptor instead.
func (*GetMyLikedAssetsResponse) Descriptor() ([]byte, []int) { func (*GetMyLikedAssetsResponse) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{34} return file_social_proto_rawDescGZIP(), []int{37}
} }
func (x *GetMyLikedAssetsResponse) GetBase() *common.BaseResponse { func (x *GetMyLikedAssetsResponse) GetBase() *common.BaseResponse {
@ -2276,7 +2491,7 @@ type LikedAssetsData struct {
func (x *LikedAssetsData) Reset() { func (x *LikedAssetsData) Reset() {
*x = LikedAssetsData{} *x = LikedAssetsData{}
mi := &file_social_proto_msgTypes[35] mi := &file_social_proto_msgTypes[38]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2288,7 +2503,7 @@ func (x *LikedAssetsData) String() string {
func (*LikedAssetsData) ProtoMessage() {} func (*LikedAssetsData) ProtoMessage() {}
func (x *LikedAssetsData) ProtoReflect() protoreflect.Message { func (x *LikedAssetsData) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[35] mi := &file_social_proto_msgTypes[38]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2301,7 +2516,7 @@ func (x *LikedAssetsData) ProtoReflect() protoreflect.Message {
// Deprecated: Use LikedAssetsData.ProtoReflect.Descriptor instead. // Deprecated: Use LikedAssetsData.ProtoReflect.Descriptor instead.
func (*LikedAssetsData) Descriptor() ([]byte, []int) { func (*LikedAssetsData) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{35} return file_social_proto_rawDescGZIP(), []int{38}
} }
func (x *LikedAssetsData) GetItems() []*LikedAssetItem { func (x *LikedAssetsData) GetItems() []*LikedAssetItem {
@ -2357,7 +2572,7 @@ type LikedAssetItem struct {
func (x *LikedAssetItem) Reset() { func (x *LikedAssetItem) Reset() {
*x = LikedAssetItem{} *x = LikedAssetItem{}
mi := &file_social_proto_msgTypes[36] mi := &file_social_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2369,7 +2584,7 @@ func (x *LikedAssetItem) String() string {
func (*LikedAssetItem) ProtoMessage() {} func (*LikedAssetItem) ProtoMessage() {}
func (x *LikedAssetItem) ProtoReflect() protoreflect.Message { func (x *LikedAssetItem) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[36] mi := &file_social_proto_msgTypes[39]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2382,7 +2597,7 @@ func (x *LikedAssetItem) ProtoReflect() protoreflect.Message {
// Deprecated: Use LikedAssetItem.ProtoReflect.Descriptor instead. // Deprecated: Use LikedAssetItem.ProtoReflect.Descriptor instead.
func (*LikedAssetItem) Descriptor() ([]byte, []int) { func (*LikedAssetItem) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{36} return file_social_proto_rawDescGZIP(), []int{39}
} }
func (x *LikedAssetItem) GetAssetId() int64 { func (x *LikedAssetItem) GetAssetId() int64 {
@ -2459,7 +2674,7 @@ type GetMyTodayLikedAssetsRequest struct {
func (x *GetMyTodayLikedAssetsRequest) Reset() { func (x *GetMyTodayLikedAssetsRequest) Reset() {
*x = GetMyTodayLikedAssetsRequest{} *x = GetMyTodayLikedAssetsRequest{}
mi := &file_social_proto_msgTypes[37] mi := &file_social_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2471,7 +2686,7 @@ func (x *GetMyTodayLikedAssetsRequest) String() string {
func (*GetMyTodayLikedAssetsRequest) ProtoMessage() {} func (*GetMyTodayLikedAssetsRequest) ProtoMessage() {}
func (x *GetMyTodayLikedAssetsRequest) ProtoReflect() protoreflect.Message { func (x *GetMyTodayLikedAssetsRequest) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[37] mi := &file_social_proto_msgTypes[40]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2484,7 +2699,7 @@ func (x *GetMyTodayLikedAssetsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyTodayLikedAssetsRequest.ProtoReflect.Descriptor instead. // Deprecated: Use GetMyTodayLikedAssetsRequest.ProtoReflect.Descriptor instead.
func (*GetMyTodayLikedAssetsRequest) Descriptor() ([]byte, []int) { func (*GetMyTodayLikedAssetsRequest) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{37} return file_social_proto_rawDescGZIP(), []int{40}
} }
func (x *GetMyTodayLikedAssetsRequest) GetPage() int32 { func (x *GetMyTodayLikedAssetsRequest) GetPage() int32 {
@ -2512,7 +2727,7 @@ type GetMyTodayLikedAssetsResponse struct {
func (x *GetMyTodayLikedAssetsResponse) Reset() { func (x *GetMyTodayLikedAssetsResponse) Reset() {
*x = GetMyTodayLikedAssetsResponse{} *x = GetMyTodayLikedAssetsResponse{}
mi := &file_social_proto_msgTypes[38] mi := &file_social_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2524,7 +2739,7 @@ func (x *GetMyTodayLikedAssetsResponse) String() string {
func (*GetMyTodayLikedAssetsResponse) ProtoMessage() {} func (*GetMyTodayLikedAssetsResponse) ProtoMessage() {}
func (x *GetMyTodayLikedAssetsResponse) ProtoReflect() protoreflect.Message { func (x *GetMyTodayLikedAssetsResponse) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[38] mi := &file_social_proto_msgTypes[41]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2537,7 +2752,7 @@ func (x *GetMyTodayLikedAssetsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyTodayLikedAssetsResponse.ProtoReflect.Descriptor instead. // Deprecated: Use GetMyTodayLikedAssetsResponse.ProtoReflect.Descriptor instead.
func (*GetMyTodayLikedAssetsResponse) Descriptor() ([]byte, []int) { func (*GetMyTodayLikedAssetsResponse) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{38} return file_social_proto_rawDescGZIP(), []int{41}
} }
func (x *GetMyTodayLikedAssetsResponse) GetBase() *common.BaseResponse { func (x *GetMyTodayLikedAssetsResponse) GetBase() *common.BaseResponse {
@ -2565,7 +2780,7 @@ type GetMyWeekLikedAssetsRequest struct {
func (x *GetMyWeekLikedAssetsRequest) Reset() { func (x *GetMyWeekLikedAssetsRequest) Reset() {
*x = GetMyWeekLikedAssetsRequest{} *x = GetMyWeekLikedAssetsRequest{}
mi := &file_social_proto_msgTypes[39] mi := &file_social_proto_msgTypes[42]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2577,7 +2792,7 @@ func (x *GetMyWeekLikedAssetsRequest) String() string {
func (*GetMyWeekLikedAssetsRequest) ProtoMessage() {} func (*GetMyWeekLikedAssetsRequest) ProtoMessage() {}
func (x *GetMyWeekLikedAssetsRequest) ProtoReflect() protoreflect.Message { func (x *GetMyWeekLikedAssetsRequest) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[39] mi := &file_social_proto_msgTypes[42]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2590,7 +2805,7 @@ func (x *GetMyWeekLikedAssetsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyWeekLikedAssetsRequest.ProtoReflect.Descriptor instead. // Deprecated: Use GetMyWeekLikedAssetsRequest.ProtoReflect.Descriptor instead.
func (*GetMyWeekLikedAssetsRequest) Descriptor() ([]byte, []int) { func (*GetMyWeekLikedAssetsRequest) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{39} return file_social_proto_rawDescGZIP(), []int{42}
} }
func (x *GetMyWeekLikedAssetsRequest) GetPage() int32 { func (x *GetMyWeekLikedAssetsRequest) GetPage() int32 {
@ -2618,7 +2833,7 @@ type GetMyWeekLikedAssetsResponse struct {
func (x *GetMyWeekLikedAssetsResponse) Reset() { func (x *GetMyWeekLikedAssetsResponse) Reset() {
*x = GetMyWeekLikedAssetsResponse{} *x = GetMyWeekLikedAssetsResponse{}
mi := &file_social_proto_msgTypes[40] mi := &file_social_proto_msgTypes[43]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2630,7 +2845,7 @@ func (x *GetMyWeekLikedAssetsResponse) String() string {
func (*GetMyWeekLikedAssetsResponse) ProtoMessage() {} func (*GetMyWeekLikedAssetsResponse) ProtoMessage() {}
func (x *GetMyWeekLikedAssetsResponse) ProtoReflect() protoreflect.Message { func (x *GetMyWeekLikedAssetsResponse) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[40] mi := &file_social_proto_msgTypes[43]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2643,7 +2858,7 @@ func (x *GetMyWeekLikedAssetsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetMyWeekLikedAssetsResponse.ProtoReflect.Descriptor instead. // Deprecated: Use GetMyWeekLikedAssetsResponse.ProtoReflect.Descriptor instead.
func (*GetMyWeekLikedAssetsResponse) Descriptor() ([]byte, []int) { func (*GetMyWeekLikedAssetsResponse) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{40} return file_social_proto_rawDescGZIP(), []int{43}
} }
func (x *GetMyWeekLikedAssetsResponse) GetBase() *common.BaseResponse { func (x *GetMyWeekLikedAssetsResponse) GetBase() *common.BaseResponse {
@ -2672,7 +2887,7 @@ type GetUserLikedAssetsRequest struct {
func (x *GetUserLikedAssetsRequest) Reset() { func (x *GetUserLikedAssetsRequest) Reset() {
*x = GetUserLikedAssetsRequest{} *x = GetUserLikedAssetsRequest{}
mi := &file_social_proto_msgTypes[41] mi := &file_social_proto_msgTypes[44]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2684,7 +2899,7 @@ func (x *GetUserLikedAssetsRequest) String() string {
func (*GetUserLikedAssetsRequest) ProtoMessage() {} func (*GetUserLikedAssetsRequest) ProtoMessage() {}
func (x *GetUserLikedAssetsRequest) ProtoReflect() protoreflect.Message { func (x *GetUserLikedAssetsRequest) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[41] mi := &file_social_proto_msgTypes[44]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2697,7 +2912,7 @@ func (x *GetUserLikedAssetsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetUserLikedAssetsRequest.ProtoReflect.Descriptor instead. // Deprecated: Use GetUserLikedAssetsRequest.ProtoReflect.Descriptor instead.
func (*GetUserLikedAssetsRequest) Descriptor() ([]byte, []int) { func (*GetUserLikedAssetsRequest) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{41} return file_social_proto_rawDescGZIP(), []int{44}
} }
func (x *GetUserLikedAssetsRequest) GetUserId() int64 { func (x *GetUserLikedAssetsRequest) GetUserId() int64 {
@ -2732,7 +2947,7 @@ type GetUserLikedAssetsResponse struct {
func (x *GetUserLikedAssetsResponse) Reset() { func (x *GetUserLikedAssetsResponse) Reset() {
*x = GetUserLikedAssetsResponse{} *x = GetUserLikedAssetsResponse{}
mi := &file_social_proto_msgTypes[42] mi := &file_social_proto_msgTypes[45]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -2744,7 +2959,7 @@ func (x *GetUserLikedAssetsResponse) String() string {
func (*GetUserLikedAssetsResponse) ProtoMessage() {} func (*GetUserLikedAssetsResponse) ProtoMessage() {}
func (x *GetUserLikedAssetsResponse) ProtoReflect() protoreflect.Message { func (x *GetUserLikedAssetsResponse) ProtoReflect() protoreflect.Message {
mi := &file_social_proto_msgTypes[42] mi := &file_social_proto_msgTypes[45]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -2757,7 +2972,7 @@ func (x *GetUserLikedAssetsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetUserLikedAssetsResponse.ProtoReflect.Descriptor instead. // Deprecated: Use GetUserLikedAssetsResponse.ProtoReflect.Descriptor instead.
func (*GetUserLikedAssetsResponse) Descriptor() ([]byte, []int) { func (*GetUserLikedAssetsResponse) Descriptor() ([]byte, []int) {
return file_social_proto_rawDescGZIP(), []int{42} return file_social_proto_rawDescGZIP(), []int{45}
} }
func (x *GetUserLikedAssetsResponse) GetBase() *common.BaseResponse { func (x *GetUserLikedAssetsResponse) GetBase() *common.BaseResponse {
@ -2939,7 +3154,25 @@ const file_social_proto_rawDesc = "" +
"\basset_id\x18\x01 \x01(\x03R\aassetId\"e\n" + "\basset_id\x18\x01 \x01(\x03R\aassetId\"e\n" +
"\x16CheckAssetLikeResponse\x120\n" + "\x16CheckAssetLikeResponse\x120\n" +
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12\x19\n" + "\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x12\x19\n" +
"\bis_liked\x18\x02 \x01(\bR\aisLiked\"e\n" + "\bis_liked\x18\x02 \x01(\bR\aisLiked\"g\n" +
"\x15GetAssetLikersRequest\x12\x19\n" +
"\basset_id\x18\x01 \x01(\x03R\aassetId\x12\x1b\n" +
"\tpage_size\x18\x02 \x01(\x05R\bpageSize\x12\x16\n" +
"\x06cursor\x18\x03 \x01(\x03R\x06cursor\"\xce\x01\n" +
"\x16GetAssetLikersResponse\x120\n" +
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x120\n" +
"\x05users\x18\x02 \x03(\v2\x1a.topfans.social.AssetLikerR\x05users\x12\x14\n" +
"\x05total\x18\x03 \x01(\x03R\x05total\x12\x19\n" +
"\bhas_more\x18\x04 \x01(\bR\ahasMore\x12\x1f\n" +
"\vnext_cursor\x18\x05 \x01(\x03R\n" +
"nextCursor\"\x91\x01\n" +
"\n" +
"AssetLiker\x12\x17\n" +
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x1a\n" +
"\bnickname\x18\x02 \x01(\tR\bnickname\x12\x16\n" +
"\x06avatar\x18\x03 \x01(\tR\x06avatar\x12\x1b\n" +
"\tfan_level\x18\x04 \x01(\x05R\bfanLevel\x12\x19\n" +
"\bliked_at\x18\x05 \x01(\x03R\alikedAt\"e\n" +
"\x17GetMyLikedAssetsRequest\x12\x12\n" + "\x17GetMyLikedAssetsRequest\x12\x12\n" +
"\x04page\x18\x01 \x01(\x05R\x04page\x12\x1b\n" + "\x04page\x18\x01 \x01(\x05R\x04page\x12\x1b\n" +
"\tpage_size\x18\x02 \x01(\x05R\bpageSize\x12\x19\n" + "\tpage_size\x18\x02 \x01(\x05R\bpageSize\x12\x19\n" +
@ -2982,7 +3215,7 @@ const file_social_proto_rawDesc = "" +
"\tpage_size\x18\x03 \x01(\x05R\bpageSize\"\x83\x01\n" + "\tpage_size\x18\x03 \x01(\x05R\bpageSize\"\x83\x01\n" +
"\x1aGetUserLikedAssetsResponse\x120\n" + "\x1aGetUserLikedAssetsResponse\x120\n" +
"\x04base\x18\x01 \x01(\v2\x1c.topfans.common.BaseResponseR\x04base\x123\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" + "\x04data\x18\x02 \x01(\v2\x1f.topfans.social.LikedAssetsDataR\x04data2\xa7\x15\n" +
"\rSocialService\x12\x8d\x01\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" + "\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" + "\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" +
@ -2997,7 +3230,8 @@ const file_social_proto_rawDesc = "" +
"\rGetUsersPaged\x12$.topfans.social.GetUsersPagedRequest\x1a%.topfans.social.GetUsersPagedResponse\"\x1c\x82\xd3\xe4\x93\x02\x16\x12\x14/api/v1/social/users\x12\x7f\n" + "\rGetUsersPaged\x12$.topfans.social.GetUsersPagedRequest\x1a%.topfans.social.GetUsersPagedResponse\"\x1c\x82\xd3\xe4\x93\x02\x16\x12\x14/api/v1/social/users\x12\x7f\n" +
"\tLikeAsset\x12 .topfans.social.LikeAssetRequest\x1a!.topfans.social.LikeAssetResponse\"-\x82\xd3\xe4\x93\x02'\"%/api/v1/social/assets/{asset_id}/like\x12\x85\x01\n" + "\tLikeAsset\x12 .topfans.social.LikeAssetRequest\x1a!.topfans.social.LikeAssetResponse\"-\x82\xd3\xe4\x93\x02'\"%/api/v1/social/assets/{asset_id}/like\x12\x85\x01\n" +
"\vUnlikeAsset\x12\".topfans.social.UnlikeAssetRequest\x1a#.topfans.social.UnlikeAssetResponse\"-\x82\xd3\xe4\x93\x02'*%/api/v1/social/assets/{asset_id}/like\x12\x8e\x01\n" + "\vUnlikeAsset\x12\".topfans.social.UnlikeAssetRequest\x1a#.topfans.social.UnlikeAssetResponse\"-\x82\xd3\xe4\x93\x02'*%/api/v1/social/assets/{asset_id}/like\x12\x8e\x01\n" +
"\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" + "\x0eCheckAssetLike\x12%.topfans.social.CheckAssetLikeRequest\x1a&.topfans.social.CheckAssetLikeResponse\"-\x82\xd3\xe4\x93\x02'\x12%/api/v1/social/assets/{asset_id}/like\x12\x90\x01\n" +
"\x0eGetAssetLikers\x12%.topfans.social.GetAssetLikersRequest\x1a&.topfans.social.GetAssetLikersResponse\"/\x82\xd3\xe4\x93\x02)\x12'/api/v1/social/assets/{asset_id}/likers\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" + "\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" + "\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-assets\x12\x99\x01\n" + "\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" +
@ -3015,7 +3249,7 @@ func file_social_proto_rawDescGZIP() []byte {
return file_social_proto_rawDescData return file_social_proto_rawDescData
} }
var file_social_proto_msgTypes = make([]protoimpl.MessageInfo, 43) var file_social_proto_msgTypes = make([]protoimpl.MessageInfo, 46)
var file_social_proto_goTypes = []any{ var file_social_proto_goTypes = []any{
(*FriendRequest)(nil), // 0: topfans.social.FriendRequest (*FriendRequest)(nil), // 0: topfans.social.FriendRequest
(*Friendship)(nil), // 1: topfans.social.Friendship (*Friendship)(nil), // 1: topfans.social.Friendship
@ -3050,89 +3284,96 @@ var file_social_proto_goTypes = []any{
(*UnlikeAssetResponse)(nil), // 30: topfans.social.UnlikeAssetResponse (*UnlikeAssetResponse)(nil), // 30: topfans.social.UnlikeAssetResponse
(*CheckAssetLikeRequest)(nil), // 31: topfans.social.CheckAssetLikeRequest (*CheckAssetLikeRequest)(nil), // 31: topfans.social.CheckAssetLikeRequest
(*CheckAssetLikeResponse)(nil), // 32: topfans.social.CheckAssetLikeResponse (*CheckAssetLikeResponse)(nil), // 32: topfans.social.CheckAssetLikeResponse
(*GetMyLikedAssetsRequest)(nil), // 33: topfans.social.GetMyLikedAssetsRequest (*GetAssetLikersRequest)(nil), // 33: topfans.social.GetAssetLikersRequest
(*GetMyLikedAssetsResponse)(nil), // 34: topfans.social.GetMyLikedAssetsResponse (*GetAssetLikersResponse)(nil), // 34: topfans.social.GetAssetLikersResponse
(*LikedAssetsData)(nil), // 35: topfans.social.LikedAssetsData (*AssetLiker)(nil), // 35: topfans.social.AssetLiker
(*LikedAssetItem)(nil), // 36: topfans.social.LikedAssetItem (*GetMyLikedAssetsRequest)(nil), // 36: topfans.social.GetMyLikedAssetsRequest
(*GetMyTodayLikedAssetsRequest)(nil), // 37: topfans.social.GetMyTodayLikedAssetsRequest (*GetMyLikedAssetsResponse)(nil), // 37: topfans.social.GetMyLikedAssetsResponse
(*GetMyTodayLikedAssetsResponse)(nil), // 38: topfans.social.GetMyTodayLikedAssetsResponse (*LikedAssetsData)(nil), // 38: topfans.social.LikedAssetsData
(*GetMyWeekLikedAssetsRequest)(nil), // 39: topfans.social.GetMyWeekLikedAssetsRequest (*LikedAssetItem)(nil), // 39: topfans.social.LikedAssetItem
(*GetMyWeekLikedAssetsResponse)(nil), // 40: topfans.social.GetMyWeekLikedAssetsResponse (*GetMyTodayLikedAssetsRequest)(nil), // 40: topfans.social.GetMyTodayLikedAssetsRequest
(*GetUserLikedAssetsRequest)(nil), // 41: topfans.social.GetUserLikedAssetsRequest (*GetMyTodayLikedAssetsResponse)(nil), // 41: topfans.social.GetMyTodayLikedAssetsResponse
(*GetUserLikedAssetsResponse)(nil), // 42: topfans.social.GetUserLikedAssetsResponse (*GetMyWeekLikedAssetsRequest)(nil), // 42: topfans.social.GetMyWeekLikedAssetsRequest
(*common.BaseResponse)(nil), // 43: topfans.common.BaseResponse (*GetMyWeekLikedAssetsResponse)(nil), // 43: topfans.social.GetMyWeekLikedAssetsResponse
(*GetUserLikedAssetsRequest)(nil), // 44: topfans.social.GetUserLikedAssetsRequest
(*GetUserLikedAssetsResponse)(nil), // 45: topfans.social.GetUserLikedAssetsResponse
(*common.BaseResponse)(nil), // 46: topfans.common.BaseResponse
} }
var file_social_proto_depIdxs = []int32{ var file_social_proto_depIdxs = []int32{
43, // 0: topfans.social.SendFriendRequestResponse.base:type_name -> topfans.common.BaseResponse 46, // 0: topfans.social.SendFriendRequestResponse.base:type_name -> topfans.common.BaseResponse
20, // 1: topfans.social.SendFriendRequestResponse.matched_users:type_name -> topfans.social.FanProfileSearchResult 20, // 1: topfans.social.SendFriendRequestResponse.matched_users:type_name -> topfans.social.FanProfileSearchResult
43, // 2: topfans.social.GetFriendRequestsResponse.base:type_name -> topfans.common.BaseResponse 46, // 2: topfans.social.GetFriendRequestsResponse.base:type_name -> topfans.common.BaseResponse
0, // 3: topfans.social.GetFriendRequestsResponse.items:type_name -> topfans.social.FriendRequest 0, // 3: topfans.social.GetFriendRequestsResponse.items:type_name -> topfans.social.FriendRequest
43, // 4: topfans.social.HandleFriendRequestResponse.base:type_name -> topfans.common.BaseResponse 46, // 4: topfans.social.HandleFriendRequestResponse.base:type_name -> topfans.common.BaseResponse
43, // 5: topfans.social.GetFriendListResponse.base:type_name -> topfans.common.BaseResponse 46, // 5: topfans.social.GetFriendListResponse.base:type_name -> topfans.common.BaseResponse
1, // 6: topfans.social.GetFriendListResponse.items:type_name -> topfans.social.Friendship 1, // 6: topfans.social.GetFriendListResponse.items:type_name -> topfans.social.Friendship
43, // 7: topfans.social.DeleteFriendResponse.base:type_name -> topfans.common.BaseResponse 46, // 7: topfans.social.DeleteFriendResponse.base:type_name -> topfans.common.BaseResponse
43, // 8: topfans.social.SetFriendRemarkResponse.base:type_name -> topfans.common.BaseResponse 46, // 8: topfans.social.SetFriendRemarkResponse.base:type_name -> topfans.common.BaseResponse
43, // 9: topfans.social.CheckFriendshipResponse.base:type_name -> topfans.common.BaseResponse 46, // 9: topfans.social.CheckFriendshipResponse.base:type_name -> topfans.common.BaseResponse
43, // 10: topfans.social.GetFriendCountResponse.base:type_name -> topfans.common.BaseResponse 46, // 10: topfans.social.GetFriendCountResponse.base:type_name -> topfans.common.BaseResponse
43, // 11: topfans.social.SearchUserForFriendResponse.base:type_name -> topfans.common.BaseResponse 46, // 11: topfans.social.SearchUserForFriendResponse.base:type_name -> topfans.common.BaseResponse
20, // 12: topfans.social.SearchUserForFriendResponse.user:type_name -> topfans.social.FanProfileSearchResult 20, // 12: topfans.social.SearchUserForFriendResponse.user:type_name -> topfans.social.FanProfileSearchResult
43, // 13: topfans.social.GetRandomUsersResponse.base:type_name -> topfans.common.BaseResponse 46, // 13: topfans.social.GetRandomUsersResponse.base:type_name -> topfans.common.BaseResponse
21, // 14: topfans.social.GetRandomUsersResponse.users:type_name -> topfans.social.RandomUser 21, // 14: topfans.social.GetRandomUsersResponse.users:type_name -> topfans.social.RandomUser
43, // 15: topfans.social.GetUsersPagedResponse.base:type_name -> topfans.common.BaseResponse 46, // 15: topfans.social.GetUsersPagedResponse.base:type_name -> topfans.common.BaseResponse
24, // 16: topfans.social.GetUsersPagedResponse.users:type_name -> topfans.social.PagedUser 24, // 16: topfans.social.GetUsersPagedResponse.users:type_name -> topfans.social.PagedUser
43, // 17: topfans.social.LikeAssetResponse.base:type_name -> topfans.common.BaseResponse 46, // 17: topfans.social.LikeAssetResponse.base:type_name -> topfans.common.BaseResponse
43, // 18: topfans.social.UnlikeAssetResponse.base:type_name -> topfans.common.BaseResponse 46, // 18: topfans.social.UnlikeAssetResponse.base:type_name -> topfans.common.BaseResponse
43, // 19: topfans.social.CheckAssetLikeResponse.base:type_name -> topfans.common.BaseResponse 46, // 19: topfans.social.CheckAssetLikeResponse.base:type_name -> topfans.common.BaseResponse
43, // 20: topfans.social.GetMyLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse 46, // 20: topfans.social.GetAssetLikersResponse.base:type_name -> topfans.common.BaseResponse
35, // 21: topfans.social.GetMyLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData 35, // 21: topfans.social.GetAssetLikersResponse.users:type_name -> topfans.social.AssetLiker
36, // 22: topfans.social.LikedAssetsData.items:type_name -> topfans.social.LikedAssetItem 46, // 22: topfans.social.GetMyLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse
43, // 23: topfans.social.GetMyTodayLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse 38, // 23: topfans.social.GetMyLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData
35, // 24: topfans.social.GetMyTodayLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData 39, // 24: topfans.social.LikedAssetsData.items:type_name -> topfans.social.LikedAssetItem
43, // 25: topfans.social.GetMyWeekLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse 46, // 25: topfans.social.GetMyTodayLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse
35, // 26: topfans.social.GetMyWeekLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData 38, // 26: topfans.social.GetMyTodayLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData
43, // 27: topfans.social.GetUserLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse 46, // 27: topfans.social.GetMyWeekLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse
35, // 28: topfans.social.GetUserLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData 38, // 28: topfans.social.GetMyWeekLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData
2, // 29: topfans.social.SocialService.SendFriendRequest:input_type -> topfans.social.SendFriendRequestRequest 46, // 29: topfans.social.GetUserLikedAssetsResponse.base:type_name -> topfans.common.BaseResponse
4, // 30: topfans.social.SocialService.GetFriendRequests:input_type -> topfans.social.GetFriendRequestsRequest 38, // 30: topfans.social.GetUserLikedAssetsResponse.data:type_name -> topfans.social.LikedAssetsData
6, // 31: topfans.social.SocialService.HandleFriendRequest:input_type -> topfans.social.HandleFriendRequestRequest 2, // 31: topfans.social.SocialService.SendFriendRequest:input_type -> topfans.social.SendFriendRequestRequest
8, // 32: topfans.social.SocialService.GetFriendList:input_type -> topfans.social.GetFriendListRequest 4, // 32: topfans.social.SocialService.GetFriendRequests:input_type -> topfans.social.GetFriendRequestsRequest
10, // 33: topfans.social.SocialService.DeleteFriend:input_type -> topfans.social.DeleteFriendRequest 6, // 33: topfans.social.SocialService.HandleFriendRequest:input_type -> topfans.social.HandleFriendRequestRequest
12, // 34: topfans.social.SocialService.SetFriendRemark:input_type -> topfans.social.SetFriendRemarkRequest 8, // 34: topfans.social.SocialService.GetFriendList:input_type -> topfans.social.GetFriendListRequest
14, // 35: topfans.social.SocialService.CheckFriendship:input_type -> topfans.social.CheckFriendshipRequest 10, // 35: topfans.social.SocialService.DeleteFriend:input_type -> topfans.social.DeleteFriendRequest
16, // 36: topfans.social.SocialService.GetFriendCount:input_type -> topfans.social.GetFriendCountRequest 12, // 36: topfans.social.SocialService.SetFriendRemark:input_type -> topfans.social.SetFriendRemarkRequest
18, // 37: topfans.social.SocialService.SearchUserForFriend:input_type -> topfans.social.SearchUserForFriendRequest 14, // 37: topfans.social.SocialService.CheckFriendship:input_type -> topfans.social.CheckFriendshipRequest
22, // 38: topfans.social.SocialService.GetRandomUsers:input_type -> topfans.social.GetRandomUsersRequest 16, // 38: topfans.social.SocialService.GetFriendCount:input_type -> topfans.social.GetFriendCountRequest
25, // 39: topfans.social.SocialService.GetUsersPaged:input_type -> topfans.social.GetUsersPagedRequest 18, // 39: topfans.social.SocialService.SearchUserForFriend:input_type -> topfans.social.SearchUserForFriendRequest
27, // 40: topfans.social.SocialService.LikeAsset:input_type -> topfans.social.LikeAssetRequest 22, // 40: topfans.social.SocialService.GetRandomUsers:input_type -> topfans.social.GetRandomUsersRequest
29, // 41: topfans.social.SocialService.UnlikeAsset:input_type -> topfans.social.UnlikeAssetRequest 25, // 41: topfans.social.SocialService.GetUsersPaged:input_type -> topfans.social.GetUsersPagedRequest
31, // 42: topfans.social.SocialService.CheckAssetLike:input_type -> topfans.social.CheckAssetLikeRequest 27, // 42: topfans.social.SocialService.LikeAsset:input_type -> topfans.social.LikeAssetRequest
33, // 43: topfans.social.SocialService.GetMyLikedAssets:input_type -> topfans.social.GetMyLikedAssetsRequest 29, // 43: topfans.social.SocialService.UnlikeAsset:input_type -> topfans.social.UnlikeAssetRequest
37, // 44: topfans.social.SocialService.GetMyTodayLikedAssets:input_type -> topfans.social.GetMyTodayLikedAssetsRequest 31, // 44: topfans.social.SocialService.CheckAssetLike:input_type -> topfans.social.CheckAssetLikeRequest
39, // 45: topfans.social.SocialService.GetMyWeekLikedAssets:input_type -> topfans.social.GetMyWeekLikedAssetsRequest 33, // 45: topfans.social.SocialService.GetAssetLikers:input_type -> topfans.social.GetAssetLikersRequest
41, // 46: topfans.social.SocialService.GetUserLikedAssets:input_type -> topfans.social.GetUserLikedAssetsRequest 36, // 46: topfans.social.SocialService.GetMyLikedAssets:input_type -> topfans.social.GetMyLikedAssetsRequest
3, // 47: topfans.social.SocialService.SendFriendRequest:output_type -> topfans.social.SendFriendRequestResponse 40, // 47: topfans.social.SocialService.GetMyTodayLikedAssets:input_type -> topfans.social.GetMyTodayLikedAssetsRequest
5, // 48: topfans.social.SocialService.GetFriendRequests:output_type -> topfans.social.GetFriendRequestsResponse 42, // 48: topfans.social.SocialService.GetMyWeekLikedAssets:input_type -> topfans.social.GetMyWeekLikedAssetsRequest
7, // 49: topfans.social.SocialService.HandleFriendRequest:output_type -> topfans.social.HandleFriendRequestResponse 44, // 49: topfans.social.SocialService.GetUserLikedAssets:input_type -> topfans.social.GetUserLikedAssetsRequest
9, // 50: topfans.social.SocialService.GetFriendList:output_type -> topfans.social.GetFriendListResponse 3, // 50: topfans.social.SocialService.SendFriendRequest:output_type -> topfans.social.SendFriendRequestResponse
11, // 51: topfans.social.SocialService.DeleteFriend:output_type -> topfans.social.DeleteFriendResponse 5, // 51: topfans.social.SocialService.GetFriendRequests:output_type -> topfans.social.GetFriendRequestsResponse
13, // 52: topfans.social.SocialService.SetFriendRemark:output_type -> topfans.social.SetFriendRemarkResponse 7, // 52: topfans.social.SocialService.HandleFriendRequest:output_type -> topfans.social.HandleFriendRequestResponse
15, // 53: topfans.social.SocialService.CheckFriendship:output_type -> topfans.social.CheckFriendshipResponse 9, // 53: topfans.social.SocialService.GetFriendList:output_type -> topfans.social.GetFriendListResponse
17, // 54: topfans.social.SocialService.GetFriendCount:output_type -> topfans.social.GetFriendCountResponse 11, // 54: topfans.social.SocialService.DeleteFriend:output_type -> topfans.social.DeleteFriendResponse
19, // 55: topfans.social.SocialService.SearchUserForFriend:output_type -> topfans.social.SearchUserForFriendResponse 13, // 55: topfans.social.SocialService.SetFriendRemark:output_type -> topfans.social.SetFriendRemarkResponse
23, // 56: topfans.social.SocialService.GetRandomUsers:output_type -> topfans.social.GetRandomUsersResponse 15, // 56: topfans.social.SocialService.CheckFriendship:output_type -> topfans.social.CheckFriendshipResponse
26, // 57: topfans.social.SocialService.GetUsersPaged:output_type -> topfans.social.GetUsersPagedResponse 17, // 57: topfans.social.SocialService.GetFriendCount:output_type -> topfans.social.GetFriendCountResponse
28, // 58: topfans.social.SocialService.LikeAsset:output_type -> topfans.social.LikeAssetResponse 19, // 58: topfans.social.SocialService.SearchUserForFriend:output_type -> topfans.social.SearchUserForFriendResponse
30, // 59: topfans.social.SocialService.UnlikeAsset:output_type -> topfans.social.UnlikeAssetResponse 23, // 59: topfans.social.SocialService.GetRandomUsers:output_type -> topfans.social.GetRandomUsersResponse
32, // 60: topfans.social.SocialService.CheckAssetLike:output_type -> topfans.social.CheckAssetLikeResponse 26, // 60: topfans.social.SocialService.GetUsersPaged:output_type -> topfans.social.GetUsersPagedResponse
34, // 61: topfans.social.SocialService.GetMyLikedAssets:output_type -> topfans.social.GetMyLikedAssetsResponse 28, // 61: topfans.social.SocialService.LikeAsset:output_type -> topfans.social.LikeAssetResponse
38, // 62: topfans.social.SocialService.GetMyTodayLikedAssets:output_type -> topfans.social.GetMyTodayLikedAssetsResponse 30, // 62: topfans.social.SocialService.UnlikeAsset:output_type -> topfans.social.UnlikeAssetResponse
40, // 63: topfans.social.SocialService.GetMyWeekLikedAssets:output_type -> topfans.social.GetMyWeekLikedAssetsResponse 32, // 63: topfans.social.SocialService.CheckAssetLike:output_type -> topfans.social.CheckAssetLikeResponse
42, // 64: topfans.social.SocialService.GetUserLikedAssets:output_type -> topfans.social.GetUserLikedAssetsResponse 34, // 64: topfans.social.SocialService.GetAssetLikers:output_type -> topfans.social.GetAssetLikersResponse
47, // [47:65] is the sub-list for method output_type 37, // 65: topfans.social.SocialService.GetMyLikedAssets:output_type -> topfans.social.GetMyLikedAssetsResponse
29, // [29:47] is the sub-list for method input_type 41, // 66: topfans.social.SocialService.GetMyTodayLikedAssets:output_type -> topfans.social.GetMyTodayLikedAssetsResponse
29, // [29:29] is the sub-list for extension type_name 43, // 67: topfans.social.SocialService.GetMyWeekLikedAssets:output_type -> topfans.social.GetMyWeekLikedAssetsResponse
29, // [29:29] is the sub-list for extension extendee 45, // 68: topfans.social.SocialService.GetUserLikedAssets:output_type -> topfans.social.GetUserLikedAssetsResponse
0, // [0:29] is the sub-list for field type_name 50, // [50:69] is the sub-list for method output_type
31, // [31:50] is the sub-list for method input_type
31, // [31:31] is the sub-list for extension type_name
31, // [31:31] is the sub-list for extension extendee
0, // [0:31] is the sub-list for field type_name
} }
func init() { file_social_proto_init() } func init() { file_social_proto_init() }
@ -3146,7 +3387,7 @@ func file_social_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_social_proto_rawDesc), len(file_social_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_social_proto_rawDesc), len(file_social_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 43, NumMessages: 46,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View File

@ -64,6 +64,8 @@ const (
SocialServiceUnlikeAssetProcedure = "/topfans.social.SocialService/UnlikeAsset" SocialServiceUnlikeAssetProcedure = "/topfans.social.SocialService/UnlikeAsset"
// SocialServiceCheckAssetLikeProcedure is the fully-qualified name of the SocialService's CheckAssetLike RPC. // SocialServiceCheckAssetLikeProcedure is the fully-qualified name of the SocialService's CheckAssetLike RPC.
SocialServiceCheckAssetLikeProcedure = "/topfans.social.SocialService/CheckAssetLike" SocialServiceCheckAssetLikeProcedure = "/topfans.social.SocialService/CheckAssetLike"
// SocialServiceGetAssetLikersProcedure is the fully-qualified name of the SocialService's GetAssetLikers RPC.
SocialServiceGetAssetLikersProcedure = "/topfans.social.SocialService/GetAssetLikers"
// SocialServiceGetMyLikedAssetsProcedure is the fully-qualified name of the SocialService's GetMyLikedAssets RPC. // SocialServiceGetMyLikedAssetsProcedure is the fully-qualified name of the SocialService's GetMyLikedAssets RPC.
SocialServiceGetMyLikedAssetsProcedure = "/topfans.social.SocialService/GetMyLikedAssets" SocialServiceGetMyLikedAssetsProcedure = "/topfans.social.SocialService/GetMyLikedAssets"
// SocialServiceGetMyTodayLikedAssetsProcedure is the fully-qualified name of the SocialService's GetMyTodayLikedAssets RPC. // SocialServiceGetMyTodayLikedAssetsProcedure is the fully-qualified name of the SocialService's GetMyTodayLikedAssets RPC.
@ -94,6 +96,7 @@ type SocialService interface {
LikeAsset(ctx context.Context, req *LikeAssetRequest, opts ...client.CallOption) (*LikeAssetResponse, error) LikeAsset(ctx context.Context, req *LikeAssetRequest, opts ...client.CallOption) (*LikeAssetResponse, error)
UnlikeAsset(ctx context.Context, req *UnlikeAssetRequest, opts ...client.CallOption) (*UnlikeAssetResponse, error) UnlikeAsset(ctx context.Context, req *UnlikeAssetRequest, opts ...client.CallOption) (*UnlikeAssetResponse, error)
CheckAssetLike(ctx context.Context, req *CheckAssetLikeRequest, opts ...client.CallOption) (*CheckAssetLikeResponse, error) CheckAssetLike(ctx context.Context, req *CheckAssetLikeRequest, opts ...client.CallOption) (*CheckAssetLikeResponse, error)
GetAssetLikers(ctx context.Context, req *GetAssetLikersRequest, opts ...client.CallOption) (*GetAssetLikersResponse, error)
GetMyLikedAssets(ctx context.Context, req *GetMyLikedAssetsRequest, opts ...client.CallOption) (*GetMyLikedAssetsResponse, error) GetMyLikedAssets(ctx context.Context, req *GetMyLikedAssetsRequest, opts ...client.CallOption) (*GetMyLikedAssetsResponse, error)
GetMyTodayLikedAssets(ctx context.Context, req *GetMyTodayLikedAssetsRequest, opts ...client.CallOption) (*GetMyTodayLikedAssetsResponse, error) GetMyTodayLikedAssets(ctx context.Context, req *GetMyTodayLikedAssetsRequest, opts ...client.CallOption) (*GetMyTodayLikedAssetsResponse, error)
GetMyWeekLikedAssets(ctx context.Context, req *GetMyWeekLikedAssetsRequest, opts ...client.CallOption) (*GetMyWeekLikedAssetsResponse, error) GetMyWeekLikedAssets(ctx context.Context, req *GetMyWeekLikedAssetsRequest, opts ...client.CallOption) (*GetMyWeekLikedAssetsResponse, error)
@ -232,6 +235,14 @@ func (c *SocialServiceImpl) CheckAssetLike(ctx context.Context, req *CheckAssetL
return resp, nil return resp, nil
} }
func (c *SocialServiceImpl) GetAssetLikers(ctx context.Context, req *GetAssetLikersRequest, opts ...client.CallOption) (*GetAssetLikersResponse, error) {
resp := new(GetAssetLikersResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetAssetLikers", opts...); err != nil {
return nil, err
}
return resp, nil
}
func (c *SocialServiceImpl) GetMyLikedAssets(ctx context.Context, req *GetMyLikedAssetsRequest, opts ...client.CallOption) (*GetMyLikedAssetsResponse, error) { func (c *SocialServiceImpl) GetMyLikedAssets(ctx context.Context, req *GetMyLikedAssetsRequest, opts ...client.CallOption) (*GetMyLikedAssetsResponse, error) {
resp := new(GetMyLikedAssetsResponse) resp := new(GetMyLikedAssetsResponse)
if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyLikedAssets", opts...); err != nil { if err := c.conn.CallUnary(ctx, []interface{}{req}, resp, "GetMyLikedAssets", opts...); err != nil {
@ -266,7 +277,7 @@ func (c *SocialServiceImpl) GetUserLikedAssets(ctx context.Context, req *GetUser
var SocialService_ClientInfo = client.ClientInfo{ var SocialService_ClientInfo = client.ClientInfo{
InterfaceName: "topfans.social.SocialService", InterfaceName: "topfans.social.SocialService",
MethodNames: []string{"SendFriendRequest", "GetFriendRequests", "HandleFriendRequest", "GetFriendList", "DeleteFriend", "SetFriendRemark", "CheckFriendship", "GetFriendCount", "SearchUserForFriend", "GetRandomUsers", "GetUsersPaged", "LikeAsset", "UnlikeAsset", "CheckAssetLike", "GetMyLikedAssets", "GetMyTodayLikedAssets", "GetMyWeekLikedAssets", "GetUserLikedAssets"}, MethodNames: []string{"SendFriendRequest", "GetFriendRequests", "HandleFriendRequest", "GetFriendList", "DeleteFriend", "SetFriendRemark", "CheckFriendship", "GetFriendCount", "SearchUserForFriend", "GetRandomUsers", "GetUsersPaged", "LikeAsset", "UnlikeAsset", "CheckAssetLike", "GetAssetLikers", "GetMyLikedAssets", "GetMyTodayLikedAssets", "GetMyWeekLikedAssets", "GetUserLikedAssets"},
ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) { ConnectionInjectFunc: func(dubboCliRaw interface{}, conn *client.Connection) {
dubboCli := dubboCliRaw.(*SocialServiceImpl) dubboCli := dubboCliRaw.(*SocialServiceImpl)
dubboCli.conn = conn dubboCli.conn = conn
@ -289,6 +300,7 @@ type SocialServiceHandler interface {
LikeAsset(context.Context, *LikeAssetRequest) (*LikeAssetResponse, error) LikeAsset(context.Context, *LikeAssetRequest) (*LikeAssetResponse, error)
UnlikeAsset(context.Context, *UnlikeAssetRequest) (*UnlikeAssetResponse, error) UnlikeAsset(context.Context, *UnlikeAssetRequest) (*UnlikeAssetResponse, error)
CheckAssetLike(context.Context, *CheckAssetLikeRequest) (*CheckAssetLikeResponse, error) CheckAssetLike(context.Context, *CheckAssetLikeRequest) (*CheckAssetLikeResponse, error)
GetAssetLikers(context.Context, *GetAssetLikersRequest) (*GetAssetLikersResponse, error)
GetMyLikedAssets(context.Context, *GetMyLikedAssetsRequest) (*GetMyLikedAssetsResponse, error) GetMyLikedAssets(context.Context, *GetMyLikedAssetsRequest) (*GetMyLikedAssetsResponse, error)
GetMyTodayLikedAssets(context.Context, *GetMyTodayLikedAssetsRequest) (*GetMyTodayLikedAssetsResponse, error) GetMyTodayLikedAssets(context.Context, *GetMyTodayLikedAssetsRequest) (*GetMyTodayLikedAssetsResponse, error)
GetMyWeekLikedAssets(context.Context, *GetMyWeekLikedAssetsRequest) (*GetMyWeekLikedAssetsResponse, error) GetMyWeekLikedAssets(context.Context, *GetMyWeekLikedAssetsRequest) (*GetMyWeekLikedAssetsResponse, error)
@ -517,6 +529,21 @@ var SocialService_ServiceInfo = server.ServiceInfo{
return triple_protocol.NewResponse(res), nil return triple_protocol.NewResponse(res), nil
}, },
}, },
{
Name: "GetAssetLikers",
Type: constant.CallUnary,
ReqInitFunc: func() interface{} {
return new(GetAssetLikersRequest)
},
MethodFunc: func(ctx context.Context, args []interface{}, handler interface{}) (interface{}, error) {
req := args[0].(*GetAssetLikersRequest)
res, err := handler.(SocialServiceHandler).GetAssetLikers(ctx, req)
if err != nil {
return nil, err
}
return triple_protocol.NewResponse(res), nil
},
},
{ {
Name: "GetMyLikedAssets", Name: "GetMyLikedAssets",
Type: constant.CallUnary, Type: constant.CallUnary,

View File

@ -260,6 +260,31 @@ message CheckAssetLikeResponse {
bool is_liked = 2; // bool is_liked = 2; //
} }
//
message GetAssetLikersRequest {
int64 asset_id = 1; // ID
int32 page_size = 2; // 20100
int64 cursor = 3; // created_at0
}
//
message GetAssetLikersResponse {
topfans.common.BaseResponse base = 1;
repeated AssetLiker users = 2; //
int64 total = 3; //
bool has_more = 4; //
int64 next_cursor = 5; //
}
//
message AssetLiker {
int64 user_id = 1; // ID
string nickname = 2; //
string avatar = 3; // URL
int32 fan_level = 4; //
int64 liked_at = 5; //
}
// ==================== ==================== // ==================== ====================
// //
@ -446,6 +471,13 @@ service SocialService {
}; };
} }
//
rpc GetAssetLikers(GetAssetLikersRequest) returns (GetAssetLikersResponse) {
option (google.api.http) = {
get: "/api/v1/social/assets/{asset_id}/likers"
};
}
// ========== ========== // ========== ==========
// //

View File

@ -159,7 +159,7 @@ CREATE TABLE IF NOT EXISTS asset_likes (
star_id BIGINT NOT NULL, star_id BIGINT NOT NULL,
created_at BIGINT NOT NULL, created_at BIGINT NOT NULL,
CONSTRAINT uk_asset_likes_user_asset UNIQUE (user_id, asset_id) CONSTRAINT uk_asset_likes_user_asset_exhibition UNIQUE (user_id, asset_id, exhibition_id)
); );
CREATE INDEX IF NOT EXISTS idx_asset_likes_asset ON asset_likes(asset_id); CREATE INDEX IF NOT EXISTS idx_asset_likes_asset ON asset_likes(asset_id);

View File

@ -0,0 +1,3 @@
-- 为游标分页新增索引(幂等)
-- 支持查询WHERE asset_id = ? AND created_at < ? ORDER BY created_at DESC
CREATE INDEX IF NOT EXISTS idx_asset_likes_asset_created ON asset_likes(asset_id, created_at DESC);

View File

@ -0,0 +1,26 @@
-- 修改 asset_likes 表唯一约束(幂等)
-- 原约束: (user_id, asset_id) - 用户对某藏品只能点赞一次
-- 新约束: (user_id, asset_id, exhibition_id) - 用户对某藏品在同一展出中只能点赞一次
-- 下架后重新展出,用户可以再次点赞
-- 删除旧约束(如果存在)
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'uk_asset_likes_user_asset'
) THEN
ALTER TABLE asset_likes DROP CONSTRAINT uk_asset_likes_user_asset;
END IF;
END $$;
-- 添加新约束(如果不存在)
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'uk_asset_likes_user_asset_exhibition'
) THEN
ALTER TABLE asset_likes ADD CONSTRAINT uk_asset_likes_user_asset_exhibition UNIQUE (user_id, asset_id, exhibition_id);
END IF;
END $$;

View File

@ -373,6 +373,28 @@ func (p *SocialProvider) CheckAssetLike(ctx context.Context, req *pb.CheckAssetL
}, nil }, nil
} }
// GetAssetLikers 获取资产点赞用户列表
func (p *SocialProvider) GetAssetLikers(ctx context.Context, req *pb.GetAssetLikersRequest) (*pb.GetAssetLikersResponse, error) {
// 从上下文获取用户信息starID 可选,用于 JOIN fan_profiles
_, starID, err := extractUserInfo(ctx)
if err != nil {
// starID 获取失败不影响查询,使用 0 让 service 层自动获取
starID = 0
logger.Logger.Warn("Failed to extract star_id from context, will get from asset",
zap.Error(err),
)
}
logger.Logger.Debug("GetAssetLikers called",
zap.Int64("asset_id", req.AssetId),
zap.Int64("star_id", starID),
zap.Int64("cursor", req.Cursor),
zap.Int32("page_size", req.PageSize),
)
return p.assetLikeService.GetAssetLikers(ctx, req.AssetId, starID, req.Cursor, req.PageSize)
}
// ========== 我的作品相关 ========== // ========== 我的作品相关 ==========
// GetMyLikedAssets 获取我点赞的作品列表 // GetMyLikedAssets 获取我点赞的作品列表

View File

@ -136,6 +136,26 @@ type SocialRepository interface {
// pageSize: 每页数量 // pageSize: 每页数量
// 返回: 作品列表、总数量 // 返回: 作品列表、总数量
GetUserLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error) GetUserLikedAssets(userID, starID int64, page, pageSize int) ([]*LikedAssetInfo, int64, error)
// ========== 藏品点赞用户相关 ==========
// GetByAssetWithUsers 获取资产的点赞用户列表(带用户信息,游标分页)
// assetID: 资产ID
// starID: 明星ID用于 JOIN fan_profiles
// cursor: 游标(上一页最后一条的 created_at首次请求传0
// limit: 每页数量
// 返回: 点赞用户列表
GetByAssetWithUsers(assetID, starID int64, cursor int64, limit int) ([]*AssetLikeWithUser, error)
}
// AssetLikeWithUser 点赞记录+用户信息
type AssetLikeWithUser struct {
UserID int64
Nickname string `gorm:"column:nickname"` // 来自 fan_profiles.nickname
Avatar string `gorm:"column:avatar_url"` // 来自 users.avatar_url
FanLevel int32 `gorm:"column:fan_level"` // 来自 fan_profiles.level
LikedAt int64 `gorm:"column:liked_at"`
StarID int64 `gorm:"column:star_id"` // 来自 al.star_id用于 JOIN fan_profiles
} }
// LikedAssetInfo 我点赞的作品信息 // LikedAssetInfo 我点赞的作品信息
@ -849,3 +869,36 @@ func (r *socialRepositoryImpl) GetUserLikedAssets(userID, starID int64, page, pa
return items, total, nil return items, total, nil
} }
// ========== 藏品点赞用户相关实现 ==========
// GetByAssetWithUsers 获取资产的点赞用户列表(带用户信息,游标分页)
func (r *socialRepositoryImpl) GetByAssetWithUsers(assetID, starID int64, cursor int64, limit int) ([]*AssetLikeWithUser, error) {
var results []*AssetLikeWithUser
query := r.db.Table("asset_likes al").
Select(`al.user_id,
al.star_id,
COALESCE(fp.nickname, '匿名用户') as nickname,
u.avatar_url,
COALESCE(fp.level, 1) as fan_level,
al.created_at as liked_at`).
Joins("JOIN users u ON al.user_id = u.id").
Joins("LEFT JOIN fan_profiles fp ON al.user_id = fp.user_id AND al.star_id = fp.star_id").
Where("al.asset_id = ?", assetID)
// 游标分页cursor=0 时跳过游标条件,返回第一页
if cursor > 0 {
query = query.Where("al.created_at < ?", cursor)
}
err := query.Order("al.created_at DESC").
Limit(limit).
Scan(&results).Error
if err != nil {
return nil, err
}
return results, nil
}

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/topfans/backend/pkg/database"
"github.com/topfans/backend/pkg/logger" "github.com/topfans/backend/pkg/logger"
assetPb "github.com/topfans/backend/pkg/proto/asset" assetPb "github.com/topfans/backend/pkg/proto/asset"
pbCommon "github.com/topfans/backend/pkg/proto/common" pbCommon "github.com/topfans/backend/pkg/proto/common"
@ -107,6 +108,9 @@ func (s *AssetLikeService) LikeAsset(ctx context.Context, assetID, userID, starI
zap.Int64("star_id", starID), zap.Int64("star_id", starID),
) )
// 缓存失效
_ = database.InvalidateAssetLikersCache(ctx, assetID)
return nil return nil
} }
@ -167,6 +171,9 @@ func (s *AssetLikeService) UnlikeAsset(ctx context.Context, assetID, userID, sta
zap.Int64("star_id", starID), zap.Int64("star_id", starID),
) )
// 缓存失效
_ = database.InvalidateAssetLikersCache(ctx, assetID)
return nil return nil
} }
@ -484,3 +491,162 @@ func (s *AssetLikeService) GetUserLikedAssets(ctx context.Context, req *pb.GetUs
}, nil }, nil
} }
// GetAssetLikers 获取资产点赞用户列表(带缓存)
func (s *AssetLikeService) GetAssetLikers(ctx context.Context, assetID, starID int64, cursor int64, pageSize int32) (*pb.GetAssetLikersResponse, error) {
logger.Logger.Debug("AssetLikeService.GetAssetLikers called",
zap.Int64("asset_id", assetID),
zap.Int64("star_id", starID),
zap.Int64("cursor", cursor),
zap.Int32("page_size", pageSize),
)
// 参数校验
if pageSize <= 0 {
pageSize = 20
}
if pageSize > 100 {
pageSize = 100
}
// 0. 校验资产是否存在
getAssetReq := &assetPb.GetAssetForRPCRequest{AssetId: assetID}
getAssetResp, err := s.assetClient.GetAssetForRPC(ctx, getAssetReq)
if err != nil {
logger.Logger.Error("Failed to get asset for RPC",
zap.Error(err),
zap.Int64("asset_id", assetID),
)
return &pb.GetAssetLikersResponse{
Base: &pbCommon.BaseResponse{
Code: pbCommon.StatusCode_STATUS_INTERNAL_ERROR,
Message: "Failed to get asset",
Timestamp: time.Now().UnixMilli(),
},
}, nil
}
if getAssetResp.Base.Code != pbCommon.StatusCode_STATUS_OK {
logger.Logger.Warn("Asset not found",
zap.Int64("asset_id", assetID),
)
return &pb.GetAssetLikersResponse{
Base: &pbCommon.BaseResponse{
Code: pbCommon.StatusCode_STATUS_NOT_FOUND,
Message: "Asset not found",
Timestamp: time.Now().UnixMilli(),
},
}, nil
}
// 1. 先查缓存
cache, err := database.GetAssetLikersCache(ctx, assetID)
if err != nil {
logger.Logger.Warn("Failed to get asset likers cache",
zap.Error(err),
zap.Int64("asset_id", assetID),
)
// 缓存错误不影响主流程,继续查 DB
}
if cache != nil && len(cache.Users) > 0 {
// 缓存命中,从缓存中切片返回
return sliceFromCache(cache, cursor, pageSize)
}
// 2. 缓存未命中,查 DB
// 从已获取的资产信息中获取 starID
actualStarID := getAssetResp.StarId
if actualStarID == 0 {
actualStarID = starID // 兜底使用传入的 starID
}
// 查询数据库,最多缓存 1000 条
dbResults, err := s.socialRepo.GetByAssetWithUsers(assetID, actualStarID, 0, 1000)
if err != nil {
logger.Logger.Error("Failed to get asset likers from DB",
zap.Error(err),
zap.Int64("asset_id", assetID),
)
return &pb.GetAssetLikersResponse{
Base: &pbCommon.BaseResponse{
Code: pbCommon.StatusCode_STATUS_INTERNAL_ERROR,
Message: "Failed to get asset likers",
Timestamp: time.Now().UnixMilli(),
},
}, nil
}
// 3. 写入缓存
total := int64(len(dbResults))
cacheUsers := make([]database.AssetLikerWithTotal, 0, len(dbResults))
for _, r := range dbResults {
cacheUsers = append(cacheUsers, database.AssetLikerWithTotal{
UserID: r.UserID,
Nickname: r.Nickname,
Avatar: r.Avatar,
FanLevel: r.FanLevel,
LikedAt: r.LikedAt,
StarID: r.StarID,
})
}
cache = &database.AssetLikersCache{
Users: cacheUsers,
Total: total,
UpdatedAt: time.Now().UnixMilli(),
}
_ = database.SetAssetLikersCache(ctx, assetID, cache, 60*time.Second)
// 4. 返回数据
return sliceFromCache(cache, cursor, pageSize)
}
// sliceFromCache 从缓存中按游标切片
func sliceFromCache(cache *database.AssetLikersCache, cursor int64, pageSize int32) (*pb.GetAssetLikersResponse, error) {
users := cache.Users
total := cache.Total
// 找到起始位置
start := 0
if cursor > 0 {
for i, u := range users {
if u.LikedAt < cursor {
start = i
break
}
}
}
// 找到结束位置
end := start + int(pageSize)
hasMore := end < len(users)
if end > len(users) {
end = len(users)
}
// 构建返回结果
pbUsers := make([]*pb.AssetLiker, 0, end-start)
var nextCursor int64
for i := start; i < end; i++ {
u := users[i]
pbUsers = append(pbUsers, &pb.AssetLiker{
UserId: u.UserID,
Nickname: u.Nickname,
Avatar: u.Avatar,
FanLevel: u.FanLevel,
LikedAt: u.LikedAt,
})
nextCursor = u.LikedAt
}
return &pb.GetAssetLikersResponse{
Base: &pbCommon.BaseResponse{
Code: pbCommon.StatusCode_STATUS_OK,
Message: "success",
Timestamp: time.Now().UnixMilli(),
},
Users: pbUsers,
Total: total,
HasMore: hasMore,
NextCursor: nextCursor,
}, nil
}

View File

@ -1129,11 +1129,11 @@ ALTER TABLE ONLY public.activity_user_stats
-- --
-- Name: asset_likes uk_asset_likes_user_asset; Type: CONSTRAINT; Schema: public; Owner: - -- Name: asset_likes uk_asset_likes_user_asset_exhibition; Type: CONSTRAINT; Schema: public; Owner: -
-- --
ALTER TABLE ONLY public.asset_likes ALTER TABLE ONLY public.asset_likes
ADD CONSTRAINT uk_asset_likes_user_asset UNIQUE (user_id, asset_id); ADD CONSTRAINT uk_asset_likes_user_asset_exhibition UNIQUE (user_id, asset_id, exhibition_id);
-- --
@ -1250,6 +1250,12 @@ CREATE INDEX idx_asset_likes_asset ON public.asset_likes USING btree (asset_id);
CREATE INDEX idx_asset_likes_user_star ON public.asset_likes USING btree (user_id, star_id); CREATE INDEX idx_asset_likes_user_star ON public.asset_likes USING btree (user_id, star_id);
--
-- Name: idx_asset_likes_asset_created; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX IF NOT EXISTS idx_asset_likes_asset_created ON public.asset_likes USING btree (asset_id, created_at DESC);
-- --
-- Name: idx_registry_owner_star; Type: INDEX; Schema: public; Owner: - -- Name: idx_registry_owner_star; Type: INDEX; Schema: public; Owner: -

View File

@ -196,17 +196,16 @@
</scroll-view> </scroll-view>
<!-- 点赞用户弹窗 --> <!-- 点赞用户弹窗 -->
<LikeUsersModal :visible="showLikeUsersModal" :tabs="['今日', '历史']" @close="showLikeUsersModal = false" <LikeUsersModal :visible="showLikeUsersModal" :tabs="[]" @close="showLikeUsersModal = false">
@tab-change="handleLikeUsersTabChange">
<template #content> <template #content>
<view class="like-users-list"> <view class="like-users-list">
<view v-for="(user, index) in displayedLikeUsers" :key="index" class="like-user-item"> <view v-for="(user, index) in allLikedUsers" :key="index" class="like-user-item">
<image class="like-user-avatar" :src="user.avatar" mode="aspectFill"></image> <image class="like-user-avatar" :src="user.avatar" mode="aspectFill"></image>
<view class="like-user-info"> <view class="like-user-info">
<text class="like-user-name">{{ user.nickname }}</text> <text class="like-user-name">{{ user.nickname }}</text>
</view> </view>
<!-- 拜访按钮 --> <!-- 拜访按钮 -->
<view class="visit-button" @tap="handleVisit"> <view class="visit-button" @tap="handleVisit(user)">
<image class="visit-icon" src="/static/square/dianjibaifang.png" mode="aspectFit" lazy-load> <image class="visit-icon" src="/static/square/dianjibaifang.png" mode="aspectFit" lazy-load>
</image> </image>
<text class="visit-text">点击拜访</text> <text class="visit-text">点击拜访</text>
@ -221,7 +220,7 @@
<script setup> <script setup>
import { ref, computed, onUnmounted } from 'vue'; import { ref, computed, onUnmounted } from 'vue';
import { onLoad, onShow, onHide } from '@dcloudio/uni-app'; import { onLoad, onShow, onHide } from '@dcloudio/uni-app';
import { getAssetDetailApi, getMintOrderDetailApi, likeAssetApi, unlikeAssetApi, getAssetMaterialsApi } from '@/utils/api.js'; import { getAssetDetailApi, getMintOrderDetailApi, likeAssetApi, unlikeAssetApi, getAssetMaterialsApi, getAssetLikersApi } from '@/utils/api.js';
import { getAssetCoverRealUrl } from '@/utils/assetImageHelper.js'; import { getAssetCoverRealUrl } from '@/utils/assetImageHelper.js';
import LikeUsersModal from '@/pages/components/LikeUsersModal.vue'; import LikeUsersModal from '@/pages/components/LikeUsersModal.vue';
import ShareReportButtons from '@/pages/components/ShareReportButtons.vue'; import ShareReportButtons from '@/pages/components/ShareReportButtons.vue';
@ -317,15 +316,53 @@ const loadCurrentUser = () => {
}; };
// 6 // 6
// avatar: , ellipseX: X, ellipseY: Y, size: // API
const likedUsers = ref([ const ellipseConfig = [
{ avatar: '/static/sucai/image-01.png', ellipseX: -40, ellipseY: -40, size: 0.85 }, { ellipseX: -40, ellipseY: -40, size: 0.85 },
{ avatar: '/static/sucai/image-02.png', ellipseX: 40, ellipseY: -40, size: 0.85 }, { ellipseX: 40, ellipseY: -40, size: 0.85 },
{ avatar: '/static/sucai/image-03.png', ellipseX: -96, ellipseY: 0, size: 0.9 }, { ellipseX: -96, ellipseY: 0, size: 0.9 },
{ avatar: '/static/sucai/image-04.png', ellipseX: 120, ellipseY: -40, size: 0.9 }, { ellipseX: 120, ellipseY: -40, size: 0.9 },
{ avatar: '/static/sucai/image-05.png', ellipseX: 64, ellipseY: 32 }, { ellipseX: 64, ellipseY: 32, size: 1 },
{ avatar: '/static/sucai/image-06.png', ellipseX: -16, ellipseY: 32, size: 1.15 } { ellipseX: -16, ellipseY: 32, size: 1.15 }
]); ];
// API
const likedUsers = ref([]);
//
const loadLikedUsers = async (assetId) => {
try {
likedUsersLoading.value = true;
//
const res = await getAssetLikersApi(assetId, 20, 0);
if (res.code === 200 && res.data?.users) {
//
likedUsers.value = res.data?.users.slice(0, 6).map((user, index) => {
const config = ellipseConfig[index] || { ellipseX: 0, ellipseY: 0, size: 1 };
return {
avatar: user.avatar || '/static/sucai/default-avatar.png',
ellipseX: config.ellipseX,
ellipseY: config.ellipseY,
size: config.size
};
});
//
allLikedUsers.value = res.data?.users.map(user => ({
userId: user.user_id,
nickname: user.nickname || '匿名用户',
avatar: user.avatar || '/static/sucai/default-avatar.png',
liked_at: user.liked_at || 0
}));
}
} catch (e) {
console.error('加载点赞用户失败:', e);
// 使 v-if="likeCount > 0"
likedUsers.value = [];
allLikedUsers.value = [];
} finally {
likedUsersLoading.value = false;
}
};
// ---- ---- // ---- ----
const activeStickers = ref([]); const activeStickers = ref([]);
@ -383,27 +420,16 @@ const showShareModal = ref(false);
const shareCoverUrl = ref(''); const shareCoverUrl = ref('');
const shareQrcodeUrl = ref(''); const shareQrcodeUrl = ref('');
// / // API
const todayLikeUsers = ref([ const allLikedUsers = ref([]);
{ userId: '1', nickname: '用户A', avatar: '/static/sucai/image-01.png', time: '10分钟前' }, const likedUsersLoading = ref(false);
{ userId: '2', nickname: '用户B', avatar: '/static/sucai/image-02.png', time: '30分钟前' },
{ userId: '3', nickname: '用户C', avatar: '/static/sucai/image-03.png', time: '1小时前' },
]);
const historyLikeUsers = ref([
{ userId: '4', nickname: '用户D', avatar: '/static/sucai/image-04.png', time: '昨天' },
{ userId: '5', nickname: '用户E', avatar: '/static/sucai/image-05.png', time: '3天前' },
]);
const displayedLikeUsers = computed(() => {
return likeUsersActiveTab.value === 0 ? todayLikeUsers.value : historyLikeUsers.value;
});
const handleLikeUsersTabChange = ({ tabIndex }) => { const handleLikeUsersTabChange = ({ tabIndex }) => {
likeUsersActiveTab.value = tabIndex; likeUsersActiveTab.value = tabIndex;
}; };
// 访 // 访
const handleVisit = () => { const handleVisit = (user) => {
uni.navigateTo({ uni.navigateTo({
url: `/pages/profile/hisWorks?userId=${user.userId}&nickname=${encodeURIComponent(user.nickname)}` url: `/pages/profile/hisWorks?userId=${user.userId}&nickname=${encodeURIComponent(user.nickname)}`
}); });
@ -598,6 +624,8 @@ const loadData = async () => {
coverUrl.value = ''; // coverUrl.value = ''; //
}); });
console.log('loadData 执行成功'); console.log('loadData 执行成功');
//
loadLikedUsers(assetId);
} else { } else {
throw new Error(res.message || '获取藏品详情失败'); throw new Error(res.message || '获取藏品详情失败');
} }
@ -641,12 +669,11 @@ const handleLike = async () => {
}); });
} catch (err) { } catch (err) {
const errMsg = err?.message || ''; const errMsg = err?.message || '';
const errCode = err?.code || err?.data?.code || ''; const errData = err?.data?.message || '';
if (errMsg.includes('未在展示中')) { //
uni.showToast({ title: '未展览无法点赞', icon: 'none', duration: 2000 }); const showMsg = errData || errMsg || '点赞失败';
} else { uni.showToast({ title: showMsg, icon: 'none', duration: 2000 });
uni.showToast({ title: '今日已点赞', icon: 'none', duration: 2000 }); console.log('点赞错误:', err);
}
} finally { } finally {
liking.value = false; liking.value = false;
} }
@ -812,8 +839,8 @@ onUnmounted(() => {
} }
.back-icon { .back-icon {
width: 80rpx; width: 64rpx;
height: 80rpx; height: 64rpx;
} }
.header-actions { .header-actions {

View File

@ -31,7 +31,7 @@
</view> </view>
<!-- 胶囊按钮区域 --> <!-- 胶囊按钮区域 -->
<view class="tab-section"> <view v-if="tabs && tabs.length > 0" class="tab-section">
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" <view v-for="(tab, index) in tabs" :key="index" class="tab-item"
:class="{ 'active': activeTabIndex === index }" @tap="handleTabClick(index)"> :class="{ 'active': activeTabIndex === index }" @tap="handleTabClick(index)">
<text class="tab-text">{{ tab }}</text> <text class="tab-text">{{ tab }}</text>
@ -60,7 +60,7 @@ const props = defineProps({
}, },
tabs: { tabs: {
type: Array, type: Array,
default: () => ['今日', '历史'] default: () => []
} }
}); });
@ -209,8 +209,8 @@ defineExpose({
} }
.back-icon { .back-icon {
width: 56rpx; width: 40rpx;
height: 56rpx; height: 40rpx;
} }
.close-icon { .close-icon {

View File

@ -439,7 +439,6 @@ const handleExhibitionCardTap = (item, index) => {
// //
await loadExhibitedAssets(); await loadExhibitedAssets();
await loadLikedAssets(); await loadLikedAssets();
// } // }
uni.showToast({ title: '点赞成功', icon: 'success' }); uni.showToast({ title: '点赞成功', icon: 'success' });

View File

@ -380,6 +380,14 @@ export function unlikeAssetApi(assetId) {
}) })
} }
// 获取资产点赞用户列表
export function getAssetLikersApi(assetId, pageSize = 6, cursor = 0) {
return request({
url: `/api/v1/social/assets/${assetId}/likers?page_size=${pageSize}&cursor=${cursor}`,
method: 'GET'
})
}
// 获取我的展馆槽位信息 // 获取我的展馆槽位信息
export function getMyGalleriesApi() { export function getMyGalleriesApi() {
return request({ return request({

View File

@ -44,17 +44,14 @@ export function doubleTapLike(assetId, exhibitionId, callback) {
const key = getStorageKey(assetId, actualExhibitionId); const key = getStorageKey(assetId, actualExhibitionId);
try { // 不再做本地缓存检查,统一由后端判断唯一性
const storage = uni.getStorageSync(LIKE_STORAGE_KEY) || {}; // 这样可以避免:用户清缓存后、后端已重置、但本地存储还有旧数据 导致的问题
if (storage[key]) { // if (storage[key]) {
const msg = actualExhibitionId ? '本次展示已点赞' : '今日已点赞'; // const msg = actualExhibitionId ? '本次展示已点赞' : '今日已点赞';
uni.showToast({ title: msg, icon: 'none' }); // uni.showToast({ title: msg, icon: 'none' });
if (actualCallback) actualCallback(false); // if (actualCallback) actualCallback(false);
return; // return;
} // }
} catch (e) {
console.error('读取点赞记录失败:', e);
}
likeAssetApi(assetId).then(res => { likeAssetApi(assetId).then(res => {
console.log('点赞成功', res); console.log('点赞成功', res);
@ -75,7 +72,10 @@ export function doubleTapLike(assetId, exhibitionId, callback) {
if (actualCallback) actualCallback(true, res.data); if (actualCallback) actualCallback(true, res.data);
}).catch(err => { }).catch(err => {
console.error('点赞失败:', err); console.error('点赞失败:', err);
uni.showToast({ title: '点赞失败', icon: 'none' }); const errMsg = err?.message || '';
const errData = err?.data?.message || '';
const showMsg = errData || errMsg || '点赞失败';
uni.showToast({ title: showMsg, icon: 'none' });
if (actualCallback) actualCallback(false); if (actualCallback) actualCallback(false);
}); });
} }