package user_m import ( "git.hilo.cn/hilo-common/domain" "git.hilo.cn/hilo-common/resource/mysql" "github.com/sirupsen/logrus" "gorm.io/gorm" "gorm.io/gorm/clause" "hilo-group/_const/enum/res_e" "hilo-group/domain/model/common" "hilo-group/domain/model/count_m" "hilo-group/domain/model/fruit_m" "hilo-group/domain/model/gift_m" "hilo-group/domain/model/luckybox_m" "hilo-group/domain/model/res_m" "hilo-group/domain/model/rocket_m" "hilo-group/myerr" "hilo-group/myerr/bizerr" "time" ) //用户道具 type UserMedal struct { mysql.Entity *domain.Model `gorm:"-"` UserId mysql.ID MedalId uint32 //MedalType res_m2.ResMedalType //Scope res_m2.ResMedalScope EndTime *time.Time } func GetUserMedalMerge(logger *logrus.Entry, db *gorm.DB, userId mysql.ID) ([]uint32, error) { // 缓存拿 res, _ := common.GetUserMedalMergeCache(userId) if res != nil { return res, nil } // 数据库加载 result, err := GetUserMedal(db, userId) if err != nil { return nil, err } logger.Infof("GetUserMedalMerge, user %d, %+v", userId, result) medalTypes, medalList, err := res_m.GetUserMedalLevelMap(db) if err != nil { return nil, err } //logger.Infof("GetUserMedalLevelMap, user %d, medalMap %+v", medalTypes) //logger.Infof("GetUserMedalLevelMap, user %d, medalList %+v", medalList) maxGrades := make(map[uint8]int, 0) maxMedalIds := make(map[uint8]uint32, 0) for _, m := range result { mt := medalTypes[uint64(m)] if mt > 0 { if r, ok := medalList[mt]; ok { for i, j := range r { if j == uint64(m) { if i+1 > maxGrades[mt] { maxGrades[mt] = i + 1 maxMedalIds[mt] = m logger.Infof("maxGrade of %d set to %d, due to %d", mt, i+1, m) } break } } } } } //logger.Infof("maxGrade %+v", maxGrades) //logger.Infof("maxMedalIds %+v", maxMedalIds) mIds := result result = make([]uint32, 0) for _, m := range mIds { mt := medalTypes[uint64(m)] if mt == 0 || maxMedalIds[mt] == m { result = append(result, m) } } // 写入缓存 common.SetUserMedalMergeCache(userId, result) return result, nil } func GetUserMedal(db *gorm.DB, userId mysql.ID) ([]uint32, error) { rows := make([]UserMedal, 0) if err := db.Model(&UserMedal{}).Where("user_id = ? AND (end_time >= NOW() or end_time is null)", userId).Find(&rows).Error; err != nil { return nil, err } result := make([]uint32, 0) for _, i := range rows { result = append(result, i.MedalId) } return result, nil } func BatchGetUserMedalMerge(logger *logrus.Entry, db *gorm.DB, userIds []mysql.ID) (map[uint64][]uint32, error) { result := make(map[uint64][]uint32, 0) for _, u := range userIds { a, err := GetUserMedalMerge(logger, db, u) if err != nil { return nil, err } result[u] = a } return result, nil } func BatchGetUserMedal(db *gorm.DB, userIds []mysql.ID) (map[uint64][]uint32, error) { rows := make([]UserMedal, 0) if err := db.Model(&UserMedal{}).Where("user_id IN ? and (end_time >= NOW() or end_time is null)", userIds).Find(&rows).Error; err != nil { return nil, err } result := make(map[uint64][]uint32, 0) for _, i := range rows { if _, ok := result[i.UserId]; !ok { result[i.UserId] = make([]uint32, 0) } result[i.UserId] = append(result[i.UserId], i.MedalId) } return result, nil } func (um *UserMedal) Create(db *gorm.DB, day int) error { err := db.Clauses(clause.OnConflict{ DoUpdates: clause.Assignments(map[string]interface{}{ "end_time": gorm.Expr("DATE_ADD(GREATEST(end_time,NOW()), INTERVAL ? DAY);", day)}), }).Create(um).Error // 删除勋章缓存, 延迟删除 common.DelUserMedalMergeCacheDelay(um.UserId) return err } func (um *UserMedal) Delete(db *gorm.DB) error { err := db.Where(um).Delete(&UserMedal{}).Error // 删除勋章缓存 common.DelUserMedalMergeCache(um.UserId) return err } func GetUserMedalThreshold(model *domain.Model, userId mysql.ID, resMedalId mysql.ID) (uint64, error) { resMedalObtain, err := res_m.ResMedalObtainGetByMedalId(model, resMedalId) if err != nil { return 0, err } if resMedalObtain == nil { return 0, myerr.NewSysErrorF("res_m.ResMedalObtainGetByMedalId nil resMedalId:%v", resMedalId) } if resMedalObtain.Type == res_e.WealthResMedalObtainType { wealthGrade, _, err := GetWealthGrade(model, userId) if err != nil { return 0, err } else { return uint64(wealthGrade), nil } } else if resMedalObtain.Type == res_e.CharmResMedalObtainType { charmGrade, _, err := GetCharmGrade(model, userId) if err != nil { return 0, err } else { return uint64(charmGrade), nil } } else if resMedalObtain.Type == res_e.GiftResMedalObtainType { sum, err := gift_m.SumSendGift(model, userId, resMedalObtain.ResGiftId) if err != nil { return 0, err } return uint64(sum), nil } else if resMedalObtain.Type == res_e.BoomRocketResMedalObtainType { s, err := rocket_m.GetUserTopCount(model.Db, userId) if err != nil { return 0, err } return uint64(s), nil } else if resMedalObtain.Type == res_e.ActityResMedalObtainType { wealthGrade, _, err := GetActityGrade(model, userId) if err != nil { return 0, err } else { return uint64(wealthGrade), nil } } else if resMedalObtain.Type == res_e.FruitKingResMedalObtainType { diamond, err := fruit_m.SumAwardAll(model.Db, userId) if err != nil { return 0, err } else { return uint64(diamond), nil } } else if resMedalObtain.Type == res_e.LuckyBoxKingResMedalObtainType { diamond, err := luckybox_m.GetSumLuckyboxDiamondV2(model, userId) if err != nil { return 0, err } else { return diamond, nil } } else if resMedalObtain.Type == res_e.VideoChatResMedalObtainType { videoSeconds, err := count_m.GetVideoChatTimeTotal(model, userId) if err != nil { return 0, err } else { return uint64(videoSeconds / 60), nil // min } } else { return 0, myerr.NewSysErrorF("GetUserMedalThreshold 类型错误 ResMedalType:%v", resMedalObtain.Type) } } //增加勋章 func (user *User) AddPublicMedal(resMedalId mysql.ID) (*UserMedal, error) { //判断是否已经拥有了该勋章 var n int64 if err := user.Db.Model(&UserMedal{}).Where(&UserMedal{ UserId: user.ID, MedalId: uint32(resMedalId), }).Count(&n).Error; err != nil { return nil, myerr.WrapErr(err) } if n > 0 { return nil, myerr.NewWaringErrorF("用户 userId:%v, 已经获取了勋章 resMedalId:%v", user.ID, resMedalId) } resMedal, err := res_m.GetResMedalById(user.Model, resMedalId) if err != nil { return nil, err } //检查是否符合要求 threshold, err := GetUserMedalThreshold(user.Model, user.ID, resMedalId) if err != nil { return nil, err } if threshold < uint64(resMedal.Threshold) { return nil, bizerr.UserMedalThresholdLimit } // return &UserMedal{ Model: user.Model, UserId: user.ID, MedalId: uint32(resMedalId), //MedalType: resMedal.Type, //Scope: resMedal.Scope, EndTime: nil, }, nil }