354 lines
13 KiB
Go
354 lines
13 KiB
Go
|
package dao
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"context"
|
||
|
"encoding/binary"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"math"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"go-common/app/job/main/figure-timer/model"
|
||
|
"go-common/library/log"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
"github.com/tsuna/gohbase/hrpc"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// record
|
||
|
_hbaseRecordTable = "ugc:figurecalcrecord"
|
||
|
_hbaseRecordFC = "x"
|
||
|
_hbaseRecordQLawfulPosX = "pos_lawful"
|
||
|
_hbaseRecordQLawfulNegX = "neg_lawful"
|
||
|
_hbaseRecordQWidePosX = "pos_wide"
|
||
|
_hbaseRecordQWideNegX = "neg_wide"
|
||
|
_hbaseRecordQFriendlyPosX = "pos_friendly"
|
||
|
_hbaseRecordQFriendlyNegX = "neg_friendly"
|
||
|
_hbaseRecordQCreativityPosX = "pos_creativity"
|
||
|
_hbaseRecordQCreativityNegX = "neg_creativity"
|
||
|
_hbaseRecordQBountyPosX = "pos_bounty"
|
||
|
_hbaseRecordQBountyNegX = "neg_bounty"
|
||
|
// UserInfo
|
||
|
_hbaseUserTable = "ugc:figureuserstatus"
|
||
|
_hbaseUserFC = "user"
|
||
|
_hbaseUserQExp = "exp"
|
||
|
_hbaseUserQSpy = "spy_score"
|
||
|
_hbaseUserQArchiveViews = "archive_views"
|
||
|
_hbaseUserQVip = "vip_status"
|
||
|
_hbaseUserQDisciplineCommittee = "discipline_committee"
|
||
|
// ActionCounter
|
||
|
_hbaseActionTable = "ugc:figureactioncounter"
|
||
|
_hbaseActionFC = "user"
|
||
|
_hbaseActionQCoinCount = "coins"
|
||
|
_hbaseActionQReplyCount = "replies"
|
||
|
_hbaseActionQDanmakuCount = "danmaku"
|
||
|
_hbaseActionQCoinLowRisk = "coin_low_risk"
|
||
|
_hbaseActionQCoinHighRisk = "coin_high_risk"
|
||
|
_hbaseActionQReplyLowRisk = "reply_low_risk"
|
||
|
_hbaseActionQReplyHighRisk = "reply_high_risk"
|
||
|
_hbaseActionQReplyLiked = "reply_liked"
|
||
|
_hbaseActionQReplyUnLiked = "reply_hate"
|
||
|
|
||
|
_hbaseActionQReportReplyPassed = "report_reply_passed"
|
||
|
_hbaseActionQReportDanmakuPassed = "report_danmaku_passed"
|
||
|
_hbaseActionQPublishReplyDeleted = "publish_reply_deleted"
|
||
|
_hbaseActionQPublishDanmakuDeleted = "publish_danmaku_deleted"
|
||
|
_hbaseActionQPayMoney = "pay_money"
|
||
|
_hbaseActionQPayLiveMoney = "pay_live_money"
|
||
|
)
|
||
|
|
||
|
func rowKeyFigureRecord(mid int64, weekTS int64) (key string) {
|
||
|
return fmt.Sprintf("%d_%d", mid, weekTS)
|
||
|
}
|
||
|
|
||
|
func rowKeyUserInfo(mid int64) (key string) {
|
||
|
return fmt.Sprintf("%d", mid)
|
||
|
}
|
||
|
|
||
|
func rowKeyActionCounter(mid int64, dayTS int64) (key string) {
|
||
|
return fmt.Sprintf("%d_%d", mid, dayTS)
|
||
|
}
|
||
|
|
||
|
// UserInfo get it from hbase
|
||
|
func (d *Dao) UserInfo(c context.Context, mid int64, weekVer int64) (userInfo *model.UserInfo, err error) {
|
||
|
var (
|
||
|
result *hrpc.Result
|
||
|
key = rowKeyUserInfo(mid)
|
||
|
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.ReadTimeout))
|
||
|
)
|
||
|
defer cancel()
|
||
|
if result, err = d.hbase.GetStr(ctx, _hbaseUserTable, key); err != nil {
|
||
|
err = errors.Wrapf(err, "hbase.GetStr(%s,%s)", _hbaseUserTable, key)
|
||
|
return
|
||
|
}
|
||
|
userInfo = &model.UserInfo{Mid: mid, SpyScore: math.MaxUint64}
|
||
|
for _, c := range result.Cells {
|
||
|
if c == nil {
|
||
|
continue
|
||
|
}
|
||
|
if bytes.Equal([]byte(_hbaseUserFC), c.Family) {
|
||
|
switch string(c.Qualifier) {
|
||
|
case _hbaseUserQExp:
|
||
|
userInfo.Exp = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseUserQSpy:
|
||
|
userInfo.SpyScore = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseUserQArchiveViews:
|
||
|
userInfo.ArchiveViews = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseUserQVip:
|
||
|
userInfo.VIPStatus = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseUserQDisciplineCommittee:
|
||
|
userInfo.DisciplineCommittee = binary.BigEndian.Uint16(c.Value)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// 未获取到spy分值特殊处理
|
||
|
if userInfo.SpyScore == math.MaxUint64 {
|
||
|
userInfo.SpyScore = 100
|
||
|
}
|
||
|
log.Info("User Info [%+v]", userInfo)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// PutCalcRecord put record all the params x.
|
||
|
func (d *Dao) PutCalcRecord(c context.Context, record *model.FigureRecord, weekTS int64) (err error) {
|
||
|
var (
|
||
|
key = rowKeyFigureRecord(record.Mid, weekTS)
|
||
|
lawfulPosX = make([]byte, 8)
|
||
|
lawfulNegX = make([]byte, 8)
|
||
|
widePosX = make([]byte, 8)
|
||
|
wideNegX = make([]byte, 8)
|
||
|
friendlyPosX = make([]byte, 8)
|
||
|
friendlyNegX = make([]byte, 8)
|
||
|
creativityPosX = make([]byte, 8)
|
||
|
creativityNegX = make([]byte, 8)
|
||
|
bountyPosX = make([]byte, 8)
|
||
|
bountyNegX = make([]byte, 8)
|
||
|
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.WriteTimeout))
|
||
|
)
|
||
|
defer cancel()
|
||
|
binary.BigEndian.PutUint64(lawfulPosX, uint64(record.XPosLawful))
|
||
|
binary.BigEndian.PutUint64(lawfulNegX, uint64(record.XNegLawful))
|
||
|
binary.BigEndian.PutUint64(widePosX, uint64(record.XPosWide))
|
||
|
binary.BigEndian.PutUint64(wideNegX, uint64(record.XNegWide))
|
||
|
binary.BigEndian.PutUint64(friendlyPosX, uint64(record.XPosFriendly))
|
||
|
binary.BigEndian.PutUint64(friendlyNegX, uint64(record.XNegFriendly))
|
||
|
binary.BigEndian.PutUint64(creativityPosX, uint64(record.XPosCreativity))
|
||
|
binary.BigEndian.PutUint64(creativityNegX, uint64(record.XNegCreativity))
|
||
|
binary.BigEndian.PutUint64(bountyPosX, uint64(record.XPosBounty))
|
||
|
binary.BigEndian.PutUint64(bountyNegX, uint64(record.XNegBounty))
|
||
|
values := map[string]map[string][]byte{_hbaseRecordFC: {
|
||
|
_hbaseRecordQLawfulPosX: lawfulPosX,
|
||
|
_hbaseRecordQLawfulNegX: lawfulNegX,
|
||
|
_hbaseRecordQWideNegX: wideNegX,
|
||
|
_hbaseRecordQFriendlyPosX: friendlyPosX,
|
||
|
_hbaseRecordQFriendlyNegX: friendlyNegX,
|
||
|
_hbaseRecordQCreativityPosX: creativityPosX,
|
||
|
_hbaseRecordQCreativityNegX: creativityNegX,
|
||
|
_hbaseRecordQBountyPosX: bountyPosX,
|
||
|
_hbaseRecordQBountyNegX: bountyNegX,
|
||
|
}}
|
||
|
if _, err = d.hbase.PutStr(ctx, _hbaseRecordTable, key, values); err != nil {
|
||
|
err = errors.Wrapf(err, "hbase.Put(%s,%s,%+v) error(%v)", _hbaseRecordTable, key, values, err)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// CalcRecords get it from hbase
|
||
|
func (d *Dao) CalcRecords(c context.Context, mid int64, weekTSFrom, weekTSTo int64) (figureRecords []*model.FigureRecord, err error) {
|
||
|
var (
|
||
|
scanner hrpc.Scanner
|
||
|
keyFrom = rowKeyFigureRecord(mid, weekTSFrom)
|
||
|
keyTo = rowKeyFigureRecord(mid, weekTSTo)
|
||
|
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.ReadTimeout))
|
||
|
)
|
||
|
defer cancel()
|
||
|
if scanner, err = d.hbase.ScanRangeStr(ctx, _hbaseRecordTable, keyFrom, keyTo); err != nil {
|
||
|
err = errors.Wrapf(err, "hbase.ScanRangeStr(%s,%s,%s)", _hbaseRecordTable, keyFrom, keyTo)
|
||
|
return
|
||
|
}
|
||
|
for {
|
||
|
res, err := scanner.Next()
|
||
|
if err != nil {
|
||
|
if err != io.EOF {
|
||
|
err = errors.WithStack(err)
|
||
|
return nil, err
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
figureRecord := &model.FigureRecord{Mid: mid}
|
||
|
for i, c := range res.Cells {
|
||
|
if c == nil {
|
||
|
continue
|
||
|
}
|
||
|
if bytes.Equal([]byte(_hbaseRecordFC), c.Family) {
|
||
|
switch string(c.Qualifier) {
|
||
|
case _hbaseRecordQLawfulPosX:
|
||
|
figureRecord.XPosLawful = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQLawfulNegX:
|
||
|
figureRecord.XNegLawful = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQWidePosX:
|
||
|
figureRecord.XPosWide = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQWideNegX:
|
||
|
figureRecord.XNegWide = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQFriendlyPosX:
|
||
|
figureRecord.XPosFriendly = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQFriendlyNegX:
|
||
|
figureRecord.XNegFriendly = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQCreativityPosX:
|
||
|
figureRecord.XPosCreativity = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQCreativityNegX:
|
||
|
figureRecord.XNegCreativity = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQBountyPosX:
|
||
|
figureRecord.XPosBounty = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseRecordQBountyNegX:
|
||
|
figureRecord.XNegBounty = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
}
|
||
|
}
|
||
|
if i == 0 {
|
||
|
figureRecord.Version = time.Unix(parseVersion(string(c.Row), c.Timestamp), 0)
|
||
|
}
|
||
|
}
|
||
|
log.Info("User figure record [%+v]", figureRecord)
|
||
|
figureRecords = append(figureRecords, figureRecord)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ActionCounter .
|
||
|
func (d *Dao) ActionCounter(c context.Context, mid int64, ts int64) (actionCounter *model.ActionCounter, err error) {
|
||
|
var (
|
||
|
result *hrpc.Result
|
||
|
key = rowKeyActionCounter(mid, ts)
|
||
|
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.ReadTimeout))
|
||
|
)
|
||
|
defer cancel()
|
||
|
log.Info("Get mid [%d] key [%s]", mid, key)
|
||
|
if result, err = d.hbase.GetStr(ctx, _hbaseActionTable, key); err != nil {
|
||
|
err = errors.Wrapf(err, "hbase.GetStr(%s,%s)", _hbaseActionTable, key)
|
||
|
return
|
||
|
}
|
||
|
actionCounter = &model.ActionCounter{Mid: mid}
|
||
|
for i, c := range result.Cells {
|
||
|
if c == nil {
|
||
|
continue
|
||
|
}
|
||
|
if bytes.Equal([]byte(_hbaseActionFC), c.Family) {
|
||
|
switch string(c.Qualifier) {
|
||
|
case _hbaseActionQCoinCount:
|
||
|
actionCounter.CoinCount = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseActionQReplyCount:
|
||
|
actionCounter.ReplyCount = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQDanmakuCount:
|
||
|
actionCounter.DanmakuCount = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQCoinLowRisk:
|
||
|
actionCounter.CoinLowRisk = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseActionQCoinHighRisk:
|
||
|
actionCounter.CoinHighRisk = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseActionQReplyLowRisk:
|
||
|
actionCounter.ReplyLowRisk = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseActionQReplyHighRisk:
|
||
|
actionCounter.ReplyHighRisk = binary.BigEndian.Uint64(c.Value)
|
||
|
case _hbaseActionQReplyLiked:
|
||
|
actionCounter.ReplyLiked = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQReplyUnLiked:
|
||
|
actionCounter.ReplyUnliked = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQReportReplyPassed:
|
||
|
actionCounter.ReportReplyPassed = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQReportDanmakuPassed:
|
||
|
actionCounter.ReportDanmakuPassed = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQPublishReplyDeleted:
|
||
|
actionCounter.PublishReplyDeleted = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQPublishDanmakuDeleted:
|
||
|
actionCounter.PublishDanmakuDeleted = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQPayMoney:
|
||
|
actionCounter.PayMoney = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
case _hbaseActionQPayLiveMoney:
|
||
|
actionCounter.PayLiveMoney = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
|
||
|
}
|
||
|
}
|
||
|
if i == 0 {
|
||
|
actionCounter.Version = time.Unix(parseVersion(string(c.Row), c.Timestamp), 0)
|
||
|
}
|
||
|
}
|
||
|
log.Info("User action counter [%+v]", actionCounter)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// // ActionCounters .
|
||
|
// func (d *Dao) ActionCounters(c context.Context, mid int64, tsfrom int64, tsto int64) (actionCounters []*model.ActionCounter, err error) {
|
||
|
// var (
|
||
|
// scan *hrpc.Scan
|
||
|
// results []*hrpc.Result
|
||
|
// keyFrom = rowKeyActionCounter(mid, tsfrom)
|
||
|
// keyTo = rowKeyActionCounter(mid, tsto)
|
||
|
// ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.ReadTimeout))
|
||
|
// )
|
||
|
// defer cancel()
|
||
|
// log.Info("Scan mid [%d] keyFrom [%s] keyTo [%s]", mid, keyFrom, keyTo)
|
||
|
// if scan, err = hrpc.NewScanRangeStr(ctx, _hbaseActionTable, keyFrom, keyTo); err != nil {
|
||
|
// err = errors.Wrapf(err, "hrcp.NewScanRangeStr(%s,%s,%s)", _hbaseActionTable, keyFrom, keyTo)
|
||
|
// return
|
||
|
// }
|
||
|
// if results, err = d.hbase.Scan(ctx, scan); err != nil {
|
||
|
// err = errors.Wrapf(err, "hbase.Scan(%s,%s,%s)", _hbaseActionTable, keyFrom, keyTo)
|
||
|
// return
|
||
|
// }
|
||
|
// if len(results) == 0 {
|
||
|
// return
|
||
|
// }
|
||
|
// for _, res := range results {
|
||
|
// if res == nil {
|
||
|
// continue
|
||
|
// }
|
||
|
// actionCounter := &model.ActionCounter{Mid: mid}
|
||
|
// for i, c := range res.Cells {
|
||
|
// if c == nil {
|
||
|
// continue
|
||
|
// }
|
||
|
// if bytes.Equal([]byte(_hbaseActionFC), c.Family) {
|
||
|
// switch string(c.Qualifier) {
|
||
|
// case _hbaseActionQCoinCount:
|
||
|
// actionCounter.CoinCount = binary.BigEndian.Uint64(c.Value)
|
||
|
// case _hbaseActionQReplyCount:
|
||
|
// actionCounter.ReplyCount = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
// case _hbaseActionQCoinLowRisk:
|
||
|
// actionCounter.CoinLowRisk = binary.BigEndian.Uint64(c.Value)
|
||
|
// case _hbaseActionQCoinHighRisk:
|
||
|
// actionCounter.CoinHighRisk = binary.BigEndian.Uint64(c.Value)
|
||
|
// case _hbaseActionQReplyLowRisk:
|
||
|
// actionCounter.ReplyLowRisk = binary.BigEndian.Uint64(c.Value)
|
||
|
// case _hbaseActionQReplyHighRisk:
|
||
|
// actionCounter.ReplyHighRisk = binary.BigEndian.Uint64(c.Value)
|
||
|
// case _hbaseActionQReplyLiked:
|
||
|
// actionCounter.ReplyLiked = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
// case _hbaseActionQReplyUnLiked:
|
||
|
// actionCounter.ReplyUnliked = int64(binary.BigEndian.Uint64(c.Value))
|
||
|
// }
|
||
|
// }
|
||
|
// if i == 0 {
|
||
|
// actionCounter.Version = time.Unix(parseVersion(string(c.Row), c.Timestamp), 0)
|
||
|
// }
|
||
|
// }
|
||
|
// log.Info("User action counter [%+v]", actionCounter)
|
||
|
// actionCounters = append(actionCounters, actionCounter)
|
||
|
// }
|
||
|
// return
|
||
|
// }
|
||
|
|
||
|
func parseVersion(rowKey string, timestamp *uint64) (ts int64) {
|
||
|
strs := strings.Split(rowKey, "_")
|
||
|
if len(strs) < 2 {
|
||
|
return int64(*timestamp)
|
||
|
}
|
||
|
var err error
|
||
|
if ts, err = strconv.ParseInt(strs[1], 10, 64); err != nil {
|
||
|
return int64(*timestamp)
|
||
|
}
|
||
|
return ts
|
||
|
}
|