go-common/app/interface/main/credit/service/labour.go

232 lines
5.9 KiB
Go
Raw Normal View History

2019-04-22 10:49:16 +00:00
package service
import (
"context"
"encoding/json"
"time"
model "go-common/app/interface/main/credit/model"
"go-common/app/service/main/archive/api"
arcMDL "go-common/app/service/main/archive/model/archive"
blkmdl "go-common/app/service/main/member/model/block"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
xtime "go-common/library/time"
"go-common/library/xstr"
)
// AddQs add labour question.
func (s *Service) AddQs(c context.Context, qs *model.LabourQs) (err error) {
return s.dao.AddQs(c, qs)
}
// SetQs set labour question field.
func (s *Service) SetQs(c context.Context, id int64, ans int64, status int64) (err error) {
return s.dao.SetQs(c, id, ans, status)
}
// DelQs del labour question.
func (s *Service) DelQs(c context.Context, id int64, isDel int64) (err error) {
return s.dao.DelQs(c, id, isDel)
}
// GetQs get question.
func (s *Service) GetQs(c context.Context, mid int64) (qs []*model.LabourQs, err error) {
var (
ok bool
arc *api.Arc
getids, qsids, avids []int64
marc map[int64]*api.Arc
block *blkmdl.RPCResInfo
)
defer func() {
if err == nil {
if len(avids) != 0 {
marc, _ = s.arcRPC.Archives3(c, &arcMDL.ArgAids2{Aids: avids, RealIP: metadata.String(c, metadata.RemoteIP)})
}
for _, q := range qs {
qsids = append(qsids, q.ID)
if arc, ok = marc[q.AvID]; !ok {
log.Warn("aid(%d) is not extists, [mid(%d)-qid(%d)]", q.AvID, mid, q.ID)
q.AvID = 0
continue
}
q.AvTitle = arc.Title
if !model.ArcVisible(arc.State) {
log.Warn("aid(%d) atitle(%s) state(%d) is not visible, [mid(%d)-qid(%d)]", q.AvID, q.AvTitle, arc.State, mid, q.ID)
q.AvID = 0
}
}
qsCache := &model.QsCache{
Stime: xtime.Time(time.Now().Unix()),
QsStr: xstr.JoinInts(qsids),
}
s.dao.SetQsCache(c, mid, qsCache)
}
}()
if block, err = s.memRPC.BlockInfo(c, &blkmdl.RPCArgInfo{MID: mid}); err != nil {
return
}
status := int8(block.BlockStatus)
if status == model.BlockStatusNone {
err = ecode.CreditNoblock
return
}
if status == model.BlockStatusForever {
err = ecode.CreditForeverBlock
return
}
var qsIDs *model.AIQsID
qsIDs, err = s.dao.GetQS(c, mid)
if err != nil {
log.Error("s.dao.GetQS(%d,%s) error(%+v)", mid, metadata.String(c, metadata.RemoteIP), err)
err = nil
qs = s.question
avids = s.avIDs
return
}
getids = append(getids, qsIDs.Pend...)
getids = append(getids, qsIDs.Done...)
idStr := xstr.JoinInts(getids)
if _, qs, avids, err = s.dao.QsAllList(c, idStr); err != nil {
return
}
if len(qs) != s.c.Property.QsNum {
log.Warn("creditQsNumError(mid:%d,idstr:%s,qs:%+v),len:%d", mid, idStr, qs, len(qs))
qs = s.question
avids = s.avIDs
}
return
}
// CommitQs commit questions.
func (s *Service) CommitQs(c context.Context, mid int64, refer string, ua string, buvid string, ans *model.LabourAns) (commitRs *model.CommitRs, err error) {
var (
num int64
qs map[int64]*model.LabourQs
block *blkmdl.RPCResInfo
)
if block, err = s.memRPC.BlockInfo(c, &blkmdl.RPCArgInfo{MID: mid}); err != nil {
return
}
status := int8(block.BlockStatus)
if status == model.BlockStatusNone {
err = ecode.CreditNoblock
return
}
if status == model.BlockStatusForever {
err = ecode.CreditForeverBlock
return
}
if len(ans.ID) != s.c.Property.QsNum || len(ans.Answer) != s.c.Property.QsNum {
err = ecode.CreditAnsNumError
log.Error("CreditAnsNumError(mid:%d,id:%+vans:%+v)", mid, ans.ID, ans.Answer)
return
}
idStr := xstr.JoinInts(ans.ID)
qsCache, _ := s.dao.GetQsCache(c, mid)
if qsCache == nil || qsCache.QsStr != idStr {
err = ecode.RequestErr
return
}
if qs, _, _, err = s.dao.QsAllList(c, idStr); err != nil {
return
}
if len(qs) != s.c.Property.QsNum {
log.Error("CreditRightAnsNumError(mid:%d,qs:%+v)", mid, qs)
}
for id, qsid := range ans.ID {
if ans.Answer[id] != 1 && ans.Answer[id] != 2 {
err = ecode.RequestErr
log.Error("CreditAnsError(mid:%d,id:%+vans:%+v)", mid, ans.ID, ans.Answer)
return
}
if v, ok := qs[qsid]; ok {
if v.Ans == ans.Answer[id] {
num++
}
}
}
commitRs = &model.CommitRs{}
commitRs.Score = num * s.c.Property.PerScore
if commitRs.Score >= 100 {
commitRs.Score = 100
if status == model.BlockStatusNone {
commitRs.Day = 0
} else {
rts := time.Until(time.Unix(block.EndTime, 0))
commitRs.Day = int64(rts / (time.Hour * 24))
if int64(rts%(time.Hour*24)) > 0 {
commitRs.Day++
}
}
}
anstr, err := json.Marshal(ans)
if err != nil {
log.Error("json.Marshal() error(%v)", err)
return
}
id, err := s.dao.AddAnsLog(c, mid, commitRs.Score, string(anstr), qsCache.Stime)
if err != nil {
return
}
var msg model.DataBusResult
msg.Mid = mid
msg.Buvid = buvid
msg.IP = metadata.String(c, metadata.RemoteIP)
msg.Ua = ua
msg.Refer = refer
msg.Score = commitRs.Score
for idx, qsid := range ans.ID {
var rs = model.Rs{}
rs.ID = qsid
rs.Ans = ans.Answer[idx]
if v, ok := qs[qsid]; ok {
rs.Question = v.Question
rs.TrueAns = v.Ans
rs.AvID = v.AvID
rs.Status = v.Status
rs.Source = v.Source
rs.Ctime = v.Ctime
rs.Mtime = v.Mtime
}
msg.Rs = append(msg.Rs, rs)
}
if err = s.dao.PubLabour(c, id, msg); err != nil {
log.Error("s.dao.PubLabour(%d,%+v) error(%+v)", id, msg, err)
return
}
log.Info("PubLabour id(%d) msg(%+v)", id, msg)
s.dao.DelQsCache(c, mid)
return
}
// IsAnswered labour check user is answwered question between the time.
func (s *Service) IsAnswered(c context.Context, mid int64, mtime int64) (state int8, err error) {
var (
mc = true
found bool
)
if state, found, err = s.dao.GetAnswerStateCache(c, mid); err != nil {
err = nil
mc = false
}
if found {
return
}
var status bool
if status, err = s.dao.AnswerStatus(c, mid, time.Unix(mtime, 0)); err != nil {
return
}
if status {
state = model.LabourOkAnswer
}
if mc {
s.addCache(func() {
s.dao.SetAnswerStateCache(context.TODO(), mid, state)
})
}
return
}