You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
5.9 KiB
231 lines
5.9 KiB
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:%+v,ans:%+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:%+v,ans:%+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 |
|
}
|
|
|