package data import ( "context" "git.gz.internal.jumaiyx.cn/job/room-mike-hot-timer/internal/biz" "git.gz.internal.jumaiyx.cn/job/room-mike-hot-timer/internal/data/model" "git.gz.internal.jumaiyx.cn/job/room-mike-hot-timer/internal/util" "git.gz.internal.jumaiyx.cn/pkg/log" "github.com/pkg/errors" "gorm.io/gorm" "k8s.io/apimachinery/pkg/util/json" "strings" "time" ) type roomMikeRepo struct { data *Data log log.Logger tx *model.Tx // 事务使用 } func NewRoomMikeRepo(data *Data, logger log.Logger) biz.RoomMikeRepo { return &roomMikeRepo{ data: data, log: logger, tx: model.NewTx(data.db), } } func (r *roomMikeRepo) Begin(ctx context.Context, tx *model.Tx) *model.Tx { if tx == nil { return r.tx.Begin(ctx) } return r.tx.SetTx(tx) } func (r *roomMikeRepo) query(ctx context.Context, cond *biz.RoomMikeCond) *gorm.DB { db := r.tx.Db(ctx).Model(&model.RoomMike{}).Debug() if cond.Id != 0 { db = db.Where("id=?", cond.Id) } if cond.RoomId != 0 { db = db.Where("room_id=?", cond.RoomId) } if cond.Uid != 0 { db = db.Where("uid=?", cond.Uid) } if cond.MikeNo != "" { db = db.Where("mike_no=?", cond.MikeNo) } if cond.Status != 0 { db = db.Where("status=?", cond.Status) } if cond.OpenStatus != 0 { db = db.Where("open_status=?", cond.OpenStatus) } if len(cond.States) > 0 { //gorm.DB{}.Where("id=?", 1) wdb := r.data.db for _, state := range cond.States { wdb = wdb.Or("status=?", state) //db = db.Where("status = ?", state) } db = db.Where(wdb) } if cond.Offset != 0 { db = db.Offset(cond.Offset) } if cond.Limit != 0 { db = db.Limit(cond.Limit) } if cond.OrderBy != nil { db = db.Order(strings.Join(cond.OrderBy, ",")) } return db } func (r *roomMikeRepo) Exist(ctx context.Context, cond *biz.RoomMikeCond) (bool, error) { var count int64 if err := r.query(ctx, cond).Count(&count).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { r.log.Errorf("get mike count err%v", err) return false, err } if count == 0 { return false, nil } return true, nil } func (r *roomMikeRepo) First(ctx context.Context, cond *biz.RoomMikeCond) (*model.RoomMike, error) { mike := &model.RoomMike{} if err := r.query(ctx, cond).First(&mike).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { r.log.Errorf("get mike list err%v", err) return nil, err } return mike, nil } func (r *roomMikeRepo) List(ctx context.Context, cond *biz.RoomMikeCond) ([]*model.RoomMike, error) { var mikes []*model.RoomMike if err := r.query(ctx, cond).Find(&mikes).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { r.log.Errorf("get mike list err%v", err) return nil, err } return mikes, nil } func (r *roomMikeRepo) Create(ctx context.Context, mike *model.RoomMike) error { db := r.tx.Db(ctx) if err := db.Model(&model.RoomMike{}).Create(mike).Error; err != nil { r.log.Errorf("create mike err:%v", err) return err } return nil } func (r *roomMikeRepo) Update(ctx context.Context, cond *biz.RoomMikeCond, data map[string]interface{}) error { if err := r.query(ctx, cond).Updates(data).Error; err != nil { r.log.Errorf("update mike err:%v", err) return err } return nil } func (r *roomMikeRepo) UpdateStatus(ctx context.Context, id uint, status int32) error { if err := r.data.db.Debug().Model(&model.RoomMike{}).Where("id=?", id).Update("status", status).Error; err != nil { r.log.Errorf("Update mike status err:%v", err) return err } return nil } func (r *roomMikeRepo) UpdateOpenStatus(ctx context.Context, id uint, status int32) error { if err := r.data.db.Debug().Model(&model.RoomMike{}).Where("id=?", id).Update("open_status", status).Error; err != nil { r.log.Errorf("Update mike status err:%v", err) return err } return nil } func (r *roomMikeRepo) Delete(ctx context.Context, cond *biz.RoomMikeCond) error { db := r.query(ctx, cond) if err := db.Delete(&model.RoomMike{}).Error; err != nil { r.log.Errorf("delete mike err:%v", err) return err } return nil } func (r *roomMikeRepo) SetMikeHotLock(ctx context.Context, roomId, uid int64) bool { b, err := r.data.cache.SetNX(ctx, model.MikeHotLockRedisKey(roomId, uid), 1, time.Second*100) if err != nil { r.log.Errorf("Set mike hot lock err:%v", err) } return b } func (r *roomMikeRepo) CreateMikeHot(ctx context.Context, mikeHot *model.MikeUpHot, lockCheck bool) error { key := model.MikeUpHotListKey mikeHot.Timer = time.Now().Unix() hot, err := json.Marshal(mikeHot) if err != nil { r.log.Errorf("Create mike hot json marshal err:%v", err) return err } err = r.data.cache.LPush(ctx, key, string(hot)) if err != nil { r.log.Errorf("Create mike hot err:%v", err) return err } r.SetMikeHotLock(ctx, mikeHot.RoomId, mikeHot.Uid) if lockCheck { h, err := r.data.cache.HGet(ctx, model.MikeUpHotHashRedisKey(mikeHot.RoomId), util.Int64TarnsString(mikeHot.MikeId)) if err != nil { r.log.Errorf("Get mike hot err:%v", err) return err } if h == "" { r.log.Error("Mike hot lock") return model.ErrMikeHotLockOvertime } } err = r.data.cache.HSet(ctx, model.MikeUpHotHashRedisKey(mikeHot.RoomId), mikeHot.MikeId, hot) if err != nil { r.log.Errorf("Create mike hot table err:%v", err) return err } defer func() { r.data.cache.Del(ctx, model.MikeHotLockRedisKey(mikeHot.RoomId, mikeHot.Uid)) }() return nil } func (r *roomMikeRepo) PushMikeHot(ctx context.Context, mikeHot *model.MikeUpHot) error { key := model.MikeUpHotListKey mikeHot.Timer = time.Now().Unix() hot, err := json.Marshal(mikeHot) if err != nil { r.log.Errorf("Create mike hot json marshal err:%v", err) return err } err = r.data.cache.LPush(ctx, key, string(hot)) if err != nil { r.log.Errorf("Create mike hot err:%v", err) return err } return nil } func (r *roomMikeRepo) DeleteMikeHot(ctx context.Context, roomId, mikeId int64) error { if mikeId == 0 { err := r.data.cache.Del(ctx, model.MikeUpHotHashRedisKey(roomId)) if err != nil { r.log.Errorf("Delete mike hot table err:%v", err) return err } } else { err := r.data.cache.HDel(ctx, model.MikeUpHotHashRedisKey(roomId), util.Int64TarnsString(mikeId)) if err != nil { r.log.Errorf("Delete mike hot table err:%v", err) return err } } return nil } func (r *roomMikeRepo) GetMikeHotPop(ctx context.Context) (*model.MikeUpHot, error) { lLen, err := r.data.cache.LLen(ctx, model.MikeUpHotListKey) if err != nil { r.log.Errorf("Get mike hot len err:%v", err) return nil, err } if lLen == 0 { return &model.MikeUpHot{}, nil } hot, err := r.data.cache.RPop(ctx, model.MikeUpHotListKey) if err != nil { r.log.Errorf("Get mike hot pop err:%v", err) return nil, err } var mikeHot *model.MikeUpHot err = json.Unmarshal([]byte(hot), &mikeHot) if err != nil { r.log.Errorf("Get mike hot pop json unmarshal err:%v", err) err = r.data.cache.LPush(ctx, model.MikeUpHotListKey, hot) if err != nil { r.log.Errorf("Get mike hot lpush err:%v", err) } return nil, err } return mikeHot, nil } func (r *roomMikeRepo) GetMikeHot(ctx context.Context, roomId, mikeId int64) (*model.MikeUpHot, bool, error) { exists, err := r.data.cache.HExists(ctx, model.MikeUpHotHashRedisKey(roomId), util.Int64TarnsString(mikeId)) if err != nil { r.log.Errorf("Get mike hot exists err:%v", err) return nil, false, err } if !exists { return nil, false, nil } hot, err := r.data.cache.HGet(ctx, model.MikeUpHotHashRedisKey(roomId), util.Int64TarnsString(mikeId)) if err != nil { r.log.Errorf("Get mike hot err:%v", err) return nil, false, err } var miekHot *model.MikeUpHot err = json.Unmarshal([]byte(hot), &miekHot) if err != nil { r.log.Errorf("Get mike hot json unmarshal err:%v", err) return nil, false, err } return miekHot, true, nil } func (r *roomMikeRepo) GetRoomMikeHot(ctx context.Context, roomId int64) ([]*model.MikeUpHot, error) { hots, err := r.data.cache.HGetAll(ctx, model.MikeUpHotHashRedisKey(roomId)) if err != nil { r.log.Errorf("Get room mike hot err:%v", err) return nil, err } var mikeHots []*model.MikeUpHot for _, hot := range hots { var mikeHot *model.MikeUpHot err = json.Unmarshal([]byte(hot), &mikeHot) if err != nil { r.log.Errorf("Get room mike hot json unmarshal err:%v", err) return nil, err } mikeHots = append(mikeHots, mikeHot) } return mikeHots, nil }