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

315 lines
8.3 KiB
Go

package academy
import (
"context"
"time"
"go-common/app/interface/main/creative/model/academy"
"go-common/app/interface/openplatform/article/model"
"go-common/app/service/main/archive/api"
"go-common/library/log"
"go-common/library/sync/errgroup"
xtime "go-common/library/time"
"github.com/davecgh/go-spew/spew"
)
// TagList get all tag.
func (s *Service) TagList(c context.Context) (res map[string][]*academy.Tag, err error) {
res = s.TagsCache
return
}
// AddFeedBack add feedback.
func (s *Service) AddFeedBack(c context.Context, category, course, suggest string, mid int64) (id int64, err error) {
fb := &academy.FeedBack{
Category: category,
Course: course,
Suggest: suggest,
CTime: xtime.Time(time.Now().Unix()),
MTime: xtime.Time(time.Now().Unix()),
}
if id, err = s.aca.AddFeedBack(c, fb, mid); err != nil {
log.Error("s.aca.AddFeedBack error(%v)", err)
}
return
}
// ArchivesWithES get all archive by es.
func (s *Service) ArchivesWithES(c context.Context, aca *academy.EsParam) (res *academy.ArchiveList, err error) {
var sear *academy.SearchResult
res = &academy.ArchiveList{
Items: []*academy.ArchiveMeta{},
Page: &academy.ArchivePage{},
}
aca.TidsMap = s.filterTIDs(aca.Tid)
if sear, err = s.aca.ArchivesWithES(c, aca); err != nil {
log.Error("s.aca.ArchivesWithES sear(%+v)|param(%+v)|error(%v)", sear, aca, err)
return
}
if sear == nil || len(sear.Result) == 0 {
log.Error("s.aca.ArchivesWithES has no data sear(%+v)|param(%+v)|error(%v)", sear, aca, err)
return
}
res.Page.Total = sear.Page.Total
res.Page.Pn = sear.Page.Num
res.Page.Ps = sear.Page.Size
var searRes []*academy.EsArc
if aca.Keyword != "" { //搜索关键词红点
searRes = make([]*academy.EsArc, 0, len(sear.Result)/2)
for i := 0; i < len(sear.Result)-1; i += 2 {
sear.Result[i].Title = sear.Result[i+1].Title
searRes = append(searRes, sear.Result[i])
}
} else {
searRes = sear.Result
}
oids := make([]int64, 0, len(sear.Result))
aidTIDsMap := make(map[int64][]int64)
busAIDsMap := make(map[int][]int64)
busAidMap := make(map[int64]int)
highTitleMap := make(map[int64][]string)
for _, v := range searRes {
busAIDsMap[v.Business] = append(busAIDsMap[v.Business], v.OID)
oids = append(oids, v.OID)
aidTIDsMap[v.OID] = v.TID
busAidMap[v.OID] = v.Business
if aca.Keyword != "" { //搜索关键词红点
highTitleMap[v.OID] = v.Title
}
}
var (
g, _ = errgroup.WithContext(c)
tagInfo map[int64]map[string][]*academy.Tag
arcs map[int64]*api.Arc
arts map[int64]*model.Meta
st map[int64]*api.Stat
)
g.Go(func() error { //获取各种查询对象信息
switch aca.Business {
case academy.BusinessForAll: //查询所有
if ids, ok := busAIDsMap[academy.BusinessForArchive]; ok { //稿件
g.Go(func() error {
arcs, err = s.arc.Archives(c, ids, aca.IP)
if err != nil {
log.Error("s.arc.Archives oids(%+v)|business(%d)|error(%v)", ids, aca.Business, err)
return err
}
st, err = s.arc.Stats(c, ids, aca.IP)
if err != nil {
log.Error("s.arc.Stats oids(%+v)|business(%d)|error(%v)", ids, aca.Business, err)
}
return err
})
}
if ids, ok := busAIDsMap[academy.BusinessForArticle]; ok { //文章
g.Go(func() error {
arts, err = s.art.ArticleMetas(context.Background(), ids, aca.IP)
if err != nil {
log.Error("s.arc.ArticleMetas oids(%+v)|business(%d)|error(%v)", ids, aca.Business, err)
}
return err
})
}
case academy.BusinessForArchive: //稿件
arcs, err = s.arc.Archives(context.Background(), oids, aca.IP)
if err != nil {
log.Error("s.arc.Archives oids(%+v)|business(%d)|error(%v)", oids, aca.Business, err)
return err
}
st, err = s.arc.Stats(c, oids, aca.IP)
if err != nil {
log.Error("s.arc.Stats oids(%+v)|business(%d)|error(%v)", oids, aca.Business, err)
}
return err
case academy.BusinessForArticle: //文章
arts, err = s.art.ArticleMetas(context.Background(), oids, aca.IP)
if err != nil {
log.Error("s.arc.ArticleMetas oids(%+v)|business(%d)|error(%v)", oids, aca.Business, err)
}
return err
}
return nil
})
g.Go(func() error {
tagInfo, err = s.bindTags(c, aidTIDsMap)
return err
})
if g.Wait() != nil {
log.Error("s.aca.ArchivesWithES g.Wait() error(%v)", err)
return
}
items := make([]*academy.ArchiveMeta, 0, len(oids))
for _, oid := range oids {
a := &academy.ArchiveMeta{
OID: oid,
}
if v, ok := tagInfo[oid]; ok {
a.Tags = v
}
bs, ok := busAidMap[oid]
if !ok {
log.Error("s.aca.ArchivesWithES oid(%d) get invalid business", oid)
return
}
a.Business = bs
switch a.Business {
case academy.BusinessForArchive: //稿件
a = bindArchiveInfo(oid, arcs, a)
if t, ok := st[oid]; ok {
a.ArcStat = t
} else {
a.ArcStat = &api.Stat{}
}
case academy.BusinessForArticle: //文章
a = bindArticleInfo(oid, arts, a)
}
if aca.Keyword != "" {
if ht, ok := highTitleMap[oid]; ok && len(ht) > 0 {
a.HighLightTitle = ht[0]
}
}
items = append(items, a)
}
res.Items = items
return
}
func bindArchiveInfo(oid int64, arcs map[int64]*api.Arc, a *academy.ArchiveMeta) (res *academy.ArchiveMeta) {
if v, ok := arcs[oid]; ok {
a.Title = v.Title
a.State = v.State
a.Type = v.TypeName
a.Cover = v.Pic
a.UName = v.Author.Name
a.Face = v.Author.Face
a.MID = v.Author.Mid
a.Duration = v.Duration
a.Rights = v.Rights
}
res = a
return
}
func bindArticleInfo(oid int64, arts map[int64]*model.Meta, a *academy.ArchiveMeta) (res *academy.ArchiveMeta) {
if v, ok := arts[oid]; ok && v != nil {
a.Title = v.Title
a.State = v.State
a.MID = v.Author.Mid
a.Comment = v.Summary
if v.Category != nil {
a.Type = v.Category.Name
}
if len(v.ImageURLs) > 0 {
a.Cover = v.ImageURLs[0]
}
if v.Author != nil {
a.UName = v.Author.Name
a.Face = v.Author.Face
}
if v.Stats != nil {
a.ArtStat = v.Stats
} else {
a.ArtStat = &model.Stats{}
}
}
res = a
return
}
func (s *Service) bindTags(c context.Context, tidsMap map[int64][]int64) (res map[int64]map[string][]*academy.Tag, err error) {
res = make(map[int64]map[string][]*academy.Tag)
for oid, tids := range tidsMap {
tgs := s.getTagsByTIDs(tids)
if len(tgs) == 0 {
continue
}
oidTag := make(map[string][]*academy.Tag)
ctgs := make(map[int64][]*academy.Tag)
for _, tg := range tgs {
k := academy.TagClassMap(int(tg.Type))
if tg.Type == academy.Classify { //获取多个分类标签
ctgs[tg.ParentID] = append(ctgs[tg.ParentID], tg)
} else {
oidTag[k] = append(oidTag[k], tg)
}
}
for pid, tgs := range ctgs {
if p, ok := s.TagMapCache[pid]; ok {
tp := *p
tp.Children = tgs
oidTag[academy.TagClassMap(academy.Classify)] = append(oidTag[academy.TagClassMap(academy.Classify)], &tp)
}
}
res[oid] = oidTag
}
return
}
func (s *Service) filterTIDs(tids []int64) (res map[int][]int64) {
if len(tids) == 0 {
return
}
log.Info("s.filterTIDs origin tids(%+v)", tids)
res = make(map[int][]int64)
ochs := make([]int64, 0) //原始提交的二级标签
ops := make([]int64, 0) //原始提交的一级标签
qchs := make([]int64, 0) //通过一级标签查询出来的二级标签
for _, id := range tids {
t, ok := s.parentChildMapCache[id]
if !ok || t == nil {
continue
}
if t.Type == academy.Classify {
if t.ParentID != 0 { //原始提交的二级标签
ochs = append(ochs, id)
} else if t.ParentID == 0 && len(t.Children) > 0 { //通过一级标签查询出来的二级标签
for _, v := range t.Children {
qchs = append(qchs, v.ID)
}
} else if t.ParentID == 0 && len(t.Children) == 0 {
ops = append(ops, id)
}
} else {
res[int(t.Type)] = append(res[int(t.Type)], id)
}
}
if len(ochs) > 0 { //如果分类标签中提交了原始的二级标签则认为按该二级标签进行筛选,如果可以查询到二级标签认为筛选全部二级,否则一级参与查询.
res[academy.Classify] = ochs
} else if len(qchs) > 0 {
res[academy.Classify] = qchs
} else if len(ops) > 0 {
res[academy.Classify] = ops
}
log.Info("s.filterTIDs res(%s)", spew.Sdump(res))
return
}
func (s *Service) getTagsByTIDs(tids []int64) (res []*academy.Tag) {
res = make([]*academy.Tag, 0)
if len(tids) == 0 {
return
}
for _, tid := range tids {
tag, ok := s.TagMapCache[tid]
if !ok || tag == nil {
continue
}
res = append(res, tag)
}
return
}