382 lines
8.8 KiB
Go
382 lines
8.8 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
"time"
|
|
|
|
"go-common/app/interface/main/growup/model"
|
|
|
|
"go-common/library/ecode"
|
|
"go-common/library/log"
|
|
xtime "go-common/library/time"
|
|
)
|
|
|
|
const (
|
|
ceilings = 50000
|
|
rule = 1
|
|
detail = 3
|
|
question = 5
|
|
answer = 6
|
|
)
|
|
|
|
// GetAwardUpStatus get award up status
|
|
func (s *Service) GetAwardUpStatus(c context.Context, awardID, mid int64) (status *model.AwardUpStatus, err error) {
|
|
joined, err := s.isJoined(c, mid, awardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
fans, err := s.getUpFans(c, mid)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
status = &model.AwardUpStatus{
|
|
Joined: joined,
|
|
Qualified: checkQualification(fans),
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetWinningRecord get winning record
|
|
func (s *Service) GetWinningRecord(c context.Context, mid int64) (rs []*model.WinningRecord, err error) {
|
|
awardIDs, err := s.dao.GetAwardJoinRecord(c, mid)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if len(awardIDs) == 0 {
|
|
return
|
|
}
|
|
|
|
as := make([]int64, 0)
|
|
for awardID := range awardIDs {
|
|
as = append(as, awardID)
|
|
}
|
|
|
|
awards, err := s.dao.JoinedSpecialAwards(c, as)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
sort.Slice(awards, func(i, j int) bool {
|
|
return awards[i].CycleStart < awards[j].CycleStart
|
|
})
|
|
|
|
// am map[award_id]prize_id
|
|
am, err := s.dao.AwardIDsByWinner(c, mid)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
now := time.Now().Unix()
|
|
rs = make([]*model.WinningRecord, 0)
|
|
for _, award := range awards {
|
|
// in selection
|
|
if now > int64(award.CycleEnd) && award.OpenStatus == 1 {
|
|
rs = append(rs, &model.WinningRecord{
|
|
AwardID: award.AwardID,
|
|
AwardName: award.AwardName,
|
|
State: 2,
|
|
})
|
|
continue
|
|
}
|
|
// finished
|
|
if award.OpenStatus == 2 {
|
|
wr := &model.WinningRecord{
|
|
AwardID: award.AwardID,
|
|
AwardName: award.AwardName,
|
|
}
|
|
if prizeID, ok := am[award.AwardID]; ok {
|
|
wr.PrizeID = prizeID
|
|
wr.State = 1
|
|
}
|
|
rs = append(rs, wr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetWinningPoster get prize winning poster
|
|
func (s *Service) GetWinningPoster(c context.Context, mid int64, awardID, prizeID int64) (poster *model.Poster, err error) {
|
|
accs, err := s.dao.AccountInfos(c, []int64{mid})
|
|
if err != nil {
|
|
return
|
|
}
|
|
if len(accs) <= 0 {
|
|
return
|
|
}
|
|
|
|
award, err := s.dao.GetAwardSchedule(c, awardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// am map[award_id]division_name
|
|
names, err := s.dao.DivisionName(c, mid)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
bonus, err := s.dao.AwardBonus(c, awardID, prizeID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
poster = &model.Poster{
|
|
AwardName: award.AwardName,
|
|
Nickname: accs[mid].Nickname,
|
|
Face: accs[mid].Face,
|
|
PrizeName: fmt.Sprintf("最佳%s新秀奖", names[awardID]),
|
|
Date: award.CycleEnd.Time().Format("2006-01"),
|
|
Bonus: bonus,
|
|
}
|
|
return
|
|
}
|
|
|
|
// JoinAward sign up award
|
|
func (s *Service) JoinAward(c context.Context, mid int64, awardID int64) (err error) {
|
|
joined, err := s.isJoined(c, mid, awardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if joined {
|
|
err = ecode.GrowupSpecialAwardJoined
|
|
return
|
|
}
|
|
|
|
fans, err := s.getUpFans(c, mid)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if !checkQualification(fans) {
|
|
err = ecode.GrowupSpecialAwardUnqualified
|
|
return
|
|
}
|
|
_, err = s.dao.AddToAwardRecord(c, mid, awardID)
|
|
return
|
|
}
|
|
|
|
// if fans count >= ceilings, no qualification
|
|
func checkQualification(fans int64) bool {
|
|
return fans < ceilings
|
|
}
|
|
|
|
// if joined special award
|
|
func (s *Service) isJoined(c context.Context, mid, awardID int64) (joined bool, err error) {
|
|
count, err := s.dao.JoinedCount(c, mid, awardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
joined = count != 0
|
|
return
|
|
}
|
|
|
|
// AwardList award_id: award_name
|
|
func (s *Service) AwardList(c context.Context) (as []*model.SimpleSpecialAward, err error) {
|
|
as, err = s.dao.PastAwards(c)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
sort.Slice(as, func(i, j int) bool {
|
|
return as[i].CycleStart < as[j].CycleStart
|
|
})
|
|
return
|
|
}
|
|
|
|
// Winners get winners by award id
|
|
func (s *Service) Winners(c context.Context, awardID int64) (as []*model.Account, err error) {
|
|
mids, err := s.dao.GetWinners(c, awardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
infos, err := s.dao.AccountInfos(c, mids)
|
|
if err != nil {
|
|
return
|
|
}
|
|
for _, mid := range mids {
|
|
a := &model.Account{Mid: mid}
|
|
as = append(as, a)
|
|
if info, ok := infos[mid]; ok {
|
|
a.Name = info.Nickname
|
|
a.Face = info.Face
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// AwardDetail get award detail include schedule & resource
|
|
func (s *Service) AwardDetail(c context.Context, awardID int64) (data map[string]interface{}, err error) {
|
|
schedule, err := s.dao.GetAwardSchedule(c, awardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
// rs map[resource_type]map[index]content
|
|
rs, err := s.dao.GetResources(c, awardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
qas := make([]*model.QA, len(rs[question]))
|
|
for i := 0; i < len(rs[question]); i++ {
|
|
qas[i] = &model.QA{}
|
|
}
|
|
|
|
res := map[string]interface{}{
|
|
"qa": qas,
|
|
"rule": "",
|
|
"detail": "",
|
|
}
|
|
|
|
for rt, cs := range rs {
|
|
if rt == rule {
|
|
res["rule"] = cs[1]
|
|
}
|
|
if rt == detail {
|
|
res["detail"] = cs[1]
|
|
}
|
|
if rt == question || rt == answer {
|
|
for index, content := range cs {
|
|
if index < 0 || index > len(qas) {
|
|
continue
|
|
}
|
|
qa := qas[index-1]
|
|
if rt == question {
|
|
qa.Question = content
|
|
}
|
|
if rt == answer {
|
|
qa.Answer = content
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
data = map[string]interface{}{
|
|
"schedule": schedule,
|
|
"resource": res,
|
|
}
|
|
return
|
|
}
|
|
|
|
// SpecialAwardInfo special award info
|
|
func (s *Service) SpecialAwardInfo(c context.Context, mid int64) (data map[string]interface{}, err error) {
|
|
var (
|
|
nowTime = xtime.Time(time.Now().Unix())
|
|
winRecord []string
|
|
upStates []*model.UpAwardState
|
|
)
|
|
|
|
awards, nowAward, nextAward, err := s.getRecentSpecialAward(c, nowTime)
|
|
if err != nil {
|
|
log.Error("s.getRecentSpecialAward error(%v)", err)
|
|
return
|
|
}
|
|
|
|
if mid > 0 {
|
|
winRecord, err = s.getAwardWinRecord(c, mid, awards)
|
|
if err != nil {
|
|
log.Error("s.getAwardWinRecord error(%v)", err)
|
|
return
|
|
}
|
|
upStates, err = s.getUpAwardState(c, mid, awards)
|
|
if err != nil {
|
|
log.Error("s.getUpAwardState error(%v)", err)
|
|
return
|
|
}
|
|
}
|
|
data = map[string]interface{}{
|
|
"win_record": winRecord,
|
|
"now": nowAward,
|
|
"next": nextAward,
|
|
"up_states": upStates,
|
|
}
|
|
return
|
|
}
|
|
|
|
// get now and next special award
|
|
func (s *Service) getRecentSpecialAward(c context.Context, nowTime xtime.Time) (awards []*model.SpecialAward, nowAward, nextAward *model.SpecialAward, err error) {
|
|
awards, err = s.dao.GetSpecialAwards(c)
|
|
if err != nil {
|
|
log.Error("s.dao.GetSpecialAwards error(%v)", err)
|
|
return
|
|
}
|
|
sort.Slice(awards, func(i, j int) bool {
|
|
return awards[i].CycleStart < awards[j].CycleStart
|
|
})
|
|
for i := 0; i < len(awards); i++ {
|
|
if awards[i].CycleStart <= nowTime && awards[i].CycleEnd >= nowTime {
|
|
nowAward = awards[i]
|
|
} else if awards[i].CycleStart > nowTime {
|
|
nextAward = awards[i]
|
|
break
|
|
}
|
|
}
|
|
if nowAward != nil {
|
|
nowAward.Duration = int64(nowAward.CycleEnd - nowTime)
|
|
nowAward.Divisions, err = s.dao.GetSpecialAwardDivision(c, nowAward.AwardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
if nextAward != nil {
|
|
nextAward.Duration = int64(nextAward.CycleStart - nowTime)
|
|
nextAward.Divisions, err = s.dao.GetSpecialAwardDivision(c, nextAward.AwardID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) getAwardWinRecord(c context.Context, mid int64, awards []*model.SpecialAward) (awardNames []string, err error) {
|
|
awardIDs, err := s.dao.GetAwardWinRecord(c, mid)
|
|
if err != nil {
|
|
log.Error("s.dao.GetAwardWinRecord error(%v)", err)
|
|
return
|
|
}
|
|
awardNames = make([]string, 0)
|
|
for i := len(awards) - 1; i >= 0; i-- {
|
|
if awardIDs[awards[i].AwardID] {
|
|
awardNames = append(awardNames, awards[i].AwardName)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) getUpAwardState(c context.Context, mid int64, awards []*model.SpecialAward) (upStates []*model.UpAwardState, err error) {
|
|
upStates = make([]*model.UpAwardState, 0)
|
|
now := xtime.Time(time.Now().Unix())
|
|
awardIDs, err := s.dao.GetAwardJoinRecord(c, mid)
|
|
if err != nil {
|
|
log.Error("s.dao.GetAwardJoinRecord error(%v)", err)
|
|
return
|
|
}
|
|
winIDs, err := s.dao.GetAwardWinRecord(c, mid)
|
|
if err != nil {
|
|
log.Error("s.dao.GetAwardWinRecord error(%v)", err)
|
|
return
|
|
}
|
|
for i := 0; i < len(awards); i++ {
|
|
upState := &model.UpAwardState{AwardName: awards[i].AwardName}
|
|
date := awards[i].AnnounceDate.Time()
|
|
doubleCreativeStart := time.Date(date.Year(), date.Month()+1, 15, 0, 0, 0, 0, time.Local)
|
|
doubleCreativeEnd := doubleCreativeStart.AddDate(0, 0, 14)
|
|
if now > awards[i].CycleEnd && now <= awards[i].AnnounceDate && awardIDs[awards[i].AwardID] { // 评选中
|
|
upState.State = 1
|
|
} else if now > awards[i].AnnounceDate && now < xtime.Time(doubleCreativeStart.Unix()) && winIDs[awards[i].AwardID] { // 双倍即将开始
|
|
upState.State = 2
|
|
} else if now >= xtime.Time(doubleCreativeStart.Unix()) && now <= xtime.Time(doubleCreativeEnd.Unix()) && winIDs[awards[i].AwardID] { // 双倍中
|
|
upState.State = 3
|
|
}
|
|
if upState.State != 0 {
|
|
upStates = append(upStates, upState)
|
|
}
|
|
}
|
|
return
|
|
}
|