From c05927f89e1e753899ac16283f4d280d1c1f352f Mon Sep 17 00:00:00 2001 From: hujiebin Date: Fri, 26 May 2023 16:30:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=90=AC=E8=BF=90=E4=BA=86svip=E7=9A=84?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _const/enum/cp_e/{grade.go => level.go} | 50 ++--- cv/cp_cv/space.go | 54 ++--- domain/model/cp_m/grade.go | 255 ++++++++++++++++++++++++ domain/model/cp_m/repo.go | 10 + route/cp_r/space.go | 28 +-- 5 files changed, 333 insertions(+), 64 deletions(-) rename _const/enum/cp_e/{grade.go => level.go} (67%) create mode 100644 domain/model/cp_m/grade.go create mode 100644 domain/model/cp_m/repo.go diff --git a/_const/enum/cp_e/grade.go b/_const/enum/cp_e/level.go similarity index 67% rename from _const/enum/cp_e/grade.go rename to _const/enum/cp_e/level.go index 0d5b5a5..1730a9f 100644 --- a/_const/enum/cp_e/grade.go +++ b/_const/enum/cp_e/level.go @@ -2,28 +2,32 @@ package cp_e import "git.hilo.cn/hilo-common/resource/mysql" -type CpGrade int +const ( + EffectDays = 30 // 30天有效期 +) + +type CpLevel int const ( - CpGrade0 CpGrade = 0 // 无称号 - CpGrade1 CpGrade = 1 // 恋爱CP - CpGrade2 CpGrade = 2 // 甜蜜CP - CpGrade3 CpGrade = 3 // 忠诚CP - CpGrade4 CpGrade = 4 // 炽热CP - CpGrade5 CpGrade = 5 // 荣耀CP + CpLevel0 CpLevel = 0 // 无称号 + CpLevel1 CpLevel = 1 // 恋爱CP + CpLevel2 CpLevel = 2 // 甜蜜CP + CpLevel3 CpLevel = 3 // 忠诚CP + CpLevel4 CpLevel = 4 // 炽热CP + CpLevel5 CpLevel = 5 // 荣耀CP - CpGradeMax = CpGrade5 + CpLevelMax = CpLevel5 ) var ( - // cp等级 - CpGradeExp = map[CpGrade]mysql.Num{ - CpGrade0: 0, - CpGrade1: 200000, - CpGrade2: 800000, - CpGrade3: 1000000, - CpGrade4: 3000000, - CpGrade5: 10000000, + // cp等级积分 + CpLevelPoints = map[CpLevel]mysql.Num{ + CpLevel0: 0, + CpLevel1: 200000, + CpLevel2: 800000, + CpLevel3: 1000000, + CpLevel4: 3000000, + CpLevel5: 10000000, } // cp特权名称 // todo 翻译 CpPrivilegeNameMsgId = map[CpPrivilege]uint{ @@ -37,13 +41,13 @@ var ( CpPrivilegeMicEffect: 0, } // cp等级icon // todo ui - CpGradeIcon = map[CpGrade]string{ - CpGrade0: "icon0.png", - CpGrade1: "icon1.png", - CpGrade2: "icon2.png", - CpGrade3: "icon3.png", - CpGrade4: "icon4.png", - CpGrade5: "icon5.png", + CpLevelIcon = map[CpLevel]string{ + CpLevel0: "icon0.png", + CpLevel1: "icon1.png", + CpLevel2: "icon2.png", + CpLevel3: "icon3.png", + CpLevel4: "icon4.png", + CpLevel5: "icon5.png", } // cp特权icon // todo ui CpPrivilegeIcon = map[CpPrivilege]string{ diff --git a/cv/cp_cv/space.go b/cv/cp_cv/space.go index 2e3582b..a2a7ee8 100644 --- a/cv/cp_cv/space.go +++ b/cv/cp_cv/space.go @@ -19,17 +19,17 @@ type CvCpInfo struct { } // cp等级 -type CvCpGrade struct { - Grade cp_e.CpGrade `json:"grade"` // 等级 0:无称号 1:恋爱CP 2:甜蜜CP 3:忠诚CP 4:炽热CP 5:荣耀CP - Exp uint32 `json:"exp"` // 经验值 - NextExp uint32 `json:"nextExp,omitempty"` // 下个等级所需经验值 - RemainExp uint32 `json:"remainExp,omitempty"` // 还需要多少经验值到下一个级别 - ExpireAt string `json:"expireAt,omitempty"` // 有效期 +type CvCpLevel struct { + Level cp_e.CpLevel `json:"level"` // 等级 0:无称号 1:恋爱CP 2:甜蜜CP 3:忠诚CP 4:炽热CP 5:荣耀CP + Points uint32 `json:"points"` // CP值 + NextPoints uint32 `json:"nextPoints,omitempty"` // 下个等级所需CP值 + RemainPoints uint32 `json:"remainPoints,omitempty"` // 还需要多少CP值到下一个级别 + ExpireAt string `json:"expireAt,omitempty"` // 有效期 } // 资源等级 -type CvResGrade struct { - Grade cp_e.CpGrade `json:"grade"` // 等级 +type CvResLevel struct { + Level cp_e.CpLevel `json:"level"` // 等级 Icon string `json:"icon"` // 等级icon图 } @@ -44,36 +44,36 @@ type CvPrivilege struct { // cp空间页 type CvSpace struct { CpInfo CvCpInfo `json:"cpInfo"` // cp信息 - CpGrade CvCpGrade `json:"cpGrade"` // cp等级 - ResGradeList []CvResGrade `json:"resGradeList"` // 资源等级列表,无称号/恋爱CP/甜蜜CP/忠诚CP/炽热CP/荣耀CP + CpLevel CvCpLevel `json:"cpLevel"` // cp等级 + ResLevelList []CvResLevel `json:"resLevelList"` // 资源等级列表,无称号/恋爱CP/甜蜜CP/忠诚CP/炽热CP/荣耀CP PrivilegeList []CvPrivilege `json:"privilegeList"` // 等级特权 } -var CvResGradeList = []CvResGrade{ - {cp_e.CpGrade0, cp_e.CpGradeIcon[cp_e.CpGrade0]}, - {cp_e.CpGrade1, cp_e.CpGradeIcon[cp_e.CpGrade1]}, - {cp_e.CpGrade2, cp_e.CpGradeIcon[cp_e.CpGrade2]}, - {cp_e.CpGrade3, cp_e.CpGradeIcon[cp_e.CpGrade3]}, - {cp_e.CpGrade4, cp_e.CpGradeIcon[cp_e.CpGrade4]}, - {cp_e.CpGrade5, cp_e.CpGradeIcon[cp_e.CpGrade5]}, +var CvResLevelList = []CvResLevel{ + {cp_e.CpLevel0, cp_e.CpLevelIcon[cp_e.CpLevel0]}, + {cp_e.CpLevel1, cp_e.CpLevelIcon[cp_e.CpLevel1]}, + {cp_e.CpLevel2, cp_e.CpLevelIcon[cp_e.CpLevel2]}, + {cp_e.CpLevel3, cp_e.CpLevelIcon[cp_e.CpLevel3]}, + {cp_e.CpLevel4, cp_e.CpLevelIcon[cp_e.CpLevel4]}, + {cp_e.CpLevel5, cp_e.CpLevelIcon[cp_e.CpLevel5]}, } -var CpGradePrivilegeList = map[cp_e.CpGrade][]CvPrivilege{ - cp_e.CpGrade0: {}, - cp_e.CpGrade1: { +var CpLevelPrivilegeList = map[cp_e.CpLevel][]CvPrivilege{ + cp_e.CpLevel0: {}, + cp_e.CpLevel1: { {cp_e.CpPrivilegeSpace, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeSpace], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeSpace]}, {cp_e.CpPrivilegeBanner, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeBanner], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeBanner]}, {cp_e.CpPrivilegeMedal, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeMedal], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeMedal]}, {cp_e.CpPrivilegeCert, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeCert], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeCert]}, }, - cp_e.CpGrade2: { + cp_e.CpLevel2: { {cp_e.CpPrivilegeSpace, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeSpace], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeSpace]}, {cp_e.CpPrivilegeBanner, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeBanner], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeBanner]}, {cp_e.CpPrivilegeMedal, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeMedal], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeMedal]}, {cp_e.CpPrivilegeCert, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeCert], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeCert]}, {cp_e.CpPrivilegeRoomEffect, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeRoomEffect], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeRoomEffect]}, }, - cp_e.CpGrade3: { + cp_e.CpLevel3: { {cp_e.CpPrivilegeSpace, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeSpace], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeSpace]}, {cp_e.CpPrivilegeBanner, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeBanner], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeBanner]}, {cp_e.CpPrivilegeMedal, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeMedal], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeMedal]}, @@ -81,7 +81,7 @@ var CpGradePrivilegeList = map[cp_e.CpGrade][]CvPrivilege{ {cp_e.CpPrivilegeRoomEffect, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeRoomEffect], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeRoomEffect]}, {cp_e.CpPrivilegeHeadwear, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeHeadwear], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeHeadwear]}, }, - cp_e.CpGrade4: { + cp_e.CpLevel4: { {cp_e.CpPrivilegeSpace, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeSpace], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeSpace]}, {cp_e.CpPrivilegeBanner, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeBanner], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeBanner]}, {cp_e.CpPrivilegeMedal, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeMedal], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeMedal]}, @@ -90,7 +90,7 @@ var CpGradePrivilegeList = map[cp_e.CpGrade][]CvPrivilege{ {cp_e.CpPrivilegeHeadwear, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeHeadwear], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeHeadwear]}, {cp_e.CpPrivilegeActiveProfile, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeActiveProfile], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeActiveProfile]}, }, - cp_e.CpGrade5: { + cp_e.CpLevel5: { {cp_e.CpPrivilegeSpace, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeSpace], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeSpace]}, {cp_e.CpPrivilegeBanner, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeBanner], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeBanner]}, {cp_e.CpPrivilegeMedal, cp_e.CpPrivilegeNameMsgId[cp_e.CpPrivilegeMedal], "", cp_e.CpPrivilegeIcon[cp_e.CpPrivilegeMedal]}, @@ -102,9 +102,9 @@ var CpGradePrivilegeList = map[cp_e.CpGrade][]CvPrivilege{ }, } -func CopyCpGradePrivilegeList(grade cp_e.CpGrade, lang string) []CvPrivilege { - privileges := make([]CvPrivilege, len(CpGradePrivilegeList[grade])) - copy(privileges, CpGradePrivilegeList[grade]) +func CopyCpLevelPrivilegeList(Level cp_e.CpLevel, lang string) []CvPrivilege { + privileges := make([]CvPrivilege, len(CpLevelPrivilegeList[Level])) + copy(privileges, CpLevelPrivilegeList[Level]) for i, v := range privileges { privileges[i].Name = GetTranslate(v.NameMsgId, lang) } diff --git a/domain/model/cp_m/grade.go b/domain/model/cp_m/grade.go new file mode 100644 index 0000000..ca1a689 --- /dev/null +++ b/domain/model/cp_m/grade.go @@ -0,0 +1,255 @@ +package cp_m + +import ( + "fmt" + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-user/_const/enum/cp_e" + "hilo-user/myerr" + "time" +) + +// cp等级 +type CpLevel struct { + mysql.Entity + CpId mysql.ID + SmallUserId mysql.ID + LargeUserId mysql.ID + Points mysql.Num + Level cp_e.CpLevel + ExpireAt time.Time +} + +// cp等级积分明细 +type CpLevelDetail struct { + mysql.Entity + CpId mysql.ID + SmallUserId mysql.ID + LargeUserId mysql.ID + AddReduce mysql.AddReduce + Num mysql.Num + BefNum mysql.Num + AftNum mysql.Num + Remark string +} + +// 添加cp等级积分增减明细 +func AddCpLevelDetail(model *domain.Model, detail CpLevelDetail) error { + return model.DB().Create(&detail).Error +} + +// 增加cp等级积分 +// 送礼1钻石=1点数 +// condition +// 1.记录不存在,首充加points计算level增加90天有效期 +// 2.记录存在 +// 2.1 在有效期内,直接加points后判断新level,升级需要更新有效期 +// 2.2 不有效期内,算首充,重置points后判断新level,升级需要更新有效期 +func AddCpLevelPoints(model *domain.Model, userId mysql.ID, points mysql.Num) (err error) { + start := time.Now() + defer func() { + model.Log.Infof("AddCpLevelPoints cost:%v,err:%v", time.Now().Sub(start), err) + }() + cpId := mysql.ID(1) // todo get from weijian + small, large := mysql.ID(4552), mysql.ID(7642) // todo get from weijian + var cpLevel CpLevel + var cpLevelDetails []CpLevelDetail + if err := model.DB().Model(CpLevel{}).Where("cp_id = ?", cpId).First(&cpLevel).Error; err != nil { + if err != gorm.ErrRecordNotFound { + return myerr.WrapErr(err) + } + // 明细 + cpLevelDetails = append(cpLevelDetails, CpLevelDetail{ + CpId: cpId, + SmallUserId: small, + LargeUserId: large, + AddReduce: mysql.ADD, + Num: points, + BefNum: 0, + AftNum: points, + Remark: fmt.Sprintf("send %d gift diamonds", points), + }) + // 1.记录不存在,首充加points计算level增加90天有效期 + var level cp_e.CpLevel + for l := cp_e.CpLevelMax; l >= cp_e.CpLevel0; l-- { + if cp_e.CpLevelPoints[l] <= points { + level = l + break + } + } + if level > 0 { + points = points - cp_e.CpLevelPoints[level] // 减去用于已用于升级的积分 + // 明细 + cpLevelDetails = append(cpLevelDetails, CpLevelDetail{ + CpId: cpId, + SmallUserId: small, + LargeUserId: large, + AddReduce: mysql.REDUCE, + Num: cp_e.CpLevelPoints[level], + BefNum: cp_e.CpLevelPoints[level] + points, + AftNum: points, + Remark: fmt.Sprintf("Become LEVEL%d", level), + }) + } + cpLevel = CpLevel{ + CpId: cpId, + SmallUserId: small, + LargeUserId: large, + Points: points, + Level: level, + ExpireAt: time.Now().AddDate(0, 0, cp_e.EffectDays), + } + } else { + // 2.记录存在 + // 2.1 在有效期内,直接加points后判断新level,升级需要更新有效期 + if cpLevel.ExpireAt.After(time.Now()) { + cpLevel.Points += points + // 明细 + cpLevelDetails = append(cpLevelDetails, CpLevelDetail{ + CpId: cpId, + SmallUserId: small, + LargeUserId: large, + AddReduce: mysql.ADD, + Num: points, + BefNum: cpLevel.Points - points, + AftNum: cpLevel.Points, + Remark: fmt.Sprintf("send %d gift diamonds", points), + }) + oldLevel := cpLevel.Level + levelPoint := cp_e.CpLevelPoints[oldLevel] // 已经用于升级的积分 + for level := cp_e.CpLevelMax; level > oldLevel; level-- { + if cp_e.CpLevelPoints[level] <= cpLevel.Points+levelPoint { + cpLevel.Level = level + break + } + } + // 升级 + if oldLevel != cpLevel.Level { + // 减去已用于升级的积分 + cpLevel.Points = cpLevel.Points - (cp_e.CpLevelPoints[cpLevel.Level] - cp_e.CpLevelPoints[oldLevel]) + cpLevel.ExpireAt = time.Now().AddDate(0, 0, cp_e.EffectDays) + // 明细 + cpLevelDetails = append(cpLevelDetails, CpLevelDetail{ + CpId: cpId, + SmallUserId: small, + LargeUserId: large, + AddReduce: mysql.REDUCE, + Num: cp_e.CpLevelPoints[cpLevel.Level] - cp_e.CpLevelPoints[oldLevel], + BefNum: cpLevel.Points + cp_e.CpLevelPoints[cpLevel.Level] - cp_e.CpLevelPoints[oldLevel], + AftNum: cpLevel.Points, + Remark: fmt.Sprintf("Become LEVEL%d", cpLevel.Level), + }) + } + } else { + // 2.2 不有效期内,算首充,重置points后判断新level,更新有效期30天 + oldPoints := cpLevel.Points + cpLevel.Points = points + // 明细 + cpLevelDetails = append(cpLevelDetails, CpLevelDetail{ + CpId: cpId, + SmallUserId: small, + LargeUserId: large, + AddReduce: mysql.ADD, + Num: points, + BefNum: oldPoints, + AftNum: cpLevel.Points, + Remark: fmt.Sprintf("send %d gift diamonds", points), + }) + for level := cp_e.CpLevelMax; level >= cp_e.CpLevel0; level-- { + if cp_e.CpLevelPoints[level] <= cpLevel.Points { + cpLevel.Level = level + break + } + } + if cpLevel.Level > 0 { + cpLevel.Points -= cp_e.CpLevelPoints[cpLevel.Level] // 减去已用于升级的积分 + // 明细 + cpLevelDetails = append(cpLevelDetails, CpLevelDetail{ + CpId: cpId, + SmallUserId: small, + LargeUserId: large, + AddReduce: mysql.REDUCE, + Num: cp_e.CpLevelPoints[cpLevel.Level], + BefNum: cpLevel.Points + cp_e.CpLevelPoints[cpLevel.Level], + AftNum: cpLevel.Points, + Remark: fmt.Sprintf("Become SVIP%d", cpLevel.Level), + }) + } + cpLevel.ExpireAt = time.Now().AddDate(0, 0, cp_e.EffectDays) + } + } + // 顺序增加明细 + for _, detail := range cpLevelDetails { + if err := AddCpLevelDetail(model, detail); err != nil { + return myerr.WrapErr(err) + } + } + return cpLevel.Persistence(model) +} + +// 清理过期svip积分 +// 降级保级: 积分清零,svip去到大于0的等级,有效期90天 +// svip0:积分清零,有效期保持过期 +func ClearExpireUserSvipPoints(model *domain.Model) error { + var cpLevels []*CpLevel + // 过期 + (积分 or level) 大于0 + if err := model.DB().Model(CpLevel{}).Where("expire_at < ? AND (points > 0 or level > 0) ", time.Now()).Find(&cpLevels).Error; err != nil { + return myerr.WrapErr(err) + } + for _, cpLevel := range cpLevels { + var doubleCheck CpLevel + if err := model.DB().Model(CpLevel{}).Where("id = ?", cpLevel.ID).First(&doubleCheck).Error; err != nil { + model.Log.Errorf("double check fail:%v", err) + continue + } + if doubleCheck.ExpireAt.After(time.Now()) { + continue + } + oldPoints := cpLevel.Points + cpLevel.Level, cpLevel.Points = cp_e.CpLevel0, 0 // 清零 + var newLevel cp_e.CpLevel + // 0级不刷新30天有效期 + for level := cp_e.CpLevelMax; level > cp_e.CpLevel0; level-- { + if cp_e.CpLevelPoints[level] <= oldPoints { + newLevel = level + break + } + } + // 降级/保级刷新30天有效期 + if newLevel > 0 { + cpLevel.Level = newLevel + cpLevel.ExpireAt = time.Now().AddDate(0, 0, cp_e.EffectDays) + // 明细 + if err := AddCpLevelDetail(model, CpLevelDetail{ + CpId: cpLevel.CpId, + SmallUserId: cpLevel.SmallUserId, + LargeUserId: cpLevel.LargeUserId, + AddReduce: mysql.REDUCE, + Num: cp_e.CpLevelPoints[newLevel], + BefNum: oldPoints, + AftNum: 0, + Remark: fmt.Sprintf("Become LEVEL%d", newLevel), + }); err != nil { + model.Log.Errorf("AddCpLevelDetail fail:%v", err) + } + } + if err := cpLevel.Persistence(model); err != nil { + model.Log.Errorf("cpLevel persistence fail:%v", err) + } + // 明细 + if err := AddCpLevelDetail(model, CpLevelDetail{ + CpId: cpLevel.CpId, + SmallUserId: cpLevel.SmallUserId, + LargeUserId: cpLevel.LargeUserId, + AddReduce: mysql.SET, + Num: oldPoints - cp_e.CpLevelPoints[newLevel], + BefNum: oldPoints - cp_e.CpLevelPoints[newLevel], + AftNum: 0, + Remark: fmt.Sprintf("Expired clear"), + }); err != nil { + model.Log.Errorf("AddCpLevelDetail fail:%v", err) + } + } + return nil +} diff --git a/domain/model/cp_m/repo.go b/domain/model/cp_m/repo.go new file mode 100644 index 0000000..8a0f1be --- /dev/null +++ b/domain/model/cp_m/repo.go @@ -0,0 +1,10 @@ +package cp_m + +import ( + "git.hilo.cn/hilo-common/domain" + "hilo-user/domain/model" +) + +func (p *CpLevel) Persistence(m *domain.Model) error { + return model.Persistent(m.DB(), p) +} diff --git a/route/cp_r/space.go b/route/cp_r/space.go index d437a6c..bbc5e04 100644 --- a/route/cp_r/space.go +++ b/route/cp_r/space.go @@ -41,27 +41,27 @@ func CpSpace(c *gin.Context) (*mycontext.MyContext, error) { return myContext, err } expireAt := "" // todo - cpGrade := cp_e.CpGrade3 // todo get from db - nextExp := cp_e.CpGradeExp[cp_e.CpGradeMax] - remainExp := mysql.Num(0) - if cpGrade != cp_e.CpGradeMax { - nextExp = cp_e.CpGradeExp[cpGrade+1] - remainExp = nextExp - cp_e.CpGradeExp[cpGrade] // todo get from db + cpLevel := cp_e.CpLevel3 // todo get from db + nextPoints := cp_e.CpLevelPoints[cp_e.CpLevelMax] + remainPoints := mysql.Num(0) + if cpLevel != cp_e.CpLevelMax { + nextPoints = cp_e.CpLevelPoints[cpLevel+1] + remainPoints = nextPoints - cp_e.CpLevelPoints[cpLevel] // todo get from db } response := cp_cv.CvSpace{ CpInfo: cp_cv.CvCpInfo{ UserInfo: user_cv.UserToTiny(*userInfo), CpUserInfo: user_cv.UserToTiny(*cpUserInfo), }, - CpGrade: cp_cv.CvCpGrade{ - Grade: cpGrade, - Exp: cp_e.CpGradeExp[cpGrade], // todo get from db - NextExp: nextExp, - RemainExp: remainExp, - ExpireAt: expireAt, + CpLevel: cp_cv.CvCpLevel{ + Level: cpLevel, + Points: cp_e.CpLevelPoints[cpLevel], // todo get from db + NextPoints: nextPoints, + RemainPoints: remainPoints, + ExpireAt: expireAt, }, - ResGradeList: cp_cv.CvResGradeList, - PrivilegeList: cp_cv.CopyCpGradePrivilegeList(cpGrade, lang), + ResLevelList: cp_cv.CvResLevelList, + PrivilegeList: cp_cv.CopyCpLevelPrivilegeList(cpLevel, lang), } resp.ResponseOk(c, response) return myContext, nil -- 2.22.0