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

22
app/admin/main/up/BUILD Normal file
View File

@@ -0,0 +1,22 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/up/cmd:all-srcs",
"//app/admin/main/up/conf:all-srcs",
"//app/admin/main/up/dao:all-srcs",
"//app/admin/main/up/http:all-srcs",
"//app/admin/main/up/model:all-srcs",
"//app/admin/main/up/service:all-srcs",
"//app/admin/main/up/util:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,80 @@
#### up主admin接口项目
##### Version 1.2.7
> 1. account service gorpc to grpc
##### Version 1.2.6
> 1.crm 解决up签约列表的完成度显示问题(带入时间变更)
##### Version 1.2.5
> 1.crm 解决up签约列表的完成度显示问题
##### Version 1.2.4
> 1.crm 任务历史条件更新
##### Version 1.2.3
> 1.crm 签约up请假总次数展示
##### Version 1.2.2
> 1.crm 签约up主详细内容排序问题
##### Version 1.2.0
> 1.crm 签约管理二期需求
##### Version 1.1.4
> 1.修复util的trim
##### Version 1.1.3
> 1.修复签约标签错误的问题
##### Version 1.1.2
> 1.调整筛选的功能,现在可以对两种属性做与操作
##### Version 1.1.1
> 1.增加合同上传的强制性判断
##### Version 1.1.0
> 1.完成1.1的需求增加大量hbase数据查询接口
##### Version 0.1.10
> 1.增加刷新排行榜的命令
> 2.限制筛选数量超过10000
##### Version 0.1.9
> 1.去掉无用的trace
##### Version 0.1.8
> 1.修复评分历史最新数据获取的问题
##### Version 0.1.7
> 1.修复认证的问题
##### Version 0.1.6
> 1.修复筛选位发生偏移的问题
##### Version 0.1.5
> 1.修复数据读取错误
##### Version 0.1.4
> 1.修复内容分、质量分缺失
##### Version 0.1.3
> 1.修复数据bug-修复trend列表乱序的问题修复up rank定时更新的问题
##### Version 0.1.2
> 1.修复分数没有写入历史记录库
##### Version 0.1.1
> 1.修复默认参数为0的问题
##### Version 0.1.0
> 1.初次上线
##### Version 0.0.3
> 1.修复测试出的签约相关bug
##### Version 0.0.2
> 1.合入main/BUILD文
##### Version 0.0.1
> 1.建立项目

View File

@@ -0,0 +1,12 @@
# Owner
shencen
wangzhe01
# Author
shencen
fengpengfei
shaojiatong
# Reviewer
haoguanwei
shencen

18
app/admin/main/up/OWNERS Normal file
View File

@@ -0,0 +1,18 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- fengpengfei
- shaojiatong
- shencen
- wangzhe01
labels:
- admin
- admin/main/up
- main
options:
no_parent_owners: true
reviewers:
- fengpengfei
- haoguanwei
- shaojiatong
- shencen

View File

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

View File

@@ -0,0 +1,43 @@
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"],
data = ["up-admin.toml"],
importmap = "go-common/app/admin/main/up/cmd",
importpath = "go-common/app/admin/main/up/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/http:go_default_library",
"//library/log:go_default_library",
"//library/queue/databus/report: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,50 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/admin/main/up/conf"
"go-common/app/admin/main/up/http"
"go-common/library/log"
manager "go-common/library/queue/databus/report"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
log.Error("conf.Init() error(%v)", err)
panic(err)
}
// init log
log.Init(conf.Conf.XLog)
defer log.Close()
log.SetFormat("[%D %T] [%L] [%S] %M")
log.Info("up-adminstart")
// service init
http.Init(conf.Conf)
//logCli.Init(conf.Conf.LogCli)
// manager log init
manager.InitManager(nil)
// init signal
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("up-admin get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGINT:
http.Svc.Close()
log.Info("up-adminexit")
time.Sleep(1 * time.Second)
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,201 @@
# This is a TOML document. Boom.
version = "1.0.0"
consume = true
istest = true
IsMaster = true
[host]
api = "http://api.bilibili.co"
live = "http://api.live.bilibili.co"
search = "http://bili-search.bilibili.co"
manager = "http://manager.bilibili.co"
data = "http://data.bilibili.co"
tag = "http://dl-test.bilibili.com"
videoup = "http://archive.api.bilibili.co"
[xlog]
stdout = true
[httpClient]
[httpClient.normal]
key = "b8f239ca38a53308"
secret = "5460ef72fe13c10dfb53442b9111427e"
dial = "500ms"
timeout = "1s"
keepAlive = "60s"
timer = 10
[httpClient.normal.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[httpClient.slow]
key = "b8f239ca38a53308"
secret = "5460ef72fe13c10dfb53442b9111427e"
dial = "1s"
timeout = "10s"
keepAlive = "60s"
timer = 10
[httpClient.slow.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[HTTPServer]
addr = "0.0.0.0:7810"
timeout = "5s"
[db]
[db.creative]
name = "[creative]tcp@172.16.33.205:3308"
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_creative?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 5
idleTimeout ="4h"
queryTimeout = "5s"
execTimeout = "5s"
tranTimeout = "5s"
[db.creative.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[db.manager]
name = "172.16.33.205:3308"
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_manager?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8"
active = 5
idle = 2
idleTimeout ="4h"
queryTimeout = "5s"
execTimeout = "5s"
tranTimeout = "10s"
[db.manager.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[db.upcrm]
dsn = "upcrm:DdL6c5JaWCYKMAQ10PURbfeImow9HXlx@tcp(172.16.33.205:3306)/bilibili_upcrm?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 1
idleTimeout = "4h"
[db.archiveOrm]
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_archive?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 1
idleTimeout = "4h"
[articleRPC]
timeout = "1s"
[GRPCClient]
[GRPCClient.Archive]
timeout = "30s"
[GRPCClient.Account]
timeout = "30s"
[monitor]
moni="http://moni.bilibili.co/dashboard/db/databus?orgId=1"
host = "http://bap.bilibili.co"
username="fengpengfei"
appToken = "jLgSvndTeranxGMN"
appSecret = "CcCdlEBYqxqrgAieJuFVZUsgPmweLRms"
intervalAlarm = "5m"
[memcache]
upExpire = "1800s"
[memcache.up]
name = "up-admin"
proto = "tcp"
addr = "172.16.0.148:11211"
idle = 5
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[auth]
managerHost = "http://uat-manager.bilibili.co"
dashboardHost = "http://dashboard-mng.bilibili.co"
dashboardCaller = "manager-go"
[auth.DsHTTPClient]
key = "manager-go"
secret = "949bbb2dd3178252638c2407578bc7ad"
dial = "3s"
timeout = "3s"
keepAlive = "60s"
[auth.DsHTTPClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[auth.MaHTTPClient]
key = "f6433799dbd88751"
secret = "36f8ddb1806207fe07013ab6a77a3935"
dial = "1s"
timeout = "1s"
keepAlive = "60s"
[auth.MaHTTPClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[auth.session]
sessionIDLength = 32
cookieLifeTime = 1800
cookieName = "mng-go"
domain = ".bilibili.co"
[auth.session.Memcache]
name = "go-business/auth"
proto = "unix"
addr = "/tmp/uat-manager-auth-mc.sock"
active = 10
idle = 5
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[hbase]
master = ""
meta = ""
dialTimeout = "1s"
readTimeout = "150ms"
readsTimeout = "600ms"
writeTimeout = "200ms"
writesTimeout = "600ms"
[hbase.zookeeper]
root = ""
addrs = ["172.18.33.163:2181","172.18.33.164:2181","172.18.33.165:2181"]
timeout = "30s"
[BfsConf]
addr = "http://uat-bfs.bilibili.co"
bucket = "upcrm"
key = "9a261e35316e49b1"
secret = "906c328bbabb0ffa140c1b291b7259"
# 上传文件大小限制为10M
maxFileSize = 10485760
[TimeConf]
# 每天定时刷新排行
RefreshUpRankTime = "15:00:00"
[MailConf]
host = "smtp.exmail.qq.com"
port = 465
username = "2333@bilibili.com"
password = "2333"

View File

@@ -0,0 +1,46 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importmap = "go-common/app/admin/main/up/conf",
importpath = "go-common/app/admin/main/up/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/conf:go_default_library",
"//library/database/hbase.v2:go_default_library",
"//library/database/orm:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/net/trace:go_default_library",
"//library/queue/databus: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,234 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/orm"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
"go-common/library/net/rpc"
"go-common/library/net/rpc/warden"
"go-common/library/net/trace"
"go-common/library/queue/databus"
"go-common/library/time"
"go-common/library/database/hbase.v2"
"github.com/BurntSushi/toml"
)
// Conf info.
var (
ConfPath string
Conf = &Config{}
client *conf.Client
)
// Config struct.
type Config struct {
// bm
HTTPServer *blademaster.ServerConfig
// db
DB *DB
// base
// elk
XLog *log.Config
// report log
LogCli *log.AgentConfig
// httpClinet
HTTPClient *HTTPClient
// tracer
Tracer *trace.Config
// host
Host *Host
// ArchStatus
ArchStatus map[string]string
// Redis
Redis *Redis
// Databus
Env string
Consume bool
IsTest bool
UpSub *upSub
ChanSize int64
Monitor *Monitor
// rpc client2
ArticleRPC *rpc.ClientConfig
// identify
App *blademaster.App
Memcache *MC
//API HOST
API string
Live string
// auth
Auth *permit.Config
// hbase
HBase *HBaseConfig
HBase2 *HBaseConfig
BfsConf *Bfs
Debug bool
TimeConf *TimeConfig
MailConf *Mail
// manager log config
ManagerLog *databus.Config
// GRPCClient
GRPCClient *GRPC
}
// GRPC .
type GRPC struct {
Archive *warden.ClientConfig
Account *warden.ClientConfig
}
// HBaseConfig for new hbase client.
type HBaseConfig struct {
*hbase.Config
WriteTimeout time.Duration
ReadTimeout time.Duration
}
//UpSub upsub config
type upSub struct {
*databus.Config
UpChanSize int
ConsumeLimit int
RoutineLimit int
}
// DB conf.
type DB struct {
// Creative db
Creative *sql.Config
Manager *sql.Config
Upcrm *orm.Config
}
// Redis conf.
type Redis struct {
Databus *struct {
*redis.Config
Expire time.Duration
}
}
// HTTPClient conf.
type HTTPClient struct {
Normal *blademaster.ClientConfig
Slow *blademaster.ClientConfig
}
// Host conf.
type Host struct {
API string
Live string
Search string
Manager string
Data string
Tag string
Coverrec string
Videoup string
}
// Monitor conf.
type Monitor struct {
Host string
Moni string
UserName string
AppSecret string
AppToken string
IntervalAlarm time.Duration
}
//App for key secret.
type App struct {
Key string
Secret string
}
//MC memcache
type MC struct {
UpExpire time.Duration
Up *memcache.Config
}
// Bfs struct.
type Bfs struct {
Addr string
Bucket string
Key string
Secret string
MaxFileSize int
}
//TimeConfig 定期任务时间
type TimeConfig struct {
TaskScheduleTime string // 每天定时检查完成的task情况format "10:59:59"
CheckDueScheduleTime string // 每天定时检查快要过期的任务format "10:59:59"
RefreshUpRankTime string // 每天定时检查upRank表的任务format "10:59:59"
}
//Mail 邮件配置
type Mail struct {
Host string
Port int
Username, Password string
}
func init() {
flag.StringVar(&ConfPath, "conf", "", "default config path")
}
// 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 (
tomlStr string
ok bool
tmpConf *Config
)
if tomlStr, ok = client.Value("up-admin.toml"); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(tomlStr, &tmpConf); err != nil {
return errors.New("could not decode toml config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,60 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"upload_test.go",
"utils_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"upload.go",
"utils.go",
],
importmap = "go-common/app/admin/main/up/dao",
importpath = "go-common/app/admin/main/up/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf: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",
"//app/admin/main/up/dao/data:all-srcs",
"//app/admin/main/up/dao/email:all-srcs",
"//app/admin/main/up/dao/global:all-srcs",
"//app/admin/main/up/dao/manager:all-srcs",
"//app/admin/main/up/dao/tag:all-srcs",
"//app/admin/main/up/dao/upcrm:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,78 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"api_test.go",
"center_test.go",
"dao_test.go",
"field_test.go",
"hbase_set2_test.go",
"hbase_test.go",
"phase_three_test.go",
"utils_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/model/datamodel:go_default_library",
"//library/database/hbase.v2:go_default_library",
"//vendor/github.com/bouk/monkey:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/github.com/tsuna/gohbase/hrpc:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"api.go",
"center.go",
"dao.go",
"field.go",
"hbase.go",
"hbase_set2.go",
"phase_three.go",
"utils.go",
],
importpath = "go-common/app/admin/main/up/dao/data",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/model/datamodel:go_default_library",
"//app/admin/main/up/util/hbaseutil:go_default_library",
"//app/interface/main/creative/model/data:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/hbase.v2:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/sync/errgroup:go_default_library",
"//vendor/github.com/tsuna/gohbase/hrpc:go_default_library",
"@org_golang_x_net//context: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,101 @@
package data
import (
"context"
"net/url"
"strconv"
"strings"
"go-common/app/interface/main/creative/model/data"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_statURL = "/data/member/upinfo/%d.json"
_tagURL = "/tag_predict"
_tagv2URL = "/tag_predict/v2"
_coverURL = "/cover_recomm"
)
// Tags get predict tag.
func (d *Dao) Tags(c context.Context, mid int64, tid uint16, title, filename, desc, cover string) (t *data.Tags, err error) {
params := url.Values{}
params.Set("typeid", strconv.Itoa(int(tid)))
params.Set("title", title)
params.Set("filename", filename)
params.Set("desc", desc)
params.Set("cover", cover)
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data *data.Tags `json:"data"`
}
if err = d.client.Get(c, d.tagURI, "", params, &res); err != nil {
log.Error("data url(%s) error(%v)", d.tagURI+"?"+params.Encode(), err)
err = ecode.CreativeDataErr
return
}
if res.Code != 0 {
log.Error("data url(%s) res(%v)", d.tagURI+"?"+params.Encode(), res)
err = ecode.CreativeDataErr
return
}
t = res.Data
return
}
// TagsWithChecked get predict tag with checked mark.
func (d *Dao) TagsWithChecked(c context.Context, mid int64, tid uint16, title, filename, desc, cover string, tagFrom int8) (t []*data.CheckedTag, err error) {
params := url.Values{}
t = make([]*data.CheckedTag, 0)
params.Set("client_type", strconv.Itoa(int(tagFrom)))
params.Set("typeid", strconv.Itoa(int(tid)))
params.Set("title", title)
params.Set("filename", filename)
params.Set("desc", desc)
params.Set("cover", cover)
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data struct {
Tags []*data.CheckedTag `json:"tags"`
} `json:"data"`
}
log.Info("TagsWithChecked url(%s)", d.tagV2URI+"?"+params.Encode())
if err = d.client.Get(c, d.tagV2URI, "", params, &res); err != nil {
log.Error("data url(%s) error(%v)", d.tagV2URI+"?"+params.Encode(), err)
err = ecode.CreativeDataErr
return
}
if res.Code != 0 {
log.Error("data url(%s) res(%v)", d.tagV2URI+"?"+params.Encode(), res)
err = ecode.CreativeDataErr
return
}
t = res.Data.Tags
return
}
// RecommendCovers get recommend covers from AI.
func (d *Dao) RecommendCovers(c context.Context, mid int64, fns []string) (cvs []string, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("filename", strings.Join(fns, ","))
var res struct {
Code int `json:"code"`
Data []string `json:"data"`
}
if err = d.client.Get(c, d.coverBFSURI, "", params, &res); err != nil {
log.Error("Covers url(%s) error(%v)", d.coverBFSURI+"?"+params.Encode(), err)
err = ecode.CreativeDataErr
return
}
if res.Code != 0 {
log.Error("Covers url(%s) res(%v)", d.coverBFSURI+"?"+params.Encode(), res)
err = ecode.CreativeDataErr
return
}
cvs = res.Data
return
}

View File

@@ -0,0 +1,87 @@
package data
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestDataTags(t *testing.T) {
convey.Convey("Tags", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
tid = uint16(0)
title = ""
filename = ""
desc = ""
cover = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.tagURI).Reply(200).BodyString(`
{
"code":0,
"data": {"tags" : ["1"]}
}`)
no, err := d.Tags(c, mid, tid, title, filename, desc, cover)
ctx.Convey("Then err should be nil.no should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(no, convey.ShouldNotBeNil)
})
})
})
}
func TestDataTagsWithChecked(t *testing.T) {
convey.Convey("TagsWithChecked", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
tid = uint16(0)
title = ""
filename = ""
desc = ""
cover = ""
tagFrom = int8(0)
)
defer gock.OffAll()
httpMock("GET", d.tagV2URI).Reply(200).BodyString(`
{
"code":0,
"data": {"tags" : []}
}`)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
no, err := d.TagsWithChecked(c, mid, tid, title, filename, desc, cover, tagFrom)
ctx.Convey("Then err should be nil.no should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(no, convey.ShouldNotBeNil)
})
})
})
}
func TestDataRecommendCovers(t *testing.T) {
convey.Convey("RecommendCovers", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
fns = []string{}
)
defer gock.OffAll()
httpMock("GET", d.coverBFSURI).Reply(200).BodyString(`
{
"code":0,
"data": ["1"]
}`)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cvs, err := d.RecommendCovers(c, mid, fns)
ctx.Convey("Then err should be nil.cvs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(cvs, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,556 @@
package data
import (
"bytes"
"strconv"
"time"
"go-common/app/admin/main/up/model/datamodel"
"go-common/app/admin/main/up/util/hbaseutil"
"go-common/app/interface/main/creative/model/data"
"go-common/library/ecode"
"go-common/library/log"
"github.com/tsuna/gohbase/hrpc"
"golang.org/x/net/context"
)
// ViewerBase visitor data analysis.
func (d *Dao) ViewerBase(c context.Context, mid int64, dt time.Time) (res *datamodel.ViewerBaseInfo, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
key = hbaseMd5Key(mid)
genTableName = generateTableNameFunc(HBaseUpViewerBase, dt, -7)
)
defer cancel()
if result, err = d.getDataWithBackup(ctx, d.hbase, genTableName, 2, key); err != nil {
log.Error("ViewerBase d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", HBaseUpViewerBase, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("ViewerBase no data tableName(%s)|mid(%d)|key(%v)", HBaseUpViewerBase, mid, key)
return
}
res = &datamodel.ViewerBaseInfo{}
families := make(map[string]string, 2)
families["f"] = ""
families["g"] = ""
fb := &datamodel.ViewerBaseData{}
gb := &datamodel.ViewerBaseData{}
for _, c := range result.Cells {
if c == nil {
continue
}
if _, ok := families[string(c.Family)]; ok {
var data = gb
if string(c.Family) == "f" {
data = fb
}
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
/*
f:plat0 web-pc播放
f:plat1 web-h5播放
f:plat2 站外播放
f:plat3 ios播放
f:plat4 android播放
*/
switch {
case bytes.Equal(c.Qualifier, []byte("male")):
data.Male = v
case bytes.Equal(c.Qualifier, []byte("female")):
data.Female = v
case bytes.Equal(c.Qualifier, []byte("age1")):
data.Age1 = v
case bytes.Equal(c.Qualifier, []byte("age2")):
data.Age2 = v
case bytes.Equal(c.Qualifier, []byte("age3")):
data.Age3 = v
case bytes.Equal(c.Qualifier, []byte("age4")):
data.Age4 = v
case bytes.Equal(c.Qualifier, []byte("plat0")):
data.PlatPC = v
case bytes.Equal(c.Qualifier, []byte("plat1")):
data.PlatH5 = v
case bytes.Equal(c.Qualifier, []byte("plat2")):
data.PlatOut = v
case bytes.Equal(c.Qualifier, []byte("plat3")):
data.PlatIOS = v
case bytes.Equal(c.Qualifier, []byte("plat4")):
data.PlatAndroid = v
case bytes.Equal(c.Qualifier, []byte("else")):
data.PlatOtherApp = v
}
}
}
res.Fans = fb
res.Guest = gb
return
}
// ViewerArea visitor area data analysis.
func (d *Dao) ViewerArea(c context.Context, mid int64, dt time.Time) (res *datamodel.ViewerAreaInfo, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
key = hbaseMd5Key(mid)
genTableName = generateTableNameFunc(HBaseUpViewerArea, dt, -7)
)
defer cancel()
if result, err = d.getDataWithBackup(ctx, d.hbase, genTableName, 2, key); err != nil {
log.Error("ViewerArea d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", HBaseUpViewerArea, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("ViewerArea no data tableName(%s)|mid(%d)|key(%v)", HBaseUpViewerArea, mid, key)
return
}
res = &datamodel.ViewerAreaInfo{}
families := make(map[string]string, 2)
families["f"] = ""
families["g"] = ""
for _, c := range result.Cells {
if c == nil {
continue
}
if _, ok := families[string(c.Family)]; ok {
a := string(c.Qualifier[:])
var list = &res.Guest
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
if string(c.Family) == "f" {
list = &res.Fans
}
*list = append(*list, datamodel.ViewerAreaData{Area: a, Viewers: v})
}
}
return
}
// ViewerTrend visitor trend data analysis.
func (d *Dao) ViewerTrend(c context.Context, mid int64, dt time.Time) (res map[string]*data.Trend, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
genTableName = generateTableNameFunc(HBaseUpViewerTrend, dt, -7)
key = hbaseMd5Key(mid)
)
defer cancel()
if result, err = d.getDataWithBackup(ctx, d.hbase, genTableName, 2, key); err != nil {
log.Error("ViewerTrend d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", HBaseUpViewerTrend, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("ViewerTrend no data tableName(%s)|mid(%d)|key(%v)", HBaseUpViewerTrend, mid, key)
return
}
families := make(map[string]string, 4)
families["fs"] = ""
families["ft"] = ""
families["gs"] = ""
families["gt"] = ""
res = make(map[string]*data.Trend)
ftd := &data.Trend{}
gtd := &data.Trend{}
ty := make(map[int]int64)
tg := make(map[int]int64)
nty := make(map[int]int64)
ntg := make(map[int]int64)
for _, c := range result.Cells {
if c == nil {
continue
}
if _, ok := families[string(c.Family)]; ok {
if string(c.Family) == "fs" {
tid, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
ty[tid] = v
ftd.Ty = ty
} else if string(c.Family) == "gs" {
tid, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
nty[tid] = v
gtd.Ty = nty
}
if string(c.Family) == "ft" {
o, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
tg[o] = v
ftd.Tag = tg
} else if string(c.Family) == "gt" {
o, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
ntg[o] = v
gtd.Tag = ntg
}
}
}
res["fan"] = ftd
res["guest"] = gtd
return
}
// RelationFansDay up relation 30 days analysis.
func (d *Dao) RelationFansDay(c context.Context, mid int64) (res datamodel.RelationFanHistoryData, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseUpRelationFansDay
key = hbaseMd5Key(mid)
parser = hbaseutil.Parser{
ParseIntFunc: hbaseutil.StringToUint,
}
)
defer cancel()
if result, err = d.hbase.GetStr(ctx, tableName, key); err != nil {
log.Error("RelationFansDay d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", tableName, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("RelationFansDay no data tableName(%s)|mid(%d)|key(%v)", tableName, mid, key)
return
}
if err = parser.Parse(result.Cells, &res); err != nil {
log.Error("parse cell fail, err=%v", err)
return
}
/*
families := make(map[string]string, 2)
families["a"] = "" //某日新增关注量
families["u"] = "" //某日取关量
fd := make(map[string]int)
nfd := make(map[string]int)
for _, c := range result.Cells {
if c == nil {
continue
}
if _, ok := families[string(c.Family)]; ok {
if string(c.Family) == "a" {
k := string(c.Qualifier[:])
v, _ := strconv.Atoi(string(c.Value[:]))
fd[k] = v
} else if string(c.Family) == "u" {
k := string(c.Qualifier[:])
v, _ := strconv.Atoi(string(c.Value[:]))
nfd[k] = v
}
}
}
res["follow"] = fd
res["unfollow"] = nfd
*/
return
}
// RelationFansHistory up relation history.
func (d *Dao) RelationFansHistory(c context.Context, mid int64, month string) (res datamodel.RelationFanHistoryData, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseUpRelationFansHistory
key = string(hbaseMd5Key(mid)) + "_" + month
parser = hbaseutil.Parser{ParseIntFunc: hbaseutil.StringToUint}
)
defer cancel()
if result, err = d.hbase.GetStr(ctx, tableName, key); err != nil {
log.Error("RelationFansHistory d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", tableName, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("RelationFansHistory no data tableName(%s)|mid(%d)|key(%v)", tableName, mid, key)
return
}
if err = parser.Parse(result.Cells, &res); err != nil {
log.Error("parse cell fail, err=%v", err)
return
}
return
}
// RelationFansMonth up relation 400 days analysis.
func (d *Dao) RelationFansMonth(c context.Context, mid int64) (res datamodel.RelationFanHistoryData, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseUpRelationFansMonth
key = hbaseMd5Key(mid)
parser = hbaseutil.Parser{ParseIntFunc: hbaseutil.StringToUint}
)
defer cancel()
if result, err = d.hbase.GetStr(ctx, tableName, key); err != nil {
log.Error("RelationFansMonth d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", tableName, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("RelationFansMonth no data tableName(%s)|mid(%d)|key(%v)", tableName, mid, key)
return
}
if err = parser.Parse(result.Cells, &res); err != nil {
log.Error("parse cell fail, err=%v", err)
return
}
return
}
// ViewerActionHour visitor action hour analysis.
func (d *Dao) ViewerActionHour(c context.Context, mid int64, dt string) (res map[string]*data.ViewerActionHour, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseUpViewerActionHour + dt
key = hbaseMd5Key(mid)
)
defer cancel()
if result, err = d.hbase.GetStr(ctx, tableName, key); err != nil {
log.Error("ViewerActionHour d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", tableName, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("ViewerActionHour no data tableName(%s)|mid(%d)|key(%v)", tableName, mid, key)
return
}
families := make(map[string]string, 4)
families["fp"] = "" //播放数
families["fr"] = "" //评论数
families["fd"] = "" //弹幕数
families["fe"] = "" //充电数
families["fs"] = "" //承包数
res = make(map[string]*data.ViewerActionHour)
view := make(map[int]int)
reply := make(map[int]int)
danmu := make(map[int]int)
elec := make(map[int]int)
con := make(map[int]int)
fah := &data.ViewerActionHour{}
gah := &data.ViewerActionHour{}
for _, c := range result.Cells {
if c == nil {
continue
}
if _, ok := families[string(c.Family)]; ok {
if string(c.Family) == "fp" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
view[k] = v
fah.View = view
} else if string(c.Family) == "gp" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
view[k] = v
gah.View = view
}
if string(c.Family) == "fr" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
reply[k] = v
fah.Reply = reply
} else if string(c.Family) == "gr" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
reply[k] = v
gah.Reply = reply
}
if string(c.Family) == "fd" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
danmu[k] = v
fah.Dm = danmu
} else if string(c.Family) == "gd" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
danmu[k] = v
gah.Dm = danmu
}
if string(c.Family) == "fe" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
elec[k] = v
fah.Elec = elec
} else if string(c.Family) == "ge" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
elec[k] = v
gah.Elec = elec
}
if string(c.Family) == "fs" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
con[k] = v
fah.Contract = con
} else if string(c.Family) == "gs" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
con[k] = v
gah.Contract = con
}
}
}
res["fan"] = fah
res["not_fan"] = gah
return
}
// UpIncr for Play/Dm/Reply/Fav/Share/Elec/Coin incr.
func (d *Dao) UpIncr(c context.Context, mid int64, ty int8, now string) (res *data.UpDataIncrMeta, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, d.hbaseTimeOut)
tableName string
IncrKey string
key = hbaseMd5Key(mid)
)
defer cancel()
switch {
case ty == data.Play:
tableName = HBaseUpPlayInc + now
case ty == data.Dm:
tableName = HBaseUpDmInc + now
case ty == data.Reply:
tableName = HBaseUpReplyInc + now
case ty == data.Share:
tableName = HBaseUpShareInc + now
case ty == data.Coin:
tableName = HBaseUpCoinInc + now
case ty == data.Fav:
tableName = HBaseUpFavInc + now
case ty == data.Elec:
tableName = HBaseUpElecInc + now
}
IncrKey, _ = data.IncrTy(ty)
if result, err = d.hbase.GetStr(ctx, tableName, key); err != nil {
log.Error("UpIncr d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", tableName, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("UpIncr no data tableName(%s)|mid(%d)|key(%v)", tableName, mid, key)
return
}
families := make(map[string]string, 4)
families["u"] = "" //单日播放增量 u:play ...
families["av"] = "" //播放top稿件 av:1
families["v"] = "" //top稿件播放增量 v:1
families["rk"] = "" //up主播放量排名 rk: [tid]
aids := make(map[int]int64)
incs := make(map[int]int)
rk := make(map[int]int)
var incr int
for _, c := range result.Cells {
if c == nil {
continue
}
if _, ok := families[string(c.Family)]; ok {
if string(c.Family) == "av" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
aids[k] = v
} else if string(c.Family) == "v" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
incs[k] = v
} else if string(c.Family) == "rk" {
k, _ := strconv.Atoi(string(c.Qualifier[:]))
v, _ := strconv.Atoi(string(c.Value[:]))
rk[k] = v
} else if string(c.Family) == "u" {
if bytes.Equal(c.Qualifier, []byte(IncrKey)) {
v, _ := strconv.Atoi(string(c.Value[:]))
if v < 0 {
v = 0
}
incr = v
}
}
}
}
res = &data.UpDataIncrMeta{}
res.Incr = incr
res.TopAIDList = aids
res.TopIncrList = incs
res.Rank = rk
return
}
// ThirtyDayArchive for Play/Dm/Reply/Fav/Share/Elec/Coin for archive 30 days.
func (d *Dao) ThirtyDayArchive(c context.Context, mid int64, ty int8) (res []*data.ThirtyDay, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName string
key = hbaseMd5Key(mid)
)
defer cancel()
switch {
case ty == data.Play:
tableName = HBasePlayArc
case ty == data.Dm:
tableName = HBaseDmArc
case ty == data.Reply:
tableName = HBaseReplyArc
case ty == data.Share:
tableName = HBaseShareArc
case ty == data.Coin:
tableName = HBaseCoinArc
case ty == data.Fav:
tableName = HBaseFavArc
case ty == data.Elec:
tableName = HBaseElecArc
case ty == data.Like:
tableName = HBaseLikeArc
}
if result, err = d.hbase.GetStr(ctx, tableName, key); err != nil {
log.Error("ThirtyDayArchive d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", tableName, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("ThirtyDay no data tableName(%s)|mid(%d)|key(%v)", tableName, mid, key)
return
}
res = make([]*data.ThirtyDay, 0, len(result.Cells))
for _, c := range result.Cells {
if c == nil {
continue
}
qual := string(c.Qualifier[:])
val := string(c.Value[:])
if string(c.Family) == "u" {
t, v, err := parseKeyValue(qual, val)
if err != nil {
break
}
td := &data.ThirtyDay{}
td.DateKey = t
td.TotalIncr = v
res = append(res, td)
}
}
log.Info("ThirtyDayArchive mid(%d) type(%d) return data(%+v)", mid, ty, res)
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
}

