Files
go-common/app/interface/main/growup/service/special_award.go
2019-04-22 18:49:16 +08:00

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
}