Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"act_test.go",
"like_test.go",
"match_test.go",
"missiongroup_test.go",
"service_test.go",
"subject_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/activity/conf:go_default_library",
"//app/interface/main/activity/model/like:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"act.go",
"bnj.go",
"like.go",
"match.go",
"missiongroup.go",
"service.go",
"subject.go",
],
importpath = "go-common/app/interface/main/activity/service/like",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/activity/conf:go_default_library",
"//app/interface/main/activity/dao/bnj:go_default_library",
"//app/interface/main/activity/dao/like:go_default_library",
"//app/interface/main/activity/model/bnj:go_default_library",
"//app/interface/main/activity/model/like:go_default_library",
"//app/interface/main/tag/model:go_default_library",
"//app/interface/main/tag/rpc/client:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/api/gorpc:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//app/service/main/coin/api/gorpc:go_default_library",
"//app/service/main/coin/model:go_default_library",
"//app/service/main/spy/model:go_default_library",
"//app/service/main/spy/rpc/client:go_default_library",
"//app/service/main/thumbup/model:go_default_library",
"//app/service/main/thumbup/rpc/client:go_default_library",
"//app/service/main/usersuit/model:go_default_library",
"//app/service/main/usersuit/rpc/client:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/sync/pipeline/fanout:go_default_library",
"//library/time:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,51 @@
package like
import (
"context"
"sync/atomic"
"time"
"go-common/app/interface/main/activity/model/like"
"go-common/library/log"
)
// RedDot get hot dot.
func (s *Service) RedDot(c context.Context, mid int64) (redDot *like.RedDot, err error) {
var lastTs int64
redDot = new(like.RedDot)
if mid <= 0 {
return
}
if lastTime, e := s.dao.CacheRedDotTs(c, mid); e != nil {
log.Error("s.dao.CacheRedDotTs mid(%d) error(%+v)", mid, e)
} else {
lastTs = lastTime
}
if s.newestSubTs > lastTs {
redDot.RedDot = true
}
return
}
// ClearRetDot clear red dot.
func (s *Service) ClearRetDot(c context.Context, mid int64) (err error) {
if err = s.dao.AddCacheRedDotTs(c, mid, time.Now().Unix()); err != nil {
log.Error("s.dao.AddCacheRedDotTs mid(%d) error(%+v)", mid, err)
}
return
}
func (s *Service) newestSubTsproc() {
for {
if like, err := s.dao.NewestSubject(context.Background(), like.VIDEOALL); err != nil || like == nil {
log.Error("actNewTsproc s.dao.NewestSubject error(%+v)", err)
time.Sleep(5 * time.Second)
} else {
newTs := like.Ctime.Time().Unix()
if newTs > s.newestSubTs {
atomic.StoreInt64(&s.newestSubTs, newTs)
}
}
time.Sleep(time.Duration(s.c.Interval.NewestSubTsInterval))
}
}

View File

@@ -0,0 +1,17 @@
package like
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_HotDot(t *testing.T) {
Convey("test hot dot", t, WithService(func(s *Service) {
mid := int64(908085)
data, err := s.RedDot(context.Background(), mid)
So(err, ShouldBeNil)
Println(data)
}))
}

View File

@@ -0,0 +1,71 @@
package like
import (
"context"
"strconv"
"go-common/app/interface/main/activity/model/bnj"
"go-common/app/interface/main/activity/model/like"
suitmdl "go-common/app/service/main/usersuit/model"
"go-common/library/ecode"
"go-common/library/log"
)
// Reward get bnj preview reward.
func (s *Service) Reward(c context.Context, mid int64, step int) (err error) {
reward, ok := s.reward[step]
if !ok {
err = ecode.RequestErr
return
}
var (
likeActs map[int64]int
likeScore map[int64]int64
check bool
)
actID := s.c.Bnj2019.ActID
subID := s.c.Bnj2019.SubID
if likeScore, err = s.dao.LikeActLidCounts(c, []int64{subID}); err != nil {
log.Error("Reward s.dao.LikeActLidCounts(subID:%d) error(%+v)", subID, err)
return
}
if score, ok := likeScore[subID]; !ok || score < reward.Condition {
err = ecode.ActivityBnjSubLow
return
}
if likeActs, err = s.dao.LikeActs(c, actID, mid, []int64{subID}); err != nil {
log.Error("Reward s.dao.LikeActs(subID:%d,actID:%d,mid:%d) error(%+v)", subID, actID, mid, err)
return
}
if isSub, ok := likeActs[subID]; !ok || isSub == 0 {
if _, err = s.LikeAct(c, &like.ParamAddLikeAct{Sid: actID, Lid: subID, Score: 1}, mid); err != nil {
return
}
}
// check has reward
if check, err = s.bnjDao.CacheHasReward(c, mid, subID, step); err != nil || !check {
log.Error("Reward s.dao.CacheHasReward(mid:%d,subID:%d,step:%d) error(%v) check(%v)", mid, subID, step, err, check)
err = ecode.ActivityBnjHasReward
return
}
switch reward.RewardType {
case bnj.RewardTypePendant:
rewardID, e := strconv.ParseInt(reward.RewardID, 10, 64)
if e != nil {
err = ecode.ActivityRewardConfErr
return
}
err = s.suit.GrantByMids(c, &suitmdl.ArgGrantByMids{Mids: []int64{mid}, Pid: rewardID, Expire: reward.Expire})
case bnj.RewardTypeCoupon:
err = s.bnjDao.GrantCoupon(c, mid, reward.RewardID)
// TODO check err code
}
if err != nil {
log.Error("Reward (%+v) error(%+v)", reward, err)
err = ecode.ActivityBnjRewardFail
if e := s.bnjDao.DelCacheHasReward(c, mid, subID, step); e != nil {
log.Error("s.dao.DelCacheHasReward(%+v) error(%v)", reward, e)
}
}
return
}

View File

