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,21 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/up-rating/cmd:all-srcs",
"//app/admin/main/up-rating/conf:all-srcs",
"//app/admin/main/up-rating/dao:all-srcs",
"//app/admin/main/up-rating/http:all-srcs",
"//app/admin/main/up-rating/model:all-srcs",
"//app/admin/main/up-rating/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,7 @@
#### up-rating-admin
##### Version 0.0.1
> 1. 初始化up-rating-admin
#### Version 0.0.2
> 1. 新榜单

View File

@@ -0,0 +1,8 @@
# Owner
gaopeng
# Author
gaopeng,shaozhenyu,limengqing
# Reviewer
all

View File

@@ -0,0 +1,13 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- gaopeng
- gaopeng,shaozhenyu,limengqing
labels:
- admin
- admin/main/up-rating
- main
options:
no_parent_owners: true
reviewers:
- gaopeng,shaozhenyu,limengqing

View File

@@ -0,0 +1,10 @@
#### up-rating-admin
##### 项目简介
> up-rating-admin
##### 编译环境
> 请只用golang v1.8.x以上版本编译执行
##### 依赖包
> 1.公共包go-common

View File

@@ -0,0 +1,42 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
importpath = "go-common/app/admin/main/up-rating/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up-rating/conf:go_default_library",
"//app/admin/main/up-rating/http:go_default_library",
"//app/admin/main/up-rating/service:go_default_library",
"//library/log:go_default_library",
"//library/net/trace: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,46 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"go-common/app/admin/main/up-rating/conf"
"go-common/app/admin/main/up-rating/http"
"go-common/app/admin/main/up-rating/service"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
// init conf,log,trace,stat,perf
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Log)
defer log.Close()
trace.Init(conf.Conf.Tracer)
defer trace.Close()
svr := service.New(conf.Conf)
http.Init(conf.Conf, svr)
log.SetFormat("[%D %T] [%L] [%S] %M")
log.Info("up-rating-admin start")
// signal handler
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("up-rating-admin get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
log.Info("up-rating-admin exit")
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,30 @@
# This is a TOML document. Boom.
version = "1.0.0"
[log]
stdout = true
dir = "/data/log/up-rating-admin/"
[db]
[db.rating]
dsn = "gaopeng:V8ktIf7HzvpPSsZeNy5ClWw1RYFAmUDJ@tcp(172.16.33.205:3308)/bilibili_up_rating?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
idle = 5
idleTimeout = "4h"
queryTimeout = "5s"
execTimeout = "5s"
tranTimeout = "10s"
[db.level.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[rpcclient]
[rpcclient.account]
timeout = "1s"
[bm]
addr = "0.0.0.0:8410"
maxListen = 10
timeout = "10s"

View File

@@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/admin/main/up-rating/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/conf:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/trace:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/BurntSushi/toml: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,106 @@
package conf
import (
"errors"
"flag"
"go-common/library/conf"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/rpc"
"go-common/library/net/trace"
"go-common/library/time"
"github.com/BurntSushi/toml"
)
var (
// ConfPath local config path
ConfPath string
// Conf config
Conf = &Config{}
client *conf.Client
)
// Config str
type Config struct {
// base
// channal len
ChanSize int64
// log
Log *log.Config
// identify
App *bm.App
// tracer
Tracer *trace.Config
// tick load pgc
Tick time.Duration
// db
DB *DB
// BM HTTPServers
BM *bm.ServerConfig
// rpc client
RPCClient *RPCClient
}
// RPCClient is rpc client config
type RPCClient struct {
Account *rpc.ClientConfig
}
// DB is db config
type DB struct {
Rating *sql.Config
}
func init() {
flag.StringVar(&ConfPath, "conf", "", "default config path")
}
// Init init conf
func Init() (err error) {
if ConfPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(ConfPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,62 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"authority.go",
"dao.go",
"parameter.go",
"score.go",
"statistics.go",
],
importpath = "go-common/app/admin/main/up-rating/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up-rating/conf:go_default_library",
"//app/admin/main/up-rating/model:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/xstr:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/up-rating/dao/global:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"authority_test.go",
"dao_test.go",
"parameter_test.go",
"score_test.go",
"statistics_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/admin/main/up-rating/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,42 @@
package dao
import (
"context"
"fmt"
"strings"
"go-common/library/xstr"
)
const (
_addAuthoritySQL = "INSERT INTO up_white_list(mid) VALUES %s ON DUPLICATE KEY UPDATE is_deleted=0"
_rmAuthoritySQL = "UPDATE up_white_list SET is_deleted = 1 WHERE mid IN (%s)"
)
// AddAuthority .
func (d *Dao) AddAuthority(c context.Context, mids []int64) (int64, error) {
if len(mids) == 0 {
return 0, nil
}
s := make([]string, 0)
for _, v := range mids {
s = append(s, fmt.Sprintf("(%d)", v))
}
res, err := d.db.Exec(c, fmt.Sprintf(_addAuthoritySQL, strings.Join(s, ",")))
if err != nil {
return 0, err
}
return res.RowsAffected()
}
// RmAuthority .
func (d *Dao) RmAuthority(c context.Context, mids []int64) (int64, error) {
if len(mids) == 0 {
return 0, nil
}
res, err := d.db.Exec(c, fmt.Sprintf(_rmAuthoritySQL, xstr.JoinInts(mids)))
if err != nil {
return 0, err
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,40 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAddAuthority(t *testing.T) {
convey.Convey("AddAuthority", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1, 2}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, err := d.AddAuthority(c, mids)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoRmAuthority(t *testing.T) {
convey.Convey("RmAuthority", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1, 2}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, err := d.RmAuthority(c, mids)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"context"
"go-common/app/admin/main/up-rating/conf"
"go-common/library/database/sql"
)
// Dao dao
type Dao struct {
c *conf.Config
db *sql.DB
}
// New fn
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.DB.Rating),
}
return
}
// Ping ping health.
func (d *Dao) Ping(c context.Context) (err error) {
return d.db.Ping(c)
}
// Close close connections of db.
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
}

View File

@@ -0,0 +1,34 @@
package dao
import (
"flag"
"go-common/app/admin/main/up-rating/conf"
"os"
"testing"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-rating-admin")
flag.Set("conf_token", "15a509f907688750c0f2fceb768005f5")
flag.Set("tree_id", "66972")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/up-rating-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,53 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"account.go",
"resource.go",
],
importpath = "go-common/app/admin/main/up-rating/dao/global",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up-rating/conf:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/account/rpc/client:go_default_library",
"//library/log: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"],
)
go_test(
name = "go_default_test",
srcs = [
"account_test.go",
"resource_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/admin/main/up-rating/conf:go_default_library",
"//library/net/rpc:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,35 @@
package global
import (
"context"
accmdl "go-common/app/service/main/account/model"
"go-common/library/log"
)
// MID gets mid by nickname
func MID(c context.Context, nickname string) (mid int64, err error) {
res, err := GetAccRPC().InfosByName3(c, &accmdl.ArgNames{Names: []string{nickname}})
if err != nil {
log.Error("InfosByName3 fail, nickname=%+v, err=%+v", nickname, err)
return
}
for k := range res {
mid = k
}
return
}
// Names get nicknames by mids
func Names(c context.Context, mids []int64) (res map[int64]string, err error) {
res = make(map[int64]string)
infos, err := GetAccRPC().Infos3(c, &accmdl.ArgMids{Mids: mids})
if err != nil {
log.Error("Infos3 fail, mids=%+v, err=%+v", mids, err)
return
}
for k, v := range infos {
res[k] = v.Name
}
return
}

View File

@@ -0,0 +1,40 @@
package global
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestGlobalMID(t *testing.T) {
convey.Convey("MID", t, func(ctx convey.C) {
var (
c = context.Background()
nickname = "hashbaz"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
mid, err := MID(c, nickname)
ctx.Convey("Then err should be nil.mid should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(mid, convey.ShouldNotBeNil)
})
})
})
}
func TestGlobalNames(t *testing.T) {
convey.Convey("Names", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{40052}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := Names(c, mids)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,20 @@
package global
import (
"go-common/app/admin/main/up-rating/conf"
accrpc "go-common/app/service/main/account/rpc/client"
)
var (
accRPC *accrpc.Service3
)
// Init resources
func Init(c *conf.Config) {
accRPC = accrpc.New3(c.RPCClient.Account)
}
// GetAccRPC .
func GetAccRPC() *accrpc.Service3 {
return accRPC
}

View File

@@ -0,0 +1,47 @@
package global
import (
"flag"
"os"
"testing"
"go-common/app/admin/main/up-rating/conf"
"go-common/library/net/rpc"
"github.com/smartystreets/goconvey/convey"
)
func TestGlobalInit(t *testing.T) {
convey.Convey("Init", t, func(ctx convey.C) {
var (
c = &conf.Config{RPCClient: &conf.RPCClient{Account: &rpc.ClientConfig{}}}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Init(c)
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-rating-admin")
flag.Set("conf_token", "15a509f907688750c0f2fceb768005f5")
flag.Set("tree_id", "66972")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/up-rating-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
Init(conf.Conf)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,50 @@
package dao
import (
"context"
"fmt"
"go-common/library/log"
)
var (
// select
_allParameterSQL = "SELECT name, value FROM rating_parameter"
// insert
_inParameterSQL = "INSERT INTO rating_parameter(name, value, remark) VALUES %s ON DUPLICATE KEY UPDATE value=VALUES(value), remark=VALUES(remark)"
)
// GetAllParameter get all parameter
func (d *Dao) GetAllParameter(c context.Context) (parameters map[string]int64, err error) {
parameters = make(map[string]int64)
rows, err := d.db.Query(c, _allParameterSQL)
if err != nil {
log.Error("d.db.Query GetAllParameter error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var name string
var vaule int64
err = rows.Scan(&name, &vaule)
if err != nil {
log.Error("rows.Scan GetAllParameter error(%v)", err)
return
}
parameters[name] = vaule
}
return
}
// InsertParameter insert vals into rating_parameter
func (d *Dao) InsertParameter(c context.Context, val string) (rows int64, err error) {
if val == "" {
return
}
res, err := d.db.Exec(c, fmt.Sprintf(_inParameterSQL, val))
if err != nil {
return
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,39 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetAllParameter(t *testing.T) {
convey.Convey("GetAllParameter", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
parameters, err := d.GetAllParameter(c)
ctx.Convey("Then err should be nil.parameters should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(parameters, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoInsertParameter(t *testing.T) {
convey.Convey("InsertParameter", t, func(ctx convey.C) {
var (
c = context.Background()
val = "('wmaafans',100,'活跃粉丝数')"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
rows, err := d.InsertParameter(c, val)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,120 @@
package dao
import (
"context"
"fmt"
"go-common/app/admin/main/up-rating/model"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_scoreTotalSQL = "SELECT count(*) FROM up_rating_%02d WHERE cdate=? %s"
_scoreListSQL = "SELECT mid, tag_id, cdate, creativity_score, influence_score, credit_score, magnetic_score FROM up_rating_%02d WHERE cdate=? %s"
_levelListSQL = "SELECT mid, total_fans, total_avs FROM up_level_info_%02d WHERE cdate=? AND mid IN (%s)"
_upScoresSQL = "SELECT cdate, creativity_score, influence_score, credit_score, magnetic_score FROM up_rating_%02d WHERE mid = ?"
_upScoreSQL = "SELECT cdate, creativity_score, influence_score, credit_score, magnetic_score FROM up_rating_%02d WHERE mid = ? AND cdate=?"
_taskStatusSQL = "SELECT status FROM task_status WHERE date=?"
)
// Total counts scores
func (d *Dao) Total(c context.Context, mon int, date, where string) (total int64, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_scoreTotalSQL, mon, where), date)
if err = row.Scan(&total); err != nil {
log.Error("d.Total row.Scan error(%v)", err)
}
return
}
// ScoreList return info
func (d *Dao) ScoreList(c context.Context, mon int, date, where string) (list []*model.RatingInfo, err error) {
list = make([]*model.RatingInfo, 0)
rows, err := d.db.Query(c, fmt.Sprintf(_scoreListSQL, mon, where), date)
if err != nil {
log.Error("d.ScoreList d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
v := &model.RatingInfo{}
err = rows.Scan(&v.Mid, &v.TagID, &v.ScoreDate, &v.CreativityScore, &v.InfluenceScore, &v.CreditScore, &v.MagneticScore)
if err != nil {
log.Error("d.ScoreList rows.Scan error(%v)", err)
return
}
list = append(list, v)
}
err = rows.Err()
return
}
// LevelList returns info
func (d *Dao) LevelList(c context.Context, mon int, date string, mids []int64) (list []*model.RatingInfo, err error) {
list = make([]*model.RatingInfo, 0, len(mids))
rows, err := d.db.Query(c, fmt.Sprintf(_levelListSQL, mon, xstr.JoinInts(mids)), date)
if err != nil {
log.Error("d.LevelList d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
v := &model.RatingInfo{}
if err = rows.Scan(&v.Mid, &v.TotalFans, &v.TotalAvs); err != nil {
log.Error("d.LevelList rows.Scan error(%v)", err)
return
}
list = append(list, v)
}
err = rows.Err()
return
}
// UpScores ...
func (d *Dao) UpScores(c context.Context, mon int, mid int64) (list []*model.RatingInfo, err error) {
list = make([]*model.RatingInfo, 0)
rows, err := d.db.Query(c, fmt.Sprintf(_upScoresSQL, mon), mid)
if err != nil {
log.Error("d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
v := &model.RatingInfo{}
err = rows.Scan(&v.ScoreDate, &v.CreativityScore, &v.InfluenceScore, &v.CreditScore, &v.MagneticScore)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
list = append(list, v)
}
err = rows.Err()
return
}
// UpScore ...
func (d *Dao) UpScore(c context.Context, mon int, mid int64, date string) (res *model.RatingInfo, err error) {
res = new(model.RatingInfo)
row := d.db.QueryRow(c, fmt.Sprintf(_upScoreSQL, mon), mid, date)
err = row.Scan(&res.ScoreDate, &res.CreativityScore, &res.InfluenceScore, &res.CreditScore, &res.MagneticScore)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Error("row.Scan error(%v)", err)
}
return
}
// TaskStatus returns status of task on date
func (d *Dao) TaskStatus(c context.Context, date string) (status int, err error) {
row := d.db.QueryRow(c, _taskStatusSQL, date)
if err = row.Scan(&status); err != nil {
log.Error("d.TaskStatus row.Scan error(%v)", err)
}
return
}

View File

@@ -0,0 +1,118 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoTotal(t *testing.T) {
convey.Convey("Total", t, func(ctx convey.C) {
var (
c = context.Background()
mon = int(6)
date = "2018-06-01"
where = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_06(mid,cdate,creativity_score) VALUES(1001, '2018-06-01', 100) ON DUPLICATE KEY UPDATE creativity_score=VALUES(creativity_score)")
total, err := d.Total(c, mon, date, where)
ctx.Convey("Then err should be nil.total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoScoreList(t *testing.T) {
convey.Convey("ScoreList", t, func(ctx convey.C) {
var (
c = context.Background()
mon = int(6)
date = "2018-06-01"
where = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_06(mid,cdate,creativity_score) VALUES(1001, '2018-06-01', 100) ON DUPLICATE KEY UPDATE creativity_score=VALUES(creativity_score)")
list, err := d.ScoreList(c, mon, date, where)
ctx.Convey("Then err should be nil.list should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(list, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoLevelList(t *testing.T) {
convey.Convey("LevelList", t, func(ctx convey.C) {
var (
c = context.Background()
mon = int(6)
date = "2018-06-01"
mids = []int64{1001}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_06(mid,cdate,creativity_score) VALUES(1001, '2018-06-01', 100) ON DUPLICATE KEY UPDATE creativity_score=VALUES(creativity_score)")
list, err := d.LevelList(c, mon, date, mids)
ctx.Convey("Then err should be nil.list should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(list, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpScore(t *testing.T) {
convey.Convey("UpScore", t, func(ctx convey.C) {
var (
c = context.Background()
mon = int(6)
mid = int64(1001)
date = "2018-06-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.UpScore(c, mon, mid, date)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTaskStatus(t *testing.T) {
convey.Convey("TaskStatus", t, func(ctx convey.C) {
var (
c = context.Background()
date = "2018-06-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO task_status(date,type) VALUES('2018-06-01', 2) ON DUPLICATE KEY UPDATE type=VALUES(type)")
status, err := d.TaskStatus(c, date)
ctx.Convey("Then err should be nil.status should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(status, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpScores(t *testing.T) {
convey.Convey("UpScores", t, func(ctx convey.C) {
var (
c = context.Background()
mon = int(6)
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_06(mid,cdate,creativity_score) VALUES(1001, '2018-06-01', 100) ON DUPLICATE KEY UPDATE creativity_score=VALUES(creativity_score)")
list, err := d.UpScores(c, mon, mid)
ctx.Convey("Then err should be nil.list should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(list, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,119 @@
package dao
import (
"context"
"fmt"
"go-common/app/admin/main/up-rating/model"
"go-common/library/log"
)
const (
_totalType int64 = iota
_creativeType
_influenceType
_creditType
)
const (
// select
_ratingStatisticsSQL = "SELECT ups,section,tips,total_score,creativity_score,influence_score,credit_score,fans,avs,coin,play,tag_id,ctype,cdate FROM up_rating_statistics WHERE cdate = '%s' AND ctype = ? AND tag_id IN (%s)"
_trendAscCountSQL = "SELECT count(*) FROM up_rating_trend_asc WHERE date='%s' %s"
_trendDescCountSQL = "SELECT count(*) FROM up_rating_trend_desc WHERE date='%s' %s"
_trendAscSQL = "SELECT mid,magnetic_score,creativity_score,influence_score,credit_score,%s_diff FROM up_rating_trend_asc WHERE date='%s' %s"
_trendDescSQL = "SELECT mid,magnetic_score,creativity_score,influence_score,credit_score,%s_diff FROM up_rating_trend_desc WHERE date='%s' %s"
)
// GetRatingStatis get rating statistics
func (d *Dao) GetRatingStatis(c context.Context, ctype int64, date, tags string) (statis []*model.RatingStatis, err error) {
statis = make([]*model.RatingStatis, 0)
rows, err := d.db.Query(c, fmt.Sprintf(_ratingStatisticsSQL, date, tags), ctype)
if err != nil {
log.Error("d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
s := &model.RatingStatis{}
err = rows.Scan(
&s.Ups, &s.Section, &s.Tips, &s.TotalScore, &s.CreativityScore, &s.InfluenceScore, &s.CreditScore, &s.Fans, &s.Avs, &s.Coin, &s.Play, &s.TagID, &s.CType, &s.CDate)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
switch ctype {
case _totalType:
s.Score = s.TotalScore
case _creativeType:
s.Score = s.CreativityScore
case _influenceType:
s.Score = s.InfluenceScore
case _creditType:
s.Score = s.CreditScore
}
statis = append(statis, s)
}
err = rows.Err()
return
}
// AscTrendCount asc trend count
func (d *Dao) AscTrendCount(c context.Context, date string, query string) (count int, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_trendAscCountSQL, date, query))
if err = row.Scan(&count); err != nil {
log.Error("d.db.Query error(%v)", err)
}
return
}
// DescTrendCount desc trend count
func (d *Dao) DescTrendCount(c context.Context, date string, query string) (count int, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_trendDescCountSQL, date, query))
if err = row.Scan(&count); err != nil {
log.Error("d.db.Query error(%v)", err)
}
return
}
// GetTrendAsc get asc trend
func (d *Dao) GetTrendAsc(c context.Context, ctype string, date string, query string) (ts []*model.Trend, err error) {
rows, err := d.db.Query(c, fmt.Sprintf(_trendAscSQL, ctype, date, query))
if err != nil {
return
}
ts = make([]*model.Trend, 0)
defer rows.Close()
for rows.Next() {
t := &model.Trend{}
err = rows.Scan(&t.MID, &t.MagneticScore, &t.CreativityScore, &t.InfluenceScore, &t.CreditScore, &t.DValue)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
ts = append(ts, t)
}
return
}
// GetTrendDesc get desc trend
func (d *Dao) GetTrendDesc(c context.Context, ctype string, date string, query string) (ts []*model.Trend, err error) {
rows, err := d.db.Query(c, fmt.Sprintf(_trendDescSQL, ctype, date, query))
if err != nil {
return
}
ts = make([]*model.Trend, 0)
defer rows.Close()
for rows.Next() {
t := &model.Trend{}
err = rows.Scan(&t.MID, &t.MagneticScore, &t.CreativityScore, &t.InfluenceScore, &t.CreditScore, &t.DValue)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
ts = append(ts, t)
}
return
}

View File

@@ -0,0 +1,101 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAscTrendCount(t *testing.T) {
convey.Convey("AscTrendCount", t, func(ctx convey.C) {
var (
c = context.Background()
date = "2018-06-01"
query = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_trend_asc(mid) VALUES(1001) ON DUPLICATE KEY UPDATE mid=VALUES(mid)")
count, err := d.AscTrendCount(c, date, query)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoDescTrendCount(t *testing.T) {
convey.Convey("DescTrendCount", t, func(ctx convey.C) {
var (
c = context.Background()
date = "2018-06-01"
query = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_trend_desc(mid) VALUES(1001) ON DUPLICATE KEY UPDATE mid=VALUES(mid)")
count, err := d.DescTrendCount(c, date, query)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetRatingStatis(t *testing.T) {
convey.Convey("GetRatingStatis", t, func(ctx convey.C) {
var (
c = context.Background()
ctype = int64(0)
date = "2018-06-01"
query = "2"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_statistics(cdate,tag_id,ctype,section) VALUES('2018-06-01',2,2,1) ON DUPLICATE KEY UPDATE tag_id=VALUES(tag_id)")
statis, err := d.GetRatingStatis(c, ctype, date, query)
ctx.Convey("Then err should be nil.statis should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(statis, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetTrendAsc(t *testing.T) {
convey.Convey("GetTrendAsc", t, func(ctx convey.C) {
var (
c = context.Background()
ctype = "magnetic"
date = "2018-06-01"
query = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_trend_asc(mid,date) VALUES(1001,'2018-06-01') ON DUPLICATE KEY UPDATE mid=VALUES(mid)")
ts, err := d.GetTrendAsc(c, ctype, date, query)
ctx.Convey("Then err should be nil.ts should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ts, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetTrendDesc(t *testing.T) {
convey.Convey("GetTrendDesc", t, func(ctx convey.C) {
var (
c = context.Background()
ctype = "magnetic"
date = "2018-06-01"
query = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.db.Exec(c, "INSERT INTO up_rating_trend_desc(mid,date) VALUES(1001,'2018-06-01') ON DUPLICATE KEY UPDATE mid=VALUES(mid)")
ts, err := d.GetTrendDesc(c, ctype, date, query)
ctx.Convey("Then err should be nil.ts should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ts, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"authority.go",
"csv.go",
"http.go",
"parameter.go",
"score.go",
"statistics.go",
],
importpath = "go-common/app/admin/main/up-rating/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up-rating/conf:go_default_library",
"//app/admin/main/up-rating/model:go_default_library",
"//app/admin/main/up-rating/service:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/render: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,38 @@
package http
import (
"go-common/library/log"
"go-common/library/net/http/blademaster"
)
func addAuthority(c *blademaster.Context) {
v := new(struct {
MIDS []int64 `form:"mids,split" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
num, err := svr.AddAuthority(c, v.MIDS)
if err != nil {
log.Error("svr.AddAuthority error(%v) arg(%v)", err, v)
c.JSON(nil, err)
return
}
c.JSON(num, nil)
}
func removeAuthority(c *blademaster.Context) {
v := new(struct {
MIDS []int64 `form:"mids,split" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
num, err := svr.RemoveAuthority(c, v.MIDS)
if err != nil {
log.Error("svr.RemoveAuthority error(%v) arg(%v)", err, v)
c.JSON(nil, err)
return
}
c.JSON(num, nil)
}

View File

@@ -0,0 +1,47 @@
package http
import (
"fmt"
"net/http"
"github.com/pkg/errors"
)
// CSVContentType
var (
CSVContentType = []string{"application/csv"}
_ Render = CSV{}
)
// Render http reponse render.
type Render interface {
Render(http.ResponseWriter) error
WriteContentType(w http.ResponseWriter)
}
// CSV str.
type CSV struct {
Content []byte
Title string
}
// WriteContentType fn
func (j CSV) WriteContentType(w http.ResponseWriter) {
writeContentType(w, CSVContentType, j.Title)
}
func writeContentType(w http.ResponseWriter, value []string, title string) {
header := w.Header()
if val := header["Content-Type"]; len(val) == 0 {
header["Content-Type"] = value
}
header["Content-Disposition"] = append(header["Content-Disposition"], fmt.Sprintf("attachment; filename=%s.csv", title))
}
// Render (JSON) writes data with json ContentType.
func (j CSV) Render(w http.ResponseWriter) (err error) {
if _, err = w.Write(j.Content); err != nil {
err = errors.WithStack(err)
}
return
}

View File

@@ -0,0 +1,67 @@
package http
import (
"net/http"
"go-common/app/admin/main/up-rating/conf"
"go-common/app/admin/main/up-rating/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
var (
svr *service.Service
)
// Init init
func Init(c *conf.Config, s *service.Service) {
svr = s
engine := bm.DefaultServer(c.BM)
initRouter(engine)
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
func initRouter(r *bm.Engine) {
r.Ping(ping)
rating := r.Group("/allowance/api/x/admin/rating")
statis := rating.Group("/statis")
{
statis.GET("/graph", statisGraph)
statis.GET("/list", statisList)
statis.GET("/export", statisExport)
}
score := rating.Group("/score")
{
score.GET("/list", scoreList)
score.GET("/export", scoreExport)
score.GET("/up/current", scoreCurrent)
score.GET("/up/history", scoreHistory)
}
param := rating.Group("/param")
{
param.POST("/insert", paramInsert)
}
trend := rating.Group("trend")
{
trend.GET("/ascend/list", ascList)
trend.GET("/descend/list", descList)
}
au := rating.Group("authority")
{
au.POST("/add", addAuthority)
au.POST("/remove", removeAuthority)
}
}
// ping check server ok.
func ping(c *bm.Context) {
var err error
if err = svr.Ping(c); err != nil {
log.Error("up-rating-admin ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}

View File

@@ -0,0 +1,22 @@
package http
import (
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func paramInsert(c *bm.Context) {
v := new(struct {
Name string `form:"name"`
Value int `form:"value"`
Remark string `form:"remark"`
})
if err := c.Bind(v); err != nil {
return
}
err := svr.InsertParameter(c, v.Name, v.Remark, v.Value)
if err != nil {
log.Error("svr.InsertParameter error(%v)", err)
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,112 @@
package http
import (
"fmt"
"net/http"
"time"
"go-common/app/admin/main/up-rating/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
)
func scoreList(ctx *blademaster.Context) {
arg := new(model.RatingListArg)
if err := ctx.Bind(arg); err != nil {
log.Error("scoreList ctx.Bind error(%v)", err)
return
}
date := time.Now()
if arg.ScoreDate != "" {
var err error
if date, err = time.ParseInLocation("2006-01", arg.ScoreDate, time.Local); err != nil {
log.Error("date(%s) parse error", arg.ScoreDate)
err = ecode.RequestErr
return
}
}
res, total, err := svr.RatingList(ctx, arg, date)
if err != nil {
log.Error("svr.RatingList error(%v) arg(%v)", err, arg)
ctx.JSON(nil, err)
return
}
ctx.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": res,
"paging": &model.Paging{
Ps: arg.Limit,
Total: total,
},
}))
}
func scoreCurrent(ctx *blademaster.Context) {
arg := new(struct {
MID int64 `form:"mid" validate:"required"`
})
if err := ctx.Bind(arg); err != nil {
log.Error("ctx.Bind error(%v)", err)
return
}
res, err := svr.ScoreCurrent(ctx, arg.MID)
if err != nil {
log.Error("svr.ScoreCurrent error(%v) arg(%v)", err, arg)
ctx.JSON(nil, err)
return
}
ctx.JSON(res, nil)
}
func scoreHistory(ctx *blademaster.Context) {
arg := new(model.UpRatingHistoryArg)
if err := ctx.Bind(arg); err != nil {
log.Error("ctx.Bind error(%v)", err)
return
}
types := []model.ScoreType{
model.Creativity,
model.Influence,
model.Credit,
}
if arg.ScoreType != model.Magnetic {
types = []model.ScoreType{arg.ScoreType}
}
res, err := svr.ScoreHistory(ctx, types, arg.Mid, arg.Month == 0, arg.Month)
if err != nil {
log.Error("svr.RatingList error(%v) arg(%v)", err, arg)
ctx.JSON(nil, err)
return
}
ctx.JSON(&model.UpRatingHistoryResp{Data: res}, nil)
}
func scoreExport(ctx *blademaster.Context) {
arg := new(model.RatingListArg)
if err := ctx.Bind(arg); err != nil {
log.Error("scoreList ctx.Bind error(%v)", err)
return
}
date := time.Now()
if arg.ScoreDate != "" {
var err error
if date, err = time.ParseInLocation("2006-01", arg.ScoreDate, time.Local); err != nil {
log.Error("date(%s) parse error", arg.ScoreDate)
err = ecode.RequestErr
return
}
}
content, err := svr.ExportScores(ctx, arg, date)
if err != nil {
ctx.JSON(nil, err)
log.Error("up-rating svr.ExportScores error(%v)", err)
return
}
ctx.Render(http.StatusOK, CSV{
Content: content,
Title: fmt.Sprintf("%s-%s", time.Now().Format("2006-01-02"), "scores"),
})
}

View File

@@ -0,0 +1,142 @@
package http
import (
"fmt"
"net/http"
"time"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
)
var (
_layout = "2006-01-02"
)
func statisGraph(c *bm.Context) {
v := new(struct {
Type int64 `form:"type"`
TagID string `form:"tag_id" validate:"required"`
Compare int `form:"compare"`
})
if err := c.Bind(v); err != nil {
return
}
data, err := svr.StatisGraph(c, v.Type, v.TagID, v.Compare)
if err != nil {
log.Error("svr.StatisGraph error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func statisList(c *bm.Context) {
v := new(struct {
Type int64 `form:"type"`
TagID string `form:"tag_id" validate:"required"`
Compare int `form:"compare"`
})
if err := c.Bind(v); err != nil {
return
}
data, err := svr.StatisList(c, v.Type, v.TagID, v.Compare)
if err != nil {
log.Error("svr.StatisList error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func statisExport(c *bm.Context) {
v := new(struct {
Type int64 `form:"type"`
TagID string `form:"tag_id" validate:"required"`
Compare int `form:"compare"`
})
if err := c.Bind(v); err != nil {
return
}
content, err := svr.StatisExport(c, v.Type, v.TagID, v.Compare)
if err != nil {
log.Error("svr.StatisExport error(%v)", err)
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, CSV{
Content: content,
Title: fmt.Sprintf("%s-%s", time.Now().Format("2006-01-02"), "statistics"),
})
}
func ascList(c *bm.Context) {
v := new(struct {
Type string `form:"type" validate:"required"`
Tags []int64 `form:"tag_ids,split" validate:"required"`
Date string `form:"date" validate:"required"`
ScoreMin int `form:"score_min"`
ScoreMax int `form:"score_max"`
MID int64 `form:"mid"`
From int `form:"from" default:"0" validate:"min=0"`
Limit int `form:"limit" default:"20" validate:"min=1"`
})
if err := c.Bind(v); err != nil {
return
}
date, err := time.Parse(_layout, v.Date)
if err != nil {
return
}
total, data, err := svr.GetTrendAsc(c, v.Type, v.Tags, date, v.ScoreMin, v.ScoreMax, v.MID, v.From, v.Limit)
if err != nil {
log.Error("svr.GetTrendAsc error(%v)", err)
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": data,
"paging": map[string]int{
"page_size": v.Limit,
"total": total,
},
}))
}
func descList(c *bm.Context) {
v := new(struct {
Type string `form:"type" validate:"required"`
Tags []int64 `form:"tag_ids,split" validate:"required"`
Date string `form:"date" validate:"required"`
ScoreMin int `form:"score_min"`
ScoreMax int `form:"score_max"`
MID int64 `form:"mid"`
From int `form:"from" default:"0" validate:"min=0"`
Limit int `form:"limit" default:"20" validate:"min=1"`
})
if err := c.Bind(v); err != nil {
return
}
date, err := time.Parse(_layout, v.Date)
if err != nil {
return
}
total, data, err := svr.GetTrendDesc(c, v.Type, v.Tags, date, v.ScoreMin, v.ScoreMax, v.MID, v.From, v.Limit)
if err != nil {
log.Error("svr.GetTrendDesc error(%v)", err)
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": data,
"paging": map[string]int{
"page_size": v.Limit,
"total": total,
},
}))
}

View File

@@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"parameter.go",
"score.go",
"statistics.go",
],
importpath = "go-common/app/admin/main/up-rating/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//library/time: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,22 @@
package model
// RatingParameter rating weight args
type RatingParameter struct {
WDP int64 // dp weight
WDC int64 // dc weight
WDV int64 // dv weight
WMDV int64 // mdv weight
WCS int64
WCSR int64
WMAAFans int64
WMAHFans int64
WIS int64
WISR int64
// 信用分
HBASE int64
HR int64
HV int64
HVM int64
HL int64
HLM int64
}

View File

@@ -0,0 +1,87 @@
package model
import (
"time"
)
// ScoreType .
type ScoreType int8
// ScoreType enums
const (
Magnetic ScoreType = iota
Creativity
Influence
Credit
)
// RatingListArg .
type RatingListArg struct {
ScoreDate string `form:"score_date"` // 年月 "2006-01"
Mid int64 `form:"mid"` // up id
Tags []int64 `form:"tag_ids,split" validate:"required"` // 分区
ScoreType ScoreType `form:"score_type" default:"0"` // 分数段类型
ScoreMin int64 `form:"score_min"` // 左闭右开
ScoreMax int64 `form:"score_max"` // 左闭右开
From int64 `form:"from" default:"0" validate:"min=0"`
Limit int64 `form:"limit" default:"20" validate:"min=1"`
}
// RatingListResp .
type RatingListResp struct {
Result []*RatingInfo `json:"result"`
}
// RatingInfo .
type RatingInfo struct {
Mid int64 `json:"mid"`
TagID int `json:"tag_id"`
ScoreDate time.Time `json:"-"`
Date string `json:"date"`
NickName string `json:"nickname"`
TotalFans int64 `json:"total_fans"`
TotalAvs int64 `json:"total_avs"`
CreativityScore int64 `json:"creativity_score"`
InfluenceScore int64 `json:"influence_score"`
CreditScore int64 `json:"credit_score"`
MagneticScore int64 `json:"magnetic_score"`
}
// Paging .
type Paging struct {
Ps int64 `json:"page_size"`
Total int64 `json:"total"`
}
// UpRatingHistoryArg .
type UpRatingHistoryArg struct {
Mid int64 `form:"mid" validate:"required"`
Month int `form:"month" default:"0" validate:"min=0"`
ScoreType ScoreType `form:"score_type" default:"0"`
}
// UpRatingHistoryResp .
type UpRatingHistoryResp struct {
Data []*UpScoreHistory `json:"score_data"`
}
// UpScoreHistory .
type UpScoreHistory struct {
ScoreType ScoreType `json:"type"`
Date []int64 `json:"date"`
Score []int64 `json:"score"`
}
// ScoreCurrentResp .
type ScoreCurrentResp struct {
Date int64 `json:"date"`
Credit *ScoreCurrent `json:"credit_score"`
Influence *ScoreCurrent `json:"influence_score"`
Creativity *ScoreCurrent `json:"creativity_score"`
}
// ScoreCurrent .
type ScoreCurrent struct {
Current int64 `json:"current"`
Diff int64 `json:"diff"`
}

View File

@@ -0,0 +1,40 @@
package model
import (
"go-common/library/time"
)
// RatingStatis rating statitics
type RatingStatis struct {
Ups int64 `json:"ups"`
Section int64 `json:"-"`
Tips string `json:"tips"`
Score int64 `json:"score"`
TotalScore int64 `json:"-"`
CreativityScore int64 `json:"creativity_score"`
InfluenceScore int64 `json:"influence_score"`
CreditScore int64 `json:"credit_score"`
Fans int64 `json:"fans"`
Avs int64 `json:"avs"`
Coin int64 `json:"coin"`
Play int64 `json:"play"`
CDate time.Time `json:"-"`
TagID int64 `json:"-"`
CType int64 `json:"-"`
Proportion string `json:"proportion"`
Compare int64 `json:"compare"`
ComparePropor string `json:"compare_propor"`
}
// Trend rating trend
type Trend struct {
MID int64 `json:"mid"`
Nickname string `json:"nickname"`
DValue int `json:"d_value"`
MagneticScore int64 `json:"magnetic_score"`
CreativityScore int64 `json:"creativity_score"`
InfluenceScore int64 `json:"influence_score"`
CreditScore int64 `json:"credit_score"`
Avs int64 `json:"avs"`
Fans int64 `json:"fans"`
}

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"authority.go",
"cache.go",
"parameter.go",
"score.go",
"service.go",
"statistics.go",
"transfer.go",
],
importpath = "go-common/app/admin/main/up-rating/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up-rating/conf:go_default_library",
"//app/admin/main/up-rating/dao:go_default_library",
"//app/admin/main/up-rating/dao/global:go_default_library",
"//app/admin/main/up-rating/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/xstr: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,13 @@
package service
import "context"
// AddAuthority .
func (s *Service) AddAuthority(c context.Context, mids []int64) (int64, error) {
return s.dao.AddAuthority(c, mids)
}
// RemoveAuthority .
func (s *Service) RemoveAuthority(c context.Context, mids []int64) (int64, error) {
return s.dao.RmAuthority(c, mids)
}

View File

@@ -0,0 +1,41 @@
package service
import (
"time"
)
// Cache simple cache
type Cache struct {
d int64 // duration seconds
mc map[string]interface{} // map cache
snap time.Time
}
// NewCache new cache
func NewCache(d int64) *Cache {
c := &Cache{
d: d,
mc: make(map[string]interface{}),
snap: time.Now(),
}
return c
}
// Get ...
func (c *Cache) Get(key string) (val interface{}) {
c.check()
return c.mc[key]
}
// Set ...
func (c *Cache) Set(key string, val interface{}) {
c.check()
c.mc[key] = val
}
func (c *Cache) check() {
if int64(time.Since(c.snap).Seconds()) > c.d {
c.mc = make(map[string]interface{})
c.snap = time.Now()
}
}

View File

@@ -0,0 +1,59 @@
package service
import (
"context"
"fmt"
"go-common/app/admin/main/up-rating/model"
)
// InsertParameter insert parameter
func (s *Service) InsertParameter(c context.Context, name, remark string, value int) (err error) {
_, err = s.dao.InsertParameter(c, fmt.Sprintf("('%s', %d, '%s')", name, value, remark))
return
}
func (s *Service) getTypeScore(c context.Context, ctype int64) (score int64, err error) {
params, err := s.getAllParameter(c)
if err != nil {
return
}
switch ctype {
case 0:
score = params.WCSR + params.HR + params.WISR
case 1:
score = params.WCSR
case 2:
score = params.WISR
case 3:
score = params.HR
}
return
}
func (s *Service) getAllParameter(c context.Context) (rp *model.RatingParameter, err error) {
parameters, err := s.dao.GetAllParameter(c)
if err != nil {
return
}
rp = &model.RatingParameter{
WDP: parameters["wdp"],
WDC: parameters["wdc"],
WDV: parameters["wdv"],
WMDV: parameters["wmdv"],
WCS: parameters["wcs"],
WCSR: parameters["wcsr"],
WMAAFans: parameters["wmaafans"],
WMAHFans: parameters["wmahfans"],
WIS: parameters["wis"],
WISR: parameters["wisr"],
HBASE: parameters["hbase"],
HR: parameters["hr"],
HV: parameters["hv"],
HVM: parameters["hvm"],
HL: parameters["hl"],
HLM: parameters["hlm"],
}
return
}

View File

@@ -0,0 +1,252 @@
package service
import (
"context"
"fmt"
"sort"
"time"
"go-common/app/admin/main/up-rating/dao/global"
"go-common/app/admin/main/up-rating/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/xstr"
)
// RatingList returns rating info list
func (s *Service) RatingList(c context.Context, arg *model.RatingListArg, date time.Time) (res []*model.RatingInfo, total int64, err error) {
var (
cdate = getStartMonthlyDate(date)
cdateStr = cDateStr(cdate)
mon = int(cdate.Month())
)
res = make([]*model.RatingInfo, 0)
q := scoreListQuery(arg)
total = 10000
// if total, err = s.dao.Total(c, mon, cdateStr, q); err != nil {
// log.Error("s.dao.Total error(%v)", err)
// return
// }
// if total == 0 {
// return
// }
// scores
q += fmt.Sprintf(" ORDER BY id ASC LIMIT %d, %d", arg.From, arg.Limit)
if res, err = s.dao.ScoreList(c, mon, cdateStr, q); err != nil {
log.Error("s.dao.ScoreList error(%v)", err)
return
}
if len(res) == 0 {
return
}
var (
m = make(map[int64]*model.RatingInfo, len(res))
mids = make([]int64, 0, len(res))
)
for _, v := range res {
mids = append(mids, v.Mid)
m[v.Mid] = v
}
// fans and avs
levelInfos, err := s.dao.LevelList(c, mon, cdateStr, mids)
if err != nil {
log.Error("s.dao.LevelList error(%v)", err)
return
}
for _, v := range levelInfos {
score := m[v.Mid]
score.TotalAvs = v.TotalAvs
score.TotalFans = v.TotalFans
}
// nicknames
r, err := global.Names(c, mids)
if err != nil {
log.Error("global.Names error(%v)", err)
return
}
for _, v := range res {
v.NickName = r[v.Mid]
v.Date = v.ScoreDate.Format("2006-01")
}
return
}
func scoreListQuery(arg *model.RatingListArg) (where string) {
if arg.Mid > 0 {
where += fmt.Sprintf(" AND mid=%d", arg.Mid)
}
if arg.ScoreMin > 0 {
where += fmt.Sprintf(" AND %s>=%d", scoreField(arg.ScoreType), arg.ScoreMin)
}
if arg.ScoreMax > 0 {
where += fmt.Sprintf(" AND %s<%d", scoreField(arg.ScoreType), arg.ScoreMax)
}
if len(arg.Tags) > 0 {
// if len(arg.Tags) > 1 {
// s := rand.NewSource(time.Now().Unix())
// r := rand.New(s) // initialize local pseudorandom generator
// i := r.Intn(len(arg.Tags))
// where += fmt.Sprintf(" AND tag_id=%d", arg.Tags[i])
// } else {
// where += fmt.Sprintf(" AND tag_id=%d", arg.Tags[0])
// }
where += fmt.Sprintf(" AND tag_id IN (%s)", xstr.JoinInts(arg.Tags))
}
where += " AND is_deleted=0"
return
}
// ScoreCurrent returns current rating info
func (s *Service) ScoreCurrent(c context.Context, mid int64) (res *model.ScoreCurrentResp, err error) {
current, err := s.lastestScore(c, mid)
if err != nil || current == nil {
return
}
res = &model.ScoreCurrentResp{
Date: current.ScoreDate.Unix(),
Credit: &model.ScoreCurrent{Current: current.CreditScore, Diff: current.CreditScore},
Influence: &model.ScoreCurrent{Current: current.InfluenceScore, Diff: current.InfluenceScore},
Creativity: &model.ScoreCurrent{Current: current.CreativityScore, Diff: current.CreativityScore},
}
prev, err := s.upScore(c, mid, prevComputation(current.ScoreDate))
if err != nil {
return
}
if prev != nil {
res.Credit.Diff = current.CreditScore - prev.CreditScore
res.Influence.Diff = current.InfluenceScore - prev.InfluenceScore
res.Creativity.Diff = current.CreativityScore - prev.CreativityScore
}
return
}
func (s *Service) upScoreHistory(c context.Context, mid int64, queryAll bool, count int) ([]*model.RatingInfo, error) {
if queryAll {
return s.upPastScoresAll(c, mid)
}
return s.upPastScores(c, mid, count)
}
// ScoreHistory returns score history
func (s *Service) ScoreHistory(c context.Context, types []model.ScoreType, mid int64, queryAll bool, limit int) (res []*model.UpScoreHistory, err error) {
res = make([]*model.UpScoreHistory, 0)
history, err := s.upScoreHistory(c, mid, queryAll, limit)
if err != nil || len(history) <= 0 {
return
}
sort.Slice(history, func(i, j int) bool {
return history[i].ScoreDate.Before(history[j].ScoreDate)
})
var (
dates = make([]int64, 0, len(history))
m = map[model.ScoreType][]int64{
model.Credit: make([]int64, 0, len(history)),
model.Creativity: make([]int64, 0, len(history)),
model.Influence: make([]int64, 0, len(history)),
}
)
for _, v := range history {
dates = append(dates, v.ScoreDate.Unix())
m[model.Creativity] = append(m[model.Creativity], v.CreativityScore)
m[model.Credit] = append(m[model.Credit], v.CreditScore)
m[model.Influence] = append(m[model.Influence], v.InfluenceScore)
}
for _, t := range types {
res = append(res, &model.UpScoreHistory{
ScoreType: t,
Date: dates,
Score: m[t],
})
}
return
}
// ExportScores exports scores
func (s *Service) ExportScores(ctx context.Context, arg *model.RatingListArg, date time.Time) (res []byte, err error) {
ratings, _, err := s.RatingList(ctx, arg, date)
if err != nil {
log.Error("s.RatingList error(%v)", err)
return
}
data := formatScores(ratings)
res, err = formatCSV(data)
if err != nil {
log.Error("up-rating FormatCSV error(%v)", err)
}
return
}
func (s *Service) upPastScoresAll(c context.Context, mid int64) (res []*model.RatingInfo, err error) {
res = make([]*model.RatingInfo, 0)
for f := 1; f <= 12; f++ {
var list []*model.RatingInfo
if list, err = s.dao.UpScores(c, f, mid); err != nil {
log.Error("s.dao.UpScores error(%v)", err)
return
}
res = append(res, list...)
}
return
}
func (s *Service) upPastScores(c context.Context, mid int64, count int) (res []*model.RatingInfo, err error) {
res = make([]*model.RatingInfo, 0)
var lastScore *model.RatingInfo
if lastScore, err = s.lastestScore(c, mid); err != nil || lastScore == nil {
return
}
res = append(res, lastScore)
for f := 1; f < count; f++ {
var v *model.RatingInfo
if v, err = s.upScore(c, mid, lastScore.ScoreDate.AddDate(0, -f, 0)); err != nil {
return
}
if v != nil {
res = append(res, v)
}
}
return
}
func (s *Service) lastestScore(c context.Context, mid int64) (score *model.RatingInfo, err error) {
cdate := prevComputation(time.Now())
var b bool
if b, err = s.taskFinished(c, cdate); err != nil {
return
}
if !b {
cdate = prevComputation(cdate)
if b, err = s.taskFinished(c, cdate); err != nil {
return
}
}
if !b {
log.Error("s.latestScore cdate(%s) no data available", cdate)
err = ecode.ServerErr
return
}
return s.upScore(c, mid, cdate)
}
func (s *Service) taskFinished(c context.Context, cdate time.Time) (bool, error) {
str := cDateStr(cdate)
status, err := s.dao.TaskStatus(c, str)
if err != nil {
log.Error("s.dao.TaskStasus date(%s) error(%v)", str, err)
return false, err
}
return status == 1, nil
}
// upScore wraps dao.upScore
func (s *Service) upScore(c context.Context, mid int64, t time.Time) (*model.RatingInfo, error) {
score, err := s.dao.UpScore(c, int(t.Month()), mid, cDateStr(t))
if err != nil {
log.Error("s.dao.UpScore mid(%d) date(%s) error(%v)", mid, t, err)
return nil, err
}
return score, nil
}

View File

@@ -0,0 +1,39 @@
package service
import (
"context"
"go-common/app/admin/main/up-rating/conf"
"go-common/app/admin/main/up-rating/dao"
"go-common/app/admin/main/up-rating/dao/global"
)
// Service struct
type Service struct {
conf *conf.Config
dao *dao.Dao
cache *Cache
}
// New fn
func New(c *conf.Config) (s *Service) {
global.Init(c)
s = &Service{
conf: c,
dao: dao.New(c),
cache: NewCache(60),
}
return s
}
// Ping fn
func (s *Service) Ping(c context.Context) (err error) {
return nil
}
// Close dao
func (s *Service) Close() {
if s.dao != nil {
s.dao.Close()
}
}

View File

@@ -0,0 +1,289 @@
package service
import (
"context"
"fmt"
"time"
"go-common/app/admin/main/up-rating/dao/global"
"go-common/app/admin/main/up-rating/model"
"go-common/library/log"
"go-common/library/xstr"
)
var (
_layout = "2006-01-02"
_segment = 10
)
// StatisGraph get statistics graph data
func (s *Service) StatisGraph(c context.Context, ctype int64, tagID string, Compare int) (data interface{}, err error) {
totalScore, err := s.getTypeScore(c, ctype)
if err != nil {
log.Error("s.getTypeScore error(%v)", err)
return
}
nowStatis, now, err := s.GetLastRatingStatis(c, ctype, tagID)
if err != nil {
log.Error("s.GetRatingStatis error(%v)", err)
return
}
last := now.AddDate(0, -1*Compare, 0)
lastStatis, err := s.GetRatingStatis(c, ctype, tagID, getStartMonthlyDate(last))
if err != nil {
log.Error("s.GetRatingStatis error(%v)", err)
return
}
data = map[string]interface{}{
"xAxis": getSections(int(totalScore)),
"this_month": statisSections(nowStatis, int(totalScore)),
"compare": statisSections(lastStatis, int(totalScore)),
}
return
}
// StatisList get statistics list
func (s *Service) StatisList(c context.Context, ctype int64, tagID string, Compare int) (list []*model.RatingStatis, err error) {
list = make([]*model.RatingStatis, 0)
totalScore, err := s.getTypeScore(c, ctype)
if err != nil {
log.Error("s.getTypeScore error(%v)", err)
return
}
nowStatis, now, err := s.GetLastRatingStatis(c, ctype, tagID)
if err != nil {
log.Error("s.GetRatingStatis error(%v)", err)
return
}
last := now.AddDate(0, -1*Compare, 0)
lastStatis, err := s.GetRatingStatis(c, ctype, tagID, getStartMonthlyDate(last))
if err != nil {
log.Error("s.GetRatingStatis error(%v)", err)
return
}
list = statisProportion(nowStatis, lastStatis, getSections(int(totalScore)), int(totalScore))
return
}
// StatisExport export statis
func (s *Service) StatisExport(c context.Context, ctype int64, tagID string, Compare int) (res []byte, err error) {
list, err := s.StatisList(c, ctype, tagID, Compare)
if err != nil {
log.Error("s.StatisList error(%v)", err)
return
}
res, err = formatCSV(formatStatis(list, ctype))
if err != nil {
log.Error("StatisExport formatCSV error(%v)", err)
}
return
}
func statisProportion(now, last []*model.RatingStatis, sections []string, totalScore int) (list []*model.RatingStatis) {
var totalUps, lastTotalUps int64
list = make([]*model.RatingStatis, _segment)
for i := 0; i < _segment; i++ {
list[i] = &model.RatingStatis{
Tips: sections[i],
}
}
offset := totalScore / _segment
for _, s := range now {
totalUps += s.Ups
idx := int(s.Section) * 10 / offset
if idx >= _segment {
idx--
}
list[idx].Ups += s.Ups
list[idx].Score += s.Score
list[idx].CreativityScore += s.CreativityScore
list[idx].InfluenceScore += s.InfluenceScore
list[idx].CreditScore += s.CreditScore
list[idx].Fans += s.Fans
list[idx].Avs += s.Avs
list[idx].Coin += s.Coin
list[idx].Play += s.Play
}
for _, s := range last {
lastTotalUps += s.Ups
idx := int(s.Section) * 10 / offset
if idx >= _segment {
idx--
}
list[idx].Compare += s.Ups
}
for i := 0; i < len(list); i++ {
if totalUps > 0 {
list[i].Proportion = fmt.Sprintf("%.02f", float64(list[i].Ups*100)/float64(totalUps))
}
if lastTotalUps > 0 {
list[i].ComparePropor = fmt.Sprintf("%.02f", float64(list[i].Compare*100)/float64(lastTotalUps))
}
if list[i].Ups > 0 {
list[i].Score /= list[i].Ups
list[i].CreativityScore /= list[i].Ups
list[i].InfluenceScore /= list[i].Ups
list[i].CreditScore /= list[i].Ups
list[i].Fans /= list[i].Ups
list[i].Avs /= list[i].Ups
list[i].Coin /= list[i].Ups
list[i].Play /= list[i].Ups
}
}
return
}
func getSections(score int) (sections []string) {
sections = make([]string, _segment)
offset := score / _segment
for i := 0; i < len(sections); i++ {
sections[i] = fmt.Sprintf("%d-%d", i*offset, (i+1)*offset)
}
return sections
}
func statisSections(statis []*model.RatingStatis, totalScore int) (ups []int64) {
ups = make([]int64, _segment)
offset := totalScore / _segment
for _, s := range statis {
idx := int(s.Section) * 10 / offset
if idx >= len(ups) {
idx--
}
ups[idx] += s.Ups
}
return
}
// GetLastRatingStatis get last rating statis
func (s *Service) GetLastRatingStatis(c context.Context, ctype int64, tagID string) (statis []*model.RatingStatis, date time.Time, err error) {
statis = make([]*model.RatingStatis, 0)
times := 0
date = getStartMonthlyDate(time.Now()).AddDate(0, -1, 0)
for times < 2 {
statis, err = s.GetRatingStatis(c, ctype, tagID, date)
if err != nil {
return
}
if len(statis) > 0 {
break
}
times++
date = date.AddDate(0, -1, 0)
}
if times == 2 && len(statis) == 0 {
err = fmt.Errorf("get last statis error")
return
}
return
}
// GetRatingStatis get rating statis
func (s *Service) GetRatingStatis(c context.Context, ctype int64, tagID string, date time.Time) (statis []*model.RatingStatis, err error) {
return s.dao.GetRatingStatis(c, ctype, date.Format(_layout), tagID)
}
func getStartMonthlyDate(date time.Time) time.Time {
return time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.Local)
}
// GetTrendAsc get trend asc
func (s *Service) GetTrendAsc(c context.Context, ctype string, tags []int64, date time.Time, frl, fru int, mid int64, offset, limit int) (total int, ts []*model.Trend, err error) {
q := query(ctype, tags, frl, mid)
dsr := getStartMonthlyDate(date).Format(_layout)
total, err = s.dao.AscTrendCount(c, dsr, q)
if err != nil {
return
}
q += fmt.Sprintf(" ORDER BY %s_diff DESC,id LIMIT %d,%d", ctype, offset, limit)
ts, err = s.dao.GetTrendAsc(c, ctype, dsr, q)
if err != nil {
return
}
err = fillUpNames(c, ts)
return
}
//GetTrendDesc get trend desc
func (s *Service) GetTrendDesc(c context.Context, ctype string, tags []int64, date time.Time, frl, fru int, mid int64, offset, limit int) (total int, ts []*model.Trend, err error) {
q := query(ctype, tags, frl, mid)
dsr := getStartMonthlyDate(date).Format(_layout)
total, err = s.dao.DescTrendCount(c, dsr, q)
if err != nil {
return
}
q += fmt.Sprintf(" ORDER BY %s_diff,id LIMIT %d,%d", ctype, offset, limit)
ts, err = s.dao.GetTrendDesc(c, ctype, dsr, q)
if err != nil {
return
}
err = fillUpNames(c, ts)
return
}
func fillUpNames(c context.Context, ts []*model.Trend) (err error) {
var mids []int64
for _, trend := range ts {
mids = append(mids, trend.MID)
}
if len(mids) == 0 {
return
}
ns, err := global.Names(c, mids)
if err != nil {
return
}
for _, trend := range ts {
trend.Nickname = ns[trend.MID]
}
return
}
func getSection(ctype string, frl int) (section int, typ int) {
if ctype == "magnetic" {
typ = 0
interval := 600 / 10
section = frl / interval
}
if ctype == "creativity" {
typ = 1
interval := 200 / 10
section = frl / interval
}
if ctype == "influence" {
typ = 2
interval := 200 / 10
section = frl / interval
}
if ctype == "credit" {
typ = 3
interval := 200 / 10
section = frl / interval
}
return
}
func query(ctype string, tags []int64, frl int, mid int64) (q string) {
if len(tags) > 0 {
q += fmt.Sprintf(" AND tag_id IN (%s)", xstr.JoinInts(tags))
}
section, typ := getSection(ctype, frl)
q += fmt.Sprintf(" AND section=%d", section)
q += fmt.Sprintf(" AND ctype=%d", typ)
if mid > 0 {
q += fmt.Sprintf(" AND mid=%d", mid)
}
return
}

View File

@@ -0,0 +1,139 @@
package service
import (
"bytes"
"encoding/csv"
"strconv"
"time"
"go-common/app/admin/main/up-rating/model"
)
var (
_avCategory = map[int]string{
0: "默认",
1: "动画",
3: "音乐",
129: "舞蹈",
4: "游戏",
36: "科技",
160: "生活",
119: "鬼畜",
155: "时尚",
23: "电影",
11: "电视剧",
13: "番剧",
167: "国创",
165: "广告",
5: "娱乐",
177: "纪录片",
181: "影视",
}
_scoreField = map[model.ScoreType]string{
model.Magnetic: "magnetic_score",
model.Creativity: "creativity_score",
model.Influence: "influence_score",
model.Credit: "credit_score",
}
)
// FormatCSV format to csv data
func formatCSV(records [][]string) (data []byte, err error) {
buf := new(bytes.Buffer)
// add utf bom
if len(records) > 0 {
buf.WriteString("\xEF\xBB\xBF")
}
w := csv.NewWriter(buf)
err = w.WriteAll(records)
if err != nil {
return
}
data = buf.Bytes()
return
}
func tagDesc(tagID int) string {
if v, ok := _avCategory[tagID]; ok {
return v
}
return _avCategory[0]
}
func formatScores(ratings []*model.RatingInfo) (data [][]string) {
if len(ratings) <= 0 {
return
}
data = make([][]string, len(ratings)+1)
data[0] = []string{"月份", "UID", "昵称", "分区", "总分", "创作力", "影响力", "信用分", "投稿量", "粉丝量"}
for i, v := range ratings {
data[i+1] = []string{
v.Date,
strconv.FormatInt(v.Mid, 10),
v.NickName,
tagDesc(v.TagID),
strconv.FormatInt(v.MagneticScore, 10),
strconv.FormatInt(v.CreativityScore, 10),
strconv.FormatInt(v.InfluenceScore, 10),
strconv.FormatInt(v.CreditScore, 10),
strconv.FormatInt(v.TotalAvs, 10),
strconv.FormatInt(v.TotalFans, 10),
}
}
return
}
func scoreField(st model.ScoreType) string {
if v, ok := _scoreField[st]; ok {
return v
}
return _scoreField[model.Magnetic]
}
func cDateStr(cdate time.Time) string {
return cdate.Format("2006-01-02")
}
func prevComputation(t time.Time) time.Time {
return time.Date(t.Year(), t.Month()-1, 1, 0, 0, 0, 0, time.Local)
}
func formatStatis(list []*model.RatingStatis, ctype int64) (data [][]string) {
if len(list) <= 0 {
return
}
data = make([][]string, len(list)+1)
data[0] = []string{"分数段", "本月", "占比", "对比", "占比", "平均分"}
switch ctype {
case 0:
data[0] = append(data[0], []string{"创造力", "影响力", "信用分"}...)
case 1:
data[0] = append(data[0], []string{"平均稿件数", "平均播放量", "平均互动量"}...)
case 2:
data[0] = append(data[0], []string{"平均粉丝量"}...)
}
for i, v := range list {
data[i+1] = []string{
v.Tips,
strconv.FormatInt(v.Ups, 10),
v.Proportion,
strconv.FormatInt(v.Compare, 10),
v.ComparePropor,
strconv.FormatInt(v.Score, 10),
}
switch ctype {
case 0:
data[i+1] = append(data[i+1], []string{strconv.FormatInt(v.CreativityScore, 10), strconv.FormatInt(v.InfluenceScore, 10), strconv.FormatInt(v.CreditScore, 10)}...)
case 1:
data[i+1] = append(data[i+1], []string{strconv.FormatInt(v.Avs, 10), strconv.FormatInt(v.Play, 10), strconv.FormatInt(v.Coin, 10)}...)
case 2:
data[i+1] = append(data[i+1], []string{strconv.FormatInt(v.Fans, 10)}...)
}
}
return
}