123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- package dao
- import (
- "bytes"
- "crypto/md5"
- "encoding/hex"
- "net/url"
- "strconv"
- "time"
- "go-common/app/interface/main/creative/model/data"
- "go-common/app/interface/openplatform/article/model"
- "go-common/library/ecode"
- "go-common/library/log"
- "golang.org/x/net/context"
- )
- var (
- //HBaseArticleTable 文章作者概况
- HBaseArticleTable = "read_auth_stats_daily"
- )
- func hbaseMd5Key(aid int64) []byte {
- hasher := md5.New()
- hasher.Write([]byte(strconv.Itoa(int(aid))))
- return []byte(hex.EncodeToString(hasher.Sum(nil)))
- }
- // UpStat get the stat of article.
- func (d *Dao) UpStat(c context.Context, mid int64) (stat model.UpStat, err error) {
- var (
- tableName = HBaseArticleTable
- )
- result, err := d.hbase.Get(c, []byte(tableName), hbaseMd5Key(mid))
- if err != nil {
- log.Error("bigdata: d.hbase.Get BackupTable(%s, %d) error(%+v)", tableName, mid, err)
- PromError("bigdata:hbase")
- err = ecode.CreativeDataErr
- return
- }
- if result == nil {
- return
- }
- for _, c := range result.Cells {
- if c == nil {
- continue
- }
- v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
- if !bytes.Equal(c.Family, []byte("r")) {
- continue
- }
- switch {
- case bytes.Equal(c.Qualifier, []byte("view1")):
- stat.View = v
- case bytes.Equal(c.Qualifier, []byte("reply1")):
- stat.Reply = v
- case bytes.Equal(c.Qualifier, []byte("coin1")):
- stat.Coin = v
- case bytes.Equal(c.Qualifier, []byte("like1")):
- stat.Like = v
- case bytes.Equal(c.Qualifier, []byte("fav1")):
- stat.Fav = v
- case bytes.Equal(c.Qualifier, []byte("share1")):
- stat.Share = v
- case bytes.Equal(c.Qualifier, []byte("view0")):
- stat.PreView = v
- case bytes.Equal(c.Qualifier, []byte("reply0")):
- stat.PreReply = v
- case bytes.Equal(c.Qualifier, []byte("coin0")):
- stat.PreCoin = v
- case bytes.Equal(c.Qualifier, []byte("like0")):
- stat.PreLike = v
- case bytes.Equal(c.Qualifier, []byte("fav0")):
- stat.PreFav = v
- case bytes.Equal(c.Qualifier, []byte("share0")):
- stat.PreShare = v
- }
- }
- stat.IncrView = stat.View - stat.PreView
- stat.IncrReply = stat.Reply - stat.PreReply
- stat.IncrCoin = stat.Coin - stat.PreCoin
- stat.IncrLike = stat.Like - stat.PreLike
- stat.IncrFav = stat.Fav - stat.PreFav
- stat.IncrShare = stat.Share - stat.PreShare
- d.AddCacheUpStatDaily(c, mid, &stat)
- return
- }
- // ThirtyDayArticle for Read/Reply/Like/Fav/Coin for article 30 days.
- func (d *Dao) ThirtyDayArticle(c context.Context, mid int64) (res []*model.ThirtyDayArticle, err error) {
- var (
- tableName = "read_auth_stats" //文章30天数据
- )
- result, err := d.hbase.Get(c, []byte(tableName), hbaseMd5Key(mid))
- if err != nil {
- log.Error("bigdata: d.hbase.Get tableName(%s) mid(%d) error(%+v)", tableName, mid, err)
- PromError("bigdata:30天数据")
- err = ecode.CreativeDataErr
- return
- }
- if result == nil || len(result.Cells) == 0 {
- log.Warn("bigdata: ThirtyDay article no data (%s, %d)", tableName, mid)
- PromError("bigdata:30天数据")
- return
- }
- res = make([]*model.ThirtyDayArticle, 0, 5)
- vtds := make([]*data.ThirtyDay, 0, 30)
- ptds := make([]*data.ThirtyDay, 0, 30)
- ltds := make([]*data.ThirtyDay, 0, 30)
- ftds := make([]*data.ThirtyDay, 0, 30)
- ctds := make([]*data.ThirtyDay, 0, 30)
- view := &model.ThirtyDayArticle{Category: "view"}
- reply := &model.ThirtyDayArticle{Category: "reply"}
- like := &model.ThirtyDayArticle{Category: "like"}
- fav := &model.ThirtyDayArticle{Category: "fav"}
- coin := &model.ThirtyDayArticle{Category: "coin"}
- for _, c := range result.Cells {
- if c == nil {
- continue
- }
- family := string(c.Family)
- qual := string(c.Qualifier[:])
- val := string(c.Value[:])
- switch family {
- case "v": //"阅读量"
- t, v, err := parseKeyValue(qual, val)
- if err != nil {
- break
- }
- td := &data.ThirtyDay{}
- td.DateKey = t
- td.TotalIncr = v
- vtds = append(vtds, td)
- view.ThirtyDay = vtds
- case "p": //"评论量"
- t, v, err := parseKeyValue(qual, val)
- if err != nil {
- break
- }
- td := &data.ThirtyDay{}
- td.DateKey = t
- td.TotalIncr = v
- ptds = append(ptds, td)
- reply.Category = "reply"
- reply.ThirtyDay = ptds
- case "l": //"点赞量"
- t, v, err := parseKeyValue(qual, val)
- if err != nil {
- break
- }
- td := &data.ThirtyDay{}
- td.DateKey = t
- td.TotalIncr = v
- ltds = append(ltds, td)
- like.Category = "like"
- like.ThirtyDay = ltds
- case "f": //"收藏量"
- t, v, err := parseKeyValue(qual, val)
- if err != nil {
- break
- }
- td := &data.ThirtyDay{}
- td.DateKey = t
- td.TotalIncr = v
- ftds = append(ftds, td)
- fav.Category = "fav"
- fav.ThirtyDay = ftds
- case "c": //"投币量"
- t, v, err := parseKeyValue(qual, val)
- if err != nil {
- break
- }
- td := &data.ThirtyDay{}
- td.DateKey = t
- td.TotalIncr = v
- ctds = append(ctds, td)
- coin.Category = "coin"
- coin.ThirtyDay = ctds
- }
- }
- res = append(res, view)
- res = append(res, reply)
- res = append(res, like)
- res = append(res, fav)
- res = append(res, coin)
- return
- }
- func parseKeyValue(k string, v string) (timestamp, value int64, err error) {
- tm, err := time.Parse("20060102", k)
- if err != nil {
- log.Error("time.Parse error(%+v)", err)
- return
- }
- timestamp = tm.Unix()
- value, err = strconv.ParseInt(v, 10, 64)
- if err != nil {
- log.Error("strconv.ParseInt error(%+v)", err)
- }
- return
- }
- // SkyHorse sky horse
- func (d *Dao) SkyHorse(c context.Context, mid int64, build int, buvid string, plat int8, ps int) (res *model.SkyHorseResp, err error) {
- if buvid == "" {
- err = ecode.NothingFound
- return
- }
- params := url.Values{}
- params.Set("cmd", "article")
- params.Set("mid", strconv.FormatInt(mid, 10))
- params.Set("buvid", buvid)
- params.Set("build", strconv.Itoa(build))
- params.Set("plat", strconv.FormatInt(int64(plat), 10))
- params.Set("ts", strconv.FormatInt(time.Now().Unix(), 10))
- params.Set("request_cnt", strconv.Itoa(ps))
- params.Set("from", "8")
- res = &model.SkyHorseResp{}
- err = d.httpClient.Get(c, d.c.Article.SkyHorseURL, "", params, &res)
- if err != nil {
- PromError("bigdata:天马接口")
- log.Error("bigdata: d.client.Get(%s) error(%+v)", d.c.Article.SkyHorseURL+"?"+params.Encode(), err)
- return
- }
- // -3: 数量不足
- if res.Code != 0 && res.Code != -3 {
- PromError("bigdata:天马接口")
- log.Error("bigdata: url(%s) res: %+v", d.c.Article.SkyHorseURL+"?"+params.Encode(), res)
- err = ecode.Int(res.Code)
- return
- }
- if len(res.Data) == 0 {
- PromError("bigdata:天马返回空")
- log.Warn("bigdata: url(%s) res: %+v", d.c.Article.SkyHorseURL+"?"+params.Encode(), res)
- }
- return
- }
|