View File

@@ -0,0 +1,178 @@
package data
import (
"context"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestDataViewerBase(t *testing.T) {
convey.Convey("ViewerBase", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
dt = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.ViewerBase(c, mid, dt)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDataViewerArea(t *testing.T) {
convey.Convey("ViewerArea", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
dt = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.ViewerArea(c, mid, dt)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDataViewerTrend(t *testing.T) {
convey.Convey("ViewerTrend", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
dt = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.ViewerTrend(c, mid, dt)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDataRelationFansDay(t *testing.T) {
convey.Convey("RelationFansDay", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.RelationFansDay(c, mid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDataRelationFansHistory(t *testing.T) {
convey.Convey("RelationFansHistory", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
month = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.RelationFansHistory(c, mid, month)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDataRelationFansMonth(t *testing.T) {
convey.Convey("RelationFansMonth", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.RelationFansMonth(c, mid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDataViewerActionHour(t *testing.T) {
convey.Convey("ViewerActionHour", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
dt = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.ViewerActionHour(c, mid, dt)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDataUpIncr(t *testing.T) {
convey.Convey("UpIncr", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
ty = int8(0)
now = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.UpIncr(c, mid, ty, now)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDataThirtyDayArchive(t *testing.T) {
convey.Convey("ThirtyDayArchive", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
ty = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.ThirtyDayArchive(c, mid, ty)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDataparseKeyValue(t *testing.T) {
convey.Convey("parseKeyValue", t, func(ctx convey.C) {
var (
k = "20060102"
v = "123"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
timestamp, value, err := parseKeyValue(k, v)
ctx.Convey("Then err should be nil.timestamp,value should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(value, convey.ShouldNotBeNil)
ctx.So(timestamp, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,115 @@
package data
import (
"context"
"time"
"go-common/app/admin/main/up/conf"
"go-common/library/cache/memcache"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/database/hbase.v2"
)
// Dao is data dao.
type Dao struct {
c *conf.Config
// http
client *bm.Client
statClient *bm.Client
// uri
statURI string
tagURI string
tagV2URI string
coverBFSURI string
// mc
mc *memcache.Pool
//mcExpire int32
//mcIdxExpire int32
//statCacheOn bool
// hbase
hbase *hbase.Client
hbaseTimeOut time.Duration
// chan
missch chan func()
}
// New init dao
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
// http
client: bm.NewClient(c.HTTPClient.Slow),
statClient: bm.NewClient(c.HTTPClient.Slow),
statURI: c.Host.Data + _statURL,
tagURI: c.Host.Tag + _tagURL,
tagV2URI: c.Host.Tag + _tagv2URL,
coverBFSURI: c.Host.Coverrec + _coverURL,
// memcache
//mc: memcache.NewPool(c.Memcache.Data.Config),
//mcExpire: int32(time.Duration(c.Memcache.Data.DataExpire) / time.Second),
//mcIdxExpire: int32(time.Duration(c.Memcache.Data.IndexExpire) / time.Second),
//statCacheOn: c.StatCacheOn,
// hbase
hbase: hbase.NewClient(c.HBase.Config),
// chan
missch: make(chan func(), 1024),
hbaseTimeOut: time.Duration(time.Millisecond * 200),
}
return
}
// Stat get user stat play/fans/...
//func (d *Dao) Stat(c context.Context, ip string, mid int64) (st *data.Stat, err error) {
// // try cache
// if st, _ = d.statCache(c, mid); st != nil {
// return
// }
// // from api
// if st, err = d.stat(c, mid, ip); st != nil {
// d.AddCache(func() {
// d.addStatCache(context.Background(), mid, st)
// })
// }
// return
//}
// UpStat get up stat from hbase
//func (d *Dao) UpStat(c context.Context, mid int64, dt string) (st *data.UpBaseStat, err error) {
// // try cache
// if d.statCacheOn {
// if st, _ = d.upBaseStatCache(c, mid, dt); st != nil {
// log.Info("upBaseStatCache cache found mid(%d)", mid)
// return
// }
// }
// // from hbase
// if st, err = d.BaseUpStat(c, mid, dt); st != nil {
// d.AddCache(func() {
// d.addUpBaseStatCache(context.Background(), mid, dt, st)
// })
// }
// return
//}
// Ping ping success.
func (d *Dao) Ping(c context.Context) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: "ping", Value: []byte("pong"), Expiration: 0}); err != nil {
log.Error("mc.ping.Store error(%v)", err)
}
return
}
// Close mc close
func (d *Dao) Close() (err error) {
if d.mc != nil {
d.mc.Close()
}
if d.hbase != nil {
d.hbase.Close()
}
return
}

View File

@@ -0,0 +1,49 @@
package data
import (
"flag"
"os"
"strings"
"testing"
"go-common/app/admin/main/up/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-admin")
flag.Set("conf_token", "930697bb7def4df0713ef8080596b863")
flag.Set("tree_id", "36438")
flag.Set("conf_version", "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-admin.toml")
}
if os.Getenv("UT_LOCAL_TEST") != "" {
flag.Set("conf", "../../cmd/up-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.client.SetTransport(gock.DefaultTransport)
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,96 @@
package data
var (
//HBaseVideoTablePrefix 播放流失分布
HBaseVideoTablePrefix = "video_play_churn_"
//HBaseArchiveTablePrefix 分类分端播放
HBaseArchiveTablePrefix = "video_play_category_"
//HBaseAreaTablePrefix 地区播放
HBaseAreaTablePrefix = "video_play_area_"
//HBaseUpStatTablePrefix up主概况
HBaseUpStatTablePrefix = "up_stats_"
//HBaseUpViewerBase 观众数据,性别年龄分布 + 设备分布
HBaseUpViewerBase = "up_viewer_base_"
//HBaseUpViewerArea 地区分布
HBaseUpViewerArea = "up_viewer_area_"
//HBaseUpViewerTrend 内容倾向
HBaseUpViewerTrend = "up_viewer_trend_"
//HBaseUpViewerActionHour 行为时间分布
HBaseUpViewerActionHour = "up_viewer_action_hour_"
//HBaseUpRelationFansDay 日维度 最近30天 只保留31天
HBaseUpRelationFansDay = "up_relation_fans_day"
// HBaseUpRelationFansHistory 日维度 各月份每日数据,日更,永久保存
HBaseUpRelationFansHistory = "up_relation_fans_history"
//HBaseUpRelationFansMonth 年维度 2017.8月以后的数据永久保存
HBaseUpRelationFansMonth = "up_relation_fans_month"
//HBaseUpPlayInc 我的概况 播放相关
HBaseUpPlayInc = "up_play_inc_"
//HBaseUpDmInc 弹幕相关
HBaseUpDmInc = "up_dm_inc_"
//HBaseUpReplyInc 评论相关
HBaseUpReplyInc = "up_reply_inc_"
//HBaseUpShareInc 分享相关
HBaseUpShareInc = "up_share_inc_"
//HBaseUpCoinInc 投币相关
HBaseUpCoinInc = "up_coin_inc_"
//HBaseUpFavInc 收藏相关
HBaseUpFavInc = "up_fav_inc_"
//HBaseUpElecInc 充电相关
HBaseUpElecInc = "up_elec_inc_"
//HBaseUpFansAnalysis 粉丝管理
HBaseUpFansAnalysis = "up_fans_analysis"
//HBaseUpPlaySourceAnalysis 播放来源
HBaseUpPlaySourceAnalysis = "up_play_analysis"
//HBaseUpArcPlayAnalysis 平均观看时长、播放用户数、留存率
HBaseUpArcPlayAnalysis = "up_archive_play_analysis"
//HBaseUpArcQuery 稿件索引表
HBaseUpArcQuery = "up_archive_query"
//HBasePlayArc 播放相关 archive for 30 days
HBasePlayArc = "up_play_trend"
//HBaseDmArc 弹幕相关
HBaseDmArc = "up_dm_trend"
//HBaseReplyArc 评论相关
HBaseReplyArc = "up_reply_trend"
//HBaseShareArc 分享相关
HBaseShareArc = "up_share_trend"
//HBaseCoinArc 投币相关
HBaseCoinArc = "up_coin_trend"
//HBaseFavArc 收藏相关
HBaseFavArc = "up_fav_trend"
//HBaseElecArc 充电相关
HBaseElecArc = "up_elec_trend"
//HBaseLikeArc 点赞相关
HBaseLikeArc = "up_like_trend"
//HBaseFamilyPlat family
HBaseFamilyPlat = []byte("v")
//HBaseColumnAid aid
HBaseColumnAid = []byte("avid")
//HBaseColumnWebPC pc
HBaseColumnWebPC = []byte("plat0")
//HBaseColumnWebH5 h5
HBaseColumnWebH5 = []byte("plat1")
//HBaseColumnOutsite out
HBaseColumnOutsite = []byte("plat2")
//HBaseColumnIOS ios
HBaseColumnIOS = []byte("plat3")
//HBaseColumnAndroid android
HBaseColumnAndroid = []byte("plat4")
//HBaseColumnElse else
HBaseColumnElse = []byte("else")
//HBaseColumnFans fans
HBaseColumnFans = []byte("fans")
//HBaseColumnGuest guest
HBaseColumnGuest = []byte("guest")
//HBaseColumnAll all
HBaseColumnAll = []byte("all")
//HBaseColumnCoin coin
HBaseColumnCoin = []byte("coin")
//HBaseColumnElec elec
HBaseColumnElec = []byte("elec")
//HBaseColumnFav fav
HBaseColumnFav = []byte("fav")
//HBaseColumnShare share
HBaseColumnShare = []byte("share")
)

View File

@@ -0,0 +1 @@
package data

View File

@@ -0,0 +1,226 @@
package data
import (
"bytes"
"crypto/md5"
"encoding/hex"
"sort"
"strconv"
"time"
"go-common/app/interface/main/creative/model/data"
"go-common/library/ecode"
"go-common/library/log"
"github.com/tsuna/gohbase/hrpc"
"golang.org/x/net/context"
)
func hbaseMd5Key(aid int64) string {
hasher := md5.New()
hasher.Write([]byte(strconv.Itoa(int(aid))))
return hex.EncodeToString(hasher.Sum(nil))
}
// VideoQuitPoints get video quit points.
func (d *Dao) VideoQuitPoints(c context.Context, cid int64) (res []int64, err error) {
var (
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseVideoTablePrefix + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
backupTableName = HBaseVideoTablePrefix + time.Now().AddDate(0, 0, -2).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
key = hbaseMd5Key(cid)
)
defer cancel()
result, err := d.hbase.GetStr(ctx, tableName, key)
if err != nil {
if result, err = d.hbase.GetStr(ctx, backupTableName, key); err != nil {
log.Error("VideoQuitPoints d.hbase.GetStr backupTableName(%s)|cid(%d)|key(%v)|error(%v)", backupTableName, cid, key, err)
err = ecode.CreativeDataErr
return
}
}
if result == nil {
return
}
// get parts and max part for fill res
partMap := make(map[int]int64)
maxPart := 0
for _, c := range result.Cells {
if c != nil {
part, _ := strconv.Atoi(string(c.Qualifier[:]))
per, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
partMap[part] = per
if part > maxPart {
maxPart = part
}
}
}
var restPercent int64 = 10000 // start from 100%
for i := 1; i <= maxPart; i++ {
if _, ok := partMap[i]; ok {
restPercent = restPercent - partMap[i]
}
res = append(res, restPercent)
}
return
}
// ArchiveStat get the stat of archive.
func (d *Dao) ArchiveStat(c context.Context, aid int64) (stat *data.ArchiveData, err error) {
var (
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseArchiveTablePrefix + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
backupTableName = HBaseArchiveTablePrefix + time.Now().AddDate(0, 0, -2).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
key = hbaseMd5Key(aid)
)
defer cancel()
result, err := d.hbase.GetStr(ctx, tableName, key)
if err != nil {
if result, err = d.hbase.GetStr(ctx, backupTableName, key); err != nil {
log.Error("ArchiveStat d.hbase.GetStr backupTableName(%s)|aid(%d)|key(%v)|error(%v)", backupTableName, aid, key, err)
err = ecode.CreativeDataErr
return
}
}
if result == nil {
return
}
stat = &data.ArchiveData{}
stat.ArchiveSource = &data.ArchiveSource{}
stat.ArchiveGroup = &data.ArchiveGroup{}
stat.ArchiveStat = &data.ArchiveStat{}
for _, c := range result.Cells {
if c == nil {
continue
}
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
if !bytes.Equal(c.Family, HBaseFamilyPlat) {
continue
}
switch {
case bytes.Equal(c.Qualifier, HBaseColumnWebPC):
stat.ArchiveSource.WebPC = v
case bytes.Equal(c.Qualifier, HBaseColumnWebH5):
stat.ArchiveSource.WebH5 = v
case bytes.Equal(c.Qualifier, HBaseColumnOutsite):
stat.ArchiveSource.Outsite = v
case bytes.Equal(c.Qualifier, HBaseColumnIOS):
stat.ArchiveSource.IOS = v
case bytes.Equal(c.Qualifier, HBaseColumnAndroid):
stat.ArchiveSource.Android = v
case bytes.Equal(c.Qualifier, HBaseColumnElse):
stat.ArchiveSource.Others = v
case bytes.Equal(c.Qualifier, HBaseColumnFans):
stat.ArchiveGroup.Fans = v
case bytes.Equal(c.Qualifier, HBaseColumnGuest):
stat.ArchiveGroup.Guest = v
case bytes.Equal(c.Qualifier, HBaseColumnAll):
stat.ArchiveStat.Play = v
case bytes.Equal(c.Qualifier, HBaseColumnCoin):
stat.ArchiveStat.Coin = v
case bytes.Equal(c.Qualifier, HBaseColumnElec):
stat.ArchiveStat.Elec = v
case bytes.Equal(c.Qualifier, HBaseColumnFav):
stat.ArchiveStat.Fav = v
case bytes.Equal(c.Qualifier, HBaseColumnShare):
stat.ArchiveStat.Share = v
}
}
stat.ArchiveSource.Mainsite = stat.ArchiveSource.WebPC + stat.ArchiveSource.WebH5
stat.ArchiveSource.Mobile = stat.ArchiveSource.Android + stat.ArchiveSource.IOS
return
}
// ArchiveArea get the count of area.
func (d *Dao) ArchiveArea(c context.Context, aid int64) (res []*data.ArchiveArea, err error) {
var (
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseAreaTablePrefix + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
backupTableName = HBaseAreaTablePrefix + time.Now().AddDate(0, 0, -2).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
key = hbaseMd5Key(aid)
)
defer cancel()
result, err := d.hbase.GetStr(ctx, tableName, key)
if err != nil {
if result, err = d.hbase.GetStr(ctx, backupTableName, key); err != nil {
log.Error("ArchiveArea d.hbase.GetStr backupTableName(%s)|aid(%d)|key(%v)|error(%v)", backupTableName, aid, key, err)
err = ecode.CreativeDataErr
return
}
}
if result == nil {
return
}
var countArr []int
countMap := make(map[int64][]*data.ArchiveArea)
countSet := make(map[int]struct{}) // empty struct{} for saving memory
for _, c := range result.Cells {
if c != nil {
area := &data.ArchiveArea{}
area.Location = string(c.Qualifier[:])
area.Count, _ = strconv.ParseInt(string(c.Value[:]), 10, 64)
countMap[area.Count] = append(countMap[area.Count], area)
countSet[int(area.Count)] = struct{}{}
}
}
for key := range countSet {
countArr = append(countArr, key)
}
sort.Sort(sort.Reverse(sort.IntSlice(countArr)))
for _, c := range countArr {
if _, ok := countMap[int64(c)]; ok {
res = append(res, countMap[int64(c)]...)
}
if len(res) >= 10 {
res = res[:10] // exact 10 item
break
}
}
return
}
// BaseUpStat get base up stat.
func (d *Dao) BaseUpStat(c context.Context, mid int64, date string) (stat *data.UpBaseStat, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, d.hbaseTimeOut)
tableName = HBaseUpStatTablePrefix + date // change table at 12:00am
key = hbaseMd5Key(mid)
)
defer cancel()
if result, err = d.hbase.GetStr(ctx, tableName, key); err != nil {
log.Error("BaseUpStat d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", tableName, mid, key, err)
err = ecode.CreativeDataErr
return
}
if result == nil {
return
}
stat = &data.UpBaseStat{}
for _, c := range result.Cells {
if c == nil {
continue
}
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
if !bytes.Equal(c.Family, []byte("u")) {
continue
}
switch {
case bytes.Equal(c.Qualifier, []byte("play")):
stat.View = v
case bytes.Equal(c.Qualifier, []byte("dm")):
stat.Dm = v
case bytes.Equal(c.Qualifier, []byte("reply")):
stat.Reply = v
case bytes.Equal(c.Qualifier, []byte("fans")):
stat.Fans = v
case bytes.Equal(c.Qualifier, []byte("fav")):
stat.Fav = v
case bytes.Equal(c.Qualifier, []byte("like")):
stat.Like = v
case bytes.Equal(c.Qualifier, []byte("sh")):
stat.Share = v
}
}
return
}

View File

@@ -0,0 +1,148 @@
package data
import (
"context"
"fmt"
"sync"
"time"
"go-common/app/admin/main/up/model/datamodel"
"go-common/app/admin/main/up/util/hbaseutil"
"go-common/library/log"
"go-common/library/sync/errgroup"
"github.com/tsuna/gohbase/hrpc"
)
// 这里是集群2的数据请求
const (
// HbaseUpArchiveInfoPrefix archive info表
HbaseUpArchiveInfoPrefix = "upcrm:up_influence"
// HbaseUpArchiveTagInfoPrefix tag表
HbaseUpArchiveTagInfoPrefix = "upcrm:up_archive_tag_info"
// HbaseUpArchiveTypeInfoPrefix 分区表
HbaseUpArchiveTypeInfoPrefix = "upcrm:up_archive_type_info"
)
var (
//ErrInvalidDataType invalid data type
ErrInvalidDataType = fmt.Errorf("invalid data type")
)
//UpArchiveDataType data type
type UpArchiveDataType int
const (
//DataTypeDay7 7 day
DataTypeDay7 UpArchiveDataType = 1
//DataTypeDay30 30 day
DataTypeDay30 UpArchiveDataType = 2
//DataTypeDay90 90 day
DataTypeDay90 UpArchiveDataType = 3
//DataTypeDay180 180 day
DataTypeDay180 UpArchiveDataType = 4
//DataTypeDayAll accumulated
DataTypeDayAll UpArchiveDataType = 5
)
var (
dataType2FamilyMap = map[UpArchiveDataType]string{
DataTypeDay7: "d7",
DataTypeDay30: "d30",
DataTypeDay90: "d90",
DataTypeDay180: "d180",
DataTypeDayAll: "dall",
}
)
//UpArchiveInfo get up archive info
func (d *Dao) UpArchiveInfo(c context.Context, mids []int64, dataType UpArchiveDataType) (result map[int64]*datamodel.UpArchiveData, err error) {
var now = time.Now()
var date = now.AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
var tableName = generateTableName(HbaseUpArchiveInfoPrefix, date)
var family, ok = dataType2FamilyMap[dataType]
if !ok {
log.Error("invalid data type, type=%d", dataType)
err = ErrInvalidDataType
return
}
var group, ctx = errgroup.WithContext(c)
var lock sync.Mutex
result = make(map[int64]*datamodel.UpArchiveData)
for _, mid := range mids {
var copymid = mid
group.Go(
func() error {
var data = &datamodel.UpArchiveData{}
var key = hbaseMd5Key(copymid)
if e := d.getHbaseRowResult(ctx, tableName, key, data, hrpc.Families(map[string][]string{family: nil})); e != nil {
log.Error("get up archive info fail, mid=%d, err=%v", err)
return nil
}
lock.Lock()
result[copymid] = data
lock.Unlock()
return nil
})
}
if err = group.Wait(); err != nil {
log.Error("batch get fail, err=%v", err)
return
}
log.Info("get archive info ok, find result count=%d", len(result))
return
}
//UpArchiveTagInfo get up archive tag info
func (d *Dao) UpArchiveTagInfo(c context.Context, mid int64) (result datamodel.UpArchiveTagData, err error) {
var now = time.Now()
var date = now.AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
var tableName = generateTableName(HbaseUpArchiveTagInfoPrefix, date)
var key = hbaseMd5Key(mid)
if err = d.getHbaseRowResult(c, tableName, key, &result); err != nil {
log.Error("get up archive tag info fail, err=%v", err)
}
return
}
//UpArchiveTypeInfo get up archive type info
func (d *Dao) UpArchiveTypeInfo(c context.Context, mid int64) (result datamodel.UpArchiveTypeData, err error) {
var now = time.Now()
var date = now.AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
var tableName = generateTableName(HbaseUpArchiveTypeInfoPrefix, date)
var key = hbaseMd5Key(mid)
if err = d.getHbaseRowResult(c, tableName, key, &result); err != nil {
log.Error("get up archive type info fail, err=%v", err)
}
return
}
func (d *Dao) getHbaseRowResult(c context.Context, table, key string, result interface{}, options ...func(hrpc.Call) error) (err error) {
var ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
defer cancel()
res, err := d.hbase.GetStr(ctx, table, key, options...)
if err != nil {
log.Error("fail to get data from hbase, table=%s, key=%s, err=%v", table, key, err)
return
}
if len(res.Cells) == 0 {
log.Warn("no cells get, table=%s, key=%s, err=%v", table, key, err)
return
}
var parser = hbaseutil.Parser{}
if err = parser.Parse(res.Cells, result); err != nil {
log.Error("parse data fail, table=%s, key=%s, err=%v", table, key, err)
return
}
return
}
// dont use date string
func generateTableName(prefix, date string) string {
return prefix
}

View File

@@ -0,0 +1,102 @@
package data
import (
"context"
"reflect"
"testing"
"github.com/bouk/monkey"
"github.com/tsuna/gohbase/hrpc"
"go-common/app/admin/main/up/model/datamodel"
hbase "go-common/library/database/hbase.v2"
"github.com/smartystreets/goconvey/convey"
)
func TestDataUpArchiveInfo(t *testing.T) {
convey.Convey("UpArchiveInfo", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{}
dataType UpArchiveDataType
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.UpArchiveInfo(c, mids, dataType)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(result, convey.ShouldBeNil)
})
})
})
}
func TestDataUpArchiveTagInfo(t *testing.T) {
convey.Convey("UpArchiveTagInfo", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.UpArchiveTagInfo(c, mid)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestDataUpArchiveTypeInfo(t *testing.T) {
convey.Convey("UpArchiveTypeInfo", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.UpArchiveTypeInfo(c, mid)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestDatagetHbaseRowResult(t *testing.T) {
convey.Convey("getHbaseRowResult", t, func(ctx convey.C) {
var (
c = context.Background()
table = "crm"
key = "123"
result = datamodel.UpArchiveTypeData{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
guard := monkey.PatchInstanceMethod(reflect.TypeOf(d.hbase), "GetStr", func(_ *hbase.Client, _ context.Context, _, _ string, _ ...func(hrpc.Call) error) (*hrpc.Result, error) {
res := &hrpc.Result{}
return res, nil
})
defer guard.Unpatch()
err := d.getHbaseRowResult(c, table, key, &result)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDatagenerateTableName(t *testing.T) {
convey.Convey("generateTableName", t, func(ctx convey.C) {
var (
prefix = ""
date = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := generateTableName(prefix, date)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,87 @@
package data
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDatahbaseMd5Key(t *testing.T) {
convey.Convey("hbaseMd5Key", t, func(ctx convey.C) {
var (
aid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := hbaseMd5Key(aid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDataVideoQuitPoints(t *testing.T) {
convey.Convey("VideoQuitPoints", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.VideoQuitPoints(c, cid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDataArchiveStat(t *testing.T) {
convey.Convey("ArchiveStat", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
stat, err := d.ArchiveStat(c, aid)
ctx.Convey("Then err should be nil.stat should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(stat, convey.ShouldBeNil)
})
})
})
}
func TestDataArchiveArea(t *testing.T) {
convey.Convey("ArchiveArea", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.ArchiveArea(c, aid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}
func TestDataBaseUpStat(t *testing.T) {
convey.Convey("BaseUpStat", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
date = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
stat, err := d.BaseUpStat(c, mid, date)
ctx.Convey("Then err should be nil.stat should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(stat, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,227 @@
package data
import (
"context"
"encoding/binary"
"strconv"
"time"
"go-common/app/admin/main/up/model/datamodel"
"go-common/app/admin/main/up/util/hbaseutil"
"go-common/library/ecode"
"go-common/library/log"
"github.com/tsuna/gohbase/hrpc"
)
// reverse for string.
func reverseString(s string) string {
rs := []rune(s)
l := len(rs)
for f, t := 0, l-1; f < t; f, t = f+1, t-1 {
rs[f], rs[t] = rs[t], rs[f]
}
ns := string(rs)
if l < 10 {
for i := 0; i < 10-l; i++ {
ns = ns + "0"
}
}
return ns
}
// 粉丝管理 - up_fans_analysis
// mid倒置补0 补满共10位+0 +yyyyMMdd 累计数据
// mid倒置补0 补满共10位+1 +yyyyMMdd 7日数据
// mid倒置补0 补满共10位+2 +yyyyMMdd 30日数据
// mid倒置补0 补满共10位+3 +yyyyMMdd 90日数据
func fansRowKey(id int64, ty int) string {
idStr := strconv.FormatInt(id, 10)
s := reverseString(idStr)
s = s + strconv.Itoa(ty) + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102")
return s
}
// 稿件索引表 - up_archive_query
// [mid倒置补010位] + [投稿年月4位] + [原创/转载1位]
func arcQueryKey(id int64, dt string, cp int) string {
idStr := strconv.FormatInt(id, 10)
cpStr := strconv.Itoa(cp)
s := reverseString(idStr)
s = s + dt + cpStr
return s
}
// UpFansAnalysis for web fans analysis.
func (d *Dao) UpFansAnalysis(c context.Context, mid int64, ty int) (res *datamodel.FanInfo, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseUpFansAnalysis
//summary = make(map[string]int32) //total & classify proportion
//rankDr = make(map[string]int32) //播放时长 mid list
//rankVideoAct = make(map[string]int32) //视频互动 mid list
//rankDyAct = make(map[string]int32) //动态互动 mid list
rankMap = make(map[string]map[string]int32) //top 10 rank list
source = make(map[string]int32) //source proportion
rowkey = fansRowKey(mid, ty)
parser = hbaseutil.Parser{}
)
res = new(datamodel.FanInfo)
defer cancel()
log.Info("UpFansAnalysisForWeb mid(%d)|rowkey(%s)", mid, rowkey)
if result, err = d.hbase.GetStr(ctx, tableName, rowkey, hrpc.Families(map[string][]string{"f": nil})); err != nil {
log.Error("d.hbase.GetStr tableName(%s)|mid(%d)|rowkey(%v)|error(%v)", tableName, mid, rowkey, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("UpFansAnalysisForWeb no data tableName(%s)|mid(%d)|rowkey(%v)", tableName, mid, rowkey)
return
}
var summary datamodel.FanSummaryData
err = parser.Parse(result.Cells, &summary)
if err != nil {
log.Error("convert from hbase fail, err=%v", err)
return
}
/*
for _, c := range result.Cells {
if c == nil {
continue
}
if string(c.Family) == "f" {
k := string(c.Qualifier[:])
var v int32
if len(c.Value) == 4 {
v = byteToInt32(c.Value)
switch k {
case "all": //总粉丝
summary.Total = v
//summary["total"] = v
case "inc": //新增粉丝
summary.Inc = v
case "act": //活跃粉丝
summary.Active = v
// summary["active"] = v
//case "mdl": //领取勋章粉丝
// summary["medal"] = v
//case "elec": //充电粉丝
// summary["elec"] = v
//case "act_diff": //活跃粉丝(增量)
// summary["act_diff"] = v
//case "mdl_diff": //领取勋章粉丝(增量)
// summary["mdl_diff"] = v
//case "elec_diff": //充电粉丝(增量)
// summary["elec_diff"] = v
//case "v": //播放粉丝占比*10000
// summary["v"] = v
//case "dm": //弹幕粉丝占比*10000
// summary["dm"] = v
//case "r": //评论粉丝占比*10000
// summary["r"] = v
//case "c": //投币粉丝占比*10000
// summary["c"] = v
// //新增粉丝活跃占比
//case "inter": //互动活跃度*10000
// summary["inter"] = v
//case "vv": //观看活跃度*10000
// summary["vv"] = v
//case "da": //弹幕粉丝占比*10000
// summary["da"] = v
//case "re": //评论粉丝占比*10000
// summary["re"] = v
//case "co": //投币粉丝占比*10000
// summary["co"] = v
//case "fv": //收藏粉丝占比*10000
// summary["fv"] = v
//case "sh": //分享粉丝占比*10000
// summary["sh"] = v
//case "lk": //点赞粉丝占比*10000
// summary["lk"] = v
}
} else {
log.Error("UpFansAnalysisForWeb family[f] get dirty tableName(%s)|mid(%d)|rowkey(%s)|value(%+v)", tableName, mid, rowkey, c.Value)
}
}
if string(c.Family) == "t" {
var v int32
if len(c.Value) == 4 {
v = int32(binary.BigEndian.Uint32(c.Value))
} else {
log.Error("UpFansAnalysisForWeb family t get dirty tableName(%s)|mid(%d)|rowkey(%s)|value(%+v)", tableName, mid, fansRowKey(mid, ty), c.Value)
}
if strings.Contains(string(c.Qualifier[:]), "dr") {
rankDr[string(c.Qualifier[:])] = v
}
if strings.Contains(string(c.Qualifier[:]), "act") {
rankVideoAct[string(c.Qualifier[:])] = v
}
if strings.Contains(string(c.Qualifier[:]), "dy") {
rankDyAct[string(c.Qualifier[:])] = v
}
}
if string(c.Family) == "s" {
var v int32
if len(c.Value) == 4 {
v = int32(binary.BigEndian.Uint32(c.Value))
} else {
log.Error("UpFansAnalysisForWeb family[t] get dirty data tableName(%s)|mid(%d)|rowkey(%s)|value(%+v)", tableName, mid, rowkey, c.Value)
}
if strings.Contains(string(c.Qualifier[:]), "pf") {
if pk, ok := fanSource[string(c.Qualifier[:])]; ok {
source[pk] = v
}
}
}
}
for _, k := range fanSource { //粉丝来源页面占比如果数据平台未返回,则设置对应的key
if _, ok := source[k]; !ok {
source[k] = 0
}
}
*/
log.Info("UpFansAnalysisForWebRankMap mid(%d)|rowkey(%s)|summary(%+v)|rankMap(%+v)|source(%+v)", mid, rowkey, summary, rankMap, source)
res.Summary = summary
return
}
// UpArcQuery for play aids by mid.
func (d *Dao) UpArcQuery(c context.Context, mid int64, dt string, cp int) (res []int64, err error) {
var (
result *hrpc.Result
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
tableName = HBaseUpArcQuery
rowkey = arcQueryKey(mid, dt, cp)
)
defer cancel()
log.Info("UpArcQuery mid(%d)|rowkey(%s)", mid, rowkey)
if result, err = d.hbase.GetStr(ctx, tableName, rowkey); err != nil {
log.Error("d.hbase.GetStr tableName(%s)|mid(%d)|rowkey(%s)|error(%v)", tableName, mid, rowkey, err)
err = ecode.CreativeDataErr
return
}
if result == nil || len(result.Cells) == 0 {
log.Warn("UpArcQuery no data tableName(%s)|mid(%d)|rowkey(%s)", tableName, mid, rowkey)
return
}
res = make([]int64, 0)
for _, c := range result.Cells {
if c == nil {
continue
}
if string(c.Family) == "av" {
var v int64
if len(c.Value) == 4 {
v = int64(binary.BigEndian.Uint32(c.Value))
} else {
log.Error("UpArcQuery family[av] get dirty value tableName(%s)|rowkey(%s)", tableName, rowkey)
}
res = append(res, v)
}
}
log.Info("UpArcQuery mid(%d)|rowkey(%s)|res(%+v)", mid, rowkey, res)
return
}

View File

@@ -0,0 +1,88 @@
package data
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDatareverseString(t *testing.T) {
convey.Convey("reverseString", t, func(ctx convey.C) {
var (
s = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := reverseString(s)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDatafansRowKey(t *testing.T) {
convey.Convey("fansRowKey", t, func(ctx convey.C) {
var (
id = int64(0)
ty = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := fansRowKey(id, ty)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDataarcQueryKey(t *testing.T) {
convey.Convey("arcQueryKey", t, func(ctx convey.C) {
var (
id = int64(0)
dt = ""
cp = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := arcQueryKey(id, dt, cp)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDataUpFansAnalysis(t *testing.T) {
convey.Convey("UpFansAnalysis", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
ty = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.UpFansAnalysis(c, mid, ty)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDataUpArcQuery(t *testing.T) {
convey.Convey("UpArcQuery", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
dt = ""
cp = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.UpArcQuery(c, mid, dt, cp)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,41 @@
package data
import (
"context"
"fmt"
"time"
"go-common/library/log"
"go-common/library/database/hbase.v2"
"github.com/tsuna/gohbase/hrpc"
)
func (d *Dao) getDataWithBackup(c context.Context, client *hbase.Client, tableNameFunc func(retryCount int) string, maxRetry int, key string, options ...func(hrpc.Call) error) (result *hrpc.Result, err error) {
if client == nil {
err = fmt.Errorf("hbase client is nil")
return
}
for i := 0; i < maxRetry; i++ {
var tableName = tableNameFunc(i)
if result, err = d.hbase.GetStr(c, tableName, key, options...); err != nil {
log.Error("hbase GetStr tableName(%s)|key(%v)|error(%v)", tableName, key, err)
continue
}
break
}
return
}
func getTableName(tablePrefix string, date time.Time) string {
return tablePrefix + date.Format("20060102")
}
func generateTableNameFunc(tablePrefix string, date time.Time, dayDiff int) func(retryCount int) string {
return func(retryCount int) string {
var backdate = date.AddDate(0, 0, dayDiff*retryCount)
return getTableName(tablePrefix, backdate)
}
}

View File

@@ -0,0 +1,63 @@
package data
import (
"context"
"testing"
"time"
"go-common/library/database/hbase.v2"
"github.com/smartystreets/goconvey/convey"
"github.com/tsuna/gohbase/hrpc"
)
func TestDatagetDataWithBackup(t *testing.T) {
convey.Convey("getDataWithBackup", t, func(ctx convey.C) {
var (
c = context.Background()
client = &hbase.Client{}
tableNameFunc func(retryCount int) string
maxRetry = int(0)
key = ""
options func(hrpc.Call) error
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.getDataWithBackup(c, client, tableNameFunc, maxRetry, key, options)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldBeNil)
})
})
})
}
func TestDatagetTableName(t *testing.T) {
convey.Convey("getTableName", t, func(ctx convey.C) {
var (
tablePrefix = ""
date = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := getTableName(tablePrefix, date)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDatagenerateTableNameFunc(t *testing.T) {
convey.Convey("generateTableNameFunc", t, func(ctx convey.C) {
var (
tablePrefix = ""
date = time.Now()
dayDiff = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := generateTableNameFunc(tablePrefix, date, dayDiff)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,52 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"email_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"email.go",
],
importpath = "go-common/app/admin/main/up/dao/email",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//library/log:go_default_library",
"//vendor/gopkg.in/gomail.v2: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,26 @@
package email
import (
"crypto/tls"
"go-common/app/admin/main/up/conf"
gomail "gopkg.in/gomail.v2"
)
// Dao is redis dao.
type Dao struct {
email *gomail.Dialer
}
// New is new redis dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// mail
email: gomail.NewDialer(c.MailConf.Host, c.MailConf.Port, c.MailConf.Username, c.MailConf.Password),
}
d.email.TLSConfig = &tls.Config{
InsecureSkipVerify: true,
}
return
}

View File

@@ -0,0 +1,38 @@
package email
import (
"flag"
"os"
"testing"
"go-common/app/admin/main/up/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-admin")
flag.Set("conf_token", "930697bb7def4df0713ef8080596b863")
flag.Set("tree_id", "36438")
flag.Set("conf_version", "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-admin.toml")
}
if os.Getenv("UT_LOCAL_TEST") != "" {
flag.Set("conf", "../../cmd/up-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,39 @@
package email
import (
"os"
"go-common/app/admin/main/up/conf"
"go-common/library/log"
"gopkg.in/gomail.v2"
)
//SendMail send the email.
func (d *Dao) SendMail(body string, subject string, send ...string) (err error) {
msg := gomail.NewMessage()
msg.SetHeader("From", conf.Conf.MailConf.Username)
msg.SetHeader("To", send...)
msg.SetHeader("Subject", subject)
msg.SetBody("text/html", body, gomail.SetPartEncoding(gomail.Base64))
if err = d.email.DialAndSend(msg); err != nil {
log.Error("s.email.DialAndSend error(%v)", err)
return
}
return
}
//SendMailAttach send the email.
func (d *Dao) SendMailAttach(filename string, subject string, send []string) (err error) {
msg := gomail.NewMessage()
msg.SetHeader("From", conf.Conf.MailConf.Username)
msg.SetHeader("To", send...)
msg.SetHeader("Subject", subject)
msg.Attach(filename)
if err = d.email.DialAndSend(msg); err != nil {
log.Error("s.email.DialAndSend error(%v)", err)
return
}
err = os.Remove(filename)
return
}

View File

@@ -0,0 +1,39 @@
package email
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestEmailSendMail(t *testing.T) {
convey.Convey("SendMail", t, func(ctx convey.C) {
var (
body = ""
subject = ""
send = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SendMail(body, subject, send)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestEmailSendMailAttach(t *testing.T) {
convey.Convey("SendMailAttach", t, func(ctx convey.C) {
var (
filename = ""
subject = ""
send = []string{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SendMailAttach(filename, subject, send)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dao_test.go"],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["dao.go"],
importpath = "go-common/app/admin/main/up/dao/global",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/service/main/account/api: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,25 @@
package global
import (
"go-common/app/admin/main/up/conf"
accgrpc "go-common/app/service/main/account/api"
"github.com/pkg/errors"
)
var (
accCli accgrpc.AccountClient
)
// GetAccClient .
func GetAccClient() accgrpc.AccountClient {
return accCli
}
//Init init global
func Init(c *conf.Config) {
var err error
if accCli, err = accgrpc.NewClient(c.GRPCClient.Account); err != nil {
panic(errors.WithMessage(err, "Failed to dial account service"))
}
}

View File

@@ -0,0 +1,57 @@
package global
import (
"flag"
"os"
"testing"
"go-common/app/admin/main/up/conf"
"github.com/smartystreets/goconvey/convey"
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-admin")
flag.Set("conf_token", "930697bb7def4df0713ef8080596b863")
flag.Set("tree_id", "36438")
flag.Set("conf_version", "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-admin.toml")
}
if os.Getenv("UT_LOCAL_TEST") != "" {
flag.Set("conf", "../../cmd/up-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
Init(conf.Conf)
os.Exit(m.Run())
}
func TestGlobalGetAccClient(t *testing.T) {
convey.Convey("GetAccClient", t, func(ctx convey.C) {
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := GetAccClient()
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestGlobalInit(t *testing.T) {
convey.Convey("Init", t, func(ctx convey.C) {
ctx.Convey("When everything gose positive", func(ctx convey.C) {
Init(conf.Conf)
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}

View File

@@ -0,0 +1,54 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dao_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/model/signmodel:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["dao.go"],
importmap = "go-common/app/admin/main/up/dao/manager",
importpath = "go-common/app/admin/main/up/dao/manager",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/model/signmodel:go_default_library",
"//app/admin/main/up/model/upcrmmodel:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/time: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,173 @@
package manager
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strings"
"time"
"go-common/app/admin/main/up/conf"
"go-common/app/admin/main/up/model/signmodel"
"go-common/app/admin/main/up/model/upcrmmodel"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
xtime "go-common/library/time"
"go-common/library/xstr"
)
const (
// URLUNames url for usernames to uid
URLUNames = "/x/admin/manager/users/unames"
// URLUids url for uids to username
URLUids = "/x/admin/manager/users/uids"
// URLAuditLog url for sign up change log
URLAuditLog = "/x/admin/search/log"
)
// Dao is redis dao.
type Dao struct {
c *conf.Config
managerDB *sql.DB
HTTPClient *bm.Client
}
// New fn
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
managerDB: sql.NewMySQL(c.DB.Manager),
// http client
HTTPClient: bm.NewClient(c.HTTPClient.Normal),
}
return d
}
// Close fn
func (d *Dao) Close() {
if d.managerDB != nil {
d.managerDB.Close()
}
}
// Ping ping cpdb
func (d *Dao) Ping(c context.Context) (err error) {
return d.managerDB.Ping(c)
}
// GetUNamesByUids get name by uid
func (d *Dao) GetUNamesByUids(c context.Context, uids []int64) (res map[int64]string, err error) {
var param = url.Values{}
var uidStr = xstr.JoinInts(uids)
param.Set("uids", uidStr)
var httpRes struct {
Code int `json:"code"`
Data map[int64]string `json:"data"`
Message string `json:"message"`
}
err = d.HTTPClient.Get(c, d.c.Host.Manager+URLUNames, "", param, &httpRes)
if err != nil {
log.Error("d.client.Get(%s) error(%v)", d.c.Host.Manager+URLUNames+"?"+param.Encode(), err)
return
}
if httpRes.Code != 0 {
log.Error("url(%s) error(%v), code(%d), message(%s)", d.c.Host.Manager+URLUNames+"?"+param.Encode(), err, httpRes.Code, httpRes.Message)
}
res = httpRes.Data
return
}
// GetUIDByNames get uid by name
func (d *Dao) GetUIDByNames(c context.Context, names []string) (res map[string]int64, err error) {
var param = url.Values{}
var namesStr = strings.Join(names, ",")
param.Set("unames", namesStr)
var httpRes struct {
Code int `json:"code"`
Data map[string]int64 `json:"data"`
Message string `json:"message"`
}
err = d.HTTPClient.Get(c, d.c.Host.Manager+URLUids, "", param, &httpRes)
if err != nil {
log.Error("d.client.Get(%s) error(%v)", d.c.Host.Manager+URLUids+"?"+param.Encode(), err)
return
}
if httpRes.Code != 0 {
log.Error("url(%s) error(%v), code(%d), message(%s)", d.c.Host.Manager+URLUids+"?"+param.Encode(), err, httpRes.Code, httpRes.Message)
}
res = httpRes.Data
return
}
// SignUpAuditLogs get sign up audit log .
func (d *Dao) SignUpAuditLogs(c context.Context, arg *signmodel.SignOpSearchArg) (res *signmodel.SignAuditListReply, err error) {
params := url.Values{}
params.Set("appid", "log_audit")
params.Set("business", fmt.Sprintf("%d", signmodel.SignUpLogBizID))
params.Set("order", arg.Order)
params.Set("sort", arg.Sort)
params.Set("int_0", fmt.Sprintf("%d", arg.SignID))
params.Set("oid", fmt.Sprintf("%d", arg.Mid))
params.Set("type", fmt.Sprintf("%d", arg.Tp))
params.Set("pn", fmt.Sprintf("%d", arg.PN))
params.Set("ps", fmt.Sprintf("%d", arg.PS))
var httpRes struct {
Code int `json:"code"`
Data *signmodel.BaseAuditListReply `json:"data"`
Message string `json:"message"`
}
err = d.HTTPClient.Get(c, d.c.Host.Manager+URLAuditLog, "", params, &httpRes)
if err != nil {
log.Error("d.client.Get(%s) error(%v)", d.c.Host.Manager+URLAuditLog+"?"+params.Encode(), err)
return
}
if httpRes.Code != 0 {
log.Error("url(%s) error(%v), code(%d), message(%s)", d.c.Host.Manager+URLAuditLog+"?"+params.Encode(), err, httpRes.Code, httpRes.Message)
}
res = new(signmodel.SignAuditListReply)
res.Page = arg.PN
res.Size = arg.PS
res.Order = arg.Order
res.Sort = arg.Sort
if httpRes.Data != nil && httpRes.Data.Pager != nil {
res.TotalCount = httpRes.Data.Pager.TotalCount
}
for _, v := range httpRes.Data.Result {
ctime, _ := time.ParseInLocation(upcrmmodel.TimeFmtDateTime, v.CTime, time.Local)
var signAuit = &signmodel.SignAuditReply{
Mid: v.OID,
SignID: v.IntOne,
Tp: v.Tp,
OperID: v.UID,
OperName: v.UName,
CTime: xtime.Time(ctime.Unix()),
}
var content signmodel.SignContentReply
json.Unmarshal([]byte(v.ExtraData), &content)
signAuit.Content = &content
if signAuit.Content.New != nil {
buildSignContractURL(signAuit.Content.New)
}
if signAuit.Content.Old != nil {
buildSignContractURL(signAuit.Content.Old)
}
res.Result = append(res.Result, signAuit)
}
return
}
func buildSignContractURL(su *signmodel.SignUpArg) {
if su.ContractInfo == nil {
return
}
for _, v := range su.ContractInfo {
v.Filelink = signmodel.BuildOrcBfsURL(v.Filelink)
v.Filelink = signmodel.BuildDownloadURL(v.Filename, v.Filelink)
}
}

View File

@@ -0,0 +1,122 @@
package manager
import (
"flag"
"os"
"testing"
"context"
"github.com/smartystreets/goconvey/convey"
"go-common/app/admin/main/up/conf"
"go-common/app/admin/main/up/model/signmodel"
"gopkg.in/h2non/gock.v1"
"strings"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-admin")
flag.Set("conf_token", "930697bb7def4df0713ef8080596b863")
flag.Set("tree_id", "36438")
flag.Set("conf_version", "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-admin.toml")
}
if os.Getenv("UT_LOCAL_TEST") != "" {
flag.Set("conf", "../../cmd/up-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.HTTPClient.SetTransport(gock.DefaultTransport)
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}
func TestGetUIDByNames(t *testing.T) {
convey.Convey("TestGetUIDByNames", t, func(ctx convey.C) {
var (
names []string
c = context.Background()
)
defer gock.OffAll()
httpMock("GET", d.c.Host.Manager+URLUids).Reply(200).BodyString(`
{
"code" : 0,
"data" : { "1" : 1 }
}
`)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.GetUIDByNames(c, names)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestGetUNamesByUids(t *testing.T) {
convey.Convey("TestGetUNamesByUids", t, func(ctx convey.C) {
var (
uids = []int64{0}
c = context.Background()
)
defer gock.OffAll()
httpMock("GET", d.c.Host.Manager+URLUNames).Reply(200).BodyString(`
{
"code" : 0,
"data" : { "1" : "adm1" }
}
`)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.GetUNamesByUids(c, uids)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestSignUpAuditLogs(t *testing.T) {
convey.Convey("SendMail", t, func(ctx convey.C) {
var (
arg = &signmodel.SignOpSearchArg{}
c = context.Background()
)
defer gock.OffAll()
httpMock("GET", d.c.Host.Manager+URLAuditLog).Reply(200).BodyString(`
{
"code" : 0,
"data" : {
"order" : "asc",
"sort" : "fe"
}
}
`)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.SignUpAuditLogs(c, arg)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,56 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"tag_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"tag.go",
],
importpath = "go-common/app/admin/main/up/dao/tag",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/interface/main/creative/model/tag:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster: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,35 @@
package tag
import (
"go-common/app/admin/main/up/conf"
httpx "go-common/library/net/http/blademaster"
)
const (
_tagList = "/x/internal/tag/minfo"
_tagCheck = "/x/internal/tag/check"
_appealTag = "/videoup/archive/reason/tag"
)
// Dao define
type Dao struct {
c *conf.Config
// http
client *httpx.Client
// uri
tagList string
tagCheck string
appealTag string
}
// New init dao
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
client: httpx.NewClient(c.HTTPClient.Normal),
tagList: c.Host.API + _tagList,
tagCheck: c.Host.API + _tagCheck,
appealTag: c.Host.Videoup + _appealTag,
}
return
}

View File

@@ -0,0 +1,48 @@
package tag
import (
"flag"
"os"
"strings"
"testing"
"go-common/app/admin/main/up/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-admin")
flag.Set("conf_token", "930697bb7def4df0713ef8080596b863")
flag.Set("tree_id", "36438")
flag.Set("conf_version", "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-admin.toml")
}
if os.Getenv("UT_LOCAL_TEST") != "" {
flag.Set("conf", "../../cmd/up-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.client.SetTransport(gock.DefaultTransport)
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,86 @@
package tag
import (
"context"
"net/url"
"strconv"
"go-common/app/interface/main/creative/model/tag"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/xstr"
)
// TagList get tag list.
func (d *Dao) TagList(c context.Context, ids []int64) (tgs []*tag.Meta, err error) {
params := url.Values{}
params.Set("tag_id", xstr.JoinInts(ids))
var res struct {
Code int `json:"code"`
Data []*tag.Meta `json:"data"`
}
if err = d.client.Get(c, d.tagList, "", params, &res); err != nil {
log.Error("TagList url(%s) response(%+v) error(%v)", d.tagList, res, err)
err = ecode.CreativeTagErr
return
}
if res.Code != 0 {
log.Error("TagList url(%s) res(%v)", d.tagList, res)
err = ecode.CreativeTagErr
return
}
tgs = res.Data
return
}
// TagCheck tag check
func (d *Dao) TagCheck(c context.Context, mid int64, tagName string) (t *tag.Tag, err error) {
params := url.Values{}
params.Set("tag_name", tagName)
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data *tag.Tag `json:"data"`
}
if err = d.client.Get(c, d.tagCheck, "", params, &res); err != nil {
log.Error("TagCheck url(%s) p(%+v) response(%s) error(%v)", d.tagCheck, params.Encode(), res, err)
err = ecode.CreativeTagErr
return
}
log.Info("TagCheck url(%s) | p(%+v) |res(%v)", d.tagCheck, params.Encode(), res)
if res.Code != 0 {
log.Error("TagCheck url(%s) res(%v)", d.tagCheck, res)
err = ecode.Int(res.Code)
return
}
if res.Data != nil {
t = res.Data
}
return
}
// AppealTag appeal tag from videoup.
func (d *Dao) AppealTag(c context.Context, aid int64, ip string) (tid int64, err error) {
params := url.Values{}
params.Set("aid", strconv.FormatInt(aid, 10))
var res struct {
Code int `json:"code"`
Data *struct {
TagID int64 `json:"tag_id"`
} `json:"data"`
}
if err = d.client.Get(c, d.appealTag, ip, params, &res); err != nil {
log.Error("appeal tag error(%v)", err)
err = ecode.CreativeTagErr
return
}
if res.Code != 0 {
log.Error("appeal tag url(%s) res(%v)", d.appealTag, res)
err = ecode.Int(res.Code)
return
}
if res.Data != nil {
tid = res.Data.TagID
}
return
}

View File

@@ -0,0 +1,77 @@
package tag
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestTagTagList(t *testing.T) {
convey.Convey("TagList", t, func(ctx convey.C) {
var (
c = context.Background()
ids = []int64{}
)
defer gock.OffAll()
httpMock("GET", d.tagList).Reply(200).BodyString(`
{
"code":0,
"data": []
}`)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
tgs, err := d.TagList(c, ids)
ctx.Convey("Then err should be nil.tgs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(tgs, convey.ShouldNotBeNil)
})
})
})
}
func TestTagTagCheck(t *testing.T) {
convey.Convey("TagCheck", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
tagName = ""
)
defer gock.OffAll()
httpMock("GET", d.tagCheck).Reply(200).BodyString(`
{
"code":0,
"data": {"tags" : []}
}`)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
no, err := d.TagCheck(c, mid, tagName)
ctx.Convey("Then err should be nil.no should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(no, convey.ShouldNotBeNil)
})
})
})
}
func TestTagAppealTag(t *testing.T) {
convey.Convey("AppealTag", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
ip = ""
)
defer gock.OffAll()
httpMock("GET", d.appealTag).Reply(200).BodyString(`
{
"code":0,
"data": {"tags" : []}
}`)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
tid, err := d.AppealTag(c, aid, ip)
ctx.Convey("Then err should be nil.tid should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(tid, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,77 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"credit_log_test.go",
"dao_test.go",
"scoresection_test.go",
"sign_up_test.go",
"task_info_test.go",
"up_base_info_test.go",
"up_play_info_test.go",
"up_rank_test.go",
"up_scores_history_test.go",
"up_stats_history_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/model/signmodel:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"credit_log.go",
"dao.go",
"scoresection.go",
"sign_up.go",
"task_info.go",
"up_base_info.go",
"up_play_info.go",
"up_rank.go",
"up_scores_history.go",
"up_stats_history.go",
],
importpath = "go-common/app/admin/main/up/dao/upcrm",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/model/signmodel:go_default_library",
"//app/admin/main/up/model/upcrmmodel:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/jinzhu/gorm: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,55 @@
package upcrm
import (
"context"
"fmt"
"net/url"
"go-common/app/admin/main/up/model/upcrmmodel"
"go-common/library/log"
)
const (
creditLogURL = "http://api.bilibili.co/x/internal/upcredit/log/get"
)
//
//type ArgGetLogHistory struct {
// Mid int64 `params:"mid;Required"`
// FromDate systime.Time `params:"from_date"`
// ToDate systime.Time `params:"to_date"`
// Limit int `params:"limit" default:"20"`
//}
//LogList it's log list
type LogList struct {
LogList []upcrmmodel.SimpleCreditLogWithContent `json:"log_list"`
}
//CreditLogHTTPResult it's log result from http server
type CreditLogHTTPResult struct {
Code int `json:"code"`
Data LogList `json:"data"`
Msg string `json:"message"`
}
//GetCreditLog get credit log from upcredit server
func (d *Dao) GetCreditLog(mid int64, limit int) (result []upcrmmodel.SimpleCreditLogWithContent, err error) {
params := url.Values{}
params.Set("mid", fmt.Sprintf("%d", mid))
//params.Set("from_date", fromDate.Time().Format("2006-01-02"))
//params.Set("to_date", toDate.Time().Format("2006-01-02"))
params.Set("limit", fmt.Sprintf("%d", limit))
var c = context.Background()
var httpResult = CreditLogHTTPResult{}
err = d.httpClient.Get(c, creditLogURL, "", params, &httpResult)
if err != nil {
log.Error("get credit log http fail, request=%s?%s, err=%+v", creditLogURL, params.Encode(), err)
return
}
log.Info("get credit log http ok, result=%+v", httpResult)
result = httpResult.Data.LogList
return
}

View File

@@ -0,0 +1,23 @@
package upcrm
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmGetCreditLog(t *testing.T) {
convey.Convey("GetCreditLog", t, func(ctx convey.C) {
var (
mid = int64(1)
limit = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.GetCreditLog(mid, limit)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,51 @@
package upcrm
import (
"context"
"go-common/app/admin/main/up/conf"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
//Dao upcrm dao
type Dao struct {
// config
conf *conf.Config
// db
crmdb *gorm.DB
httpClient *bm.Client
}
//New new dao
func New(c *conf.Config) *Dao {
var d = &Dao{
conf: c,
}
crmdb, err := gorm.Open("mysql", c.DB.Upcrm.DSN)
if crmdb == nil {
log.Error("connect to db fail, err=%v", err)
return nil
}
crmdb.SingularTable(true)
d.crmdb = crmdb
d.crmdb.LogMode(c.IsTest)
return d
}
//SetHTTPClient set http client
func (d *Dao) SetHTTPClient(client *bm.Client) {
d.httpClient = client
}
//GetDb get current gorm db
func (d *Dao) GetDb() *gorm.DB {
return d.crmdb
}
// BeginTran begin transcation.
func (d *Dao) BeginTran(c context.Context) (tx *gorm.DB) {
return d.crmdb.Begin()
}

View File

@@ -0,0 +1,43 @@
package upcrm
import (
"flag"
"os"
"testing"
"go-common/app/admin/main/up/conf"
"go-common/library/net/http/blademaster"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-admin")
flag.Set("conf_token", "930697bb7def4df0713ef8080596b863")
flag.Set("tree_id", "36438")
flag.Set("conf_version", "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-admin.toml")
}
if os.Getenv("UT_LOCAL_TEST") != "" {
flag.Set("conf", "../../cmd/up-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.httpClient = blademaster.NewClient(conf.Conf.HTTPClient.Normal)
d.httpClient.SetTransport(gock.DefaultTransport)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,42 @@
package upcrm
import (
"time"
"go-common/app/admin/main/up/model/upcrmmodel"
"go-common/library/ecode"
)
const (
//ScoreTypeQuality 质量分
ScoreTypeQuality = 1
//ScoreTypePr 影响力
ScoreTypePr = 2
//ScoreTypeCredit 信用分
ScoreTypeCredit = 3
//ScoreSectionTableName table name
ScoreSectionTableName = "score_section_history"
)
//ScoreQueryHistory get history
func (d *Dao) ScoreQueryHistory(scoreType int, date time.Time) (result upcrmmodel.ScoreSectionHistory, err error) {
err = d.crmdb.Model(&result).
Where("score_type=? AND generate_date = ?", scoreType, date.Format("2006-01-02")).
Find(&result).Error
if err == ecode.NothingFound {
err = nil
}
return
}
//GetLastHistory get last update date
func (d *Dao) GetLastHistory(scoreType int) (lastHistoryDate time.Time, err error) {
var model upcrmmodel.ScoreSectionHistory
err = d.crmdb.Table(ScoreSectionTableName).Select("generate_date").Where("score_type=?", scoreType).Order("generate_date desc").Limit(1).Find(&model).Error
if err != nil {
return
}
lastHistoryDate = model.GenerateDate.Time()
return
}

View File

@@ -0,0 +1,39 @@
package upcrm
import (
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmScoreQueryHistory(t *testing.T) {
convey.Convey("ScoreQueryHistory", t, func(ctx convey.C) {
var (
scoreType = int(0)
date = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.ScoreQueryHistory(scoreType, date)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetLastHistory(t *testing.T) {
convey.Convey("GetLastHistory", t, func(ctx convey.C) {
var (
scoreType = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
lastHistoryDate, err := d.GetLastHistory(scoreType)
ctx.Convey("Then err should be nil.lastHistoryDate should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(lastHistoryDate, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,363 @@
package upcrm
import (
"time"
"go-common/app/admin/main/up/model/signmodel"
"go-common/app/admin/main/up/model/upcrmmodel"
"go-common/library/log"
xtime "go-common/library/time"
"github.com/jinzhu/gorm"
)
const (
// PayStateUnpay not pay
PayStateUnpay = 0
// PayStatePayed payed
PayStatePayed = 1
)
// InsertSignUp insert sign up
func (d *Dao) InsertSignUp(db *gorm.DB, up *signmodel.SignUp) (affectedRow int64, err error) {
var handle = db.Save(up)
err = handle.Error
affectedRow = handle.RowsAffected
return
}
// InsertPayInfo inert pay
func (d *Dao) InsertPayInfo(db *gorm.DB, info *signmodel.SignPay) (affectedRow int64, err error) {
var handle = db.Save(info)
err = handle.Error
affectedRow = handle.RowsAffected
return
}
// InsertTaskInfo insert task
func (d *Dao) InsertTaskInfo(db *gorm.DB, info *signmodel.SignTask) (affectedRow int64, err error) {
var handle = db.Save(info)
err = handle.Error
affectedRow = handle.RowsAffected
return
}
// InsertContractInfo insert contract
func (d *Dao) InsertContractInfo(db *gorm.DB, info interface{}) (affectedRow int64, err error) {
var handle = db.Save(info)
err = handle.Error
affectedRow = handle.RowsAffected
return
}
// DelPayInfo update payinfo
func (d *Dao) DelPayInfo(db *gorm.DB, ids []int64) (affectedRow int64, err error) {
var handle = db.Model(&signmodel.SignPay{}).Where("id IN (?)", ids).Update("state", 100)
err = handle.Error
affectedRow = handle.RowsAffected
return
}
// DelTaskInfo update taskInfo
func (d *Dao) DelTaskInfo(db *gorm.DB, ids []int64) (affectedRow int64, err error) {
var handle = db.Model(&signmodel.SignTask{}).Where("id IN (?)", ids).Update("state", 100)
err = handle.Error
affectedRow = handle.RowsAffected
return
}
// DelSignContract update signcontract
func (d *Dao) DelSignContract(db *gorm.DB, ids []int64) (affectedRow int64, err error) {
var handle = db.Model(&signmodel.SignContract{}).Where("id IN (?)", ids).Update("state", 100)
err = handle.Error
affectedRow = handle.RowsAffected
return
}
// SignUpID .
func (d *Dao) SignUpID(sigID int64) (su *signmodel.SignUp, msp map[int64]*signmodel.SignPay, mst map[int64]*signmodel.SignTask, msc map[int64]*signmodel.SignContract, err error) {
su = &signmodel.SignUp{}
if err = d.crmdb.Table(signmodel.TableSignUp).Where("id = ? AND state IN (0,1)", sigID).Find(su).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("db fail, err=%+v", err)
return
}
if err == gorm.ErrRecordNotFound {
err = nil
su, msp, mst, msc = nil, nil, nil, nil
return
}
var (
sps []*signmodel.SignPay
sts []*signmodel.SignTask
scs []*signmodel.SignContract
)
msp = make(map[int64]*signmodel.SignPay)
if err = d.crmdb.Table(signmodel.TableSignPay).Where("sign_id = ? AND state IN (0,1)", sigID).Find(&sps).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("db fail, err=%+v", err)
return
}
for _, v := range sps {
msp[v.ID] = v
}
mst = make(map[int64]*signmodel.SignTask)
if err = d.crmdb.Table(signmodel.TableSignTask).Where("sign_id = ? AND state = 0", sigID).Find(&sts).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("db fail, err=%+v", err)
return
}
for _, v := range sts {
mst[v.ID] = v
}
msc = make(map[int64]*signmodel.SignContract)
if err = d.crmdb.Table(signmodel.TableSignContract).Where("sign_id = ? AND state = 0", sigID).Find(&scs).Error; err != nil && err != gorm.ErrRecordNotFound {
log.Error("db fail, err=%+v", err)
return
}
for _, v := range scs {
msc[v.ID] = v
}
return
}
// GetSignIDByCondition get sign id
// arg query args
func (d *Dao) GetSignIDByCondition(arg *signmodel.SignQueryArg) (signIDs []uint32, err error) {
var signIDMap = map[uint32]struct{}{}
switch {
default:
// 如果是mid则不进行其他的查询
if arg.Mid != 0 {
var result []signmodel.SignUpOnlyID
var db = d.crmdb.Table("sign_up").Where("mid=?", arg.Mid)
err = db.Select("id").Find(&result).Error
if err != nil && err != gorm.ErrRecordNotFound {
log.Error("db fail, err=%+v", err)
return
}
for _, v := range result {
signIDMap[v.ID] = struct{}{}
}
break
}
var now = time.Now()
// 1.增加查询条件
if arg.DuePay == 1 {
var duedate = now.AddDate(0, 0, 7)
var result []signmodel.SignUpOnlySignID
// due_date and state = PayStateUnpay
err = d.crmdb.Table("sign_pay").Select("sign_id").Where("due_date <= ? and state = 0", duedate.Format(upcrmmodel.TimeFmtDate)).Where("state != 100").
Find(&result).Error
if err != nil && err != gorm.ErrRecordNotFound {
log.Error("db fail, err=%+v", err)
} else {
for _, v := range result {
signIDMap[v.SignID] = struct{}{}
}
}
}
if arg.DueSign == 1 || arg.ExpireSign == 1 {
var duedate = now.AddDate(0, 0, 30)
var result []signmodel.SignUpOnlyID
var db = d.crmdb.Table("sign_up").Select("id")
if arg.DueSign == 1 && arg.ExpireSign == 1 {
db = db.Where("end_date < ?", duedate.Format(upcrmmodel.TimeFmtDate)).Where("state != 100") // 去掉已删除的
} else {
if arg.DueSign == 1 {
db = db.Where("end_date >= ? and end_date <= ?", now.Format(upcrmmodel.TimeFmtDate), duedate.Format(upcrmmodel.TimeFmtDate))
} else if arg.ExpireSign == 1 {
db = db.Where("end_date < ?", now.Format(upcrmmodel.TimeFmtDate))
}
}
err = db.
Find(&result).Error
if err != nil && err != gorm.ErrRecordNotFound {
log.Error("db fail, err=%+v", err)
} else {
for _, v := range result {
signIDMap[v.ID] = struct{}{}
}
}
}
}
for k := range signIDMap {
signIDs = append(signIDs, k)
}
return
}
//GetSignUpByID signid 可以是nil如果是nil则会取所有的信息
// query, args, 额外的查询条件
func (d *Dao) GetSignUpByID(signID []uint32, order string, offset int, limit int, query interface{}, args ...interface{}) (result []signmodel.SignUp, err error) {
var db = d.crmdb.Table("sign_up")
if signID != nil {
db = db.Where("id in (?)", signID)
}
if query != nil {
db = db.Where(query, args)
}
if order != "" {
db = db.Order(order)
}
err = db.
Offset(offset).
Limit(limit).
Find(&result).Error
if err == gorm.ErrRecordNotFound {
err = nil
}
return
}
//GetSignUpCount get sign up's count
func (d *Dao) GetSignUpCount(query string, args ...interface{}) (count int) {
d.crmdb.Table(signmodel.TableSignUp).Where(query, args).Count(&count)
return
}
//GetTask get task by sign id and state
func (d *Dao) GetTask(signID []uint32, state ...int) (result []signmodel.SignTask, err error) {
err = d.crmdb.Table(signmodel.TableSignTask).Where("sign_id in (?) and state = ?", signID, state).Find(&result).Error
if err == gorm.ErrRecordNotFound {
err = nil
}
return
}
//GetPay get get sign id
func (d *Dao) GetPay(signID []uint32) (result []signmodel.SignPay, err error) {
err = d.crmdb.Table(signmodel.TableSignPay).Where("sign_id in (?)", signID).Find(&result).Error
if err == gorm.ErrRecordNotFound {
err = nil
}
return
}
//GetContract get get sign id
func (d *Dao) GetContract(signID []uint32) (result []signmodel.SignContract, err error) {
err = d.crmdb.Table(signmodel.TableSignContract).Where("sign_id in (?)", signID).Find(&result).Error
if err == gorm.ErrRecordNotFound {
err = nil
}
return
}
//PayComplete finish pay by pay id
func (d *Dao) PayComplete(ids []int64) (affectedRow int64, err error) {
var db = d.crmdb.Table(signmodel.TableSignPay).Where("id in (?)", ids).Updates(map[string]interface{}{"state": PayStatePayed})
err = db.Error
if err == nil {
affectedRow = db.RowsAffected
}
return
}
//SignWithName sign with name, used to send mail
type SignWithName struct {
signmodel.SignUp
Name string
}
//GetDueSignUp check due
// expireAfterDays : how many days to expire
func (d *Dao) GetDueSignUp(now time.Time, expireAfterDays int) (result []*SignWithName, err error) {
var dueDate = now.AddDate(0, 0, expireAfterDays)
var db = d.crmdb.Table(signmodel.TableSignUp).Select("id, mid, end_date, admin_id, admin_name")
// email_state = 0 是未发过邮件的意思
db = db.Where("end_date <= ? and end_date >= ? and email_state = 0", dueDate.Format(upcrmmodel.TimeFmtDate), now.Format(upcrmmodel.TimeFmtDate))
err = db.Find(&result).Error
return
}
//PayWithAdmin pay with name, used to send mail
type PayWithAdmin struct {
signmodel.SignPay
Name string
AdminID int
AdminName string
}
//GetDuePay check due
func (d *Dao) GetDuePay(now time.Time, expireAfterDays int) (result []*PayWithAdmin, err error) {
var dueDate = now.AddDate(0, 0, expireAfterDays)
err = d.crmdb.Raw("select p.id, "+
"p.sign_id, "+
"p.mid, "+
"p.due_date, "+
"p.pay_value,"+
"s.admin_id, "+
"s.admin_name"+
" from sign_pay as p left join sign_up as s on p.sign_id = s.id "+
" where p.due_date <= ? and p.email_state = 0 and p.state = 0", dueDate.Format(upcrmmodel.TimeFmtDate)).
Scan(&result).Error
return
}
//UpdateEmailState update email send state
// state : @
func (d *Dao) UpdateEmailState(table string, ids []int64, state int8) (affectedRow int64, err error) {
var db = d.crmdb.Table(table).Where("id in (?)", ids).Update("email_state", state)
err = db.Error
if err == nil {
affectedRow = db.RowsAffected
} else {
log.Error("update email state fail, err=%+v", err)
}
return
}
//CheckUpHasValidContract check if has valid contract
func (d *Dao) CheckUpHasValidContract(mid int64, date time.Time) (exist bool, err error) {
var ids []struct {
ID int
}
err = d.crmdb.Table(signmodel.TableSignUp).Select("id").Where("mid=? and end_date>=?", mid, date.Format(upcrmmodel.TimeFmtDate)).Limit(1).Find(&ids).Error
if err != nil && err != gorm.ErrRecordNotFound {
log.Error("check exist from db fail, err=%+v", err)
return
}
exist = len(ids) > 0
return
}
// GetOrCreateTaskHistory .
func (d *Dao) GetOrCreateTaskHistory(db *gorm.DB, st *signmodel.SignTask) (sth *signmodel.SignTaskHistory, init bool, err error) {
sDate, _ := signmodel.GetTaskDuration(time.Now(), st.TaskType)
sth = new(signmodel.SignTaskHistory)
err = db.Select("*").Where("task_template_id=? and generate_date=?", st.ID, sDate).Find(&sth).Error
// 创建一条,如果没找到的话
if err == gorm.ErrRecordNotFound {
sth = &signmodel.SignTaskHistory{
Mid: st.Mid,
SignID: int64(st.SignID),
TaskTemplateID: int(st.ID),
TaskType: st.TaskType,
TaskCondition: int(st.TaskCondition),
GenerateDate: xtime.Time(sDate.Unix()),
Attribute: st.Attribute,
State: signmodel.SignTaskStateRunning,
}
if err = db.Save(&sth).Error; err != nil {
log.Error("create task history fail, err=%v, task=%v", err, st)
}
init = true
}
return
}
// UpSignTaskHistory .
func (d *Dao) UpSignTaskHistory(db *gorm.DB, sth *signmodel.SignTaskHistory) (err error) {
if err = db.Table(signmodel.TableSignTaskHistory).Where("id = ?", sth.ID).UpdateColumns(
map[string]interface{}{
"task_type": sth.TaskType,
"task_condition": sth.TaskCondition,
"attribute": sth.Attribute,
"mtime": time.Now(),
}).Error; err != nil {
log.Error("dao.UpSignTaskHistory(%+v) , err=%+v", sth, err)
}
return
}

View File

@@ -0,0 +1,320 @@
package upcrm
import (
"testing"
"time"
"go-common/app/admin/main/up/model/signmodel"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmInsertSignUp(t *testing.T) {
convey.Convey("InsertSignUp", t, func(ctx convey.C) {
var (
db = d.crmdb
up = &signmodel.SignUp{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.InsertSignUp(db, up)
d.crmdb.Delete(up)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmInsertPayInfo(t *testing.T) {
convey.Convey("InsertPayInfo", t, func(ctx convey.C) {
var (
db = d.crmdb
info = &signmodel.SignPay{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.InsertPayInfo(db, info)
d.crmdb.Delete(info)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmInsertTaskInfo(t *testing.T) {
convey.Convey("InsertTaskInfo", t, func(ctx convey.C) {
var (
db = d.crmdb
info = &signmodel.SignTask{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.InsertTaskInfo(db, info)
d.crmdb.Delete(info)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmInsertContractInfo(t *testing.T) {
convey.Convey("InsertContractInfo", t, func(ctx convey.C) {
var (
db = d.crmdb
info = &signmodel.SignContract{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.InsertContractInfo(db, info)
d.crmdb.Delete(info)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmDelPayInfo(t *testing.T) {
convey.Convey("DelPayInfo", t, func(ctx convey.C) {
var (
db = d.crmdb
ids = []int64{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.DelPayInfo(db, ids)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmDelTaskInfo(t *testing.T) {
convey.Convey("DelTaskInfo", t, func(ctx convey.C) {
var (
db = d.crmdb
ids = []int64{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.DelTaskInfo(db, ids)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmDelSignContract(t *testing.T) {
convey.Convey("DelSignContract", t, func(ctx convey.C) {
var (
db = d.crmdb
ids = []int64{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.DelSignContract(db, ids)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmSignUpID(t *testing.T) {
convey.Convey("SignUpID", t, func(ctx convey.C) {
var (
sigID = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
su, msp, mst, msc, err := d.SignUpID(sigID)
ctx.Convey("Then err should be nil.su,msp,mst,msc should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(msc, convey.ShouldBeNil)
ctx.So(mst, convey.ShouldBeNil)
ctx.So(msp, convey.ShouldBeNil)
ctx.So(su, convey.ShouldBeNil)
})
})
})
}
func TestUpcrmGetSignIDByCondition(t *testing.T) {
convey.Convey("GetSignIDByCondition", t, func(ctx convey.C) {
var (
arg = &signmodel.SignQueryArg{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
signIDs, err := d.GetSignIDByCondition(arg)
ctx.Convey("Then err should be nil.signIDs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(signIDs, convey.ShouldBeNil)
})
})
})
}
func TestUpcrmGetSignUpByID(t *testing.T) {
convey.Convey("GetSignUpByID", t, func(ctx convey.C) {
var (
signID = []uint32{}
order = ""
offset = int(0)
limit = int(0)
query = interface{}(0)
args = interface{}(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.GetSignUpByID(signID, order, offset, limit, query, args)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetSignUpCount(t *testing.T) {
convey.Convey("GetSignUpCount", t, func(ctx convey.C) {
var (
query = ""
args = interface{}(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
count := d.GetSignUpCount(query, args)
ctx.Convey("Then count should not be nil.", func(ctx convey.C) {
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetTask(t *testing.T) {
convey.Convey("GetTask", t, func(ctx convey.C) {
var (
signID = []uint32{}
state = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.GetTask(signID, state)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetPay(t *testing.T) {
convey.Convey("GetPay", t, func(ctx convey.C) {
var (
signID = []uint32{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.GetPay(signID)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetContract(t *testing.T) {
convey.Convey("GetContract", t, func(ctx convey.C) {
var (
signID = []uint32{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.GetContract(signID)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmPayComplete(t *testing.T) {
convey.Convey("PayComplete", t, func(ctx convey.C) {
var (
ids = []int64{1, 2}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.PayComplete(ids)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetDueSignUp(t *testing.T) {
convey.Convey("GetDueSignUp", t, func(ctx convey.C) {
var (
now = time.Now()
expireAfterDays = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.GetDueSignUp(now, expireAfterDays)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetDuePay(t *testing.T) {
convey.Convey("GetDuePay", t, func(ctx convey.C) {
var (
now = time.Now()
expireAfterDays = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.GetDuePay(now, expireAfterDays)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmUpdateEmailState(t *testing.T) {
convey.Convey("UpdateEmailState", t, func(ctx convey.C) {
var (
table = "sign_up"
ids = []int64{}
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.UpdateEmailState(table, ids, state)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldEqual, 0)
})
})
})
}
func TestUpcrmCheckUpHasValidContract(t *testing.T) {
convey.Convey("CheckUpHasValidContract", t, func(ctx convey.C) {
var (
mid = int64(0)
date = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
exist, err := d.CheckUpHasValidContract(mid, date)
ctx.Convey("Then err should be nil.exist should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(exist, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,45 @@
package upcrm
import (
"time"
"go-common/app/admin/main/up/model/upcrmmodel"
"go-common/library/log"
xtime "go-common/library/time"
)
//StartTask start task
func (d *Dao) StartTask(taskType int, now time.Time) (affectedRow int64, err error) {
var task = &upcrmmodel.TaskInfo{}
task.TaskType = int8(taskType)
task.GenerateDate = now.Format(upcrmmodel.TimeFmtDate)
task.StartTime = xtime.Time(now.Unix())
task.TaskState = upcrmmodel.TaskStateStart
var db = d.crmdb.Model(task).Save(task)
err = db.Error
if err != nil {
log.Error("error start task info, err=%+v", err)
return
}
affectedRow = db.RowsAffected
return
}
//FinishTask finish task
func (d *Dao) FinishTask(taskType int, now time.Time, state int) (affectedRow int64, err error) {
var task = &upcrmmodel.TaskInfo{}
task.TaskType = int8(taskType)
task.GenerateDate = now.Format(upcrmmodel.TimeFmtDate)
task.EndTime = xtime.Time(now.Unix())
task.TaskState = int16(state)
var db = d.crmdb.Model(task).Where("generate_date=? and task_type=?", task.GenerateDate, taskType).Update(task)
err = db.Error
if err != nil {
log.Error("error end task info, err=%+v", err)
return
}
affectedRow = db.RowsAffected
return
}

View File

@@ -0,0 +1,42 @@
package upcrm
import (
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmStartTask(t *testing.T) {
convey.Convey("StartTask", t, func(ctx convey.C) {
var (
taskType = int(0)
now = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.StartTask(taskType, now)
err = nil
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmFinishTask(t *testing.T) {
convey.Convey("FinishTask", t, func(ctx convey.C) {
var (
taskType = int(0)
now = time.Now()
state = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affectedRow, err := d.FinishTask(taskType, now, state)
ctx.Convey("Then err should be nil.affectedRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affectedRow, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,21 @@
package upcrm
import "go-common/app/admin/main/up/model/upcrmmodel"
//QueryUpBaseInfo query db
func (d *Dao) QueryUpBaseInfo(mid int64, fields string) (result upcrmmodel.UpBaseInfo, err error) {
err = d.crmdb.Select(fields).Where("mid=?", mid).Find(&result).Error
return
}
//QueryUpBaseInfoBatchByMid query db
func (d *Dao) QueryUpBaseInfoBatchByMid(fields string, mid ...int64) (result []upcrmmodel.UpBaseInfo, err error) {
err = d.crmdb.Select(fields).Where("mid in(?)", mid).Find(&result).Error
return
}
//QueryUpBaseInfoBatchByID query db
func (d *Dao) QueryUpBaseInfoBatchByID(fields string, id ...int64) (result []upcrmmodel.UpBaseInfo, err error) {
err = d.crmdb.Select(fields).Where("id in(?)", id).Find(&result).Error
return
}

View File

@@ -0,0 +1,56 @@
package upcrm
import (
"testing"
"github.com/jinzhu/gorm"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmQueryUpBaseInfo(t *testing.T) {
convey.Convey("QueryUpBaseInfo", t, func(ctx convey.C) {
var (
mid = int64(0)
fields = "*"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.QueryUpBaseInfo(mid, fields)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, gorm.ErrRecordNotFound)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmQueryUpBaseInfoBatchByMid(t *testing.T) {
convey.Convey("QueryUpBaseInfoBatchByMid", t, func(ctx convey.C) {
var (
fields = "*"
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.QueryUpBaseInfoBatchByMid(fields, mid)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmQueryUpBaseInfoBatchByID(t *testing.T) {
convey.Convey("QueryUpBaseInfoBatchByID", t, func(ctx convey.C) {
var (
fields = "*"
id = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.QueryUpBaseInfoBatchByID(fields, id)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,15 @@
package upcrm
import "go-common/app/admin/main/up/model/upcrmmodel"
//QueryPlayInfo query db
func (d *Dao) QueryPlayInfo(mid int64, busiType []int) (result []upcrmmodel.UpPlayInfo, err error) {
err = d.crmdb.Where("mid=? and business_type in (?)", mid, busiType).Find(&result).Error
return
}
// QueryPlayInfoBatch query db
func (d *Dao) QueryPlayInfoBatch(mid []int64, busiType int) (result []*upcrmmodel.UpPlayInfo, err error) {
err = d.crmdb.Where("mid in (?) and business_type = ?", mid, busiType).Find(&result).Error
return
}

View File

@@ -0,0 +1,39 @@
package upcrm
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmQueryPlayInfo(t *testing.T) {
convey.Convey("QueryPlayInfo", t, func(ctx convey.C) {
var (
mid = int64(0)
busiType = []int{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.QueryPlayInfo(mid, busiType)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmQueryPlayInfoBatch(t *testing.T) {
convey.Convey("QueryPlayInfoBatch", t, func(ctx convey.C) {
var (
mid = []int64{}
busiType = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.QueryPlayInfoBatch(mid, busiType)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,29 @@
package upcrm
import (
"time"
"go-common/app/admin/main/up/model/upcrmmodel"
)
//QueryUpRank query up rank
func (d *Dao) QueryUpRank(rankType int, date time.Time) (result []upcrmmodel.UpRank, err error) {
err = d.crmdb.Model(&upcrmmodel.UpRank{}).Where("type=? and generate_date=?", rankType, date.Format(upcrmmodel.TimeFmtDate)).Find(&result).Error
return
}
//QueryUpRankAll query up rank all
func (d *Dao) QueryUpRankAll(date time.Time) (result []upcrmmodel.UpRank, err error) {
err = d.crmdb.Model(&upcrmmodel.UpRank{}).Where("generate_date=?", date.Format(upcrmmodel.TimeFmtDate)).Find(&result).Error
return
}
//GetUpRankLatestDate get last generate date
func (d *Dao) GetUpRankLatestDate() (date time.Time, err error) {
var rankInfo = upcrmmodel.UpRank{}
err = d.crmdb.Model(&rankInfo).Select("generate_date").Order("generate_date desc").Limit(1).Find(&rankInfo).Error
if err == nil {
date, err = time.Parse(time.RFC3339, rankInfo.GenerateDate)
}
return
}

View File

@@ -0,0 +1,51 @@
package upcrm
import (
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmQueryUpRank(t *testing.T) {
convey.Convey("QueryUpRank", t, func(ctx convey.C) {
var (
rankType = int(0)
date = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.QueryUpRank(rankType, date)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmQueryUpRankAll(t *testing.T) {
convey.Convey("QueryUpRankAll", t, func(ctx convey.C) {
var (
date = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.QueryUpRankAll(date)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetUpRankLatestDate(t *testing.T) {
convey.Convey("GetUpRankLatestDate", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
date, err := d.GetUpRankLatestDate()
ctx.Convey("Then err should be nil.date should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(date, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,32 @@
package upcrm
import (
"time"
"go-common/app/admin/main/up/model/upcrmmodel"
)
// QueryUpScoreHistory score type, 1质量分2影响分3信用分,
// 0表示所有
func (d *Dao) QueryUpScoreHistory(mid int64, scoreType []int, fromdate time.Time, todate time.Time) (result []upcrmmodel.UpScoreHistory, err error) {
err = d.crmdb.Table(upcrmmodel.GetUpScoreHistoryTableName(mid)).Where("mid=? and score_type in (?) and generate_date >= ? and generate_date <= ?", mid, scoreType, fromdate.Format(upcrmmodel.TimeFmtDate), todate.Format(upcrmmodel.TimeFmtDate)).Find(&result).Error
return
}
//GetLatestUpScoreDate 获取某个分数的最新记录日期如果出错就返回todate
func (d *Dao) GetLatestUpScoreDate(mid int64, scoreType int, todate time.Time) (date time.Time, err error) {
date = todate
var history upcrmmodel.UpScoreHistory
err = d.crmdb.Table(upcrmmodel.GetUpScoreHistoryTableName(mid)).
Select("generate_date").
Where("mid=? and score_type = ? and generate_date <= ?", mid, scoreType, todate).
Order("generate_date desc").
Limit(1).
Find(&history).
Error
if err != nil {
return
}
date = history.GenerateDate.Time()
return
}

View File

@@ -0,0 +1,44 @@
package upcrm
import (
"testing"
"time"
"github.com/jinzhu/gorm"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmQueryUpScoreHistory(t *testing.T) {
convey.Convey("QueryUpScoreHistory", t, func(ctx convey.C) {
var (
mid = int64(0)
scoreType = []int{}
fromdate = time.Now()
todate = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result, err := d.QueryUpScoreHistory(mid, scoreType, fromdate, todate)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmGetLatestUpScoreDate(t *testing.T) {
convey.Convey("GetLatestUpScoreDate", t, func(ctx convey.C) {
var (
mid = int64(0)
scoreType = int(0)
todate = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
date, err := d.GetLatestUpScoreDate(mid, scoreType, todate)
ctx.Convey("Then err should be nil.date should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, gorm.ErrRecordNotFound)
ctx.So(date, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,71 @@
package upcrm
import (
"time"
"go-common/app/admin/main/up/model/upcrmmodel"
"go-common/library/log"
"github.com/jinzhu/gorm"
)
const (
upstatshistory = "up_stats_history"
//ISO8601DATE only date format
ISO8601DATE = "2006-01-02"
)
//GetUpStatLastDate get last update date from db
func (d *Dao) GetUpStatLastDate(date time.Time) (lastday time.Time, err error) {
var lasthistory upcrmmodel.UpStatsHistory
err = d.crmdb.Table(upstatshistory).Select("generate_date").Order("generate_date desc").Limit(1).Find(&lasthistory).Error
if err != nil {
log.Error("get last date fail for up stat history, err=%+v", err)
return
}
lastday = lasthistory.GenerateDate.Time()
return
}
//QueryYesterday query yesterday db
func (d *Dao) QueryYesterday(date time.Time) (res []*upcrmmodel.UpStatsHistory, err error) {
err = d.crmdb.Table(upstatshistory).Where("generate_date = ? AND type in ( ?, ?, ? )", date.Format(ISO8601DATE), upcrmmodel.ActivityType, upcrmmodel.IncrType, upcrmmodel.TotalType).Find(&res).Error
if err == gorm.ErrRecordNotFound {
err = nil
return
}
if err != nil {
return nil, err
}
return
}
//QueryTrend query db
func (d *Dao) QueryTrend(statType int, currentDate time.Time, days int) (res []*upcrmmodel.UpStatsHistory, err error) {
// 这种type有3种子类型需要加起来
if statType == upcrmmodel.ActivityType {
days *= 3
}
err = d.crmdb.Table(upstatshistory).Where("type = ? AND generate_date <=?", statType, currentDate.Format(ISO8601DATE)).Order("generate_date desc").Limit(days).Find(&res).Error
if err == gorm.ErrRecordNotFound {
err = nil
return
}
if err != nil {
return nil, err
}
return
}
//QueryDetail query db
func (d *Dao) QueryDetail(startDate time.Time, endDate time.Time) (res []*upcrmmodel.UpStatsHistory, err error) {
err = d.crmdb.Table(upstatshistory).Where("generate_date BETWEEN ? AND ?", startDate.Format(ISO8601DATE), endDate.Format(ISO8601DATE)).Order("generate_date Desc").Find(&res).Error
if err == gorm.ErrRecordNotFound {
err = nil
return
}
if err != nil {
return nil, err
}
return
}

View File

@@ -0,0 +1,71 @@
package upcrm
import (
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestUpcrmGetUpStatLastDate(t *testing.T) {
convey.Convey("GetUpStatLastDate", t, func(ctx convey.C) {
var (
date = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
lastday, err := d.GetUpStatLastDate(date)
ctx.Convey("Then err should be nil.lastday should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(lastday, convey.ShouldNotBeNil)
})
})
})
}
func TestUpcrmQueryYesterday(t *testing.T) {
convey.Convey("QueryYesterday", t, func(ctx convey.C) {
var (
date = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.QueryYesterday(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 TestUpcrmQueryTrend(t *testing.T) {
convey.Convey("QueryTrend", t, func(ctx convey.C) {
var (
statType = int(0)
currentDate = time.Now()
days = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.QueryTrend(statType, currentDate, days)
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 TestUpcrmQueryDetail(t *testing.T) {
convey.Convey("QueryDetail", t, func(ctx convey.C) {
var (
startDate = time.Now()
endDate = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.QueryDetail(startDate, endDate)
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,84 @@
package dao
import (
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"errors"
"fmt"
"hash"
"io"
"net/http"
"strconv"
"go-common/app/admin/main/up/conf"
"go-common/library/log"
)
const (
uploadurl = "/%s/%s"
template = "%s\n%s\n%s\n%d\n"
method = "PUT"
)
var (
errUpload = errors.New("Upload failed")
)
// Upload upload picture or log file to bfs
func Upload(c context.Context, fileName, fileType string, expire int64, body io.Reader, bfsConf *conf.Bfs) (location string, err error) {
var (
url string
req *http.Request
resp *http.Response
header http.Header
code string
)
url = fmt.Sprintf(bfsConf.Addr+uploadurl, bfsConf.Bucket, fileName)
if req, err = http.NewRequest(method, url, body); err != nil {
log.Error("http.NewRequest() Upload(%v) error(%v)", url, err)
return
}
log.Info("upload url={%s}", url)
authorization := Authorize(bfsConf.Key, bfsConf.Secret, method, bfsConf.Bucket, fileName, expire)
req.Header.Set("Host", bfsConf.Addr)
req.Header.Add("Date", fmt.Sprint(expire))
req.Header.Add("Authorization", authorization)
req.Header.Add("Content-Type", fileType)
resp, err = http.DefaultClient.Do(req)
if err != nil {
log.Error("httpClient.Do(%s) error(%v)", url, err)
return
}
if resp.StatusCode != http.StatusOK {
log.Error("Upload url(%s) http.statuscode:%d", url, resp.StatusCode)
err = errUpload
return
}
header = resp.Header
code = header.Get("Code")
if code != strconv.Itoa(http.StatusOK) {
log.Error("Upload url(%s) code:%s", url, code)
err = errUpload
return
}
location = header.Get("Location")
return
}
// Authorize authorize returns authorization for upload file to bfs
func Authorize(key, secret, method, bucket, file string, expire int64) (authorization string) {
var (
content string
mac hash.Hash
signature string
)
content = fmt.Sprintf(template, method, bucket, file, expire)
mac = hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(content))
signature = base64.StdEncoding.EncodeToString(mac.Sum(nil))
authorization = fmt.Sprintf("%s:%s:%d", key, signature, expire)
return
}

View File

@@ -0,0 +1,78 @@
package dao
import (
"context"
"flag"
"io"
"os"
"testing"
"go-common/app/admin/main/up/conf"
"github.com/smartystreets/goconvey/convey"
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.up-admin")
flag.Set("conf_token", "930697bb7def4df0713ef8080596b863")
flag.Set("tree_id", "36438")
flag.Set("conf_version", "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-admin.toml")
}
if os.Getenv("UT_LOCAL_TEST") != "" {
flag.Set("conf", "../cmd/up-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
os.Exit(m.Run())
}
func TestDaoUpload(t *testing.T) {
convey.Convey("Upload", t, func(ctx convey.C) {
var (
c = context.Background()
fileName = ""
fileType = ""
expire = int64(0)
body io.Reader
bfsConf = &conf.Bfs{}
)
//defer gock.OffAll()
//httpMock("PUT", bfsConf.Addr+uploadurl).Reply(200)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
location, err := Upload(c, fileName, fileType, expire, body, bfsConf)
ctx.Convey("Then err should be nil.location should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(location, convey.ShouldEqual, "")
})
})
})
}
func TestDaoAuthorize(t *testing.T) {
convey.Convey("Authorize", t, func(ctx convey.C) {
var (
key = ""
secret = ""
method = ""
bucket = ""
file = ""
expire = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
authorization := Authorize(key, secret, method, bucket, file, expire)
ctx.Convey("Then authorization should not be nil.", func(ctx convey.C) {
ctx.So(authorization, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,73 @@
package dao
import "fmt"
const (
//logicNoOp = 0
logicOpAnd = 1
logicOpOr = 2
)
//Condition 生成的condition为
// [before] [key] [operator] ? [after]
// 如
// [(] [id] [=] ? [and]
// [ctime] [>] ? [)]
// [order by] [time] nil [] //如果value是nil不会设置placeholder ?
type Condition struct {
logicOp int
Before string
Key string
Operator string
Value interface{}
After string
}
//ConcatCondition concat conditions
func ConcatCondition(conditions ...Condition) (conditionStr string, args []interface{}, hasOperator bool) {
hasOperator = false
for _, c := range conditions {
var questionMark = "?"
if c.Value == nil {
questionMark = ""
}
if c.Operator != "" {
hasOperator = true
}
var logicOp = ""
switch c.logicOp {
case logicOpAnd:
logicOp = " and "
case logicOpOr:
logicOp = " or "
}
conditionStr += fmt.Sprintf(" %s %s %s %s %s %s", logicOp, c.Before, c.Key, c.Operator, questionMark, c.After)
if c.Value != nil {
args = append(args, c.Value)
}
}
return
}
//AndCondition and condition
func AndCondition(conditions ...Condition) (result []Condition) {
return addLogicOperator(logicOpAnd, conditions...)
}
//OrCondition or condition
func OrCondition(conditions ...Condition) (result []Condition) {
return addLogicOperator(logicOpOr, conditions...)
}
func addLogicOperator(operator int, conditions ...Condition) (result []Condition) {
var isFirst = true
for _, v := range conditions {
if isFirst {
isFirst = false
} else {
v.logicOp = operator
}
result = append(result, v)
}
return
}

View File

@@ -0,0 +1,66 @@
package dao
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoConcatCondition(t *testing.T) {
convey.Convey("ConcatCondition", t, func(ctx convey.C) {
var (
conditions Condition = Condition{Key: "id", Operator: "=", Value: 1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
conditionStr, args, hasOperator := ConcatCondition(conditions)
ctx.Convey("Then conditionStr,args,hasOperator should not be nil.", func(ctx convey.C) {
ctx.So(hasOperator, convey.ShouldNotBeNil)
ctx.So(args, convey.ShouldNotBeNil)
ctx.So(conditionStr, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAndCondition(t *testing.T) {
convey.Convey("AndCondition", t, func(ctx convey.C) {
var (
conditions Condition
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result := AndCondition(conditions)
ctx.Convey("Then result should not be nil.", func(ctx convey.C) {
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoOrCondition(t *testing.T) {
convey.Convey("OrCondition", t, func(ctx convey.C) {
var (
conditions Condition
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result := OrCondition(conditions)
ctx.Convey("Then result should not be nil.", func(ctx convey.C) {
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoaddLogicOperator(t *testing.T) {
convey.Convey("addLogicOperator", t, func(ctx convey.C) {
var (
operator = int(0)
conditions Condition
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
result := addLogicOperator(operator, conditions)
ctx.Convey("Then result should not be nil.", func(ctx convey.C) {
ctx.So(result, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,68 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["http_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"command.go",
"http.go",
"http_base.go",
"signup.go",
"up_data.go",
"up_trend.go",
"upcrm.go",
"upload.go",
],
importmap = "go-common/app/admin/main/up/http",
importpath = "go-common/app/admin/main/up/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/dao/upcrm:go_default_library",
"//app/admin/main/up/model:go_default_library",
"//app/admin/main/up/model/datamodel:go_default_library",
"//app/admin/main/up/model/signmodel:go_default_library",
"//app/admin/main/up/model/upcrmmodel:go_default_library",
"//app/admin/main/up/service:go_default_library",
"//app/admin/main/up/util:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//vendor/github.com/siddontang/go-mysql/mysql: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,15 @@
package http
import (
"context"
"go-common/app/admin/main/up/model"
"go-common/library/net/http/blademaster"
)
func commandRefreshUpRank(c *blademaster.Context) {
httpQueryFunc(new(model.CommandCommonArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.CommandRefreshUpRank(context, arg.(*model.CommandCommonArg))
},
"SignCheckTask")(c)
}

View File

@@ -0,0 +1,159 @@
package http
import (
"go-common/app/admin/main/up/conf"
"go-common/app/admin/main/up/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
//Svc service.
Svc *service.Service
authSrc *permit.Permit
idfSvc *verify.Verify
)
// Init init account service.
func Init(c *conf.Config) {
// service
initService(c)
// init internal router
engine := bm.DefaultServer(c.HTTPServer)
setupInnerEngine(engine)
// init internal server
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
func initService(c *conf.Config) {
idfSvc = verify.New(nil)
Svc = service.New(c)
authSrc = permit.New(c.Auth)
}
// innerRouter
func setupInnerEngine(e *bm.Engine) {
// monitor ping
e.Ping(ping)
e.Register(disRegister)
// base
var adminUpProfit *bm.RouterGroup
var noAdminUpProfit *bm.RouterGroup
var identifyUpProfit *bm.RouterGroup
if conf.Conf.IsTest {
adminUpProfit = e.Group("/allowance/api/x/admin/uper")
} else {
// 现在只要登录,默认放过
adminUpProfit = e.Group("/allowance/api/x/admin/uper", authSrc.Verify(), authSrc.Permit(""))
}
// 因为经常出现-401所以把这些接口的验证去掉
noAdminUpProfit = e.Group("/allowance/api/x/admin/uper")
{
//noAdminUpProfit.GET("/score/query", crmScoreQuery) // 这个接口需要干掉
noAdminUpProfit.GET("/score/query_section", crmScoreQuery)
noAdminUpProfit.GET("/score/query_up", crmScoreQueryUp)
noAdminUpProfit.GET("/score/query_up_history", crmScoreQueryUpHistory)
noAdminUpProfit.GET("/play/query", crmPlayQueryInfo)
noAdminUpProfit.GET("/info/query", crmInfoQueryUp)
noAdminUpProfit.GET("/info/account_info", crmInfoAccountInfo)
noAdminUpProfit.POST("/info/search", crmInfoSearch)
noAdminUpProfit.GET("/creditlog/query", crmCreditLogQueryUp)
noAdminUpProfit.GET("/rank/query_list", crmRankQueryList)
noAdminUpProfit.POST("/file/upload", upload)
noAdminUpProfit.GET("/data/batch_query_data", crmQueryUpInfoWithViewerData)
noAdminUpProfit.GET("/data/fan_summary", dataGetFanSummary)
noAdminUpProfit.GET("/data/fan_relation_history", dataRelationFansHistory)
noAdminUpProfit.GET("/data/up_archive_info", dataGetUpArchiveInfo)
noAdminUpProfit.GET("/data/up_archive_tag_info", dataGetUpArchiveTagInfo)
noAdminUpProfit.GET("/data/up_view_info", dataGetUpViewInfo)
}
if conf.Conf.IsTest {
identifyUpProfit = e.Group("/allowance/api/x/admin/uper")
} else {
identifyUpProfit = e.Group("/allowance/api/x/admin/uper", idfSvc.Verify)
}
{
identifyUpProfit.GET("/service/batch_query_data", crmQueryUpInfoWithViewerData)
identifyUpProfit.GET("/service/data/fan_summary", dataGetFanSummary)
identifyUpProfit.GET("/service/data/fan_relation_history", dataRelationFansHistory)
identifyUpProfit.GET("/service/data/up_archive_info", dataGetUpArchiveInfo)
identifyUpProfit.GET("/service/data/up_archive_tag_info", dataGetUpArchiveTagInfo)
noAdminUpProfit.GET("/test/get_view_base", testGetViewBase)
}
dashboard := noAdminUpProfit.Group("/dashboard")
{
dashboard.GET("/yesterday", yesterday)
dashboard.GET("/trend", trend)
dashboard.GET("/trend/detail", trendDetail)
}
// sign 需要admin验证这里需要admin的名字和id
sign := adminUpProfit.Group("/sign")
{
sign.POST("/add", signAdd)
sign.POST("/update", signUpdate)
sign.POST("/violation/add", violationAdd)
sign.POST("/violation/retract", violationRetract)
sign.GET("/violation/list", violationList)
sign.POST("/absence/add", absenceAdd)
sign.POST("/absence/retract", absenceRetract)
sign.GET("/absence/list", absenceList)
sign.GET("/up/view/check", viewCheck)
sign.GET("/query", signQuery)
sign.GET("/query/id", signQueryID)
sign.GET("/up/aduit/log", signUpAuditLogs)
sign.GET("/country/list", countrys)
sign.GET("/tid/list", tids)
sign.POST("/pay/complete", signPayComplete)
}
signNoAdmin := noAdminUpProfit.Group("/sign")
{
signNoAdmin.GET("/check_exist", signCheckExist)
}
commandNoAdmin := noAdminUpProfit.Group("/command")
{
commandNoAdmin.GET("/refresh_up_rank", commandRefreshUpRank)
}
//{
// admin.GET("/special/get", specialGet)
// admin.GET("/special/get_by_mid", specialGetByMid)
// admin.POST("/special/delete", specialDel)
// admin.POST("/special/add", specialAdd)
// admin.POST("/special/edit", specialEdit)
// admin.GET("/group/get", getGroup)
// admin.POST("/group/add", authSrc.Permit("UPGROUP_ADD"), addGroup)
// admin.POST("/group/update", updateGroup)
// admin.POST("/group/delete", authSrc.Permit("UPGROUP_ADD"), removeGroup)
//}
}
// ping check server ok.
func ping(ctx *bm.Context) {
if err := Svc.Ping(ctx); err != nil {
ctx.Error = err
ctx.AbortWithStatus(503)
}
}
// disRegister check server ok.
func disRegister(ctx *bm.Context) {
ctx.JSON(map[string]interface{}{}, nil)
}

View File

@@ -0,0 +1,88 @@
package http
import (
"context"
"encoding/json"
"fmt"
"go-common/app/admin/main/up/service"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/http/blademaster"
"io/ioutil"
)
// service的函数原型
type serviceFunc func(context context.Context, arg interface{}) (res interface{}, err error)
// 由于不支持泛型,写得比较难看
// 很多重复的代码用下面来代替
func httpQueryFunc(arg interface{}, sfunc serviceFunc, description string) (httpFunc func(c *blademaster.Context)) {
httpFunc = func(c *blademaster.Context) {
//var arg = new(upcrmmodel.ScoreQueryUpHistoryArgs)
var res interface{}
var err error
var errMsg string
switch {
default:
if err = c.Bind(arg); err != nil {
log.Error("%s, request argument bind fail, err=%v", description, err)
errMsg = fmt.Sprintf("wrong argument, %s", err.Error())
err = ecode.RequestErr
break
}
var scoreRes, e = sfunc(c, arg)
err = e
if e != nil {
errMsg = err.Error()
log.Error("%s query fail, req=%+v, err=%+v", description, arg, err)
break
}
log.Info("%s query ok, req=%+v, result=%+v", description, arg, scoreRes)
res = scoreRes
}
if err != nil {
service.BmHTTPErrorWithMsg(c, err, errMsg)
} else {
c.JSON(res, err)
}
}
return
}
func httpPostFunc(arg interface{}, sfunc serviceFunc, description string) (httpFunc func(c *blademaster.Context)) {
httpFunc = func(c *blademaster.Context) {
//var arg = new(upcrmmodel.ScoreQueryUpHistoryArgs)
var res interface{}
var err error
var errMsg string
switch {
default:
respBody, _ := ioutil.ReadAll(c.Request.Body)
if err = json.Unmarshal(respBody, arg); err != nil {
log.Error("%s, json unmarshal fail, err=%v", description, err)
errMsg = fmt.Sprintf("wrong argument, %s", err.Error())
err = ecode.RequestErr
break
}
scoreRes, e := sfunc(c, arg)
err = e
if e != nil {
errMsg = err.Error()
log.Error("%s query fail, req=%+v, err=%+v", description, arg, err)
break
}
log.Info("%s query ok, req=%+v, result=%+v", description, arg, scoreRes)
res = scoreRes
}
if err != nil {
service.BmHTTPErrorWithMsg(c, err, errMsg)
} else {
c.JSON(res, err)
}
}
return
}

View File

@@ -0,0 +1,135 @@
package http
import (
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
"flag"
"io/ioutil"
"net/http"
"net/url"
"path/filepath"
"strconv"
"strings"
"testing"
"time"
"go-common/app/admin/main/up/conf"
"github.com/davecgh/go-spew/spew"
. "github.com/smartystreets/goconvey/convey"
)
func init() {
dir, _ := filepath.Abs("../cmd/up-admin.toml")
flag.Set("conf", dir)
conf.Init()
// Init(conf.Conf)
time.Sleep(time.Second)
}
// Sign fn
func Sign(params url.Values) (sign string) {
secret := params.Get("appsecret")
params.Del("appsecret")
tmp := params.Encode()
if strings.IndexByte(tmp, '+') > -1 {
tmp = strings.Replace(tmp, "+", "%20", -1)
}
mh := md5.Sum([]byte(tmp + secret))
sign = hex.EncodeToString(mh[:])
return
}
var (
err error
req *http.Request
resp *http.Response
HOST = "http://localhost:7441"
URI = "/x/internal/up/register"
infoURI = "/x/internal/up/info"
c = context.Background()
client = &http.Client{
Timeout: time.Duration(time.Second * 2),
}
)
func Test_Up(t *testing.T) {
Convey("register", t, func() {
params := url.Values{}
params.Set("mid", strconv.FormatInt(2089809, 10))
params.Set("from", strconv.FormatInt(0, 10))
params.Set("is_author", strconv.FormatInt(0, 10))
params.Set("appkey", conf.Conf.App.Key)
params.Set("appsecret", conf.Conf.App.Secret)
params.Set("ts", strconv.FormatInt(time.Now().Unix(), 10))
sign := Sign(params)
params.Set("sign", sign)
u, _ := url.ParseRequestURI(HOST)
u.Path = URI
url := u.String()
req, err = http.NewRequest("POST", url, strings.NewReader(params.Encode()))
So(err, ShouldBeNil)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// timeout
ctx, cancel := context.WithTimeout(c, time.Second*2)
req = req.WithContext(ctx)
defer cancel()
resp, err = client.Do(req)
So(err, ShouldBeNil)
body, err1 := ioutil.ReadAll(resp.Body)
err = err1
So(err, ShouldBeNil)
defer resp.Body.Close()
var result struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Result bool `json:"result"`
} `json:"data"`
}
spew.Dump(string(body))
json.Unmarshal(body, &result)
So(result, ShouldNotBeNil)
So(result.Data.Result, ShouldBeTrue)
})
Convey("info", t, func() {
params := url.Values{}
params.Set("mid", strconv.FormatInt(2089809, 10))
params.Set("from", strconv.FormatInt(1, 10))
params.Set("appkey", conf.Conf.App.Key)
params.Set("appsecret", conf.Conf.App.Secret)
params.Set("ts", strconv.FormatInt(time.Now().Unix(), 10))
sign := Sign(params)
params.Set("sign", sign)
u, _ := url.ParseRequestURI(HOST)
u.Path = infoURI
url := u.String()
reqURL := url + "?" + params.Encode()
req, err = http.NewRequest("GET", reqURL, nil)
So(err, ShouldBeNil)
// timeout
ctx, cancel := context.WithTimeout(c, time.Second*2)
req = req.WithContext(ctx)
defer cancel()
resp, err = client.Do(req)
So(err, ShouldBeNil)
body, err := ioutil.ReadAll(resp.Body)
So(err, ShouldBeNil)
defer resp.Body.Close()
var result struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
IsAuthor bool `json:"is_author"`
} `json:"data"`
}
spew.Dump(string(body))
json.Unmarshal(body, &result)
So(result, ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,136 @@
package http
import (
"context"
"go-common/app/admin/main/up/model/signmodel"
"go-common/library/net/http/blademaster"
)
func signUpAuditLogs(c *blademaster.Context) {
httpQueryFunc(new(signmodel.SignOpSearchArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.SignUpAuditLogs(context, arg.(*signmodel.SignOpSearchArg))
},
"SignUpAuditLogs")(c)
}
func signAdd(c *blademaster.Context) {
httpPostFunc(new(signmodel.SignUpArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.SignAdd(context, arg.(*signmodel.SignUpArg))
},
"SignAdd")(c)
}
func signUpdate(c *blademaster.Context) {
httpPostFunc(new(signmodel.SignUpArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.SignUpdate(context, arg.(*signmodel.SignUpArg))
},
"SignUp")(c)
}
func violationAdd(c *blademaster.Context) {
httpPostFunc(new(signmodel.ViolationArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.ViolationAdd(context, arg.(*signmodel.ViolationArg))
},
"ViolationAdd")(c)
}
func violationRetract(c *blademaster.Context) {
httpPostFunc(new(signmodel.IDArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.ViolationRetract(context, arg.(*signmodel.IDArg))
},
"ViolationRetract")(c)
}
func violationList(c *blademaster.Context) {
httpQueryFunc(new(signmodel.PageArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.ViolationList(context, arg.(*signmodel.PageArg))
},
"ViolationList")(c)
}
func absenceAdd(c *blademaster.Context) {
httpPostFunc(new(signmodel.AbsenceArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.AbsenceAdd(context, arg.(*signmodel.AbsenceArg))
},
"AbsenceAdd")(c)
}
func absenceRetract(c *blademaster.Context) {
httpPostFunc(new(signmodel.IDArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.AbsenceRetract(context, arg.(*signmodel.IDArg))
},
"AbsenceRetract")(c)
}
func absenceList(c *blademaster.Context) {
httpQueryFunc(new(signmodel.PageArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.AbsenceList(context, arg.(*signmodel.PageArg))
},
"AbsenceList")(c)
}
func viewCheck(c *blademaster.Context) {
httpQueryFunc(new(signmodel.PowerCheckArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.ViewCheck(context, arg.(*signmodel.PowerCheckArg))
},
"ViewCheck")(c)
}
func signQuery(c *blademaster.Context) {
httpQueryFunc(new(signmodel.SignQueryArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.SignQuery(context, arg.(*signmodel.SignQueryArg))
},
"SignQuery")(c)
}
func signQueryID(c *blademaster.Context) {
httpQueryFunc(new(signmodel.SignIDArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.SignQueryID(context, arg.(*signmodel.SignIDArg))
},
"SignQueryID")(c)
}
func signPayComplete(c *blademaster.Context) {
httpPostFunc(new(signmodel.SignPayCompleteArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.SignPayComplete(context, arg.(*signmodel.SignPayCompleteArg))
},
"SignPayComplete")(c)
}
func signCheckExist(c *blademaster.Context) {
httpQueryFunc(new(signmodel.SignCheckExsitArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.SignCheckExist(context, arg.(*signmodel.SignCheckExsitArg))
},
"SignCheckExist")(c)
}
func countrys(c *blademaster.Context) {
httpQueryFunc(new(signmodel.CommonArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.Countrys(context, arg.(*signmodel.CommonArg))
},
"SignCheckExist")(c)
}
func tids(c *blademaster.Context) {
httpQueryFunc(new(signmodel.CommonArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.Tids(context, arg.(*signmodel.CommonArg))
},
"SignCheckExist")(c)
}

View File

@@ -0,0 +1,47 @@
package http
import (
"context"
"go-common/app/admin/main/up/model/datamodel"
"go-common/library/net/http/blademaster"
)
func dataGetFanSummary(c *blademaster.Context) {
httpQueryFunc(new(datamodel.GetFansSummaryArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.DataService().GetFansSummary(context, arg.(*datamodel.GetFansSummaryArg))
},
"dataGetFanSummary")(c)
}
func dataRelationFansHistory(c *blademaster.Context) {
httpQueryFunc(new(datamodel.GetRelationFansHistoryArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.DataService().GetRelationFansDay(context, arg.(*datamodel.GetRelationFansHistoryArg))
},
"dataRelationFansHistory")(c)
}
func dataGetUpArchiveInfo(c *blademaster.Context) {
httpQueryFunc(new(datamodel.GetUpArchiveInfoArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.DataService().GetUpArchiveInfo(context, arg.(*datamodel.GetUpArchiveInfoArg))
},
"dataGetUpArchiveInfo")(c)
}
func dataGetUpArchiveTagInfo(c *blademaster.Context) {
httpQueryFunc(new(datamodel.GetUpArchiveTagInfoArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.DataService().GetUpArchiveTagInfo(context, arg.(*datamodel.GetUpArchiveTagInfoArg))
},
"dataGetUpArchiveTagInfo")(c)
}
func dataGetUpViewInfo(c *blademaster.Context) {
httpQueryFunc(new(datamodel.GetUpViewInfoArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.DataService().GetUpViewInfo(context, arg.(*datamodel.GetUpViewInfoArg))
},
"dataGetUpViewInfo")(c)
}

View File

@@ -0,0 +1,70 @@
package http
import (
"go-common/app/admin/main/up/util"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
"time"
)
func yesterday(c *bm.Context) {
v := new(struct {
Date int64 `form:"date" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
res, err := Svc.Crmservice.QueryYesterday(c, time.Unix(v.Date, 0))
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(res, err)
}
func trend(c *bm.Context) {
v := new(struct {
StatType int `form:"stat_type" validate:"required"`
DateType int `form:"date_type" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
}
endDate := util.TruncateDate(time.Now())
var days = 7
if v.DateType == 2 {
days = 30
}
data, err := Svc.Crmservice.QueryTrend(c, v.StatType, endDate, days)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func trendDetail(c *bm.Context) {
v := new(struct {
DateType int `form:"date_type" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
endDate := util.TruncateDate(time.Now())
var days = 7
if v.DateType == 2 {
days = 30
}
data, err := Svc.Crmservice.QueryDetail(c, endDate, days)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,199 @@
package http
import (
"bytes"
"context"
"encoding/csv"
"fmt"
"github.com/siddontang/go-mysql/mysql"
"go-common/app/admin/main/up/dao/upcrm"
"go-common/app/admin/main/up/model/upcrmmodel"
"go-common/app/admin/main/up/service"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/http/blademaster"
"time"
)
func getTitleFields(compareType int) []string {
var compareTitle = ""
switch compareType {
case upcrmmodel.CompareType7day:
compareTitle = "7日前"
case upcrmmodel.CompareType30day:
compareTitle = "30日前"
case upcrmmodel.CompareTypeMonthFirstDay:
compareTitle = "本月1号"
}
return []string{
"分数段",
"昨日",
"占比",
compareTitle,
"占比",
}
}
func getScoreName(scoreType int) string {
var name = "分数"
switch scoreType {
case upcrm.ScoreTypePr:
name = "影响力分"
case upcrm.ScoreTypeQuality:
name = "质量分"
case upcrm.ScoreTypeCredit:
name = "信用分"
}
return name
}
func getScoreQueryContentField(result *upcrmmodel.ScoreQueryResult, index int) []string {
if result == nil {
return nil
}
var fields []string
if index >= len(result.XAxis) {
return nil
}
fields = append(fields, result.XAxis[index])
if index < len(result.YAxis) {
fields = append(fields, fmt.Sprintf("%d", result.YAxis[index].Value))
fields = append(fields, fmt.Sprintf("%0.2f%%", float32(result.YAxis[index].Percent)/100.0))
} else {
fields = append(fields, "-", "-")
}
if index < len(result.CompareAxis) {
fields = append(fields, fmt.Sprintf("%d", result.CompareAxis[index].Value))
fields = append(fields, fmt.Sprintf("%0.2f%%", float32(result.CompareAxis[index].Percent)/100.0))
} else {
fields = append(fields, "-", "-")
}
return fields
}
func crmScoreQuery(c *blademaster.Context) {
var arg = new(upcrmmodel.ScoreQueryArgs)
var res interface{}
var err error
var errMsg string
var scoreRes upcrmmodel.ScoreQueryResult
switch {
default:
if err = c.Bind(arg); err != nil {
log.Error("request argument bind fail, err=%v", err)
errMsg = fmt.Sprintf("wrong argument, %s", err.Error())
err = ecode.RequestErr
break
}
scoreRes, err = Svc.Crmservice.ScoreQuery(c, arg)
if err != nil {
errMsg = err.Error()
log.Error("score query fail, req=%+v, err=%+v", arg, err)
break
}
log.Info("score query ok, req=%+v, result=%+v", arg, scoreRes)
res = scoreRes
}
if err != nil {
service.BmHTTPErrorWithMsg(c, err, errMsg)
} else {
if arg.Export == "csv" {
c.Writer.Header().Set("Content-Type", "application/csv")
c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment;filename=\"%s_%s.csv\"", getScoreName(arg.ScoreType), time.Now().Format(mysql.TimeFormat)))
var buf = &bytes.Buffer{}
var csvWriter = csv.NewWriter(buf)
csvWriter.Write(getTitleFields(arg.CompareType))
for i := 0; i < len(scoreRes.XAxis); i++ {
csvWriter.Write(getScoreQueryContentField(&scoreRes, i))
}
csvWriter.Flush()
c.Writer.Write(buf.Bytes())
} else {
c.JSON(res, err)
}
}
}
func crmScoreQueryUp(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.ScoreQueryUpArgs),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.ScoreQueryUp(context, arg.(*upcrmmodel.ScoreQueryUpArgs))
},
"ScoreQueryUp")(c)
}
func crmScoreQueryUpHistory(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.ScoreQueryUpHistoryArgs),
// 由于不支持泛型,所以这里只能再包一层
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.ScoreQueryUpHistory(context, arg.(*upcrmmodel.ScoreQueryUpHistoryArgs))
},
"ScoreQueryUpHistory")(c)
}
func crmPlayQueryInfo(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.PlayQueryArgs),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.PlayQueryInfo(context, arg.(*upcrmmodel.PlayQueryArgs))
},
"PlayQueryInfo")(c)
}
func crmInfoQueryUp(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.InfoQueryArgs),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.UpBaseInfoQuery(context, arg.(*upcrmmodel.InfoQueryArgs))
},
"QueryBaseUpInfo")(c)
}
func crmCreditLogQueryUp(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.CreditLogQueryArgs),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.CreditLogQueryUp(context, arg.(*upcrmmodel.CreditLogQueryArgs))
},
"CreditLogQueryUp")(c)
}
func crmRankQueryList(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.UpRankQueryArgs),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.UpRankQueryList(context, arg.(*upcrmmodel.UpRankQueryArgs))
},
"UpRankQueryList")(c)
}
func crmInfoAccountInfo(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.InfoAccountInfoArgs),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.UpAccountInfo(context, arg.(*upcrmmodel.InfoAccountInfoArgs))
},
"InfoAccountInfo")(c)
}
func crmInfoSearch(c *blademaster.Context) {
httpPostFunc(new(upcrmmodel.InfoSearchArgs),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.UpInfoSearch(context, arg.(*upcrmmodel.InfoSearchArgs))
},
"UpInfoSearch")(c)
}
func testGetViewBase(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.TestGetViewBaseArgs),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.TestGetViewBase(context, arg.(*upcrmmodel.TestGetViewBaseArgs))
},
"TestGetViewBase")(c)
}
func crmQueryUpInfoWithViewerData(c *blademaster.Context) {
httpQueryFunc(new(upcrmmodel.UpInfoWithViewerArg),
func(context context.Context, arg interface{}) (res interface{}, err error) {
return Svc.Crmservice.QueryUpInfoWithViewerData(context, arg.(*upcrmmodel.UpInfoWithViewerArg))
},
"QueryUpInfoWithViewerData")(c)
}

View File

@@ -0,0 +1,73 @@
package http
import (
"io/ioutil"
"mime/multipart"
"path"
"strings"
"go-common/app/admin/main/up/conf"
"go-common/app/admin/main/up/service"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/http/blademaster"
"regexp"
"time"
)
//由数字、26个英文字母或者下划线组成的字符串
var reg = regexp.MustCompile(`^\w+$`)
// upload
func upload(c *blademaster.Context) {
var (
fileTpye string
file multipart.File
header *multipart.FileHeader
fileName string
body []byte
location string
err error
res interface{}
errMsg string
)
switch {
default:
if file, header, err = c.Request.FormFile("file"); err != nil {
errMsg = err.Error()
err = ecode.RequestErr
log.Error("c.Request().FormFile(\"file\") error(%v)", err)
break
}
defer file.Close()
fileName = header.Filename
fileTpye = strings.TrimPrefix(path.Ext(fileName), ".")
if body, err = ioutil.ReadAll(file); err != nil {
errMsg = err.Error()
err = ecode.RequestErr
log.Error("ioutil.ReadAll(c.Request().Body) error(%v)", err)
break
}
// 如果不符合规则,就不用文件名
if !reg.MatchString(fileName) {
fileName = ""
}
if location, err = Svc.Upload(c, fileName, fileTpye, time.Now(), body, conf.Conf.BfsConf); err != nil {
errMsg = err.Error()
break
}
res = struct {
URL string `json:"url"`
}{
location,
}
}
if err != nil {
service.BmHTTPErrorWithMsg(c, err, errMsg)
} else {
c.JSON(res, err)
}
}

View File

@@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"archive.go",
"command_arg.go",
"errorcode.go",
"monitor.go",
"msg.go",
"rpc.go",
],
importpath = "go-common/app/admin/main/up/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/admin/main/up/model/datamodel:all-srcs",
"//app/admin/main/up/model/signmodel:all-srcs",
"//app/admin/main/up/model/upcrmmodel:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,8 @@
package model
//Archive for db.
type Archive struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
State int `json:"state"`
}

View File

@@ -0,0 +1,9 @@
package model
//CommandCommonArg common arg for command
type CommandCommonArg struct {
}
//CommandCommonResult common result for command
type CommandCommonResult struct {
}

View File

@@ -0,0 +1,32 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"requestargs.go",
"upinfo.go",
"viewer.go",
],
importpath = "go-common/app/admin/main/up/model/datamodel",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
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,62 @@
package datamodel
type commonArg struct {
Mid int64 `form:"mid"`
}
//GetFansSummaryArg arg to get fans
type GetFansSummaryArg struct {
Mid int64 `form:"mid"`
}
//FansSummaryResult result for fans result
type FansSummaryResult struct {
FanSummary FanSummaryData `json:"fan_summary"`
}
const (
//DataType30Day 30 day
DataType30Day = 1
//DataTypeMonth by month
DataTypeMonth = 2
)
//GetRelationFansHistoryArg arg
type GetRelationFansHistoryArg struct {
Mid int64 `form:"mid"`
DataType int `form:"data_type"`
}
//GetRelationFansHistoryResult relation fan history
type GetRelationFansHistoryResult struct {
RelationFanHistoryData
}
// GetRelationFansMonthArg arg
type GetRelationFansMonthArg = GetFansSummaryArg
// GetRelationFansMonthResult relation fan history
type GetRelationFansMonthResult struct {
RelationFanHistoryData
}
//GetUpArchiveInfoArg arg
type GetUpArchiveInfoArg struct {
Mids string `form:"mids" validate:"required"`
DataType int `form:"data_type"`
}
//GetUpArchiveInfoResult result, key = mid, value = data
type GetUpArchiveInfoResult = map[int64]*UpArchiveData
//GetUpArchiveTagInfoArg tag info
type GetUpArchiveTagInfoArg = commonArg
//GetUpArchiveTagInfoResult resutl
type GetUpArchiveTagInfoResult = []*ViewerTagData
//GetUpArchiveTypeInfoArg arg to get type
type GetUpArchiveTypeInfoArg = commonArg
//GetUpViewInfoArg get up view info data
type GetUpViewInfoArg = commonArg

View File

@@ -0,0 +1,31 @@
package datamodel
//UpArchiveData hbase up archive info table
type UpArchiveData struct {
Avs int64 `json:"avs" qualifier:"avs"` // 稿件数
Play int64 `json:"play" qualifier:"play"` // 播放数
Likes int64 `json:"likes" qualifier:"likes"` // 点赞数
Danmu int64 `json:"danmu" qualifier:"danmu"` //弹幕
Reply int64 `json:"reply" qualifier:"reply"` //评论
Share int64 `json:"share" qualifier:"share"` //分享
Fav int64 `json:"fav" qualifier:"fav"` //收藏
Coin int64 `json:"coin" qualifier:"coin"` //硬币
MaxPlayAid int64 `json:"max_play_aid" qualifier:"aid"` //最高播放的aid
MaxPlay int64 `json:"max_play" qualifier:"playest"` //最高播放次数
}
//UpArchiveTagData tag data
type UpArchiveTagData struct {
// key-> index, value-> tagid
TagMap map[string]int64 `family:"tag"`
}
//UpArchiveTypeData type data
type UpArchiveTypeData struct {
Tid int64 `json:"tid" qualifier:"tid"` // 一级分区
TidName string `json:"tid_name"` // 分区名字
Count int64 `json:"count" qualifier:"cnt"` // 稿件数量
SubTid int64 `json:"sub_tid" qualifier:"sub_tid"` //二级分区
SubCount int64 `json:"sub_count" qualifier:"sub_cnt"` //稿件数量
SubTidName string `json:"sub_tid_name"` // 分区名字
}

View File

@@ -0,0 +1,123 @@
package datamodel
//for fan manager top mids.
const (
//Total 粉丝管理-累计数据
Total = iota
//Seven 粉丝管理-7日数据
Seven
//Thirty 粉丝管理-30日数据
Thirty
//Ninety 粉丝管理-90日数据
Ninety
//PlayDuration 播放时长
PlayDuration = "video_play"
//VideoAct 视频互动
VideoAct = "video_act"
//DynamicAct 动态互动
DynamicAct = "dynamic_act"
)
/* ------------- */
//ViewerTypeData type's play count
type ViewerTypeData struct {
Tid int `json:"tid"`
Name string `json:"name"`
Play int64 `json:"play"`
}
//ViewerTagData viewer tag struct
type ViewerTagData struct {
Idx int `json:"idx"`
TagID int `json:"tag_id"`
Name string `json:"name"`
}
//ViewerTypeTagInfo struct for viewer type and tag
type ViewerTypeTagInfo struct {
Type []*ViewerTypeData `json:"type"`
Tag []*ViewerTagData `json:"tag"`
}
// ViewerTrendInfo struct for viewer trend
type ViewerTrendInfo struct {
Fans *ViewerTypeTagInfo `json:"fans"`
Guest *ViewerTypeTagInfo `json:"guest"`
}
/* ------------- */
//ViewerAreaData viewer area data
type ViewerAreaData struct {
Area string `json:"area"`
Viewers int64 `json:"viewers"`
}
//ViewerAreaInfo viewer area info
type ViewerAreaInfo struct {
Fans []ViewerAreaData `json:"fans"`
Guest []ViewerAreaData `json:"guest"`
}
/* ------------- */
//ViewerBaseData base data
//f:plat0 web-pc播放
//f:plat1 web-h5播放
//f:plat2 站外播放
//f:plat3 ios播放
//f:plat4 android播放
type ViewerBaseData struct {
Male int64 `json:"male"`
Female int64 `json:"female"`
Age1 int64 `json:"age_1"` //0~16岁
Age2 int64 `json:"age_2"` // 16~25
Age3 int64 `json:"age_3"` //25~40
Age4 int64 `json:"age_4"` // 40+
PlatPC int64 `json:"plat_pc"` // pc
PlatH5 int64 `json:"plat_h5"` // h5
PlatOut int64 `json:"plat_out"` // 站外播放
PlatIOS int64 `json:"plat_ios"` // ios播放
PlatAndroid int64 `json:"plat_android"` // android播放
PlatOtherApp int64 `json:"plat_other_app"` // 其他播放
}
//ViewerBaseInfo base info
type ViewerBaseInfo struct {
Fans *ViewerBaseData `json:"fans"`
Guest *ViewerBaseData `json:"guest"`
}
/* ------------- */
//FanSummaryData fans summary data
type FanSummaryData struct {
Total int32 `json:"total" family:"f" qualifier:"all"` // 粉丝总数
Active int32 `json:"active" family:"f" qualifier:"act"` // 活跃粉丝数
Inc int32 `json:"inc" family:"f" qualifier:"inc"` // 新增粉丝
Medal int32 `json:"medal" family:"f" qualifier:"mdl"` // 领取勋章粉丝
Elec int32 `json:"elec" family:"f" qualifier:"elec"` //充电粉丝
MedalDiff int32 `json:"medal_diff" family:"f" qualifier:"mdl_diff"` //活跃粉丝(增量)
ActiveDiff int32 `json:"active_diff" family:"f" qualifier:"act_diff"` //领取勋章粉丝(增量)
ElecDiff int32 `json:"elec_diff" family:"f" qualifier:"elec_diff"` //充电粉丝(增量)
Inter int32 `json:"inter" family:"f" qualifier:"inter"` //观看活跃度*10000
ViewPercent int32 `json:"view_percent" family:"f" qualifier:"v"` //播放粉丝占比*10000
DmPercent int32 `json:"dm_percent" family:"f" qualifier:"da"` //弹幕粉丝占比*10000
ReplyPercent int32 `json:"reply_percent" family:"f" qualifier:"re"` //评论粉丝占比*10000
CoinPercent int32 `json:"coin_percent" family:"f" qualifier:"co"` //投币粉丝占比*10000
FavorPercent int32 `json:"favor_percent" family:"f" qualifier:"fv"` //收藏粉丝占比*10000
SharePercent int32 `json:"share_percent" family:"f" qualifier:"sh"` //分享粉丝占比*10000
LikePercent int32 `json:"like_percent" family:"f" qualifier:"lk"` //点赞粉丝占比*10000
}
//FanInfo fans info
type FanInfo struct {
Summary FanSummaryData `json:"summary"`
}
//RelationFanHistoryData data for relation fans follow and unfollow
type RelationFanHistoryData struct {
FollowData map[string]int `family:"a"`
UnfollowData map[string]int `family:"u"`
}

View File

@@ -0,0 +1,8 @@
package model
import "fmt"
var (
//ErrNoFileLink no update contract
ErrNoFileLink = fmt.Errorf("未上传完成!请点击上传按钮完成上传!")
)

View File

@@ -0,0 +1,13 @@
package model
// BAP for wechat msg.
type BAP struct {
UserName string `json:"username"`
Title string `json:"title"`
Content string `json:"content"`
URL string `json:"url"`
Ty string `json:"type"`
Token string `json:"token"`
Signature string `json:"signature"`
TimeStamp int64 `json:"timestamp"`
}

View File

@@ -0,0 +1,10 @@
package model
//Msg for databus consume.
type Msg struct {
MID int64 `json:"mid"`
From int `json:"from"`
IsAuthor int `json:"is_author"`
TimeStamp int64 `json:"timestamp"`
ConsumeTime int64 `json:"consume_time,omitempty"`
}

View File

@@ -0,0 +1,5 @@
gopath="$GOPATH/src"
protobuf_path="$gopath/go-common/vendor/github.com/gogo/protobuf"
echo $protobuf_path
ls "$gopath/go-common/vendor/github.com/gogo/protobuf/gogoproto/"
protoc --gofast_out=".." -I"../" -I"$gopath/go-common/vendor/" ../*.proto

View File

@@ -0,0 +1,20 @@
package model
import "time"
//ArgSpecial arg
type ArgSpecial struct {
GroupID int64
}
//ArgInfo arg
type ArgInfo struct {
Mid int64
From int
}
//ArgMidWithDate arg
type ArgMidWithDate struct {
Mid int64
Date time.Time // 需要查询的时间,如果不填,会使用当前最新的数据
}

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 = [
"requestargs.go",
"sign_up.go",
],
importpath = "go-common/app/admin/main/up/model/signmodel",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/conf:go_default_library",
"//app/admin/main/up/dao:go_default_library",
"//app/admin/main/up/util/now:go_default_library",
"//library/log:go_default_library",
"//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,87 @@
CREATE TABLE `sign_task_history` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '任务ID',
`mid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
`sign_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '签约ID',
`task_template_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'sign_task模板表中的任务ID',
`task_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务类型 0累积 1日 2周 3月 4季度',
`task_counter` int(11) NOT NULL DEFAULT '0' COMMENT '任务计数器',
`task_condition` int(11) NOT NULL DEFAULT '0' COMMENT '任务条件',
`attribute` bigint(20) NOT NULL DEFAULT '0' COMMENT '属性位',
`task_data` varchar(1024) NOT NULL DEFAULT '' COMMENT '任务存储相关数据',
`state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态1、未完成2、完成 100、删除',
`generate_date` date NOT NULL DEFAULT '0000-00-00' COMMENT '任务开始时间',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_task_template_id_generate_date` (`task_template_id`,`generate_date`),
KEY `ix_mid` (`mid`),
KEY `ix_sign_id` (`sign_id`),
KEY `ix_generate_date` (`generate_date`),
KEY `ix_mtime` (`mtime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='任务历史数据表';
CREATE TABLE `sign_task_absence` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`sign_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '签约ID',
`mid` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
`task_history_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'sign_task_history表中ID',
`absence_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '请假数量',
`reason` varchar(255) NOT NULL DEFAULT '' COMMENT '请假理由',
`state` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态0正常100删除',
`admin_id` int(11) NOT NULL DEFAULT '0' COMMENT '管理员id',
`admin_name` varchar(32) NOT NULL DEFAULT '' COMMENT '管理员name',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
KEY `ix_mid` (`mid`),
KEY `ix_sign_id` (`sign_id`),
KEY `ix_task_history_id` (`task_history_id`),
KEY `ix_mtime` (`mtime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='任务请假表';
CREATE TABLE `sign_violation_history` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`sign_id` int(11) NOT NULL DEFAULT '0' COMMENT '签约id',
`mid` bigint(20) NOT NULL DEFAULT '0' COMMENT '违约人',
`admin_id` int(11) NOT NULL DEFAULT '0' COMMENT '操作人id',
`admin_name` varchar(32) NOT NULL DEFAULT '' COMMENT '操作人名字',
`violation_reason` varchar(255) NOT NULL DEFAULT '' COMMENT '违约原因',
`state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '违约状态 1:违约 100:删除',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
KEY `ix_sign_id` (`sign_id`),
KEY `ix_mtime` (`mtime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '违约历史表';
#新增字段
alter table sign_task add column attribute bigint(20) not null default '0' comment '属性位';
alter table sign_task add column finish_note varchar(255) NOT NULL DEFAULT '' COMMENT '任务完成方式';
alter table sign_pay add column `in_tax` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是否含税:1 不含税 2含税';
alter table sign_up add column `organization` tinyint(4) NOT NULL DEFAULT '1' COMMENT '组织属性: 1个人 2公司';
alter table sign_up add column `sign_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '签约类型: 0 其他 、1独家、2首发、3独家系列、4独家双微除外、5独家微博除外';
alter table sign_up add column `age` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '年龄';
alter table sign_up add column `residence` varchar(255) NOT NULL DEFAULT '' COMMENT '居住地';
alter table sign_up add column `id_card` varchar(20) NOT NULL DEFAULT '' COMMENT '身份证';
alter table sign_up add column `phone` varchar(16) NOT NULL DEFAULT '' COMMENT '联系方式';
alter table sign_up add column `qq` bigint(20) unsigned NOT NULL COMMENT 'qq号';
alter table sign_up add column `wechat` varchar(16) NOT NULL DEFAULT '' COMMENT '微信号';
alter table sign_up add column `is_economic` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是非签署经济约 1否 2是';
alter table sign_up add column `economic_company` varchar(16) NOT NULL DEFAULT '' COMMENT '签约的经济公司';
alter table sign_up add column `task_state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '任务完成度: 1 未完成 2 已完成';
alter table sign_up add column `wechat` varchar(16) NOT NULL DEFAULT '' COMMENT '微信号';
alter table sign_up add column `leave_times` int(11) NOT NULL COMMENT '请假次数';
alter table sign_up add column `violation_times` int(11) NOT NULL COMMENT '违约次数';
alter table sign_up add column `active_tid` smallint(6) unsigned NOT NULL DEFAULT '0' COMMENT 'up所属主分区';
#新增索引
ALTER TABLE sign_up ADD INDEX ix_active_tid(`active_tid`);
ALTER TABLE sign_up ADD INDEX ix_sex(`sex`);
ALTER TABLE sign_up ADD INDEX ix_country(`country`);
ALTER TABLE sign_up ADD INDEX ix_task_state(`task_state`);
ALTER TABLE sign_up ADD INDEX ix_sign_type(`sign_type`);
alter table sign_up add `economic_begin` date NOT NULL DEFAULT '0000-00-00' COMMENT '经济约的签约开始时间';
alter table sign_up add `economic_end` date NOT NULL DEFAULT '0000-00-00' COMMENT '经济约的签约结束时间';

View File

@@ -0,0 +1,538 @@
package signmodel
import (
"fmt"
"net/url"
"strings"
"time"
"go-common/app/admin/main/up/conf"
"go-common/app/admin/main/up/dao"
xtime "go-common/library/time"
)
// const .
const (
SignUpList = 0
SignUpDetail = 1
)
// -------------------------------------------------
// CommonResponse result
type CommonResponse struct {
}
// CommonArg arg
type CommonArg struct {
}
// SignUpBaseInfo struct
type SignUpBaseInfo struct {
ID int64 `json:"id"`
Name string `json:"name"`
Sex int8 `json:"sex"`
Mid int64 `json:"mid"`
BeginDate xtime.Time `json:"begin_date"`
EndDate xtime.Time `json:"end_date"`
State int8 `json:"state"`
Country string `json:"country"`
Province string `json:"province"`
City string `json:"city"`
Note string `json:"note"`
TypeName string `json:"type_name"`
ActiveTid int16 `json:"active_tid"`
AdminID int `json:"admin_id"`
AdminName string `json:"admin_name"`
CreateTime xtime.Time `json:"create_time"`
Organization int8 `json:"organization"`
SignType int8 `json:"sign_type"`
Age int8 `json:"age"`
Residence string `json:"residence"`
IDCard string `json:"id_card"`
Phone string `json:"phone"`
QQ int64 `json:"qq"`
Wechat string `json:"wechat"`
IsEconomic int8 `json:"is_economic"`
EconomicCompany string `json:"economic_company"`
EconomicBegin xtime.Time `json:"economic_begin"`
EconomicEnd xtime.Time `json:"economic_end"`
ViolationTimes int `json:"violation_times"`
LeaveTimes int `json:"leave_times"`
}
// CopyTo copy
func (s *SignUpBaseInfo) CopyTo(dbstruct *SignUp) {
dbstruct.ID = s.ID
dbstruct.Mid = s.Mid
dbstruct.Sex = s.Sex
dbstruct.BeginDate = s.BeginDate
dbstruct.EndDate = s.EndDate
dbstruct.Country = s.Country
dbstruct.Province = s.Province
dbstruct.City = s.City
dbstruct.Note = s.Note
dbstruct.AdminID = s.AdminID
dbstruct.AdminName = s.AdminName
dbstruct.Organization = s.Organization
dbstruct.SignType = s.SignType
dbstruct.Age = s.Age
dbstruct.Residence = s.Residence
dbstruct.IDCard = s.IDCard
dbstruct.Phone = s.Phone
dbstruct.QQ = s.QQ
dbstruct.Wechat = s.Wechat
dbstruct.IsEconomic = s.IsEconomic
if s.IsEconomic == ContainEconomic {
dbstruct.EconomicCompany = s.EconomicCompany
dbstruct.EconomicBegin = s.EconomicBegin
dbstruct.EconomicEnd = s.EconomicEnd
}
}
// CopyFrom copy
func (s *SignUpBaseInfo) CopyFrom(dbstruct *SignUp) {
s.ID = dbstruct.ID
s.Mid = dbstruct.Mid
s.Sex = dbstruct.Sex
s.BeginDate = dbstruct.BeginDate
s.EndDate = dbstruct.EndDate
s.Country = dbstruct.Country
s.Province = dbstruct.Province
s.City = dbstruct.City
s.Note = dbstruct.Note
s.AdminID = dbstruct.AdminID
s.AdminName = dbstruct.AdminName
s.Organization = dbstruct.Organization
s.SignType = dbstruct.SignType
s.Age = dbstruct.Age
s.Residence = dbstruct.Residence
s.IDCard = dbstruct.IDCard
s.Phone = dbstruct.Phone
s.QQ = dbstruct.QQ
s.Wechat = dbstruct.Wechat
s.IsEconomic = dbstruct.IsEconomic
if dbstruct.IsEconomic == ContainEconomic {
s.EconomicCompany = dbstruct.EconomicCompany
s.EconomicBegin = dbstruct.EconomicBegin
s.EconomicEnd = dbstruct.EconomicEnd
}
s.State = dbstruct.State
s.ActiveTid = dbstruct.ActiveTid
s.LeaveTimes = dbstruct.LeaveTimes
s.ViolationTimes = dbstruct.ViolationTimes
s.CreateTime = dbstruct.Ctime
}
// CopyFrom .
func (t *SignTaskHistoryArg) CopyFrom(st *SignTaskHistory, absenceCounter int) {
var taskBegin, taskEnd time.Time
taskBegin, taskEnd = GetTaskDuration(st.GenerateDate.Time(), st.TaskType)
t.TaskBegin = xtime.Time(taskBegin.Unix())
t.TaskEnd = xtime.Time(taskEnd.Unix())
t.TaskType = st.TaskType
t.TaskState = int8(st.State)
t.TaskCounter = st.TaskCounter
t.TaskCondition = st.TaskCondition
t.AbsenceCounter = absenceCounter
t.IsBusinessArchive = st.AttrVal(AttrBitIsBusinessArchive)
}
// SignUpArg struct
type SignUpArg struct {
SignUpBaseInfo
PayInfo []*SignPayInfoArg `json:"pay_info"`
TaskInfo []*SignTaskInfoArg `json:"task_info"`
ContractInfo []*SignContractInfoArg `json:"contract_info"`
}
// SignUpsArg struct
type SignUpsArg struct {
SignUpBaseInfo
TaskHistoryInfo []*SignTaskHistoryArg `json:"task_history_info"`
PayInfo []*SignPayInfoArg `json:"pay_info"`
ContractInfo []*SignContractInfoArg `json:"contract_info"`
}
// SignQueryResult result
type SignQueryResult struct {
SignBaseInfo *SignUpBaseInfo `json:"sign_base_info"`
Result []*SignUpsArg `json:"result"`
TotalCount int `json:"total_count"`
Page int `json:"page"`
Size int `json:"size"`
}
// SignTaskHistoryArg struct
type SignTaskHistoryArg struct {
TaskBegin xtime.Time `json:"task_begin"`
TaskEnd xtime.Time `json:"task_end"`
TaskType int8 `json:"task_type"`
TaskState int8 `json:"task_state"`
TaskCounter int `json:"task_counter"`
TaskCondition int `json:"task_condition"`
AbsenceCounter int `json:"absence_counter"`
IsBusinessArchive int64 `json:"is_business_archive"`
}
// ViolationArg struct
type ViolationArg struct {
ID int64 `json:"id"`
SignID int64 `json:"sign_id"`
Mid int64 `json:"mid"`
ViolationReason string `json:"violation_reason"`
AdminID int64 `json:"admin_id"`
AdminName string `json:"admin_name"`
OpTime xtime.Time `json:"op_time"`
State int8 `json:"state"`
}
// ViolationResult result
type ViolationResult struct {
Result []*ViolationArg `json:"result"`
TotalCount int `json:"total_count"`
Page int `json:"page"`
Size int `json:"size"`
}
// CopyTo violationArg.
func (a *ViolationArg) CopyTo(v *SignViolationHistory) {
v.SignID = a.SignID
v.Mid = a.Mid
v.AdminID = a.AdminID
v.AdminName = a.AdminName
v.ViolationReason = a.ViolationReason
}
// CopyFrom violationArg.
func (a *ViolationArg) CopyFrom(v *SignViolationHistory) {
a.ID = v.ID
a.SignID = v.SignID
a.Mid = v.Mid
a.AdminID = v.AdminID
a.AdminName = v.AdminName
a.ViolationReason = v.ViolationReason
a.OpTime = v.Mtime
a.State = v.State
}
// AbsenceArg struct
type AbsenceArg struct {
ID int64 `json:"id"`
SignID int64 `json:"sign_id"`
Mid int64 `json:"mid"`
AbsenceCount int `json:"absence_count"`
Reason string `json:"reason"`
AdminID int64 `json:"admin_id"`
AdminName string `json:"admin_name"`
OpTime xtime.Time `json:"op_time"`
TaskBegin xtime.Time `json:"task_begin"`
TaskEnd xtime.Time `json:"task_end"`
State int8 `json:"state"`
}
// CopyTo AbsenceArg.
func (a *AbsenceArg) CopyTo(v *SignTaskAbsence) {
v.SignID = a.SignID
v.Mid = a.Mid
v.AdminID = a.AdminID
v.AdminName = a.AdminName
v.AbsenceCount = a.AbsenceCount
v.Reason = a.Reason
}
// CopyFrom AbsenceArg.
func (a *AbsenceArg) CopyFrom(v *SignTaskAbsence) {
a.ID = v.ID
a.SignID = v.SignID
a.Mid = v.Mid
a.AdminID = v.AdminID
a.AdminName = v.AdminName
a.AbsenceCount = v.AbsenceCount
a.Reason = v.Reason
a.State = v.State
a.OpTime = v.Mtime
}
// AbsenceResult result
type AbsenceResult struct {
Result []*AbsenceArg `json:"result"`
TotalCount int `json:"total_count"`
Page int `json:"page"`
Size int `json:"size"`
}
// PageArg .
type PageArg struct {
SignID int64 `form:"sign_id"`
Page int `form:"page"`
Size int `form:"size"`
}
// IDArg .
type IDArg struct {
ID int64 `json:"id"`
SignID int64 `json:"sign_id"`
AdminID int64
AdminName string
}
// PowerCheckArg .
type PowerCheckArg struct {
TIDs []int16 `form:"tids,split"`
Mid int64 `form:"mid"`
}
// PowerCheckReply .
type PowerCheckReply struct {
IsPower bool `json:"is_power"`
IsSign bool `json:"is_sign"`
}
// SignPayInfoArg =============
type SignPayInfoArg struct {
ID int64 `json:"id"`
SignID int64 `json:"sign_id"`
Mid int64 `json:"mid"`
DueDate xtime.Time `json:"due_date"`
PayValue int64 `json:"pay_value"`
Note string `json:"note"`
State int8 `json:"state"`
InTax int8 `json:"in_tax"`
}
// CopyTo copy
func (s *SignPayInfoArg) CopyTo(dbstruct *SignPay) {
dbstruct.ID = s.ID
dbstruct.SignID = s.SignID
dbstruct.Mid = s.Mid
dbstruct.DueDate = s.DueDate
dbstruct.PayValue = s.PayValue
dbstruct.Note = s.Note
dbstruct.InTax = s.InTax
}
// CopyFrom copy
func (s *SignPayInfoArg) CopyFrom(dbstruct *SignPay) {
s.ID = dbstruct.ID
s.SignID = dbstruct.SignID
s.Mid = dbstruct.Mid
s.DueDate = dbstruct.DueDate
s.PayValue = dbstruct.PayValue
s.Note = dbstruct.Note
s.State = dbstruct.State
s.InTax = dbstruct.InTax
}
// SignTaskInfoArg =============
type SignTaskInfoArg struct {
ID int64 `json:"id"`
SignID int64 `json:"sign_id"`
Mid int64 `json:"mid"`
TaskType int8 `json:"task_type"`
TaskCondition int `json:"task_condition"`
TaskCounter int `json:"task_counter"`
TaskState int8 `json:"task_state"`
IsBusinessArchive int64 `json:"is_business_archive"`
}
// CopyTo copy
func (s *SignTaskInfoArg) CopyTo(dbstruct *SignTask) {
dbstruct.ID = s.ID
dbstruct.SignID = s.SignID
dbstruct.Mid = s.Mid
dbstruct.TaskType = s.TaskType
dbstruct.TaskCondition = s.TaskCondition
dbstruct.AttrSet(s.IsBusinessArchive, AttrBitIsBusinessArchive)
dbstruct.TaskData = ""
}
// CopyFrom copy
func (s *SignTaskInfoArg) CopyFrom(dbstruct *SignTask) {
s.ID = dbstruct.ID
s.SignID = dbstruct.SignID
s.Mid = dbstruct.Mid
s.TaskType = dbstruct.TaskType
s.TaskCondition = dbstruct.TaskCondition
s.TaskCounter = dbstruct.TaskCounter
s.IsBusinessArchive = dbstruct.AttrVal(AttrBitIsBusinessArchive)
if s.TaskCounter >= s.TaskCondition {
s.TaskState = 1
}
}
// SignContractInfoArg =============
type SignContractInfoArg struct {
ID int64 `json:"id"`
SignID int64 `json:"sign_id"`
Mid int64 `json:"mid"`
Filename string `json:"filename"`
Filelink string `json:"filelink"`
}
// CopyTo copy
func (s *SignContractInfoArg) CopyTo(dbstruct *SignContract) {
dbstruct.ID = s.ID
dbstruct.SignID = s.SignID
dbstruct.Mid = s.Mid
dbstruct.Filelink = BuildOrcBfsURL(s.Filelink)
dbstruct.Filename = s.Filename
}
// CopyFrom copy
func (s *SignContractInfoArg) CopyFrom(dbstruct *SignContract) {
s.ID = dbstruct.ID
s.SignID = dbstruct.SignID
s.Mid = dbstruct.Mid
s.Filelink = BuildDownloadURL(dbstruct.Filename, dbstruct.Filelink)
s.Filename = dbstruct.Filename
}
// SignQueryArg =============
type SignQueryArg struct {
Tids []int64 `form:"tids,split"` // 权限tid
Mid int64 `form:"mid"`
DueSign int8 `form:"due_sign"` // 签约即将过期
DuePay int8 `form:"due_pay"` // 支付周期即将过期
ExpireSign int8 `form:"expire_sign"` // 签约已过期
Sex int8 `form:"sex" default:"-1"`
Country []string `form:"country,split"`
ActiveTID int16 `form:"active_tid"`
SignType int8 `form:"sign_type"`
TaskState int8 `form:"task_state"`
SignBegin xtime.Time `form:"sign_begin"`
SignEnd xtime.Time `form:"sign_end"`
IsDetail int8 `form:"is_detail"` // 是否详情
Page int `form:"page"`
Size int `form:"size"`
}
// SignIDArg .
type SignIDArg struct {
ID int64 `form:"id" validate:"required"`
}
// SignPayCompleteArg ==============
type SignPayCompleteArg struct {
IDs []int64 `json:"ids"`
}
// SignPayCompleteResult result
type SignPayCompleteResult struct {
}
// SignCheckTaskArg ==============
type SignCheckTaskArg struct {
Date string `form:"date"`
}
// SignCheckExsitArg ==============
type SignCheckExsitArg struct {
Mid int64 `form:"mid"`
}
// SignCheckExsitResult result
type SignCheckExsitResult struct {
Exist bool `json:"exist"`
}
// SignOpSearchArg .
type SignOpSearchArg struct {
Mid int64 `form:"mid"`
OpID int64 `form:"oper_id"` // 操作人
SignID int64 `form:"sign_id"`
Tp int8 `form:"type" default:"2"` // 操作类型 1:新增 2:修改
Order string `form:"order" default:"ctime"`
Sort string `form:"sort" default:"desc"`
PN int `form:"page" default:"1"`
PS int `form:"size" default:"50"`
}
// BaseAuditReply .
type BaseAuditReply struct {
CTime string `json:"ctime"`
IntOne int64 `json:"int_0"`
OID int64 `json:"oid"`
Tp int8 `json:"type"`
UID int64 `json:"uid"`
UName string `json:"uname"`
ExtraData string `json:"extra_data"`
}
// BaseAuditListReply .
type BaseAuditListReply struct {
Order string `json:"order"`
Sort string `json:"sort"`
Pager *pager `json:"page"`
Result []*BaseAuditReply `json:"result"`
}
type pager struct {
Page int `json:"num"`
Size int `json:"size"`
TotalCount int `json:"total"`
}
// SignAuditReply .
type SignAuditReply struct {
CTime xtime.Time `json:"ctime"`
SignID int64 `json:"sign_id"`
Mid int64 `json:"mid"`
Tp int8 `json:"type"`
OperID int64 `json:"oper_id"`
OperName string `json:"oper_name"`
Content *SignContentReply `json:"content"`
}
// SignAuditListReply .
type SignAuditListReply struct {
Order string `json:"order"`
Sort string `json:"sort"`
Page int `json:"page"`
Size int `json:"size"`
TotalCount int `json:"total_count"`
Result []*SignAuditReply `json:"result"`
}
// SignContentReply .
type SignContentReply struct {
New *SignUpArg `json:"new"`
Old *SignUpArg `json:"old"`
ChangeType []int8 `json:"change_type"`
}
// SignCountrysReply .
type SignCountrysReply struct {
List []string `json:"list"`
}
// SignTidsReply .
type SignTidsReply struct {
List map[int64]string `json:"list"`
}
// BuildOrcBfsURL orc bfs url.
func BuildOrcBfsURL(raw string) string {
if raw == "" {
return ""
}
ori, err := url.Parse(raw)
if err != nil {
return raw
}
values := ori.Query()
values.Del("token")
ori.RawQuery = values.Encode()
return ori.String()
}
// BuildDownloadURL .
func BuildDownloadURL(fileName string, bfsurl string) (finalurl string) {
var bfsConf = conf.Conf.BfsConf
var index = strings.LastIndex(bfsurl, "/")
if index >= 0 && index+1 < len(bfsurl) {
fileName = bfsurl[index+1:]
}
finalurl = fmt.Sprintf("%s?token=%s", bfsurl, url.QueryEscape(dao.Authorize(bfsConf.Key, bfsConf.Secret, "GET", bfsConf.Bucket, fileName, time.Now().Unix())))
return
}

View File

@@ -0,0 +1,441 @@
package signmodel
import (
"strings"
"time"
"go-common/app/admin/main/up/util/now"
"go-common/library/log"
xtime "go-common/library/time"
)
const (
// TableSignPay table name
TableSignPay = "sign_pay"
// TableSignUp table name
TableSignUp = "sign_up"
// TableSignTask table name
TableSignTask = "sign_task"
// TableSignContract table name
TableSignContract = "sign_contract"
// TableSignTaskAbsence table name
TableSignTaskAbsence = "sign_task_absence"
// TableSignTaskHistory table name
TableSignTaskHistory = "sign_task_history"
// TableSignViolationHistory table name
TableSignViolationHistory = "sign_violation_history"
)
const (
// DateDefualtFromDB .
DateDefualtFromDB = -28800
// DateDefualt .
DateDefualt = "0000-00-00"
)
const (
//TaskTypeAccumulate 0
TaskTypeAccumulate = 0
//TaskTypeDay 1
TaskTypeDay = 1
//TaskTypeWeek 2
TaskTypeWeek = 2
//TaskTypeMonth 3
TaskTypeMonth = 3
//TaskTypeQuarter 4 季度
TaskTypeQuarter = 4
)
const (
//TaskStateRunning 0
TaskStateRunning = 0
//TaskStateExpire 1
TaskStateExpire = 1
//TaskStateFinish 2
TaskStateFinish = 2
)
// const .
const (
SignUpMidAdd = 1
SignUpMidUpdate = 2
)
// const 。
const (
NotContainEconomic = 1
ContainEconomic = 2
)
const (
// SignUpLogBizID 签约up信息修改日志
SignUpLogBizID int = 261
)
const (
//SignTaskStateInit init
SignTaskStateInit = 0
//SignTaskStateRunning task running
SignTaskStateRunning = 1
//SignTaskStateFinish finish
SignTaskStateFinish = 2
//SignTaskStateDelete delete
SignTaskStateDelete = 100
)
// const 变更类型.
const (
// 年龄
ChangeSexHistory = iota + 1
// 用户id
ChangeMidHistory
// 签约周期
ChangeSignDateHistory
// 地区
ChangeAreaHistory
// 组织
ChangeOrganizationHistory
// 签约类型
ChangeSignTypeHistory
// 年龄
ChangeAgeHistory
// 居住地
ChangeResidenceHistory
// 身份证
ChangeIDCardHistory
// 联系方式
ChangePhoneHistory
// QQ
ChangeQQHistory
// 微信
ChangeWechatHistory
// 经济公司
ChangeEconomicHistory
// 签约付款周期
ChangeSignPayHistory
// 签约任务
ChangeSignTaskHistory
// 签约合同
ChangeSignContractHistory
// 签约备注
ChangeSignNoteHistory
)
const (
//EmailStateNotSend 0
EmailStateNotSend = 0
//EmailStateSendSucc 1
EmailStateSendSucc = 1
)
const (
// AttrYes on
AttrYes = int64(1)
// AttrNo off
AttrNo = int64(0)
// AttrBitIsBusinessArchive bit
AttrBitIsBusinessArchive = uint(0)
)
// SignUpOnlyID struct
type SignUpOnlyID struct {
ID uint32
}
// SignUpOnlySignID struct
type SignUpOnlySignID struct {
SignID uint32
}
// SignUp struct
type SignUp struct {
ID int64
Sex int8
Mid int64
BeginDate xtime.Time
EndDate xtime.Time
State int8
Country string
Province string
City string
Note string
AdminID int
AdminName string
EmailState int8
Ctime xtime.Time `gorm:"column:ctime"`
Mtime xtime.Time `gorm:"column:mtime"`
Organization int8
SignType int8
Age int8
Residence string
IDCard string `gorm:"column:id_card"`
Phone string
QQ int64 `gorm:"column:qq"`
Wechat string `gorm:"column:wechat"`
IsEconomic int8
EconomicCompany string
EconomicBegin xtime.Time
EconomicEnd xtime.Time
TaskState int8
LeaveTimes int
ViolationTimes int
ActiveTid int16
}
// Diff .
func (su *SignUp) Diff(oriSu *SignUp, fields map[int8]struct{}) {
if oriSu.Sex != su.Sex {
fields[ChangeSexHistory] = struct{}{}
}
if oriSu.Mid != su.Mid {
fields[ChangeMidHistory] = struct{}{}
}
if oriSu.BeginDate != su.BeginDate || oriSu.EndDate != su.EndDate {
fields[ChangeSignDateHistory] = struct{}{}
}
if !strings.EqualFold(oriSu.Country, su.Country) || !strings.EqualFold(oriSu.Province, su.Province) || !strings.EqualFold(oriSu.City, su.City) {
fields[ChangeAreaHistory] = struct{}{}
}
if oriSu.Organization != su.Organization {
fields[ChangeOrganizationHistory] = struct{}{}
}
if oriSu.SignType != su.SignType {
fields[ChangeSignTypeHistory] = struct{}{}
}
if oriSu.Age != su.Age {
fields[ChangeAgeHistory] = struct{}{}
}
if oriSu.Residence != su.Residence {
fields[ChangeResidenceHistory] = struct{}{}
}
if oriSu.IDCard != su.IDCard {
fields[ChangeIDCardHistory] = struct{}{}
}
if oriSu.Phone != su.Phone {
fields[ChangePhoneHistory] = struct{}{}
}
if oriSu.QQ != su.QQ {
fields[ChangeQQHistory] = struct{}{}
}
if oriSu.Wechat != su.Wechat {
fields[ChangeWechatHistory] = struct{}{}
}
if oriSu.EconomicBegin == DateDefualtFromDB {
oriSu.EconomicBegin = 0
}
if oriSu.EconomicEnd == DateDefualtFromDB {
oriSu.EconomicEnd = 0
}
if oriSu.IsEconomic != su.IsEconomic || !strings.EqualFold(oriSu.EconomicCompany, su.EconomicCompany) ||
oriSu.EconomicBegin != su.EconomicBegin || oriSu.EconomicEnd != su.EconomicEnd {
fields[ChangeEconomicHistory] = struct{}{}
}
if !strings.EqualFold(oriSu.Note, su.Note) {
fields[ChangeSignNoteHistory] = struct{}{}
}
su.State = oriSu.State
su.EmailState = oriSu.EmailState
su.TaskState = oriSu.TaskState
su.LeaveTimes = oriSu.LeaveTimes
su.ViolationTimes = oriSu.ViolationTimes
su.ActiveTid = oriSu.ActiveTid
su.Ctime = oriSu.Ctime
}
// SignPay struct
type SignPay struct {
ID int64
Mid int64
SignID int64
DueDate xtime.Time
PayValue int64
State int8
Note string
EmailState int8
Ctime xtime.Time `gorm:"column:ctime"`
Mtime xtime.Time `gorm:"column:mtime"`
InTax int8
}
// Diff .
func (sp *SignPay) Diff(mOriSp map[int64]*SignPay, fields map[int8]struct{}) {
var (
ok bool
oriSp *SignPay
)
if oriSp, ok = mOriSp[sp.ID]; !ok {
fields[ChangeSignPayHistory] = struct{}{}
return
}
if sp.DueDate != oriSp.DueDate || sp.PayValue != oriSp.PayValue || sp.InTax != oriSp.InTax {
fields[ChangeSignPayHistory] = struct{}{}
}
sp.Mid = oriSp.Mid
sp.SignID = oriSp.SignID
sp.State = oriSp.State
sp.Note = oriSp.Note
sp.EmailState = oriSp.EmailState
sp.Ctime = oriSp.Ctime
}
// SignTask struct
type SignTask struct {
ID int64 `gorm:"column:id"`
Mid int64 `gorm:"column:mid"`
SignID int64 `gorm:"column:sign_id"`
TaskType int8 `gorm:"column:task_type"`
TaskCounter int `gorm:"column:task_counter"`
TaskCondition int `gorm:"column:task_condition"`
TaskData string `gorm:"column:task_data"`
State int8 `gorm:"column:state"`
Ctime xtime.Time `gorm:"column:ctime"`
Mtime xtime.Time `gorm:"column:mtime"`
Attribute int64 `gorm:"column:attribute"`
FinishNote string `gorm:"column:finish_note"`
}
// Diff .
func (st *SignTask) Diff(mOriSt map[int64]*SignTask, fields map[int8]struct{}) {
var (
ok bool
oriSt *SignTask
)
if oriSt, ok = mOriSt[st.ID]; !ok {
fields[ChangeSignTaskHistory] = struct{}{}
return
}
if st.TaskType != oriSt.TaskType || st.TaskCondition != oriSt.TaskCondition ||
st.AttrVal(AttrBitIsBusinessArchive) != oriSt.AttrVal(AttrBitIsBusinessArchive) {
fields[ChangeSignTaskHistory] = struct{}{}
}
st.Mid = oriSt.Mid
st.SignID = oriSt.SignID
st.TaskCounter = oriSt.TaskCounter
st.TaskData = oriSt.TaskData
st.State = oriSt.State
st.Ctime = oriSt.Ctime
}
// AttrVal get attribute value.
func (st *SignTask) AttrVal(bit uint) int64 {
return (st.Attribute >> bit) & int64(1)
}
// AttrSet set attribute value.
func (st *SignTask) AttrSet(v int64, bit uint) {
st.Attribute = st.Attribute&(^(1 << bit)) | (v << bit)
}
// SignTaskHistory .
type SignTaskHistory struct {
ID int64 `gorm:"column:id"`
Mid int64 `gorm:"column:mid"`
SignID int64 `gorm:"column:sign_id"`
TaskTemplateID int `gorm:"column:task_template_id"`
TaskType int8 `gorm:"column:task_type"`
TaskCounter int `gorm:"column:task_counter"`
TaskCondition int `gorm:"column:task_condition"`
TaskData string `gorm:"column:task_data"`
Attribute int64 `gorm:"column:attribute"`
State int `gorm:"column:state"`
GenerateDate xtime.Time `gorm:"column:generate_date"`
Ctime xtime.Time `gorm:"column:ctime"`
Mtime xtime.Time `gorm:"column:mtime"`
}
// AttrVal get attribute value.
func (sth *SignTaskHistory) AttrVal(bit uint) int64 {
return (sth.Attribute >> bit) & int64(1)
}
// AttrSet set attribute value.
func (sth *SignTaskHistory) AttrSet(v int64, bit uint) {
sth.Attribute = sth.Attribute&(^(1 << bit)) | (v << bit)
}
//SignContract struct
type SignContract struct {
ID int64 `gorm:"column:id"`
Mid int64
SignID int64
Filename string
Filelink string
State int8
Ctime xtime.Time `gorm:"column:ctime"`
Mtime xtime.Time `gorm:"column:mtime"`
}
// Diff .
func (sc *SignContract) Diff(mOriSc map[int64]*SignContract, fields map[int8]struct{}) {
var (
ok bool
oriSc *SignContract
)
if oriSc, ok = mOriSc[sc.ID]; !ok {
log.Error("OriSc(%d) no exsits", sc.ID)
fields[ChangeSignContractHistory] = struct{}{}
return
}
if !strings.EqualFold(sc.Filelink, oriSc.Filelink) {
log.Error("file(%s)----orc_file(%s) no exsits", sc.Filelink, oriSc.Filelink)
fields[ChangeSignContractHistory] = struct{}{}
}
if !strings.EqualFold(sc.Filename, oriSc.Filename) {
log.Error("filename(%s)----orc_filename(%s) no exsits", sc.Filename, oriSc.Filename)
fields[ChangeSignContractHistory] = struct{}{}
}
sc.Mid = oriSc.Mid
sc.SignID = oriSc.SignID
sc.State = oriSc.State
sc.Ctime = oriSc.Ctime
}
// SignTaskAbsence struct
type SignTaskAbsence struct {
ID int64 `gorm:"column:id"`
SignID int64
Mid int64
TaskHistoryID int64
AbsenceCount int
Reason string
State int8
AdminID int64
AdminName string
Ctime xtime.Time `gorm:"column:ctime"`
Mtime xtime.Time `gorm:"column:mtime"`
}
// SignViolationHistory struct
type SignViolationHistory struct {
ID int64 `gorm:"column:id"`
SignID int64
Mid int64
AdminID int64
AdminName string
ViolationReason string
State int8
Ctime xtime.Time `gorm:"column:ctime"`
Mtime xtime.Time `gorm:"column:mtime"`
}
// GetTaskDuration this will return task duration, [startDate, endDate)
func GetTaskDuration(date time.Time, taskType int8) (startDate, endDate time.Time) {
var ndate = now.New(date)
now.WeekStartDay = time.Monday
switch taskType {
case TaskTypeDay:
var begin = ndate.BeginningOfDay()
return begin, begin.AddDate(0, 0, 1)
case TaskTypeWeek:
var begin = ndate.BeginningOfWeek()
return begin, begin.AddDate(0, 0, 7)
case TaskTypeMonth:
var begin = ndate.BeginningOfMonth()
return begin, begin.AddDate(0, 1, 0)
case TaskTypeQuarter:
var begin = ndate.BeginningOfQuarter()
return begin, begin.AddDate(0, 3, 0)
}
return
}

View File

@@ -0,0 +1,84 @@
# (fat 1, uat 1, prod 0)
CREATE TABLE `sign_up` (
id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '签约ID',
sex tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别,性别 0:保密 1:男 2:女',
mid int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
begin_date date NOT NULL DEFAULT '0000-00-00' COMMENT '签约开始时间',
end_date date NOT NULL DEFAULT '0000-00-00' COMMENT '签约结束时间',
state tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态0正常100删除',
country varchar(16) NOT NULL DEFAULT '' COMMENT '国家',
province varchar(16) NOT NULL DEFAULT '' COMMENT '',
city varchar(16) NOT NULL DEFAULT '' COMMENT '',
note varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
ctime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
mtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (id),
KEY ix_mid (mid),
KEY ix_begin_date (begin_date),
KEY ix_end_date (end_date),
KEY ix_mtime (mtime)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='签约表';
-- 付款表
CREATE TABLE sign_pay (
id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
mid int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
sign_id int(11) unsigned NOT NULL DEFAULT '0' COMMENT '签约ID',
due_date date NOT NULL DEFAULT '0000-00-00' COMMENT '签约结束时间',
pay_value BIGINT(20) NOT NULL DEFAULT '0' COMMENT '金额',
state tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态0未支付1已支付100删除',
note varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
ctime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
mtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (id),
KEY ix_signid (sign_id),
KEY ix_mid (mid),
KEY ix_date (due_date),
KEY ix_mtime (mtime)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='付款表';
CREATE TABLE sign_task (
id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '任务ID',
mid int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
sign_id int(11) unsigned NOT NULL DEFAULT '0' COMMENT '签约ID',
task_type tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务类型',
task_counter int(11) NOT NULL DEFAULT '0' COMMENT '任务计数器',
task_condition int(11) NOT NULL DEFAULT '0' COMMENT '任务条件',
task_data varchar(1024) NOT NULL DEFAULT '' COMMENT '任务存储相关数据', -- 任务数据比如用来存已经投过的稿件id
state tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态0正常1过期100删除',
generate_date date NOT NULL DEFAULT '0000-00-00' COMMENT '任务生成时间',
ctime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
mtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (id),
KEY ix_mid (mid),
KEY ix_signid (sign_id),
KEY ix_date (generate_date),
KEY ix_mtime (mtime)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='任务表';
-- 合同表
CREATE TABLE sign_contract (
id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '合同ID',
sign_id int(11) unsigned NOT NULL DEFAULT '0' COMMENT '签约ID',
mid int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
filename varchar(255) NOT NULL DEFAULT '' COMMENT '合同名',
filelink varchar(255) NOT NULL DEFAULT '' COMMENT '文件链接地址',
state tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态0正常100删除',
ctime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
mtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (id),
KEY ix_mid (mid),
KEY ix_signid (sign_id),
KEY ix_mtime (mtime)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='合同表';
# (fat 1, uat 1, prod 1)
alter table sign_up add column admin_id int(11) not null default 0 comment '管理员id';
alter table sign_up add column admin_name varchar(32) not null default '' comment '管理员name';
# (fat 1, uat 1, prod 1) --2018.06.26
alter table sign_up add column email_state tinyint(4) not null default 0 comment '邮件发送情况0未发送1已发送过提醒邮件';
alter table sign_pay add column email_state tinyint(4) not null default 0 comment '邮件发送情况0未发送1已发送过提醒邮件';

View File

@@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"creditlog.go",
"requestargs.go",
"score_section_history.go",
"task_info.go",
"up_base_info.go",
"up_play_info.go",
"up_rank.go",
"up_scores_history.go",
"up_stats_history.go",
],
importpath = "go-common/app/admin/main/up/model/upcrmmodel",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/up/model/datamodel:go_default_library",
"//app/admin/main/up/util:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/siddontang/go-mysql/mysql: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,28 @@
package upcrmmodel
import (
"go-common/library/time"
)
const (
//BusinessTypeArticleAudit 稿件的审核
BusinessTypeArticleAudit = 1
)
//SimpleCreditLog simple credit log
type SimpleCreditLog struct {
ID uint `json:"-"`
Type int `json:"type"`
OpType int `json:"op_type"`
Reason int `json:"reason"`
BusinessType int `json:"business_type"`
Mid int64 `json:"mid"`
Oid int64 `json:"oid"`
CTime time.Time `json:"ctime"`
}
//SimpleCreditLogWithContent simple credit log with content
type SimpleCreditLogWithContent struct {
SimpleCreditLog
Content string `form:"content" json:"content"` // 日志内容描述
}

View File

@@ -0,0 +1,364 @@
CREATE TABLE `up_base_info` (
`id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '自增ID',
`mid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
`name` varchar(36) NOT NULL DEFAULT '' COMMENT '昵称',
`sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别 0:保密 1:男 2:女',
`join_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '注册时间',
`first_up_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '第一次投稿时间',
`level` smallint(6) NOT NULL DEFAULT '0' COMMENT '等级',
`fans_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '粉丝量',
`account_state` tinyint(4) NOT NULL DEFAULT '0' COMMENT '账号状态0正常1封禁',
`activity` int(11) NOT NULL DEFAULT '0' COMMENT '活跃度',
`article_count_30day` int(11) NOT NULL DEFAULT '0' COMMENT '30天内投稿量(所有业务)',
`article_count_accumulate` int(11) NOT NULL DEFAULT '0' COMMENT '累计投稿量(各业务累加)',
`verify_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '认证类型,0-个人1-企业',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
`business_type` tinyint(4) NOT NULL COMMENT '业务类型, 1视频/2音频/3专栏',
`credit_score` int(11) NOT NULL DEFAULT '500' COMMENT '信用分',
`pr_score` int(11) NOT NULL DEFAULT '0' COMMENT '影响分',
`quality_score` int(11) NOT NULL DEFAULT '0' COMMENT '质量分',
`active_tid` smallint(6) unsigned NOT NULL DEFAULT '0' COMMENT '最多稿件分区',
`attr` int(11) NOT NULL DEFAULT '0' COMMENT '属性,以位区分',
`birthday` date NOT NULL DEFAULT '0000-00-00' COMMENT '生日',
`active_province` varchar(32) NOT NULL DEFAULT '' COMMENT '省份',
`active_city` varchar(32) NOT NULL DEFAULT '' COMMENT '城市',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_mid_type` (`mid`,`business_type`),
KEY `ix_mtime` (`mtime`),
KEY `ix_uptime` (`first_up_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='up基本信息表';
CREATE TABLE `up_play_info` (
`id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '自增ID',
`mid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
`business_type` smallint(6) unsigned NOT NULL DEFAULT '0' COMMENT '业务类型, 1视频/2音频/3专栏',
`play_count_accumulate` bigint(20) NOT NULL DEFAULT '0' COMMENT '累计播放次数',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
`article_count` int(11) NOT NULL DEFAULT '0' COMMENT '总稿件数',
`play_count_90day` bigint(20) NOT NULL DEFAULT '0' COMMENT '90天内稿件总播放次数',
`play_count_30day` bigint(20) NOT NULL DEFAULT '0' COMMENT '30天内稿件总播放次数',
`play_count_7day` bigint(20) NOT NULL DEFAULT '0' COMMENT '7天内稿件总播放次数',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_mid_bus` (`mid`,`business_type`),
KEY `ix_mtime` (`mtime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='up基本播放信息表';
CREATE TABLE `up_rank` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`mid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'up主id',
`type` smallint(6) unsigned NOT NULL DEFAULT '0' COMMENT '排行榜类型',
`value` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '排行榜数值,根据type不同代表的含义不同',
`generate_date` date NOT NULL DEFAULT '0000-00-00' COMMENT '排行榜日',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
`value2` int(11) NOT NULL DEFAULT '0' COMMENT '分数2',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_date_type_mid` (`generate_date`,`type`,`mid`),
KEY `ix_mtime` (`mtime`)
) ENGINE=InnoDB AUTO_INCREMENT=35001 DEFAULT CHARSET=utf8 COMMENT='Up蹿升榜';
CREATE TABLE `task_info` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`generate_date` date NOT NULL DEFAULT '0000-00-00' COMMENT '计算日',
`task_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任务类型',
`start_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '开始时间',
`end_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '结束时间',
`task_state` smallint(6) NOT NULL DEFAULT '0' COMMENT '任务状态, 0表示初始化, 1表示结束其他状态根据task_type定义',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_date_type` (`generate_date`,`task_type`),
KEY `ix_mtime` (`mtime`),
KEY `ix_date` (`generate_date`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 COMMENT='计算任务信息表';
-- score_section_history: table
CREATE TABLE `score_section_history` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`generate_date` date NOT NULL COMMENT '生成日期',
`score_type` smallint(6) NOT NULL DEFAULT '0' COMMENT '类型, 1质量分2影响分3信用分',
`section_0` int(11) NOT NULL DEFAULT '0' COMMENT '0~100的人数',
`section_1` int(11) NOT NULL DEFAULT '0' COMMENT '101~200',
`section_2` int(11) NOT NULL DEFAULT '0' COMMENT '201~300',
`section_3` int(11) NOT NULL DEFAULT '0' COMMENT '301~400',
`section_4` int(11) NOT NULL DEFAULT '0' COMMENT '401~500',
`section_5` int(11) NOT NULL DEFAULT '0' COMMENT '501~600',
`section_6` int(11) NOT NULL DEFAULT '0' COMMENT '601~700',
`section_7` int(11) NOT NULL DEFAULT '0' COMMENT '701~800',
`section_8` int(11) NOT NULL DEFAULT '0' COMMENT '801~900',
`section_9` int(11) NOT NULL DEFAULT '0' COMMENT '901~1000',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_date_type` (`generate_date`,`score_type`),
KEY `ix_mtime` (`mtime`)
) ENGINE=InnoDB AUTO_INCREMENT=79 DEFAULT CHARSET=utf8 COMMENT='up分数段人数分布表'
;
-- up_stats_history: table
CREATE TABLE `up_stats_history` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '1活跃、2新增可以通过累计来计算、3累计up主人数',
`sub_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '子类',
`value1` int(11) NOT NULL DEFAULT '0' COMMENT '分数',
`value2` int(11) NOT NULL DEFAULT '0' COMMENT '分数2,备用',
`generate_date` date NOT NULL DEFAULT '0000-00-00' COMMENT '生成日期',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_type_subtype_date` (`generate_date`,`type`,`sub_type`),
KEY `ix_mtime` (`mtime`)
) ENGINE=InnoDB AUTO_INCREMENT=110 DEFAULT CHARSET=utf8 COMMENT='up主总数表'
;
-- up_scores_history_00: table
CREATE TABLE `up_scores_history_00` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`mid` int(11) unsigned NOT NULL COMMENT 'up主id',
`score_type` tinyint(4) NOT NULL COMMENT '1内容分2影响分3信用分',
`score` int(11) unsigned NOT NULL COMMENT '分数',
`generate_date` date NOT NULL COMMENT '生成日期',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_mid_scoretype_date` (`mid`,`score_type`,`generate_date`),
KEY `ix_date` (`generate_date`),
KEY `ix_mtime` (`mtime`)
) ENGINE=InnoDB AUTO_INCREMENT=101239 DEFAULT CHARSET=utf8 COMMENT='up分数表'
;
-- credit_log_00: table
CREATE TABLE `credit_log_00` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`type` smallint(6) unsigned NOT NULL COMMENT '日志类型',
`op_type` smallint(6) NOT NULL COMMENT '操作类型',
`reason` smallint(6) NOT NULL COMMENT '原因类型',
`business_type` smallint(6) unsigned NOT NULL COMMENT '业务类型',
`mid` int(11) NOT NULL COMMENT 'mid',
`oid` int(11) unsigned NOT NULL COMMENT 'oid',
`uid` smallint(6) unsigned NOT NULL COMMENT '操作人员id',
`content` varchar(255) NOT NULL COMMENT '操作内容',
`extra` varchar(2000) NOT NULL DEFAULT '' COMMENT '额外信息',
`ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`mtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
KEY `ix_mtime` (`mtime`),
KEY `ix_mid` (`mid`)
) ENGINE=InnoDB AUTO_INCREMENT=394475 DEFAULT CHARSET=utf8 COMMENT='信用分日志表'
;
CREATE TABLE credit_log_00 LIKE credit_log_00;
CREATE TABLE credit_log_01 LIKE credit_log_00;
CREATE TABLE credit_log_02 LIKE credit_log_00;
CREATE TABLE credit_log_03 LIKE credit_log_00;
CREATE TABLE credit_log_04 LIKE credit_log_00;
CREATE TABLE credit_log_05 LIKE credit_log_00;
CREATE TABLE credit_log_06 LIKE credit_log_00;
CREATE TABLE credit_log_07 LIKE credit_log_00;
CREATE TABLE credit_log_08 LIKE credit_log_00;
CREATE TABLE credit_log_09 LIKE credit_log_00;
CREATE TABLE credit_log_10 LIKE credit_log_00;
CREATE TABLE credit_log_11 LIKE credit_log_00;
CREATE TABLE credit_log_12 LIKE credit_log_00;
CREATE TABLE credit_log_13 LIKE credit_log_00;
CREATE TABLE credit_log_14 LIKE credit_log_00;
CREATE TABLE credit_log_15 LIKE credit_log_00;
CREATE TABLE credit_log_16 LIKE credit_log_00;
CREATE TABLE credit_log_17 LIKE credit_log_00;
CREATE TABLE credit_log_18 LIKE credit_log_00;
CREATE TABLE credit_log_19 LIKE credit_log_00;
CREATE TABLE credit_log_20 LIKE credit_log_00;
CREATE TABLE credit_log_21 LIKE credit_log_00;
CREATE TABLE credit_log_22 LIKE credit_log_00;
CREATE TABLE credit_log_23 LIKE credit_log_00;
CREATE TABLE credit_log_24 LIKE credit_log_00;
CREATE TABLE credit_log_25 LIKE credit_log_00;
CREATE TABLE credit_log_26 LIKE credit_log_00;
CREATE TABLE credit_log_27 LIKE credit_log_00;
CREATE TABLE credit_log_28 LIKE credit_log_00;
CREATE TABLE credit_log_29 LIKE credit_log_00;
CREATE TABLE credit_log_30 LIKE credit_log_00;
CREATE TABLE credit_log_31 LIKE credit_log_00;
CREATE TABLE credit_log_32 LIKE credit_log_00;
CREATE TABLE credit_log_33 LIKE credit_log_00;
CREATE TABLE credit_log_34 LIKE credit_log_00;
CREATE TABLE credit_log_35 LIKE credit_log_00;
CREATE TABLE credit_log_36 LIKE credit_log_00;
CREATE TABLE credit_log_37 LIKE credit_log_00;
CREATE TABLE credit_log_38 LIKE credit_log_00;
CREATE TABLE credit_log_39 LIKE credit_log_00;
CREATE TABLE credit_log_40 LIKE credit_log_00;
CREATE TABLE credit_log_41 LIKE credit_log_00;
CREATE TABLE credit_log_42 LIKE credit_log_00;
CREATE TABLE credit_log_43 LIKE credit_log_00;
CREATE TABLE credit_log_44 LIKE credit_log_00;
CREATE TABLE credit_log_45 LIKE credit_log_00;
CREATE TABLE credit_log_46 LIKE credit_log_00;
CREATE TABLE credit_log_47 LIKE credit_log_00;
CREATE TABLE credit_log_48 LIKE credit_log_00;
CREATE TABLE credit_log_49 LIKE credit_log_00;
CREATE TABLE credit_log_50 LIKE credit_log_00;
CREATE TABLE credit_log_51 LIKE credit_log_00;
CREATE TABLE credit_log_52 LIKE credit_log_00;
CREATE TABLE credit_log_53 LIKE credit_log_00;
CREATE TABLE credit_log_54 LIKE credit_log_00;
CREATE TABLE credit_log_55 LIKE credit_log_00;
CREATE TABLE credit_log_56 LIKE credit_log_00;
CREATE TABLE credit_log_57 LIKE credit_log_00;
CREATE TABLE credit_log_58 LIKE credit_log_00;
CREATE TABLE credit_log_59 LIKE credit_log_00;
CREATE TABLE credit_log_60 LIKE credit_log_00;
CREATE TABLE credit_log_61 LIKE credit_log_00;
CREATE TABLE credit_log_62 LIKE credit_log_00;
CREATE TABLE credit_log_63 LIKE credit_log_00;
CREATE TABLE credit_log_64 LIKE credit_log_00;
CREATE TABLE credit_log_65 LIKE credit_log_00;
CREATE TABLE credit_log_66 LIKE credit_log_00;
CREATE TABLE credit_log_67 LIKE credit_log_00;
CREATE TABLE credit_log_68 LIKE credit_log_00;
CREATE TABLE credit_log_69 LIKE credit_log_00;
CREATE TABLE credit_log_70 LIKE credit_log_00;
CREATE TABLE credit_log_71 LIKE credit_log_00;
CREATE TABLE credit_log_72 LIKE credit_log_00;
CREATE TABLE credit_log_73 LIKE credit_log_00;
CREATE TABLE credit_log_74 LIKE credit_log_00;
CREATE TABLE credit_log_75 LIKE credit_log_00;
CREATE TABLE credit_log_76 LIKE credit_log_00;
CREATE TABLE credit_log_77 LIKE credit_log_00;
CREATE TABLE credit_log_78 LIKE credit_log_00;
CREATE TABLE credit_log_79 LIKE credit_log_00;
CREATE TABLE credit_log_80 LIKE credit_log_00;
CREATE TABLE credit_log_81 LIKE credit_log_00;
CREATE TABLE credit_log_82 LIKE credit_log_00;
CREATE TABLE credit_log_83 LIKE credit_log_00;
CREATE TABLE credit_log_84 LIKE credit_log_00;
CREATE TABLE credit_log_85 LIKE credit_log_00;
CREATE TABLE credit_log_86 LIKE credit_log_00;
CREATE TABLE credit_log_87 LIKE credit_log_00;
CREATE TABLE credit_log_88 LIKE credit_log_00;
CREATE TABLE credit_log_89 LIKE credit_log_00;
CREATE TABLE credit_log_90 LIKE credit_log_00;
CREATE TABLE credit_log_91 LIKE credit_log_00;
CREATE TABLE credit_log_92 LIKE credit_log_00;
CREATE TABLE credit_log_93 LIKE credit_log_00;
CREATE TABLE credit_log_94 LIKE credit_log_00;
CREATE TABLE credit_log_95 LIKE credit_log_00;
CREATE TABLE credit_log_96 LIKE credit_log_00;
CREATE TABLE credit_log_97 LIKE credit_log_00;
CREATE TABLE credit_log_98 LIKE credit_log_00;
CREATE TABLE credit_log_99 LIKE credit_log_00;
CREATE TABLE up_scores_history_00 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_01 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_02 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_03 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_04 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_05 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_06 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_07 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_08 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_09 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_10 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_11 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_12 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_13 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_14 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_15 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_16 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_17 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_18 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_19 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_20 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_21 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_22 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_23 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_24 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_25 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_26 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_27 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_28 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_29 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_30 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_31 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_32 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_33 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_34 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_35 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_36 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_37 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_38 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_39 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_40 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_41 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_42 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_43 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_44 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_45 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_46 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_47 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_48 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_49 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_50 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_51 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_52 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_53 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_54 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_55 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_56 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_57 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_58 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_59 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_60 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_61 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_62 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_63 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_64 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_65 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_66 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_67 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_68 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_69 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_70 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_71 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_72 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_73 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_74 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_75 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_76 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_77 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_78 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_79 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_80 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_81 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_82 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_83 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_84 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_85 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_86 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_87 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_88 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_89 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_90 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_91 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_92 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_93 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_94 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_95 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_96 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_97 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_98 LIKE up_scores_history_00;
CREATE TABLE up_scores_history_99 LIKE up_scores_history_00;
--------- 以上是建表语句 -----------
--------- 修改 up_play_info表字段有数据溢出 -----------
# (fat 1, uat 1, prod 1)
alter table up_play_info modify play_count_accumulate BIGINT(20) NOT NULL DEFAULT '0' COMMENT '累计播放次数';
alter table up_play_info modify play_count_90day BIGINT(20) NOT NULL DEFAULT '0' COMMENT '90天内稿件总播放次数';
alter table up_play_info modify play_count_30day BIGINT(20) NOT NULL DEFAULT '0' COMMENT '30天内稿件总播放次数';
alter table up_play_info modify play_count_7day BIGINT(20) NOT NULL DEFAULT '0' COMMENT '7天内稿件总播放次数';
--------- 修改 自增ID为bigint unsigned -----------
# (fat 1, uat 1, prod 1)
alter table up_play_info modify id BIGINT(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '自增ID';
alter table up_base_info modify id BIGINT(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '自增ID';

View File

@@ -0,0 +1,376 @@
package upcrmmodel
import (
"go-common/app/admin/main/up/model/datamodel"
"go-common/app/admin/main/up/util"
"go-common/library/time"
xtime "time"
)
const (
//CompareTypeNothing 0
CompareTypeNothing = 0
//CompareType7day 1
CompareType7day = 1
//CompareType30day 2
CompareType30day = 2
//CompareTypeMonthFirstDay 3
CompareTypeMonthFirstDay = 3
)
const (
//AttrBitVideo video
// see http://info.bilibili.co/pages/viewpage.action?pageId=9830931
AttrBitVideo = 0
//AttrBitAudio audio
AttrBitAudio = 1
//AttrBitArticle article
AttrBitArticle = 2
//AttrBitPhoto photo
AttrBitPhoto = 3
//AttrBitSign sign
AttrBitSign = 4
//AttrBitGrowup growup
AttrBitGrowup = 5
//AttrBitVerify verify
AttrBitVerify = 6
)
var (
//AttrGroup1 筛选用第一组attr
AttrGroup1 = map[int]int{AttrBitVideo: 0, AttrBitAudio: 0, AttrBitArticle: 0, AttrBitPhoto: 0}
//AttrGroup2 筛选用第二组attr 两组之间的关系是与
AttrGroup2 = map[int]int{AttrBitSign: 0, AttrBitGrowup: 0, AttrBitVerify: 0}
)
// ScoreQueryArgs ------------------------- requests ------------------------
type ScoreQueryArgs struct {
ScoreType int `form:"score_type"`
CompareType int `form:"compare_type"`
Export string `form:"export"`
}
//ScoreQueryUpArgs arg
type ScoreQueryUpArgs struct {
Mid int64 `form:"mid" validate:"required"`
Date string `form:"date"`
}
//ScoreQueryUpHistoryArgs arg
type ScoreQueryUpHistoryArgs struct {
Mid int64 `form:"mid" validate:"required"`
ScoreType int `form:"score_type"`
Day int `form:"day" default:"7"`
Date string `form:"date"`
}
//PlayQueryArgs arg
type PlayQueryArgs struct {
Mid int64 `form:"mid" validate:"required"`
BusinessType int `form:"business_type"`
}
//InfoQueryArgs arg
type InfoQueryArgs struct {
Mid int64 `form:"mid" validate:"required"`
}
//CreditLogQueryArgs arg
type CreditLogQueryArgs struct {
Mid int64 `form:"mid" validate:"required"`
Limit int `form:"limit"`
}
//UpRankQueryArgs arg
type UpRankQueryArgs struct {
Type int `form:"type" validate:"required"`
Page int `form:"page"` // (从1开始)
Size int `form:"size"` // 1 ~ 50
}
//InfoAccountInfoArgs arg
type InfoAccountInfoArgs struct {
Mids string `form:"mids" validate:"required"`
}
//InfoSearchArgs arg
type InfoSearchArgs struct {
AccountState int `json:"account_state"`
Activity int `json:"activity"`
Attrs UpAttr `json:"attrs"`
FirstDateBegin string `json:"first_date_begin"`
FirstDateEnd string `json:"first_date_end"`
Mid int64 `json:"mid"`
Order struct {
Field string `json:"field"`
Order string `json:"order"`
}
Page int `json:"page"`
Size int `json:"size"`
}
//TestGetViewBaseArgs test arg
type TestGetViewBaseArgs struct {
Mid int64 `form:"mid" validate:"required"`
}
// ------------------------- results ------------------------
//ScoreSection struct
type ScoreSection struct {
Section int `json:"-"`
Value int
Percent int
}
//ScoreQueryResult result
type ScoreQueryResult struct {
CompareAxis []ScoreSection `json:"compareAxis"`
XAxis []string `json:"xAxis"`
YAxis []ScoreSection `json:"yAxis"`
}
//NewEmptyScoreQueryResult make new result
func NewEmptyScoreQueryResult() ScoreQueryResult {
return ScoreQueryResult{
CompareAxis: []ScoreSection{},
XAxis: []string{},
YAxis: []ScoreSection{},
}
}
//ScoreInfo struct
type ScoreInfo struct {
Current int `json:"current"`
DiffLastDay int `json:"diff_last_day"`
}
//ScoreQueryUpResult result
type ScoreQueryUpResult struct {
PrScore ScoreInfo
QualityScore ScoreInfo
CreditScore ScoreInfo
Date time.Time
}
//ScoreHistoryInfo struct
type ScoreHistoryInfo struct {
Type int `json:"type"`
Score []int `json:"score"`
Date []time.Time `json:"date"`
}
//ScoreQueryUpHistoryResult result
type ScoreQueryUpHistoryResult struct {
ScoreData []ScoreHistoryInfo `json:"score_data"`
}
//PlayInfo struct
type PlayInfo struct {
Type int `json:"type"`
PlayCountAccumulate int64 `json:"play_count_accumulate"`
PlayCountAvg int64 `json:"play_count_avg"`
PlayCountAvg90Day int64 `json:"play_count_avg_90day"`
}
//PlayQueryResult result
type PlayQueryResult struct {
ArticleCount30Day int `json:"article_count_30day"`
ArticleCountAccumulate int `json:"article_count_accumulate"`
BusinessData []PlayInfo `json:"business_data"`
}
//CastUpPlayInfoToPlayInfo cast
func CastUpPlayInfoToPlayInfo(info UpPlayInfo) (r PlayInfo) {
r.Type = int(info.BusinessType)
r.PlayCountAccumulate = info.PlayCountAccumulate
r.PlayCountAvg = info.PlayCountAccumulate / info.ArticleCount
r.PlayCountAvg90Day = info.PlayCount90Day / info.ArticleCount
return
}
//UpAttr struct
type UpAttr struct {
AttrVerify int `json:"attr_verify"`
AttrVideo int `json:"attr_video"`
AttrAudio int `json:"attr_audio"`
AttrArticle int `json:"attr_article"`
AttrPhoto int `json:"attr_photo"`
AttrSign int `json:"attr_sign"`
AttrGrowup int `json:"attr_growup"`
}
//InfoQueryResult result
type InfoQueryResult struct {
ID uint32 `json:"-"`
Mid int64 `json:"mid"`
Name string `json:"name"`
Sex int8 `json:"sex"`
JoinTime time.Time `json:"join_time"`
FirstUpTime time.Time `json:"first_up_time"`
Level int16 `json:"level"`
FansCount int `json:"fans_count"`
AccountState int8 `json:"account_state"`
Activity int `json:"activity"`
ArticleCount30day int `json:"article_count_30day"`
ArticleCountAccumulate int `json:"article_count_accumulate"`
VerifyType int8 `json:"verify_type"`
BusinessType int8 `json:"business_type"`
CreditScore int `json:"credit_score"`
PrScore int `json:"pr_score"`
QualityScore int `json:"quality_score"`
ActiveTid int64 `json:"active_tid"`
ActiveSubtid int64 `json:"active_subtid"`
Region string `json:"region"`
Province string `json:"province"`
Age int `json:"age"`
Attr int `json:"-"`
Attrs UpAttr `json:"attrs"`
Birthday xtime.Time `json:"-"`
}
//CopyFromBaseInfo copy
func (i *InfoQueryResult) CopyFromBaseInfo(info UpBaseInfo) {
i.ID = info.ID
i.Mid = info.Mid
i.Name = info.Name
i.Sex = info.Sex
i.JoinTime = info.JoinTime
i.FirstUpTime = info.FirstUpTime
i.Level = info.Level
i.FansCount = info.FansCount
i.AccountState = info.AccountState
i.ArticleCount30day = info.ArticleCount30day
i.ArticleCountAccumulate = info.ArticleCountAccumulate
i.VerifyType = info.VerifyType
i.BusinessType = info.BusinessType
i.CreditScore = info.CreditScore
i.ActiveTid = info.ActiveTid
i.Birthday = info.Birthday
i.Region = info.ActiveCity
i.Province = info.ActiveProvince
i.Attr = info.Attr
i.PrScore = info.PrScore
i.QualityScore = info.QualityScore
i.Activity = info.Activity
}
// CalculateAttr 根据attr来计算各个attr_xx的属性
func (i *InfoQueryResult) CalculateAttr() {
// todo 计算attr属性
if util.IsBitSet(i.Attr, AttrBitVideo) {
i.Attrs.AttrVideo = 1
}
if util.IsBitSet(i.Attr, AttrBitAudio) {
i.Attrs.AttrAudio = 1
}
if util.IsBitSet(i.Attr, AttrBitArticle) {
i.Attrs.AttrArticle = 1
}
if util.IsBitSet(i.Attr, AttrBitPhoto) {
i.Attrs.AttrPhoto = 1
}
if util.IsBitSet(i.Attr, AttrBitSign) {
i.Attrs.AttrSign = 1
}
if util.IsBitSet(i.Attr, AttrBitGrowup) {
i.Attrs.AttrGrowup = 1
}
if util.IsBitSet(i.Attr, AttrBitVerify) {
i.Attrs.AttrVerify = 1
}
if !i.Birthday.IsZero() {
i.Age = int(xtime.Since(i.Birthday).Hours() / float64(24*365))
if i.Age < 0 {
i.Age = 0
}
}
}
//CreditLogInfo struct
type CreditLogInfo struct {
Time time.Time `json:"time"`
Log string `json:"log"`
}
//CreditLogUpResult result
type CreditLogUpResult struct {
Logs []CreditLogInfo `json:"logs"`
}
//UpRankInfo struct
type UpRankInfo struct {
InfoQueryResult
Rank int `json:"rank"`
Value uint `json:"value"`
Value2 int `json:"value_2"`
CompleteTime time.Time `json:"complete_time"`
RankType int16 `json:"-"`
}
//CopyFromUpRank copy
func (u *UpRankInfo) CopyFromUpRank(upRank *UpRank) {
u.Value = upRank.Value
u.Value2 = upRank.Value2
u.RankType = upRank.Type
}
//UpRankQueryResult result
type UpRankQueryResult struct {
Result []*UpRankInfo `json:"result"`
Date time.Time `json:"date"`
PageInfo
}
//PageInfo page info
type PageInfo struct {
TotalCount int `json:"total_count"`
Size int `json:"size"`
Page int `json:"page"`
}
//InfoSearchResult result
type InfoSearchResult struct {
Result []*InfoQueryResult `json:"result"`
PageInfo
}
//UpInfoWithViewerData up data with view data
type UpInfoWithViewerData struct {
Mid int64 `json:"mid"`
UpBaseInfo *InfoQueryResult `json:"up_base_info"`
ViewerTrend *datamodel.ViewerTrendInfo `json:"viewer_trend"`
ViewerArea *datamodel.ViewerAreaInfo `json:"viewer_area"`
ViewerBase *datamodel.ViewerBaseInfo `json:"viewer_base"`
UpPlayInfo *UpPlayInfo `json:"up_play_info"`
}
//UpInfoWithViewerResult info result
type UpInfoWithViewerResult struct {
Result []*UpInfoWithViewerData `json:"result"`
PageInfo
}
// -------------
const (
// FlagUpBaseData up base info
FlagUpBaseData = 1
// FlagUpPlayData up play info
FlagUpPlayData = 1 << 1
// FlagViewData view base data flag
FlagViewData = 1 << 2
)
//UpInfoWithViewerArg arg
type UpInfoWithViewerArg struct {
Mids string `form:"mids"`
Sort string `form:"sort" default:"fans_count"`
Order string `form:"order" default:"desc"`
Page int `form:"page" default:"1"`
Size int `form:"size" default:"20"`
// 需要的信息
Flag int `form:"flag" default:"0"`
}

Some files were not shown because too many files have changed in this diff Show More