package model import ( "context" "encoding/json" "fmt" "strings" "time" "github.com/go-redis/redis/v8" "gorm.io/gorm" ) // PPostAction 冒泡/文章动作 type PostAction struct { *Model PostId int64 `json:"post_id" gorm:"post_id"` // POST ID UserId int64 `json:"user_id" gorm:"user_id"` // 用户ID ActionType int8 `json:"action_type" gorm:"action_type"` // 对帖子的动作0-点赞1-收藏2-分享 } // TableName 表名称 func (*PostAction) TableName() string { return "p_post_action" } // MessageModel 消息模型 type PostActionModel struct { conn *gorm.DB redis *redis.Client } func NewPostActionModel(conn *gorm.DB, rConn *redis.Client) *PostActionModel { return &PostActionModel{ conn: conn, redis: rConn, } } func (p *PostActionModel) CreatePostAction(c context.Context, data *PostAction) error { return p.conn.WithContext(c).Create(data).Error } func (p *PostActionModel) DeletePostAction(c context.Context, data *PostAction) error { return p.conn.WithContext(c).Updates(data).Error } // CheckPostAction 检查用户是否对帖子执行过某个动作 func (p *PostActionModel) CheckPostAction(ctx context.Context, userId, postId int64, actionType int8) (bool, error) { var count int64 err := p.conn.WithContext(ctx).Model(&PostAction{}). Where("user_id = ? AND post_id = ? AND action_type = ? AND is_del = 0", userId, postId, actionType). Count(&count).Error if err != nil { return false, err } return count > 0, nil } const ( prefixUserCollectionKey = "user:collection:%d:%d:%d" // userId:page:pageSize ) // GetUserCollectionPosts 获取用户收藏的帖子列表(带缓存) func (p *PostActionModel) GetUserCollectionPosts(ctx context.Context, userId int64, page, pageSize int) ([]*Post, int64, error) { // 尝试从缓存获取 key := fmt.Sprintf(prefixUserCollectionKey, userId, page, pageSize) data, err := p.redis.Get(ctx, key).Bytes() if err == nil { var cacheData struct { Posts []*Post Total int64 } if err := json.Unmarshal(data, &cacheData); err == nil { return cacheData.Posts, cacheData.Total, nil } } // 从数据库获取 var posts []*Post var total int64 // 获取收藏总数 err = p.conn.Model(&PostAction{}). Where("user_id = ? AND action_type = ? AND is_del = 0", userId, 1). // 1表示收藏动作 Count(&total).Error if err != nil { return nil, 0, err } // 获取收藏的帖子列表 offset := (page - 1) * pageSize err = p.conn.Table("p_post_action pa"). Select("p.*"). Joins("LEFT JOIN p_post p ON p.id = pa.post_id"). Where("pa.user_id = ? AND pa.action_type = ? AND pa.is_del = 0 AND p.is_del = 0", userId, 1). Order("pa.created_on DESC"). Offset(offset). Limit(pageSize). Find(&posts).Error if err != nil { return nil, 0, err } // 写入缓存 cacheData := struct { Posts []*Post Total int64 }{ Posts: posts, Total: total, } if data, err := json.Marshal(cacheData); err == nil { p.redis.Set(ctx, key, data, 5*time.Minute) } return posts, total, nil } // ClearUserCollectionCache 清除用户收藏列表缓存 func (p *PostActionModel) ClearUserCollectionCache(ctx context.Context, userId int64) { pattern := fmt.Sprintf(prefixUserCollectionKey[:strings.LastIndex(prefixUserCollectionKey, ":")]+"*", userId) keys, err := p.redis.Keys(ctx, pattern).Result() if err != nil { return } if len(keys) > 0 { p.redis.Del(ctx, keys...) } }