@@ -0,0 +1,780 @@
package like
import (
"bytes"
"context"
"strconv"
"sync"
dao "go-common/app/interface/main/activity/dao/like"
likemdl "go-common/app/interface/main/activity/model/like"
tagmdl "go-common/app/interface/main/tag/model"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
thpmdl "go-common/app/service/main/thumbup/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
)
const (
_aidBulkSize = 100
_tagBlkSize = 50
_tagArcType = 3
_tagLikePoint = 100
_orderTypeCtime = "ctime"
_orderTypeRandom = "random"
_specialLikeRate = 1000
_businessLike = "archive"
)
var (
_emptyLikeList = make([]*likemdl.Like, 0)
_emptyArcs = make([]*api.Arc, 0)
)
// UpdateActSourceList update act arc list.
func (s *Service) updateActSourceList(c context.Context, sid int64, typ string) (err error) {
var (
likes []*likemdl.Item
)
if likes, err = s.dao.LikeList(c, sid); err != nil {
log.Error("UpdateActSourceList s.dao.LikeList(%d) error(%v)", sid, err)
return
}
s.cache.Do(c, func(c context.Context) {
if typ == _typeAll {
s.updateActCacheList(c, sid, likes)
}
if typ == _typeRegion {
s.updateActRegionList(c, sid, likes)
}
})
return
}
func (s *Service) updateActCacheList(c context.Context, sid int64, likes []*likemdl.Item) (err error) {
var (
aids []int64
tags map[int64][]*tagmdl.Tag
arcs map[int64]*api.Arc
)
likeMap := make(map[int64]*likemdl.Item, len(likes))
for _, v := range likes {
if v.Wid > 0 {
aids = append(aids, v.Wid)
likeMap[v.Wid] = v
}
}
if len(aids) == 0 {
return
}
if tags, err = s.arcTags(c, aids); err != nil {
return
}
if arcs, err = s.archives(c, aids); err != nil {
return
}
arcTagMap := make(map[int64][]*likemdl.Item, len(s.dialectTags))
tagLikePtTmp := make(map[int64]int32, len(s.dialectTags))
for aid, arcTag := range tags {
for _, tag := range arcTag {
if _, ok := s.dialectTags[tag.ID]; ok {
arcTagMap[tag.ID] = append(arcTagMap[tag.ID], likeMap[aid])
if arc, ok := arcs[aid]; ok && arc.IsNormal() {
tagLikePtTmp[tag.ID] += arc.Stat.Like
}
}
}
}
tagPtMap := make(map[int64]int32, len(s.dialectTags))
for tagID, v := range arcTagMap {
s.dao.SetLikeTagCache(c, sid, tagID, v)
if like, ok := tagLikePtTmp[tagID]; ok {
tagPt := int32(len(v)*_tagLikePoint) + like
tagPtMap[tagID] = tagPt
}
}
s.dao.SetTagLikeCountsCache(c, sid, tagPtMap)
regionMap := make(map[int16][]*likemdl.Item, len(s.dialectRegions))
for _, arc := range arcs {
if region, ok := s.arcType[int16(arc.TypeID)]; ok {
if _, ok := s.dialectRegions[region.Pid]; ok {
regionMap[region.Pid] = append(regionMap[region.Pid], likeMap[arc.Aid])
}
}
}
for rid, v := range regionMap {
s.dao.SetLikeRegionCache(c, sid, rid, v)
}
return
}
func (s *Service) updateActRegionList(c context.Context, sid int64, likes []*likemdl.Item) (err error) {
var (
aids []int64
arcs map[int64]*api.Arc
)
likeMap := make(map[int64]*likemdl.Item, len(likes))
for _, v := range likes {
if v.Wid > 0 {
aids = append(aids, v.Wid)
likeMap[v.Wid] = v
}
}
if len(aids) == 0 {
return
}
if arcs, err = s.archives(c, aids); err != nil {
return
}
regionMap := make(map[int16][]*likemdl.Item)
for _, arc := range arcs {
if region, ok := s.arcType[int16(arc.TypeID)]; ok {
regionMap[region.Pid] = append(regionMap[region.Pid], likeMap[arc.Aid])
}
}
for rid, v := range regionMap {
s.dao.SetLikeRegionCache(c, sid, rid, v)
}
return
}
func (s *Service) archives(c context.Context, aids []int64) (archives map[int64]*api.Arc, err error) {
var (
mutex = sync.Mutex{}
aidsLen = len(aids)
group, errCtx = errgroup.WithContext(c)
)
archives = make(map[int64]*api.Arc, aidsLen)
for i := 0; i < aidsLen; i += _aidBulkSize {
var partAids []int64
if i+_aidBulkSize > aidsLen {
partAids = aids[i:]
} else {
partAids = aids[i : i+_aidBulkSize]
}
group.Go(func() (err error) {
var arcs map[int64]*api.Arc
arg := &archive.ArgAids2{Aids: partAids}
if arcs, err = s.arcRPC.Archives3(errCtx, arg); err != nil {
log.Error("s.arcRPC.Archives(%v) error(%v)", partAids, err)
return
}
mutex.Lock()
for _, v := range arcs {
archives[v.Aid] = v
}
mutex.Unlock()
return
})
}
err = group.Wait()
return
}
func (s *Service) arcTags(c context.Context, aids []int64) (tags map[int64][]*tagmdl.Tag, err error) {
var (
tagErr error
mutex = sync.Mutex{}
)
group, errCtx := errgroup.WithContext(c)
aidsLen := len(aids)
tags = make(map[int64][]*tagmdl.Tag, aidsLen)
for i := 0; i < aidsLen; i += _tagBlkSize {
var partAids []int64
if i+_tagBlkSize > aidsLen {
partAids = aids[i:]
} else {
partAids = aids[i : i+_tagBlkSize]
}
group.Go(func() (err error) {
var tmpRes map[int64][]*tagmdl.Tag
arg := &tagmdl.ArgResTags{Oids: partAids, Type: _tagArcType}
if tmpRes, tagErr = s.tagRPC.ResTags(errCtx, arg); tagErr != nil {
dao.PromError("ResTags接口错误", "s.tag.ResTag(%+v) error(%v)", arg, tagErr)
return
}
mutex.Lock()
for aid, tmpTags := range tmpRes {
tags[aid] = tmpTags
}
mutex.Unlock()
return nil
})
}
group.Wait()
return
}
// TagArcList tag arc list.
func (s *Service) TagArcList(c context.Context, sid, tagID int64, pn, ps int, typ, ip string) (list []*likemdl.Like, cnt int, err error) {
var (
likes []*likemdl.Item
start, end int
aids []int64
archives map[int64]*api.Arc
)
if sid != s.c.Rule.DialectSid {
err = ecode.RequestErr
return
}
if _, ok := s.dialectTags[tagID]; !ok {
err = ecode.RequestErr
return
}
if cnt, err = s.dao.LikeTagCnt(c, sid, tagID); err != nil {
log.Error("TagArcList s.dao.LikeTagCnt sid(%d) tagID(%d) error(%v)", sid, tagID, err)
return
}
if start, end, err = s.fmtStartEnd(pn, ps, cnt, typ); err != nil {
err = nil
list = _emptyLikeList
return
}
if likes, err = s.dao.LikeTagCache(c, sid, tagID, start, end); err != nil {
log.Error("TagArcList s.dao.LikeTagCache sid(%d) tagID(%d) start(%d) end(%d) error(%+v)", sid, tagID, start, end, err)
return
}
for _, v := range likes {
if v.Wid > 0 {
aids = append(aids, v.Wid)
}
}
if len(aids) == 0 {
list = _emptyLikeList
return
}
if archives, err = s.arcRPC.Archives3(c, &archive.ArgAids2{Aids: aids, RealIP: ip}); err != nil {
log.Error("TagArcList s.arcRPC.Archives3 aids(%v) error(%+v)", aids, err)
return
}
for _, v := range likes {
if arc, ok := archives[v.Wid]; ok && arc.IsNormal() {
list = append(list, &likemdl.Like{Item: v, Archive: arc})
}
}
l := len(list)
if l == 0 {
list = _emptyLikeList
return
}
if typ == _orderTypeRandom {
s.shuffle(l, func(i, j int) {
list[i], list[j] = list[j], list[i]
})
}
return
}
// RegionArcList region arc list.
func (s *Service) RegionArcList(c context.Context, sid int64, rid int16, pn, ps int, typ, ip string) (list []*likemdl.Like, cnt int, err error) {
var (
likes []*likemdl.Item
start, end int
aids []int64
archives map[int64]*api.Arc
)
if sid != s.c.Rule.DialectSid {
err = ecode.RequestErr
return
}
if _, ok := s.dialectRegions[rid]; !ok {
err = ecode.RequestErr
return
}
if cnt, err = s.dao.LikeRegionCnt(c, sid, rid); err != nil {
log.Error("RegionArcList s.dao.LikeRegionCnt sid(%d) rid(%d) error(%v)", sid, rid, err)
return
}
if start, end, err = s.fmtStartEnd(pn, ps, cnt, typ); err != nil {
err = nil
list = _emptyLikeList
return
}
if likes, err = s.dao.LikeRegionCache(c, sid, rid, start, end); err != nil {
log.Error("RegionArcList s.dao.LikeRegionCache sid(%d) rid(%d) start(%d) end(%d) error(%+v)", sid, rid, start, end, err)
return
}
for _, v := range likes {
if v.Wid > 0 {
aids = append(aids, v.Wid)
}
}
if len(aids) == 0 {
list = _emptyLikeList
return
}
if archives, err = s.arcRPC.Archives3(c, &archive.ArgAids2{Aids: aids, RealIP: ip}); err != nil {
log.Error("RegionArcList s.arcRPC.Archives3 aids(%v) error(%+v)", aids, err)
return
}
for _, v := range likes {
if arc, ok := archives[v.Wid]; ok && arc.IsNormal() {
list = append(list, &likemdl.Like{Item: v, Archive: arc})
}
}
l := len(list)
if l == 0 {
list = _emptyLikeList
return
}
if typ == _orderTypeRandom {
s.shuffle(l, func(i, j int) {
list[i], list[j] = list[j], list[i]
})
}
return
}
// TagLikeCounts .
func (s *Service) TagLikeCounts(c context.Context, sid int64) (data map[int64]int32, err error) {
if sid != s.c.Rule.DialectSid {
err = ecode.RequestErr
return
}
return s.dao.TagLikeCountsCache(c, sid, s.c.Rule.DialectTags)
}
func (s *Service) fmtStartEnd(pn, ps, cnt int, typ string) (start, end int, err error) {
if typ == _orderTypeCtime {
start = (pn - 1) * ps
end = start + ps - 1
if start > cnt {
err = ecode.NothingFound
return
}
if end > cnt {
end = cnt
}
} else {
if ps >= cnt-1 {
start = 0
} else {
start = s.r.Intn(cnt - ps - 1)
}
end = start + ps - 1
}
return
}
func (s *Service) shuffle(l int, swap func(i, j int)) {
for i := l - 1; i > 0; i-- {
j := s.r.Intn(i + 1)
swap(i, j)
}
}
// LikeInitialize initialize like cache data .
func (s *Service) LikeInitialize(c context.Context, lid int64) (err error) {
if lid < 0 {
lid = 0
}
var likesItem []*likemdl.Item
for {
if likesItem, err = s.dao.LikeListMoreLid(c, lid); err != nil {
log.Error("dao.LikeInitialize(%d) error(%+v)", lid, err)
break
}
if len(likesItem) == 0 {
log.Info("LikeInitialize end success")
break
}
for _, val := range likesItem {
item := val
if lid < item.ID {
lid = item.ID
}
id := item.ID
//the likes offline is stored with empty data
if item.State != 1 {
item = &likemdl.Item{}
}
s.cache.Do(c, func(c context.Context) {
s.dao.AddCacheLike(c, id, item)
})
}
}
s.cache.Do(c, func(c context.Context) {
s.LikeMaxIDInitialize(c)
})
return
}
// LikeMaxIDInitialize likes max id initialize
func (s *Service) LikeMaxIDInitialize(c context.Context) (err error) {
var likeItem *likemdl.Item
if likeItem, err = s.dao.LikeMaxID(c); err != nil {
log.Error("s.dao.LikeMaxID() error(%+v)", err)
return
}
if likeItem.ID >= 0 {
if err = s.dao.AddCacheLikeMaxID(c, likeItem.ID); err != nil {
log.Error("s.dao.AddCacheLikeMaxID(%d),error(%v)", likeItem.ID, err)
}
}
return
}
// LikeUp update likes cache and like maxID cache
func (s *Service) LikeUp(c context.Context, lid int64) (err error) {
var (
likeItem *likemdl.Item
likeMaxID int64
)
group, ctx := errgroup.WithContext(c)
group.Go(func() (e error) {
if likeItem, e = s.dao.RawLike(ctx, lid); e != nil {
log.Error("LikeUp:s.dao.RawLike(%d) error(%+v)", lid, e)
}
return
})
group.Go(func() (e error) {
if likeMaxID, e = s.dao.CacheLikeMaxID(ctx); e != nil {
log.Error("LikeUp:s.dao.CacheLikeMaxID() error(%v)", e)
}
return
})
if err = group.Wait(); err != nil {
log.Error("LikeUp: group.Wait() error(%v)", err)
return
}
if likeMaxID < lid {
s.cache.Do(c, func(c context.Context) {
s.dao.AddCacheLikeMaxID(c, lid)
})
}
if likeItem.ID == 0 {
likeItem = &likemdl.Item{}
}
s.cache.Do(c, func(c context.Context) {
s.dao.AddCacheLike(c, lid, likeItem)
})
return
}
// AddLikeCtimeCache add cache .
func (s *Service) AddLikeCtimeCache(c context.Context, lid int64) (err error) {
var (
likeItem *likemdl.Item
cItems = make([]*likemdl.Item, 0, 1)
)
if likeItem, err = s.dao.RawLike(c, lid); err != nil {
log.Error("LikeUp:s.dao.RawLike(%d) error(%+v)", lid, err)
return
}
if likeItem.ID > 0 {
eg, errCtx := errgroup.WithContext(c)
cItems = append(cItems, likeItem)
eg.Go(func() (e error) {
e = s.dao.LikeListCtime(errCtx, likeItem.Sid, cItems)
return
})
eg.Go(func() (e error) {
// 初始化排行榜数据
e = s.dao.SetRedisCache(c, likeItem.Sid, lid, 0, likeItem.Type)
return
})
if err = eg.Wait(); err != nil {
log.Error("AddLikeCtimeCache eg.Wait() error(%+v)", err)
}
}
return
}
// DelLikeCtimeCache delete ctime cache.
func (s *Service) DelLikeCtimeCache(c context.Context, lid, sid int64, likeType int) (err error) {
var (
cItems = make([]*likemdl.Item, 0, 1)
)
likeItem := &likemdl.Item{
ID: lid,
Sid: sid,
Type: likeType,
}
cItems = append(cItems, likeItem)
if err = s.dao.DelLikeListCtime(c, likeItem.Sid, cItems); err != nil {
log.Error("s.dao.DelLikeListCtime(%v) error (%v)", likeItem, err)
}
return
}
// SubjectStat get subject stat .
func (s *Service) SubjectStat(c context.Context, sid int64) (score *likemdl.SubjectScore, err error) {
if sid == s.c.Rule.S8Sid {
var arcScore, artScore int64
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
var (
stat *likemdl.SubjectStat
arcErr error
)
if stat, arcErr = s.dao.CacheSubjectStat(errCtx, s.c.Rule.S8ArcSid); arcErr != nil {
log.Error("s.dao.CacheSubjectStat sid(%d) error(%v)", sid, arcErr)
}
if stat == nil {
stat = new(likemdl.SubjectStat)
}
arcScore = stat.Count*_specialLikeRate + stat.Like
return nil
})
group.Go(func() error {
var (
stat *likemdl.SubjectStat
artErr error
)
if stat, artErr = s.dao.CacheSubjectStat(errCtx, s.c.Rule.S8ArtSid); artErr != nil {
log.Error("s.dao.CacheSubjectStat sid(%d) error(%v)", sid, artErr)
}
if stat == nil {
stat = new(likemdl.SubjectStat)
}
artScore = stat.Count*_specialLikeRate + stat.Like
return nil
})
group.Wait()
score = &likemdl.SubjectScore{Score: arcScore + artScore}
} else {
var stat *likemdl.SubjectStat
if stat, err = s.dao.CacheSubjectStat(c, sid); err != nil {
log.Error("s.dao.CacheSubjectStat sid(%d) error(%v)", sid, err)
err = nil
}
if stat == nil {
stat = new(likemdl.SubjectStat)
}
if sid == s.c.Rule.KingStorySid {
score = &likemdl.SubjectScore{Score: stat.View + stat.Fav + stat.Coin + stat.Like}
} else {
score = &likemdl.SubjectScore{Score: stat.Count*_specialLikeRate + stat.Like}
}
}
return
}
// SetSubjectStat set subject stat .
func (s *Service) SetSubjectStat(c context.Context, stat *likemdl.SubjectStat) (err error) {
return s.dao.AddCacheSubjectStat(c, stat.Sid, stat)
}
// ViewRank get view rank arcs.
func (s *Service) ViewRank(c context.Context, sid int64, pn, ps int) (list []*api.Arc, count int, err error) {
var (
aidsCache string
aids, pieceAids []int64
arcs map[int64]*api.Arc
)
if aidsCache, err = s.dao.CacheViewRank(c, sid); err != nil {
log.Error("ViewRank s.dao.CacheViewRank(%d) error(%v)", sid, err)
return
}
if aids, err = xstr.SplitInts(aidsCache); err != nil {
log.Error("ViewRank xstr.SplitInts(%d,%s) error(%v)", sid, aidsCache, err)
return
}
count = len(aids)
start := (pn - 1) * ps
end := start + ps - 1
if count < start {
list = _emptyArcs
return
}
if count > end {
pieceAids = aids[start : end+1]
} else {
pieceAids = aids[start:]
}
if arcs, err = s.arcRPC.Archives3(c, &archive.ArgAids2{Aids: pieceAids}); err != nil {
log.Error("ViewRank s.arcRPC.Archives3(%v) error(%v)", aids, err)
return
}
for _, aid := range pieceAids {
if arc, ok := arcs[aid]; ok && arc.IsNormal() {
list = append(list, arc)
}
}
if len(list) == 0 {
list = _emptyArcs
}
return
}
// SetViewRank set view rank arcs.
func (s *Service) SetViewRank(c context.Context, sid int64, aids []int64) (err error) {
aidsStr := xstr.JoinInts(aids)
if err = s.dao.AddCacheViewRank(c, sid, aidsStr); err != nil {
log.Error("SetViewRank s.dao.AddCacheViewRank(%d,%s) error(%v)", sid, aidsStr, err)
}
return
}
// ObjectGroup group like data.
func (s *Service) ObjectGroup(c context.Context, sid int64, ck string) (data map[int64][]*likemdl.GroupItem, err error) {
var sids []int64
if sids, err = s.dao.SourceItemData(c, sid); err != nil {
log.Error("ObjectGroup SourceItemData(%d) error(%+v)", sid, err)
return
}
if len(sids) == 0 {
log.Warn("ObjectGroup sid(%d) len(sids) == 0", sid)
err = ecode.NothingFound
return
}
data = make(map[int64][]*likemdl.GroupItem, len(sids))
group, errCtx := errgroup.WithContext(c)
mutex := sync.Mutex{}
for _, v := range sids {
groupSid := v
group.Go(func() error {
item, e := s.dao.GroupItemData(errCtx, groupSid, ck)
if e != nil {
log.Error("ObjectGroup s.dao.GroupItemData(%d) error(%+v)", groupSid, e)
} else {
mutex.Lock()
data[groupSid] = item
mutex.Unlock()
}
return nil
})
}
group.Wait()
return
}
// SetLikeContent .
func (s *Service) SetLikeContent(c context.Context, lid int64) (err error) {
var (
conts map[int64]*likemdl.LikeContent
)
if conts, err = s.dao.RawLikeContent(c, []int64{lid}); err != nil {
log.Error("s.dao.RawLikeContent(%d) error(%+v)", lid, err)
return
}
if _, ok := conts[lid]; !ok {
conts = make(map[int64]*likemdl.LikeContent, 1)
conts[lid] = &likemdl.LikeContent{}
}
if err = s.dao.AddCacheLikeContent(c, conts); err != nil {
log.Error("s.dao.AddCacheLikeContent(%d) error(%+v)", lid, err)
}
return
}
// AddLikeActCache .
func (s *Service) AddLikeActCache(c context.Context, sid, lid, score int64) (err error) {
var (
likeItem *likemdl.Item
)
if likeItem, err = s.dao.Like(c, lid); err != nil {
log.Error("AddLikeActCache:s.dao.Like(%d) error(%+v)", lid, err)
return
}
if likeItem.ID == 0 {
return
}
if err = s.dao.SetRedisCache(c, sid, lid, score, likeItem.Type); err != nil {
log.Error("AddLikeActCache:s.dao.SetRedisCache(%d,%d,%d) error(%+v)", sid, lid, score, err)
}
return
}
// LikeActCache .
func (s *Service) LikeActCache(c context.Context, sid, lid int64) (res int64, err error) {
return s.dao.LikeActZscore(c, sid, lid)
}
// BatchInsertLikeExtend batch insert like_extend table.
func (s *Service) BatchInsertLikeExtend(c context.Context, extends []*likemdl.Extend) (res int64, err error) {
var (
buf bytes.Buffer
cnt int
rows int64
)
for _, v := range extends {
buf.WriteString("(")
buf.WriteString(strconv.FormatInt(v.Lid, 10))
buf.WriteString(",")
buf.WriteString(strconv.FormatInt(v.Like, 10))
buf.WriteString("),")
cnt++
if cnt%500 == 0 {
buf.Truncate(buf.Len() - 1)
if rows, err = s.dao.AddExtend(c, buf.String()); err != nil {
log.Error("dao.dealAddExtend() error(%+v)", err)
return
}
res += rows
buf.Reset()
}
}
if buf.Len() > 0 {
buf.Truncate(buf.Len() - 1)
if rows, err = s.dao.AddExtend(c, buf.String()); err != nil {
log.Error("dao.dealAddExtend() error(%+v)", err)
return
}
res += rows
}
return
}
// arcTag get archive and tags.
func (s *Service) arcTag(c context.Context, list []*likemdl.List, order string, mid int64) (err error) {
var (
arcsReply *api.ArcsReply
lt = len(list)
wids = make([]int64, 0, lt)
tagRes map[int64][]string
hasLikeList map[int64]int8
)
for _, v := range list {
if v.Wid > 0 {
wids = append(wids, v.Wid)
}
}
eg, errCtx := errgroup.WithContext(c)
eg.Go(func() (e error) {
arcsReply, e = s.arcClient.Arcs(errCtx, &api.ArcsRequest{Aids: wids})
return
})
eg.Go(func() (e error) {
tagRes, e = s.dao.MultiTags(errCtx, wids)
return
})
if mid != 0 && (order == dao.EsOrderLikes || order == dao.ActOrderCtime) {
eg.Go(func() (e error) {
hasLikeList, e = s.thumbup.HasLike(errCtx, &thpmdl.ArgHasLike{Business: _businessLike, MessageIDs: wids, Mid: mid})
return
})
}
if err = eg.Wait(); err != nil {
log.Error("arcTag:eg.Wait() error(%+v)", err)
return
}
for _, v := range list {
if v.Wid == 0 {
continue
}
obj := new(likemdl.ArgTag)
if _, ok := arcsReply.Arcs[v.Wid]; ok {
obj.Archive = arcsReply.Arcs[v.Wid]
}
if _, ok := tagRes[v.Wid]; ok {
obj.Tags = tagRes[v.Wid]
}
v.Object = obj
if _, ok := hasLikeList[v.Wid]; ok {
v.HasLikes = hasLikeList[v.Wid]
}
}
return
}
// LikeOidsInfo .
func (s *Service) LikeOidsInfo(c context.Context, sType int, oids []int64) (res map[int64]*likemdl.Item, err error) {
if res, err = s.dao.OidInfoFromES(c, oids, sType); err != nil {
log.Error("s.dao.OidInfoFromES(%v,%d) error(%v)", oids, sType, err)
}
return
}

