You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
4.8 KiB
Go

package containers
import (
"joybuywork/internal/consts"
"joybuywork/internal/consts/ckey"
"joybuywork/internal/repository/cache"
"joybuywork/internal/repository/dbcheck"
"joybuywork/internal/repository/finder"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/service/provider/cachecurd"
"joybuywork/internal/utils"
"joybuywork/internal/utils/logic"
pb "joybuywork/proto/go_proto/w_library"
"fmt"
"gorm.io/gen"
)
type LibraryQaRand struct {
logic.Logic
Req *pb.QaRandReq
Res *pb.QaRandRes
}
func (s *LibraryQaRand) Run() error {
return logic.Run(s)
}
func (s *LibraryQaRand) Exec() (err error) {
cpn, group, err := s.campaign()
if err != nil || group == nil {
return
}
return s.rand(cpn, group)
}
func (s *LibraryQaRand) campaign() (cpn *model.FissionCampaign, group *model.LibraryQaGroup, err error) {
cpn, err = finder.Campaign(s.Ctx, s.Req.GetCampaignId())
if err != nil {
err = s.BE().MysqlError(err)
return
}
if cpn == nil {
err = s.BE().VerifyError("not a qa campaign")
return
}
groupM := s.GetDao().LibraryQaGroup
group, err = groupM.WithContext(s.Ctx).Where(groupM.HashID.Eq(s.Req.GetGroupHashId()), groupM.DelTime.Eq(0)).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
return
}
func (s *LibraryQaRand) rand(cpn *model.FissionCampaign, group *model.LibraryQaGroup) (err error) {
m := s.GetDao().LibraryQa
var cond = []gen.Condition{
m.IsDel.Eq(mtype.No),
m.GroupID.Eq(group.ID),
}
switch cpn.FissionID {
case consts.IdQaAudio:
cond = append(cond, m.Mark.Eq(mtype.LibraryQaMarkAudio))
case consts.IdQaVideo:
cond = append(cond, m.Mark.Eq(mtype.LibraryQaMarkVideo))
}
list, err := m.WithContext(s.Ctx).Where(cond...).Find()
if err != nil {
return s.BE().MysqlError(err)
}
if len(list) == 0 {
return
}
s.Res.List = make([]*pb.QaRandRes_One, 0, len(list))
var qaMap = make(map[int64]*model.LibraryQa, len(list))
for _, v := range list {
qaMap[v.ID] = v
}
chooseIds, err := s._filter(cpn, qaMap)
if err != nil {
return
}
optionM := s.GetDao().LibraryQaOption
options, err := optionM.WithContext(s.Ctx).Where(optionM.QaID.In(chooseIds...), optionM.IsDel.Eq(mtype.No)).Find()
if err != nil {
err = s.BE().MysqlError(err)
return
}
var opMap = make(map[int64][]*model.LibraryQaOption)
for _, v := range options {
opMap[v.QaID] = append(opMap[v.QaID], v)
}
for _, id := range chooseIds {
v := qaMap[id]
one := &pb.QaRandRes_One{
Id: v.ID,
HashId: v.HashID,
Mark: v.Mark,
Title: v.Title,
CoverUrl: v.CoverURL,
LinkUrl: v.LinkURL,
ExplainText: v.ExplainText,
ExplainImg: v.ExplainImg,
Options: make([]*pb.QaRandRes_Option, 0, len(opMap[v.ID])),
CreatedAt: v.CreatedAt,
AnswerMark: v.AnswerMark,
}
for _, option := range opMap[v.ID] {
one.Options = append(one.Options, &pb.QaRandRes_Option{
Id: option.ID,
Title: option.Title,
ImgUrl: option.ImgURL,
IsRight: int32(option.IsRight),
})
}
s.Res.List = append(s.Res.List, one)
}
return
}
func (s *LibraryQaRand) _qaNum(cpn *model.FissionCampaign) (qaNum int32, err error) {
langMark := utils.NotExistGetFirst(s.Req.GetLangMark(), cpn.GetLangMarks())
if langMark == cpn.GetLangMarks()[0] {
qam := s.GetDao().FissionCampaignQa
var conf *model.FissionCampaignQa
conf, err = qam.WithContext(s.Ctx).Where(qam.CampaignID.Eq(cpn.ID)).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if conf == nil {
return
}
qaNum = conf.QaNum
return
}
lang, err := cache.NewCampaignLang(s.Ctx).FindByCampaignId(cpn.ID, langMark)
if err != nil {
err = s.BE().CacheError(err)
return
}
if lang == nil {
return
}
qaNum = lang.GetQaGroup().QaNum
return
}
func (s *LibraryQaRand) _filter(cpn *model.FissionCampaign, qaMap map[int64]*model.LibraryQa) (chooseIds []int64, err error) {
key := ckey.FissionUserQaSelect(s.Req.GetUserId())
choose, err := cachecurd.NewHMap(s.Ctx, key)
if err != nil {
return
}
selectMap, err := choose.Int64ToInt64()
if err != nil {
return
}
qaNum, err := s._qaNum(cpn)
if err != nil {
return
}
var maxNum int64
for _, num := range selectMap {
if maxNum < num {
maxNum = num
}
}
var idx int32
var selected = make(map[int64]struct{})
for id := range qaMap {
num, ok := selectMap[id]
if ok && num >= maxNum {
continue
}
chooseIds = append(chooseIds, id)
selected[id] = struct{}{}
idx++
if idx == qaNum {
break
}
}
if idx < qaNum {
for id := range qaMap {
if _, ok := selected[id]; ok {
continue
}
chooseIds = append(chooseIds, id)
idx++
if idx == qaNum {
break
}
}
}
for _, id := range chooseIds {
_, err = choose.Incr(fmt.Sprint(id), 1)
if err != nil {
return
}
}
return
}