labour.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "time"
  6. model "go-common/app/interface/main/credit/model"
  7. "go-common/app/service/main/archive/api"
  8. arcMDL "go-common/app/service/main/archive/model/archive"
  9. blkmdl "go-common/app/service/main/member/model/block"
  10. "go-common/library/ecode"
  11. "go-common/library/log"
  12. "go-common/library/net/metadata"
  13. xtime "go-common/library/time"
  14. "go-common/library/xstr"
  15. )
  16. // AddQs add labour question.
  17. func (s *Service) AddQs(c context.Context, qs *model.LabourQs) (err error) {
  18. return s.dao.AddQs(c, qs)
  19. }
  20. // SetQs set labour question field.
  21. func (s *Service) SetQs(c context.Context, id int64, ans int64, status int64) (err error) {
  22. return s.dao.SetQs(c, id, ans, status)
  23. }
  24. // DelQs del labour question.
  25. func (s *Service) DelQs(c context.Context, id int64, isDel int64) (err error) {
  26. return s.dao.DelQs(c, id, isDel)
  27. }
  28. // GetQs get question.
  29. func (s *Service) GetQs(c context.Context, mid int64) (qs []*model.LabourQs, err error) {
  30. var (
  31. ok bool
  32. arc *api.Arc
  33. getids, qsids, avids []int64
  34. marc map[int64]*api.Arc
  35. block *blkmdl.RPCResInfo
  36. )
  37. defer func() {
  38. if err == nil {
  39. if len(avids) != 0 {
  40. marc, _ = s.arcRPC.Archives3(c, &arcMDL.ArgAids2{Aids: avids, RealIP: metadata.String(c, metadata.RemoteIP)})
  41. }
  42. for _, q := range qs {
  43. qsids = append(qsids, q.ID)
  44. if arc, ok = marc[q.AvID]; !ok {
  45. log.Warn("aid(%d) is not extists, [mid(%d)-qid(%d)]", q.AvID, mid, q.ID)
  46. q.AvID = 0
  47. continue
  48. }
  49. q.AvTitle = arc.Title
  50. if !model.ArcVisible(arc.State) {
  51. log.Warn("aid(%d) atitle(%s) state(%d) is not visible, [mid(%d)-qid(%d)]", q.AvID, q.AvTitle, arc.State, mid, q.ID)
  52. q.AvID = 0
  53. }
  54. }
  55. qsCache := &model.QsCache{
  56. Stime: xtime.Time(time.Now().Unix()),
  57. QsStr: xstr.JoinInts(qsids),
  58. }
  59. s.dao.SetQsCache(c, mid, qsCache)
  60. }
  61. }()
  62. if block, err = s.memRPC.BlockInfo(c, &blkmdl.RPCArgInfo{MID: mid}); err != nil {
  63. return
  64. }
  65. status := int8(block.BlockStatus)
  66. if status == model.BlockStatusNone {
  67. err = ecode.CreditNoblock
  68. return
  69. }
  70. if status == model.BlockStatusForever {
  71. err = ecode.CreditForeverBlock
  72. return
  73. }
  74. var qsIDs *model.AIQsID
  75. qsIDs, err = s.dao.GetQS(c, mid)
  76. if err != nil {
  77. log.Error("s.dao.GetQS(%d,%s) error(%+v)", mid, metadata.String(c, metadata.RemoteIP), err)
  78. err = nil
  79. qs = s.question
  80. avids = s.avIDs
  81. return
  82. }
  83. getids = append(getids, qsIDs.Pend...)
  84. getids = append(getids, qsIDs.Done...)
  85. idStr := xstr.JoinInts(getids)
  86. if _, qs, avids, err = s.dao.QsAllList(c, idStr); err != nil {
  87. return
  88. }
  89. if len(qs) != s.c.Property.QsNum {
  90. log.Warn("creditQsNumError(mid:%d,idstr:%s,qs:%+v),len:%d", mid, idStr, qs, len(qs))
  91. qs = s.question
  92. avids = s.avIDs
  93. }
  94. return
  95. }
  96. // CommitQs commit questions.
  97. func (s *Service) CommitQs(c context.Context, mid int64, refer string, ua string, buvid string, ans *model.LabourAns) (commitRs *model.CommitRs, err error) {
  98. var (
  99. num int64
  100. qs map[int64]*model.LabourQs
  101. block *blkmdl.RPCResInfo
  102. )
  103. if block, err = s.memRPC.BlockInfo(c, &blkmdl.RPCArgInfo{MID: mid}); err != nil {
  104. return
  105. }
  106. status := int8(block.BlockStatus)
  107. if status == model.BlockStatusNone {
  108. err = ecode.CreditNoblock
  109. return
  110. }
  111. if status == model.BlockStatusForever {
  112. err = ecode.CreditForeverBlock
  113. return
  114. }
  115. if len(ans.ID) != s.c.Property.QsNum || len(ans.Answer) != s.c.Property.QsNum {
  116. err = ecode.CreditAnsNumError
  117. log.Error("CreditAnsNumError(mid:%d,id:%+v,ans:%+v)", mid, ans.ID, ans.Answer)
  118. return
  119. }
  120. idStr := xstr.JoinInts(ans.ID)
  121. qsCache, _ := s.dao.GetQsCache(c, mid)
  122. if qsCache == nil || qsCache.QsStr != idStr {
  123. err = ecode.RequestErr
  124. return
  125. }
  126. if qs, _, _, err = s.dao.QsAllList(c, idStr); err != nil {
  127. return
  128. }
  129. if len(qs) != s.c.Property.QsNum {
  130. log.Error("CreditRightAnsNumError(mid:%d,qs:%+v)", mid, qs)
  131. }
  132. for id, qsid := range ans.ID {
  133. if ans.Answer[id] != 1 && ans.Answer[id] != 2 {
  134. err = ecode.RequestErr
  135. log.Error("CreditAnsError(mid:%d,id:%+v,ans:%+v)", mid, ans.ID, ans.Answer)
  136. return
  137. }
  138. if v, ok := qs[qsid]; ok {
  139. if v.Ans == ans.Answer[id] {
  140. num++
  141. }
  142. }
  143. }
  144. commitRs = &model.CommitRs{}
  145. commitRs.Score = num * s.c.Property.PerScore
  146. if commitRs.Score >= 100 {
  147. commitRs.Score = 100
  148. if status == model.BlockStatusNone {
  149. commitRs.Day = 0
  150. } else {
  151. rts := time.Until(time.Unix(block.EndTime, 0))
  152. commitRs.Day = int64(rts / (time.Hour * 24))
  153. if int64(rts%(time.Hour*24)) > 0 {
  154. commitRs.Day++
  155. }
  156. }
  157. }
  158. anstr, err := json.Marshal(ans)
  159. if err != nil {
  160. log.Error("json.Marshal() error(%v)", err)
  161. return
  162. }
  163. id, err := s.dao.AddAnsLog(c, mid, commitRs.Score, string(anstr), qsCache.Stime)
  164. if err != nil {
  165. return
  166. }
  167. var msg model.DataBusResult
  168. msg.Mid = mid
  169. msg.Buvid = buvid
  170. msg.IP = metadata.String(c, metadata.RemoteIP)
  171. msg.Ua = ua
  172. msg.Refer = refer
  173. msg.Score = commitRs.Score
  174. for idx, qsid := range ans.ID {
  175. var rs = model.Rs{}
  176. rs.ID = qsid
  177. rs.Ans = ans.Answer[idx]
  178. if v, ok := qs[qsid]; ok {
  179. rs.Question = v.Question
  180. rs.TrueAns = v.Ans
  181. rs.AvID = v.AvID
  182. rs.Status = v.Status
  183. rs.Source = v.Source
  184. rs.Ctime = v.Ctime
  185. rs.Mtime = v.Mtime
  186. }
  187. msg.Rs = append(msg.Rs, rs)
  188. }
  189. if err = s.dao.PubLabour(c, id, msg); err != nil {
  190. log.Error("s.dao.PubLabour(%d,%+v) error(%+v)", id, msg, err)
  191. return
  192. }
  193. log.Info("PubLabour id(%d) msg(%+v)", id, msg)
  194. s.dao.DelQsCache(c, mid)
  195. return
  196. }
  197. // IsAnswered labour check user is answwered question between the time.
  198. func (s *Service) IsAnswered(c context.Context, mid int64, mtime int64) (state int8, err error) {
  199. var (
  200. mc = true
  201. found bool
  202. )
  203. if state, found, err = s.dao.GetAnswerStateCache(c, mid); err != nil {
  204. err = nil
  205. mc = false
  206. }
  207. if found {
  208. return
  209. }
  210. var status bool
  211. if status, err = s.dao.AnswerStatus(c, mid, time.Unix(mtime, 0)); err != nil {
  212. return
  213. }
  214. if status {
  215. state = model.LabourOkAnswer
  216. }
  217. if mc {
  218. s.addCache(func() {
  219. s.dao.SetAnswerStateCache(context.TODO(), mid, state)
  220. })
  221. }
  222. return
  223. }