View File

@@ -0,0 +1,74 @@
package like
import (
"context"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_fmtStartEnd(t *testing.T) {
Convey("test fmt start and end", t, WithService(func(s *Service) {
pn := 1
ps := 10
cnt := 11
typ := "random" //ctime random
start, end, err := s.fmtStartEnd(pn, ps, cnt, typ)
So(err, ShouldBeNil)
Println(start, end)
}))
}
func TestService_LikeInitialize(t *testing.T) {
Convey("test LikeInitialize", t, WithService(func(s *Service) {
lid := int64(13537)
err := s.LikeInitialize(context.Background(), lid)
time.Sleep(time.Second)
So(err, ShouldBeNil)
}))
}
func TestService_LikeMaxIDInitialize(t *testing.T) {
Convey("test LikeInitialize", t, WithService(func(s *Service) {
err := s.LikeMaxIDInitialize(context.Background())
So(err, ShouldBeNil)
}))
}
func TestService_LikeUp(t *testing.T) {
Convey("test LikeUp", t, WithService(func(s *Service) {
lid := int64(13538)
err := s.LikeUp(context.Background(), lid)
time.Sleep(time.Second)
So(err, ShouldBeNil)
}))
}
func TestService_AddLikeCtimeCache(t *testing.T) {
Convey("test LikeUp", t, WithService(func(s *Service) {
lid := int64(13540)
err := s.AddLikeCtimeCache(context.Background(), lid)
So(err, ShouldBeNil)
}))
}
func TestService_DelLikeCtimeCache(t *testing.T) {
Convey("test LikeUp", t, WithService(func(s *Service) {
err := s.DelLikeCtimeCache(context.Background(), 13537, 10296, 5)
So(err, ShouldBeNil)
}))
}
func TestService_SetLikeContent(t *testing.T) {
Convey("test LikeUp", t, WithService(func(s *Service) {
err := s.SetLikeContent(context.Background(), 13511)
So(err, ShouldBeNil)
}))
}
func TestService_AddLikeActCache(t *testing.T) {
Convey("test LikeUp", t, WithService(func(s *Service) {
err := s.AddLikeActCache(context.Background(), 10296, 13528, 7)
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,302 @@
package like
import (
"context"
"encoding/json"
"time"
"go-common/app/interface/main/activity/conf"
dao "go-common/app/interface/main/activity/dao/like"
match "go-common/app/interface/main/activity/model/like"
coinmdl "go-common/app/service/main/coin/model"
suitmdl "go-common/app/service/main/usersuit/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/library/sync/errgroup"
)
const (
_matchTable = "act_matchs"
_objectTable = "act_matchs_object"
_userLogTable = "act_match_user_log"
_reason = "参与竞猜"
)
var (
_emptyMatch = make([]*match.Match, 0)
_emptyObjects = make([]*match.Object, 0)
_emptyUserLog = make([]*match.UserLog, 0)
_emptyFollow = make([]string, 0)
)
// Match get match.
func (s *Service) Match(c context.Context, sid int64) (rs []*match.Match, err error) {
// get from cache.
if rs, err = s.dao.ActMatchCache(c, sid); err != nil || len(rs) == 0 {
if rs, err = s.dao.ActMatch(c, sid); err != nil {
log.Error("s.dao.Match sid(%d) error(%v)", sid, err)
return
}
if len(rs) == 0 {
rs = _emptyMatch
return
}
s.cache.Do(c, func(c context.Context) {
s.dao.SetActMatchCache(c, sid, rs)
})
}
return
}
// AddGuess add match guess.
func (s *Service) AddGuess(c context.Context, mid int64, p *match.ParamAddGuess) (rs int64, err error) {
var (
object *match.Object
userGuess []*match.UserLog
group *errgroup.Group
coinErr, suitErr error
count float64
ip = metadata.String(c, metadata.RemoteIP)
)
if p.Stake > conf.Conf.Rule.MaxGuessCoin {
err = ecode.ActivityOverCoin
return
}
//check mid coin count
if count, err = s.coin.UserCoins(c, &coinmdl.ArgCoinInfo{Mid: mid, RealIP: ip}); err != nil {
dao.PromError("UserCoins接口错误", "s.coin.UserCoins(%d,%s) error(%v)", mid, ip, err)
return
}
if count < float64(p.Stake) {
err = ecode.ActivityNotEnoughCoin
return
}
// get from cache.
if object, err = s.dao.ObjectCache(c, p.ObjID); err != nil || object == nil {
if object, err = s.dao.Object(c, p.ObjID); err != nil {
log.Error("s.dao.Match id(%d) error(%v)", p.ObjID, err)
return
}
if object == nil || object.ID == 0 {
err = ecode.ActivityNotExist
return
}
s.cache.Do(c, func(c context.Context) {
s.dao.SetObjectCache(c, p.ObjID, object)
})
}
if time.Now().Unix() < object.Stime.Time().Unix() {
err = ecode.ActivityNotStart
return
} else if object.Result > 0 || time.Now().Unix() > object.Etime.Time().Unix() {
err = ecode.ActivityOverEnd
return
}
sid := object.Sid
if userGuess, err = s.ListGuess(c, sid, mid); err != nil {
log.Error("s.ListGuess(%d,%d) error(%v)", sid, mid, err)
return
}
for _, userLog := range userGuess {
if userLog.MOId == p.ObjID {
err = ecode.ActivityHaveGuess
return
}
}
if rs, err = s.dao.AddGuess(c, mid, object.MatchId, p.ObjID, sid, p.Result, p.Stake); err != nil || rs == 0 {
log.Error("s.dao.AddGuess matchID(%d) objectID(%d) sid(%d) error(%v)", object.MatchId, p.ObjID, sid, err)
return
}
s.dao.DelUserLogCache(context.Background(), sid, mid)
group, errCtx := errgroup.WithContext(c)
if len(s.c.Rule.SuitPids) > 0 && len(userGuess)+1 == s.c.Rule.GuessCount {
for _, v := range s.c.Rule.SuitPids {
pid := v
group.Go(func() error {
mids := []int64{mid}
if suitErr = s.suit.GrantByMids(errCtx, &suitmdl.ArgGrantByMids{Mids: mids, Pid: pid, Expire: s.c.Rule.SuitExpire}); suitErr != nil {
dao.PromError("GrantByMids接口错误", "s.suit.GrantByMids(%d,%d,%s) error(%v)", mid, p.Stake, ip, suitErr)
}
return nil
})
}
}
group.Go(func() error {
loseCoin := float64(-p.Stake)
if _, coinErr = s.coin.ModifyCoin(errCtx, &coinmdl.ArgModifyCoin{Mid: mid, Count: loseCoin, Reason: _reason, IP: ip}); coinErr != nil {
dao.PromError("ModifyCoin接口错误", "s.coin.ModifyCoin(%d,%d,%s) error(%v)", mid, p.Stake, ip, coinErr)
}
return nil
})
if s.c.Rule.MatchLotteryID > 0 {
group.Go(func() error {
if lotteryErr := s.dao.AddLotteryTimes(errCtx, s.c.Rule.MatchLotteryID, mid); lotteryErr != nil {
log.Error("s.dao.AddLotteryTimes(%d,%d) error(%+v)", s.c.Rule.MatchLotteryID, mid, lotteryErr)
}
return nil
})
}
group.Wait()
return
}
// ListGuess get match guess list.
func (s *Service) ListGuess(c context.Context, sid, mid int64) (rs []*match.UserLog, err error) {
// get from cache.
if rs, err = s.dao.UserLogCache(c, sid, mid); err != nil || len(rs) == 0 {
if rs, err = s.dao.ListGuess(c, sid, mid); err != nil {
log.Error("s.dao.ListGuess sid(%d) mid(%d) error(%v)", sid, mid, err)
return
}
if len(rs) == 0 {
rs = _emptyUserLog
return
}
}
var (
moIDs []int64
objects map[int64]*match.Object
)
for _, v := range rs {
moIDs = append(moIDs, v.MOId)
}
if len(moIDs) == 0 {
return
}
if objects, err = s.dao.MatchSubjects(c, moIDs); err == nil {
for _, v := range rs {
if obj, ok := objects[v.MOId]; ok {
v.HomeName = obj.HomeName
v.AwayName = obj.AwayName
v.ObjResult = obj.Result
v.GameStime = obj.GameStime
}
}
}
s.cache.Do(c, func(c context.Context) {
s.dao.SetUserLogCache(c, sid, mid, rs)
})
return
}
// Guess user guess
func (s *Service) Guess(c context.Context, mid int64, p *match.ParamSid) (rs *match.UserGuess, err error) {
var (
userGuess []*match.UserLog
totalCont, winCount int64
)
if userGuess, err = s.ListGuess(c, p.Sid, mid); err != nil {
log.Error("s.ListGuess(%d,%d) error(%v)", p.Sid, mid, err)
return
}
for _, guess := range userGuess {
if guess.ObjResult > 0 {
if guess.Result == guess.ObjResult {
winCount++
}
totalCont++
}
}
rs = new(match.UserGuess)
rs.Total = totalCont
rs.Win = winCount
return
}
// ClearCache del match and object cache
func (s *Service) ClearCache(c context.Context, msg string) (err error) {
var m struct {
Table string `json:"table"`
New struct {
ID int64 `json:"id"`
Sid int64 `json:"sid"`
MatID int64 `json:"match_id"`
Mid int64 `json:"mid"`
MOId int64 `json:"m_o_id"`
} `json:"new,omitempty"`
}
if err = json.Unmarshal([]byte(msg), &m); err != nil {
log.Error("ClearCache json.Unmarshal msg(%s) error(%v)", msg, err)
return
}
log.Info("ClearCache json.Unmarshal msg(%s)", msg)
if m.Table == _matchTable {
if err = s.dao.DelActMatchCache(c, m.New.Sid, m.New.ID); err != nil {
log.Error("s.dao.DelActMatchCache sid(%d) matchID(%d) error(%v)", m.New.Sid, m.New.ID, err)
}
} else if m.Table == _objectTable {
if err = s.dao.DelObjectCache(c, m.New.ID, m.New.Sid); err != nil {
log.Error("s.dao.DelObjectCache objID(%d) Sid(%d) error(%v)", m.New.ID, m.New.Sid, err)
}
} else if m.Table == _userLogTable {
if err = s.dao.DelUserLogCache(c, m.New.Sid, m.New.Mid); err != nil {
log.Error("s.dao.DelUserLogCache mid(%d) error(%v)", m.New.Mid, err)
}
}
return
}
// AddFollow add match follow
func (s *Service) AddFollow(c context.Context, mid int64, teams []string) (err error) {
if err = s.dao.AddFollow(c, mid, teams); err != nil {
log.Error("s.dao.AddFollow mid(%d) teams(%v) error(%v)", mid, teams, err)
}
return
}
// Follow get match follow
func (s *Service) Follow(c context.Context, mid int64) (res []string, err error) {
if res, err = s.dao.Follow(c, mid); err != nil {
log.Error("s.dao.Follow mid(%d) error(%v)", mid, err)
}
if len(res) == 0 {
res = _emptyFollow
}
return
}
// ObjectsUnStart get unstart object list.
func (s *Service) ObjectsUnStart(c context.Context, mid int64, p *match.ParamObject) (rs []*match.Object, count int, err error) {
var (
userGuess []*match.UserLog
objects []*match.Object
start = (p.Pn - 1) * p.Ps
end = start + p.Ps - 1
)
// get from cache.
if rs, count, err = s.dao.ObjectsCache(c, p.Sid, start, end); err != nil || len(rs) == 0 {
if objects, err = s.dao.ObjectsUnStart(c, p.Sid); err != nil {
log.Error("s.dao.ObjectsUnStart id(%d) error(%v)", p.Sid, err)
return
}
count = len(objects)
if count == 0 || count < start {
rs = _emptyObjects
return
}
s.cache.Do(c, func(c context.Context) {
s.dao.SetObjectsCache(c, p.Sid, objects, count)
})
if count > end+1 {
rs = objects[start : end+1]
} else {
rs = objects[start:]
}
}
if mid > 0 {
if userGuess, err = s.ListGuess(c, p.Sid, mid); err != nil {
log.Error("s.ListGuess(%d,%d) error(%v)", p.Sid, mid, err)
err = nil
}
for _, rsObj := range rs {
for _, guess := range userGuess {
if rsObj.ID == guess.MOId {
rsObj.UserResult = guess.Result
break
}
}
}
}
return
}

View File

@@ -0,0 +1,88 @@
package like
import (
"context"
"testing"
"go-common/app/interface/main/activity/model/like"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_Match(t *testing.T) {
Convey("test service Match", t, WithService(func(s *Service) {
sid := int64(1)
res, err := s.Match(context.Background(), sid)
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
}))
}
func TestService_AddGuess(t *testing.T) {
Convey("test service AddGuess", t, WithService(func(s *Service) {
mid := int64(111)
objID := int64(1)
result := int64(2)
stake := int64(3)
lastID, err := s.AddGuess(context.Background(), mid, &like.ParamAddGuess{ObjID: objID, Result: result, Stake: stake})
So(err, ShouldBeNil)
So(lastID, ShouldBeGreaterThan, 0)
}))
}
func TestService_ListGuess(t *testing.T) {
Convey("test service match ListGuess", t, WithService(func(s *Service) {
sid := int64(111)
mid := int64(111)
guess, err := s.ListGuess(context.Background(), sid, mid)
So(err, ShouldBeNil)
So(len(guess), ShouldBeGreaterThan, 0)
}))
}
func TestService_Guess(t *testing.T) {
Convey("test service match Guess", t, WithService(func(s *Service) {
mid := int64(111)
sid := int64(1)
guess, err := s.Guess(context.Background(), mid, &like.ParamSid{Sid: sid})
So(err, ShouldBeNil)
So(guess, ShouldNotBeNil)
}))
}
func TestService_ClearCache(t *testing.T) {
Convey("test service ClearCache", t, WithService(func(s *Service) {
msg := `{"action":"update","table":"act_matchs_object","old":{"name":0},"new":{"id":2,"sid":12,"match_id":2}}`
err := s.ClearCache(context.Background(), msg)
So(err, ShouldBeNil)
}))
}
func TestService_AddFollow(t *testing.T) {
Convey("test service AddFollow", t, WithService(func(s *Service) {
mid := int64(111)
team := []string{"11", "22", "33"}
err := s.AddFollow(context.Background(), mid, team)
So(err, ShouldBeNil)
}))
}
func TestService_Follow(t *testing.T) {
Convey("test service Follow", t, WithService(func(s *Service) {
mid := int64(111)
teams, err := s.Follow(context.Background(), mid)
So(err, ShouldBeNil)
So(len(teams), ShouldBeGreaterThan, 0)
}))
}
func TestService_ObjectsUnStart(t *testing.T) {
Convey("test service ObjectsUnStart", t, WithService(func(s *Service) {
mid := int64(111)
sid := int64(1)
objs, total, err := s.ObjectsUnStart(context.Background(), mid, &like.ParamObject{Sid: sid, Pn: 1, Ps: 4})
So(err, ShouldBeNil)
So(total, ShouldBeGreaterThan, 0)
So(len(objs), ShouldBeGreaterThan, 0)
}))
}

View File

@@ -0,0 +1,467 @@
package like
import (
"context"
"net"
"time"
ldao "go-common/app/interface/main/activity/dao/like"
l "go-common/app/interface/main/activity/model/like"
accapi "go-common/app/service/main/account/api"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/library/sync/errgroup"
)
// MissionLike launch buff activity .
func (s *Service) MissionLike(c context.Context, sid, mid int64) (lid int64, err error) {
var (
subject *l.SubjectItem
now = time.Now().Unix()
missionGroup int64
group *l.MissionGroup
)
if subject, err = s.dao.ActSubject(c, sid); err != nil {
log.Error("s.dao.ActSubject(%d) error(%+v)", sid, err)
return
}
if subject.ID == 0 || subject.Type != l.MISSIONGROUP {
err = ecode.ActivityNotExist
return
}
if subject.Stime.Time().Unix() > now {
err = ecode.ActivityNotStart
return
}
if subject.Etime.Time().Unix() < now {
err = ecode.ActivityOverEnd
return
}
if missionGroup, err = s.dao.LikeMissionBuff(c, sid, mid); err != nil {
log.Error("s.dao.LikeMissionBuff(%d,%d) error(%+v)", sid, mid, err)
return
}
if missionGroup > 0 {
err = ecode.ActivityHasMissionGroup
return
}
group = &l.MissionGroup{
Sid: sid,
Mid: mid,
State: ldao.MissionStateInit,
}
if lid, err = s.dao.MissionGroupAdd(c, group); err != nil {
log.Error("s.dao.MissionGroupAdd(%d,%d) error(%+v)", sid, mid, err)
return
}
s.dao.AddCacheLikeMissionBuff(c, sid, lid, mid)
return
}
// MissionInfo .
func (s *Service) MissionInfo(c context.Context, sid, lid, mid int64) (res *l.MissionInfo, err error) {
var hasBufErr, hasHelpErr error
res = &l.MissionInfo{}
eg, errCtx := errgroup.WithContext(c)
eg.Go(func() error {
res.HasBuff, hasBufErr = s.dao.LikeMissionBuff(errCtx, sid, mid)
if hasBufErr != nil {
log.Error("s.dao.LikeMissionBuff(%d,%d) error(%+v)", sid, mid, hasBufErr)
}
return nil
})
eg.Go(func() error {
res.HasHelp, hasHelpErr = s.dao.ActMission(errCtx, sid, lid, mid)
if hasHelpErr != nil {
log.Error("s.dao.ActMission(%d,%d,%d) error(%+v)", sid, lid, mid, hasHelpErr)
}
return nil
})
eg.Wait()
return
}
// MissionUser .
func (s *Service) MissionUser(c context.Context, sid, lid int64) (res *l.MissionFriends, err error) {
var (
groups map[int64]*l.MissionGroup
group *l.MissionGroup
member *accapi.InfoReply
)
if groups, err = s.dao.MissionGroupItems(c, []int64{lid}); err != nil {
log.Error("s.dao.MissionGroupItems(%v) error(%v)", lid, err)
return
}
if _, ok := groups[lid]; !ok {
err = ecode.ActivityNotExist
return
}
group = groups[lid]
if group.ID == 0 || group.Sid != sid {
err = ecode.ActivityNotExist
return
}
if member, err = s.accClient.Info3(c, &accapi.MidReq{Mid: group.Mid}); err != nil {
log.Error(" s.acc.Info3(c,&accmdl.ArgMids{Mid:%d}) error(%v)", group.Mid, err)
return
}
res = &l.MissionFriends{
Name: member.Info.Name,
Face: member.Info.Face,
Mid: member.Info.Mid,
}
return
}
// MissionLikeAct help to mission group .
func (s *Service) MissionLikeAct(c context.Context, p *l.ParamMissionLikeAct, mid int64) (data *l.MissionLikeAct, err error) {
var (
subject *l.SubjectItem
groups map[int64]*l.MissionGroup
group *l.MissionGroup
memberRly *accapi.ProfileReply
now = time.Now().Unix()
ActMissionID, likeLimit, missionActCount, mLid int64
score = int64(1)
missionActList *l.ActMissionGroup
lottery *l.Lottery
subErr, groupErr, missionErr, caculErr, incrErr error
)
eg, errCtx := errgroup.WithContext(c)
eg.Go(func() error {
subject, subErr = s.dao.ActSubject(errCtx, p.Sid)
return subErr
})
eg.Go(func() error {
groups, groupErr = s.dao.MissionGroupItems(errCtx, []int64{p.Lid})
return groupErr
})
if err = eg.Wait(); err != nil {
log.Error("MissionLikeAct:eg.Wait error(%v)", err)
return
}
if _, ok := groups[p.Lid]; ok {
group = groups[p.Lid]
} else {
err = ecode.ActivityNotExist
return
}
if subject.ID == 0 || subject.Type != l.MISSIONGROUP || group.ID == 0 || group.Sid != p.Sid {
err = ecode.ActivityNotExist
return
}
if group.Mid == mid {
err = ecode.ActivityMGNotYourself
return
}
if memberRly, err = s.accClient.Profile3(c, &accapi.MidReq{Mid: mid}); err != nil {
log.Error(" s.acc.Profile3(c,&accmdl.ArgMid{Mid:%d}) error(%v)", mid, err)
return
}
if err = s.judgeUser(c, subject, memberRly.Profile); err != nil {
return
}
if subject.Lstime.Time().Unix() >= now {
err = ecode.ActivityMissionNotStart
return
}
if subject.Letime.Time().Unix() <= now {
err = ecode.ActivityMissionHasEnd
return
}
if ActMissionID, err = s.dao.ActMission(c, p.Sid, p.Lid, mid); err != nil {
log.Error("s.dao.ActMission(%v) error(%+v)", p, err)
return
}
if ActMissionID > 0 {
err = ecode.ActivityHasMission
return
}
if subject.LikeLimit > 0 {
if likeLimit, err = s.dao.MissionLikeLimit(c, p.Sid, mid); err != nil {
log.Error("s.dao.ActMission(%v) error(%+v)", p, err)
return
}
if likeLimit >= subject.LikeLimit {
err = ecode.ActivityOverMissionLimit
return
}
}
if missionActCount, err = s.dao.SetMissionTop(c, p.Sid, p.Lid, score, now); err != nil {
log.Error("s.dao.SetMissionTop(%v) error(%+v)", p, err)
return
}
missionActList = &l.ActMissionGroup{
Lid: p.Lid,
Sid: p.Sid,
Mid: mid,
Action: score,
IPv6: make([]byte, 0),
}
if IPv6 := net.ParseIP(metadata.String(c, metadata.RemoteIP)); IPv6 != nil {
missionActList.IPv6 = IPv6
}
if mLid, err = s.dao.AddActMission(c, missionActList); err != nil {
log.Error("s.dao.AddActMission(%v) error(%+v)", p, err)
return
}
egT, errCtxT := errgroup.WithContext(c)
egT.Go(func() error {
missionErr = s.dao.AddCacheActMission(errCtxT, p.Sid, mLid, p.Lid, mid)
return missionErr
})
egT.Go(func() error {
caculErr = s.CalculateAchievement(errCtxT, p.Sid, group.Mid, missionActCount)
return caculErr
})
egT.Go(func() error {
_, incrErr = s.dao.InrcMissionLikeLimit(errCtxT, p.Sid, mid, score)
return incrErr
})
if err = egT.Wait(); err != nil {
log.Error("MissionLikeAct:eg.Wait add cache error(%v)", err)
return
}
if lottery, err = s.dao.LotteryIndex(c, s.c.Rule.LotteryActID, int64(0), int64(0), mid); err != nil {
log.Error("s.dao.LotteryIndex(%d) mid(%d) error(%+v)", s.c.Rule.LotteryActID, mid, err)
return
}
data = &l.MissionLikeAct{
Mlid: mLid,
Lottery: lottery,
}
return
}
// CalculateAchievement .
func (s *Service) CalculateAchievement(c context.Context, sid, mid int64, missionCount int64) (err error) {
var (
achieves *l.Achievements
avState int64
)
if achieves, err = s.dao.ActLikeAchieves(c, sid); err != nil {
log.Error("s.dao.ActLikeAchieves(%d,%d) error(%v)", sid, mid, err)
return
}
if len(achieves.Achievements) > 0 {
for _, v := range achieves.Achievements {
if v.Unlock == missionCount {
if v.Award == ldao.HaveAward {
avState = ldao.AwardNotChange
} else {
avState = ldao.AwardNoGet
}
if _, err = s.dao.AddUserAchievment(c, &l.ActLikeUserAchievement{Aid: v.ID, Sid: sid, Mid: mid, Award: avState}); err != nil {
log.Error("s.dao.AddUserAchievment(%d,%d,%v) error(%+v)", sid, mid, v, err)
return
}
break
}
}
}
return
}
// MissionRank get user rank .
func (s *Service) MissionRank(c context.Context, sid, mid int64) (data *l.MissionRank, err error) {
data = &l.MissionRank{Rank: -1}
if data.Lid, err = s.dao.LikeMissionBuff(c, sid, mid); err != nil {
log.Error("s.dao.LikeMissionBuff(%d,%d) error(%+v)", sid, mid, err)
return
}
if data.Lid > 0 {
if data.Score, err = s.dao.MissionLidScore(c, sid, data.Lid); err != nil {
log.Error("s.dao.MissionLidScore(%d,%d) error(%+v)", sid, data.Lid, err)
return
}
if data.Rank, err = s.dao.MissionLidRank(c, sid, data.Lid); err != nil {
log.Error("s.dao.MissionLidRank(%d,%d) error(%+v)", sid, data.Lid, err)
return
}
if data.Rank >= 0 {
data.Rank = data.Rank + 1
}
}
return
}
// MissionTops get the top list .
func (s *Service) MissionTops(c context.Context, sid int64, num int) (data []*l.MissionFriends, err error) {
var (
lids []int64
lidsList map[int64]*l.MissionGroup
mids []int64
membersRly *accapi.InfosReply
)
if lids, err = s.dao.MissionScoreList(c, sid, 0, num-1); err != nil {
log.Error("s.dao.MissionScoreList(%d) error(%+v)", sid, err)
return
}
if len(lids) > 0 {
if lidsList, err = s.dao.MissionGroupItems(c, lids); err != nil {
log.Error("s.dao.MissionGroupItems(%v) error(%v)", lids, err)
return
}
mids = make([]int64, 0, len(lidsList))
for _, v := range lidsList {
if v.ID > 0 {
mids = append(mids, v.Mid)
}
}
if len(mids) > 0 {
if membersRly, err = s.accClient.Infos3(c, &accapi.MidsReq{Mids: mids}); err != nil {
log.Error("s.acc.Infos3(%v) error(%v)", mids, err)
return
}
}
data = make([]*l.MissionFriends, 0, len(lids))
for _, v := range lids {
if _, ok := lidsList[v]; ok {
n := &l.MissionFriends{Mid: lidsList[v].Mid}
if membersRly != nil {
if val, y := membersRly.Infos[lidsList[v].Mid]; y {
n.Name = val.Name
n.Face = val.Face
}
}
data = append(data, n)
}
}
}
return
}
// MissionFriendsList .
func (s *Service) MissionFriendsList(c context.Context, p *l.ParamMissionFriends, mid int64) (data []*l.MissionFriends, err error) {
var (
groups map[int64]*l.MissionGroup
ActList []*l.ActMissionGroup
ActMissions *l.ActMissionGroups
mids []int64
membersRly *accapi.InfosReply
score int64
actLen int
)
if groups, err = s.dao.MissionGroupItems(c, []int64{p.Lid}); err != nil {
log.Error("s.dao.MissionGroupItems(%d) error(%v)", p.Lid, err)
return
}
if _, ok := groups[p.Lid]; !ok {
err = ecode.ActivityNotExist
return
}
if groups[p.Lid].ID == 0 || groups[p.Lid].Mid != mid || groups[p.Lid].Sid != p.Sid {
err = ecode.ActivityNotExist
return
}
if ActMissions, err = s.dao.ActMissionFriends(c, p.Sid, p.Lid); err != nil {
log.Error("s.dao.ActMissionFriends(%v) error(%+v)", p, err)
return
}
ActList = ActMissions.ActMissionGroups
actLen = len(ActList)
score, _ = s.dao.MissionLidScore(c, p.Sid, p.Lid)
if int64(actLen) < score && actLen < p.Size {
// need to update cache
s.dao.DelCacheActMissionFriends(c, p.Sid, p.Lid)
if ActMissions, err = s.dao.ActMissionFriends(c, p.Sid, p.Lid); err != nil {
log.Error("s.dao.ActMissionFriends(%v) error(%+v)", p, err)
return
}
ActList = ActMissions.ActMissionGroups
actLen = len(ActList)
}
if actLen > p.Size {
ActList = ActList[:p.Size]
actLen = p.Size
}
mids = make([]int64, 0, actLen)
for _, v := range ActList {
mids = append(mids, v.Mid)
}
if len(mids) > 0 {
if membersRly, err = s.accClient.Infos3(c, &accapi.MidsReq{Mids: mids}); err != nil {
log.Error("s.acc.Infos3(%v) error(%v)", mids, err)
return
}
}
data = make([]*l.MissionFriends, 0, len(ActList))
for _, v := range ActList {
n := &l.MissionFriends{Mid: v.Mid}
if membersRly != nil {
if val, y := membersRly.Infos[v.Mid]; y {
n.Name = val.Name
n.Face = val.Face
}
}
data = append(data, n)
}
return
}
// MissionAward .
func (s *Service) MissionAward(c context.Context, sid, mid int64) (data []*l.MissionAward, err error) {
var (
achieves *l.Achievements
userAchieves []*l.ActLikeUserAchievement
userAchMap map[int64]*l.ActLikeUserAchievement
achErr error
userErr error
)
eg, errCtx := errgroup.WithContext(c)
eg.Go(func() error {
achieves, achErr = s.dao.ActLikeAchieves(errCtx, sid)
return achErr
})
eg.Go(func() error {
userAchieves, userErr = s.dao.UserAchievement(c, sid, mid)
return userErr
})
if err = eg.Wait(); err != nil {
log.Error("MissionAward:eg.Wait() error(%+v)", err)
return
}
userAchMap = make(map[int64]*l.ActLikeUserAchievement, len(userAchieves))
for _, v := range userAchieves {
userAchMap[v.Aid] = v
}
for _, val := range achieves.Achievements {
n := &l.MissionAward{Name: val.Name, Image: val.Image}
if v, ok := userAchMap[val.ID]; ok {
n.ID = v.ID
n.Award = v.Award
}
data = append(data, n)
}
return
}
// MissionAchieve .
func (s *Service) MissionAchieve(c context.Context, sid, id, mid int64) (res int64, err error) {
var (
useActAchieve *l.ActLikeUserAchievement
award int64
)
if useActAchieve, err = s.dao.ActUserAchieve(c, id); err != nil {
log.Error("s.dao.ActUserAchieve(%d) error(%+v)", id, err)
return
}
if useActAchieve.ID == 0 || useActAchieve.Mid != mid || useActAchieve.Sid != sid {
err = ecode.ActivityNotAward
return
}
if award, err = s.dao.CacheActUserAward(c, id); err != nil {
log.Info("s.dao.CacheActUserAward(%d) error(%v)", id, err)
}
if award > 0 {
err = ecode.ActivityHasAward
return
}
if res, err = s.dao.ActUserAchieveChange(c, id, ldao.AwardHasChange); err != nil {
log.Error("s.dao.ActUserAchieveChange(%d) error(%+v)", id, err)
return
}
s.dao.AddCacheActUserAward(c, id, id)
return
}

View File

@@ -0,0 +1,99 @@
package like
import (
"context"
"fmt"
"testing"
l "go-common/app/interface/main/activity/model/like"
"encoding/json"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_MissionLike(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
lid, err := svf.MissionLike(context.Background(), 10293, 15555180)
So(err, ShouldBeNil)
fmt.Printf("%d", lid)
}))
}
func TestService_MissionInfo(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.MissionInfo(context.Background(), 10292, 2, 442549)
So(err, ShouldBeNil)
fmt.Printf("%+v", res)
}))
}
func TestService_MissionLikeAct(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.MissionLikeAct(context.Background(), &l.ParamMissionLikeAct{Sid: 10292, Lid: 17}, 216761)
So(err, ShouldBeNil)
bs, _ := json.Marshal(res)
Printf("%+v", string(bs))
}))
}
func TestService__MissionTops(t *testing.T) {
Convey("test set like act", t, WithService(func(svf *Service) {
acts, err := svf.MissionTops(context.Background(), 10292, 50)
So(err, ShouldBeNil)
for _, v := range acts {
fmt.Printf("%+v", v)
}
}))
}
func TestService_CalculateAchievement(t *testing.T) {
Convey("test set like act", t, WithService(func(svf *Service) {
err := svf.CalculateAchievement(context.Background(), 10292, 15555180, 10)
So(err, ShouldBeNil)
}))
}
func TestService_MissionRank(t *testing.T) {
Convey("test set like act", t, WithService(func(svf *Service) {
res, err := svf.MissionRank(context.Background(), 10292, 14137123)
So(err, ShouldBeNil)
fmt.Printf("%+v", res)
}))
}
func TestService_MissionFriendsList(t *testing.T) {
Convey("test set like act", t, WithService(func(svf *Service) {
res, err := svf.MissionFriendsList(context.Background(), &l.ParamMissionFriends{Sid: 10292, Lid: 11, Size: 5}, 216761)
So(err, ShouldBeNil)
for _, v := range res {
fmt.Printf("%+v", v)
}
}))
}
func TestService_MissionAward(t *testing.T) {
Convey("test set like act", t, WithService(func(svf *Service) {
res, err := svf.MissionAward(context.Background(), 10292, 2089809)
So(err, ShouldBeNil)
for _, v := range res {
fmt.Printf("%+v", v)
}
}))
}
func TestService_MissionAchieve(t *testing.T) {
Convey("test set like act", t, WithService(func(svf *Service) {
res, err := svf.MissionAchieve(context.Background(), 10292, 4, 2089809)
So(err, ShouldBeNil)
Printf("%d", res)
}))
}
func TestService_MissionUser(t *testing.T) {
Convey("test set like act", t, WithService(func(svf *Service) {
res, err := svf.MissionUser(context.Background(), 10292, 12)
So(err, ShouldBeNil)
Printf("%+v", res)
}))
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
package like
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/activity/conf"
"go-common/app/interface/main/activity/model/like"
"fmt"
. "github.com/smartystreets/goconvey/convey"
)
var svf *Service
func init() {
dir, _ := filepath.Abs("../../cmd/activity-test.toml")
flag.Set("conf", dir)
if err := conf.Init(); err != nil {
panic(err)
}
if svf == nil {
svf = New(conf.Conf)
}
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(svf)
}
}
func TestService_Subject(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.Subject(context.Background(), 1)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
}))
}
func TestService_LikeAct(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.LikeAct(context.Background(), &like.ParamAddLikeAct{Sid: 10296, Lid: 13513, Score: 1}, 27515615)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
}))
}
func TestService_LikeActList(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.LikeActList(context.Background(), 10296, 2089809, []int64{13510, 13511, 13514, 13513})
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
fmt.Printf("res %v", res)
}))
}
func TestService_StoryKingAct(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.StoryKingAct(context.Background(), &like.ParamStoryKingAct{Sid: 10365, Lid: 2357, Score: 1}, 27515615)
So(err, ShouldBeNil)
fmt.Printf("%v", res)
}))
}
func TestService_StoryKingLeftTime(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.StoryKingLeftTime(context.Background(), 10296, 55555)
So(err, ShouldBeNil)
fmt.Printf("%d", res)
}))
}
func TestService_storyEachUsed(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.storyEachUsed(context.Background(), 10296, 216761, 13538)
So(err, ShouldBeNil)
fmt.Printf("%d", res)
}))
}
func TestService_StoryKingList(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.StoryKingList(context.Background(), &like.ParamList{Sid: 1, Pn: 1, Ps: 100, Type: "random"}, 27515257)
So(err, ShouldBeNil)
fmt.Printf("%v", res)
}))
}
func TestService_UpList(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res, err := svf.UpList(context.Background(), &like.ParamList{Sid: 10259, Pn: 1, Ps: 100, Type: "random"}, 27515257)
So(err, ShouldBeNil)
if res != nil {
if len(res.List) > 0 {
for _, v := range res.List {
fmt.Printf("%v %v", v.Item, v.Object)
}
}
}
}))
}

