go-common/app/interface/main/credit/service/labour.go
2019-04-22 18:49:16 +08:00

232 lines
5.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}