131 lines
4.1 KiB
Go
131 lines
4.1 KiB
Go
package mysqldao
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.lzcwy.cn/zhengchiliu/zt-closet-backend/global"
|
|
"git.lzcwy.cn/zhengchiliu/zt-closet-backend/internal/mysqlmodel"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
// LikeDao 点赞数据访问
|
|
type LikeDao struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewLikeDao 创建点赞 DAO
|
|
func NewLikeDao() *LikeDao {
|
|
return &LikeDao{db: global.MysqlEngine}
|
|
}
|
|
|
|
// LikeCreate 创建点赞记录
|
|
func (d *LikeDao) LikeCreate(ctx context.Context, like *mysqlmodel.Like) error {
|
|
ctx, span := global.Tracer.Start(ctx, "mysqldao.LikeCreate")
|
|
defer span.End()
|
|
|
|
if err := d.db.WithContext(ctx).Create(like).Error; err != nil {
|
|
span.RecordError(err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// LikeUpsertOn 点赞幂等写入:唯一索引冲突时仅置 status=1,防并发重复插入。
|
|
func (d *LikeDao) LikeUpsertOn(ctx context.Context, like *mysqlmodel.Like) error {
|
|
ctx, span := global.Tracer.Start(ctx, "mysqldao.LikeUpsertOn")
|
|
defer span.End()
|
|
|
|
if err := d.db.WithContext(ctx).Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "like_type"}, {Name: "target_id"}, {Name: "user_id"}},
|
|
DoUpdates: clause.AssignmentColumns([]string{"status"}),
|
|
}).Create(like).Error; err != nil {
|
|
span.RecordError(err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// LikeUpdateStatus 更新点赞状态(1=已点赞 0=已取消)
|
|
func (d *LikeDao) LikeUpdateStatus(ctx context.Context, id int64, status int8) error {
|
|
ctx, span := global.Tracer.Start(ctx, "mysqldao.LikeUpdateStatus")
|
|
defer span.End()
|
|
|
|
if err := d.db.WithContext(ctx).Model(&mysqlmodel.Like{}).Where("id = ?", id).UpdateColumn("status", status).Error; err != nil {
|
|
span.RecordError(err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// LikeGetByTargetAndUser 查询用户在目标上的点赞记录
|
|
func (d *LikeDao) LikeGetByTargetAndUser(ctx context.Context, likeType int8, targetID, userID int64) (*mysqlmodel.Like, error) {
|
|
ctx, span := global.Tracer.Start(ctx, "mysqldao.LikeGetByTargetAndUser")
|
|
defer span.End()
|
|
|
|
var like mysqlmodel.Like
|
|
if err := d.db.WithContext(ctx).Where("like_type = ? AND target_id = ? AND user_id = ?", likeType, targetID, userID).First(&like).Error; err != nil {
|
|
span.RecordError(err)
|
|
return nil, err
|
|
}
|
|
return &like, nil
|
|
}
|
|
|
|
// LikeCountByTarget 统计目标点赞数(仅 status=1)
|
|
func (d *LikeDao) LikeCountByTarget(ctx context.Context, likeType int8, targetID int64) (int64, error) {
|
|
ctx, span := global.Tracer.Start(ctx, "mysqldao.LikeCountByTarget")
|
|
defer span.End()
|
|
|
|
var count int64
|
|
if err := d.db.WithContext(ctx).Model(&mysqlmodel.Like{}).
|
|
Where("like_type = ? AND target_id = ? AND status = ?", likeType, targetID, int8(1)).
|
|
Count(&count).Error; err != nil {
|
|
span.RecordError(err)
|
|
return 0, err
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
// LikeCountByTargets 批量统计多个目标的点赞数(仅 status=1),返回 targetID -> count;空入参短路。
|
|
func (d *LikeDao) LikeCountByTargets(ctx context.Context, likeType int8, targetIDs []int64) (map[int64]int64, error) {
|
|
ctx, span := global.Tracer.Start(ctx, "mysqldao.LikeCountByTargets")
|
|
defer span.End()
|
|
|
|
counts := make(map[int64]int64, len(targetIDs))
|
|
if len(targetIDs) == 0 {
|
|
return counts, nil
|
|
}
|
|
|
|
var rows []struct {
|
|
TargetID int64 `gorm:"column:target_id"`
|
|
Cnt int64 `gorm:"column:cnt"`
|
|
}
|
|
if err := d.db.WithContext(ctx).Model(&mysqlmodel.Like{}).
|
|
Select("target_id, COUNT(*) AS cnt").
|
|
Where("like_type = ? AND target_id IN ? AND status = ?", likeType, targetIDs, int8(1)).
|
|
Group("target_id").
|
|
Scan(&rows).Error; err != nil {
|
|
span.RecordError(err)
|
|
return nil, err
|
|
}
|
|
for _, r := range rows {
|
|
counts[r.TargetID] = r.Cnt
|
|
}
|
|
return counts, nil
|
|
}
|
|
|
|
// LikeListUserIDsByTarget 查询点赞用户ID列表(仅 status=1)
|
|
func (d *LikeDao) LikeListUserIDsByTarget(ctx context.Context, likeType int8, targetID int64) ([]int64, error) {
|
|
ctx, span := global.Tracer.Start(ctx, "mysqldao.LikeListUserIDsByTarget")
|
|
defer span.End()
|
|
|
|
var ids []int64
|
|
if err := d.db.WithContext(ctx).Model(&mysqlmodel.Like{}).
|
|
Where("like_type = ? AND target_id = ? AND status = ?", likeType, targetID, int8(1)).
|
|
Pluck("user_id", &ids).Error; err != nil {
|
|
span.RecordError(err)
|
|
return nil, err
|
|
}
|
|
return ids, nil
|
|
}
|