View File

@@ -0,0 +1,248 @@
package like
import (
"context"
"time"
ldao "go-common/app/interface/main/activity/dao/like"
"go-common/app/interface/main/activity/model/like"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
// SubjectInitialize act_subject data initialize .
func (s *Service) SubjectInitialize(c context.Context, minSid int64) (err error) {
if minSid < 0 {
minSid = 0
}
var actSub []*like.SubjectItem
for {
if actSub, err = s.dao.SubjectListMoreSid(c, minSid); err != nil {
log.Error("dao.subjectListMoreSid(%d) error(%+v)", minSid, err)
break
}
// empty slice or nil
if len(actSub) == 0 {
log.Info("SubjectInitialize end success")
break
}
for _, sub := range actSub {
item := sub
if minSid < item.ID {
minSid = item.ID
}
id := item.ID
//the activity offline is stored with empty data
if item.State != ldao.SubjectValidState {
item = &like.SubjectItem{}
}
s.cache.Do(c, func(c context.Context) {
s.dao.AddCacheActSubject(c, id, item)
})
}
}
s.cache.Do(c, func(c context.Context) {
s.SubjectMaxIDInitialize(c)
})
return
}
// SubjectMaxIDInitialize Initialize act_subject max id data .
func (s *Service) SubjectMaxIDInitialize(c context.Context) (err error) {
var actSub *like.SubjectItem
if actSub, err = s.dao.SubjectMaxID(c); err != nil {
log.Error(" s.dao.SubjectMaxID() error(%+v)", err)
return
}
if actSub.ID >= 0 {
if err = s.dao.AddCacheActSubjectMaxID(c, actSub.ID); err != nil {
log.Error("s.dao.AddCacheActSubjectMaxID(%d) error(%v)", actSub.ID, err)
}
}
return
}
// SubjectUp up act_subject cahce info .
func (s *Service) SubjectUp(c context.Context, sid int64) (err error) {
var (
actSub *like.SubjectItem
maxSubID int64
)
group, ctx := errgroup.WithContext(c)
group.Go(func() (e error) {
if actSub, e = s.dao.RawActSubject(ctx, sid); e != nil {
log.Error("dao.RawActSubject(%d) error(%+v)", sid, e)
}
return
})
group.Go(func() (e error) {
if maxSubID, e = s.dao.CacheActSubjectMaxID(ctx); e != nil {
log.Error("dao.RawActSubject(%d) error(%v)", sid, e)
}
return
})
if err = group.Wait(); err != nil {
log.Error("SubjectUp error(%v)", err)
return
}
if actSub.ID == 0 || actSub.State != ldao.SubjectValidState {
actSub = &like.SubjectItem{}
}
if maxSubID < sid {
s.cache.Do(c, func(c context.Context) {
s.dao.AddCacheActSubjectMaxID(context.Background(), sid)
})
}
s.cache.Do(c, func(c context.Context) {
s.dao.AddCacheActSubject(context.Background(), sid, actSub)
})
return
}
// SubjectLikeListInitialize Initialize likes list .
func (s *Service) SubjectLikeListInitialize(c context.Context, sid int64) (err error) {
var (
actSub *like.SubjectItem
items []*like.Item
lid = int64(0)
)
if actSub, err = s.dao.RawActSubject(c, sid); err != nil {
log.Error("dao.RawActSubject(%d) error(%+v)", sid, err)
return
}
if actSub.ID == 0 {
log.Info("SubjectSLikeListInitialize end success")
return
}
for {
if items, err = s.dao.LikesBySid(c, lid, sid); err != nil {
log.Error("dao.LikesBySid(%d,%d) error(%+v)", lid, sid, err)
break
}
// empty slice or nil
if len(items) == 0 {
log.Info("SubjectSLikeListInitialize end success")
break
}
//Initialize likes ctime cache
cItems := items
s.cache.Do(c, func(c context.Context) {
s.dao.LikeListCtime(c, sid, cItems)
})
for _, val := range items {
if lid < val.ID {
lid = val.ID
}
}
}
return
}
// LikeActCountInitialize Initialize like_action cache data .
func (s *Service) LikeActCountInitialize(c context.Context, sid int64) (err error) {
var (
actSub *like.SubjectItem
items []*like.Item
lid = int64(0)
types = make(map[int64]int)
likeSumItem []*like.LidLikeSum
)
if actSub, err = s.dao.RawActSubject(c, sid); err != nil {
log.Error("dao.RawActSubject(%d) error(%+v)", sid, err)
return
}
if actSub.ID == 0 {
log.Info("SubjectSLikeListInitialize end success")
return
}
for {
if items, err = s.dao.LikesBySid(c, lid, sid); err != nil {
log.Error("dao.LikesBySid(%d,%d) error(%+v)", lid, sid, err)
break
}
if len(items) == 0 {
log.Info("SubjectSLikeListInitialize end success")
break
}
lidList := make([]int64, 0, len(items))
for _, val := range items {
if lid < val.ID {
lid = val.ID
}
lidList = append(lidList, val.ID)
types[val.ID] = val.Type
}
if likeSumItem, err = s.dao.LikeActSums(c, sid, lidList); err != nil {
log.Error(" s.dao.LikeActSums(%d,%v) error(%+v)", sid, lidList, err)
return
}
if len(likeSumItem) == 0 {
continue
}
lidLike := make(map[int64]int64, len(likeSumItem))
for _, v := range likeSumItem {
lidLike[v.Lid] = v.Likes
}
eg, errCtx := errgroup.WithContext(c)
eg.Go(func() (e error) {
e = s.dao.SetInitializeLikeCache(errCtx, sid, lidLike, types)
return
})
eg.Go(func() (e error) {
e = s.SetLikeActSum(errCtx, lidLike)
return
})
if err = eg.Wait(); err != nil {
log.Error("LikeActCountInitialize:eg.Wait() error(%+v)", err)
return
}
}
return
}
// SetLikeActSum set like_extend sum data
func (s *Service) SetLikeActSum(c context.Context, lidLikes map[int64]int64) (err error) {
var (
AddLids []*like.Extend
)
if len(lidLikes) == 0 {
return
}
for k, v := range lidLikes {
AddLids = append(AddLids, &like.Extend{Like: v, Lid: k})
}
_, err = s.BatchInsertLikeExtend(c, AddLids)
return
}
// ActSubject .
func (s *Service) ActSubject(c context.Context, sid int64) (res *like.SubjectItem, err error) {
if res, err = s.dao.ActSubject(c, sid); err != nil {
return
}
if res == nil {
err = ecode.NothingFound
}
return
}
// ActProtocol .
func (s *Service) ActProtocol(c context.Context, a *like.ArgActProtocol) (res *like.SubProtocol, err error) {
res = new(like.SubProtocol)
if res.SubjectItem, err = s.dao.ActSubject(c, a.Sid); err != nil {
log.Error("s.dao.ActSubject() error(%+v)", err)
return
}
if res.SubjectItem.ID == 0 {
err = ecode.NothingFound
return
}
now := time.Now().Unix()
if int64(res.SubjectItem.Stime) <= now && int64(res.SubjectItem.Etime) >= now {
if res.ActSubjectProtocol, err = s.dao.ActSubjectProtocol(c, a.Sid); err != nil {
log.Error("s.dao.ActSubjectProtocol(%d) error(%+v)", a.Sid, err)
}
}
return
}

View File

@@ -0,0 +1,67 @@
package like
import (
"context"
"testing"
"time"
"go-common/app/interface/main/activity/model/like"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_SubjectInitialize(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
err := svf.SubjectInitialize(context.Background(), 10292)
time.Sleep(time.Second)
So(err, ShouldBeNil)
}))
}
func TestService_SubjectMaxIDInitialize(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
err := svf.SubjectMaxIDInitialize(context.Background())
So(err, ShouldBeNil)
}))
}
func TestService_SubjectLikeListInitialize(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
err := svf.SubjectLikeListInitialize(context.Background(), 10256)
time.Sleep(time.Second)
So(err, ShouldBeNil)
}))
}
func TestService_LikeActCountInitialize(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
err := svf.LikeActCountInitialize(context.Background(), 10256)
time.Sleep(time.Second)
So(err, ShouldBeNil)
}))
}
func TestService_SubjectUp(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
err := svf.SubjectUp(context.Background(), 10256)
time.Sleep(time.Second)
So(err, ShouldBeNil)
}))
}
func TestService_ActSubject(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
data, err := svf.ActSubject(context.Background(), 10340)
time.Sleep(time.Second)
So(err, ShouldBeNil)
Printf("%+v", data)
}))
}
func TestService_ActProtocol(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
data, _ := svf.ActProtocol(context.Background(), &like.ArgActProtocol{Sid: 10274})
time.Sleep(time.Second)
Printf("%+v %+v", data, data.Protocol)
}))
}