Create & Init Project...

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

View File

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

View File

@@ -0,0 +1,188 @@
#### growup-interface
##### Version 0.0.1
> 1. 初始化growup-interface
> 2. 帐号管理视频部分CURD
##### Version 0.0.2
> 1. 兼容老系统路由
##### Version 0.0.
> 1. 更新UGC帐号默认类型
##### Version 0.0.4
> 1. 为驳回操作添加冷却时间设定
##### Version 0.0.5
> 1. 主动退出冷却时间修改
##### Version 0.0.6
> 1. 优化up主申请签约的业务逻辑
> 2. 添加up主时保护性判断up主是否在黑名单
> 3. 已存在的up主重新申请的时候更新apply_at
##### Version 0.0.7
> 1. 添加up主每月提现接口
> 2. 添加移动端稿件收入排行接口
> 3. 修改稿件title
##### Version 0.1.2
> 1. 添加用户认证
##### Version 0.1.3
> 1. 修改UP主状态接口,添加已加入过创作激励计划状态码
> 2. 修改对外接口路由前缀
##### Version 0.1.4
> 1. 添加web端稿件收入排行接口
##### Version 0.1.5
> 1. 添加up主收入汇总接口
##### Version 0.1.6
> 1. 修复展示up主稿件bug
> 2. 用户主动退出增加信用分扣除
##### Version 0.1.7
> 1. 增加up主收入统计
> 2. 增加up主退出理由
> 3. 创作激励前台api迁移 java->go
> 4. 增加创作激励计划公告板
> 5. 增加创作激励计划过去30天补贴数据展示
> 6. 创作激励前台api迁移 java->go
##### Version 0.1.8
> 1. 迁移up主退出路由
##### Version 0.1.10
> 1. 添加upSummary log
> 2. 兼容up主退出路由
##### Version 0.2.2
> 1. upSummary暂时去掉redis
##### Version 0.2.3
> 1. upSummary添加redis
##### Version 0.2.4
> 1. up主收入展示柱状图时间限制改为T-2
##### Version 0.2.5
> 1. 优化数组的截取,保证系统的稳定性
##### Version 0.2.6
> 1. 添加test
> 2. http框架迁移->bm
##### Version 0.2.7
> 1. 兼容收入展示跨月
##### Version 0.2.7
> 1. 修复路由bug
##### Version 0.2.8
> 1. 修复由AddDate导致月份获取错误的bug
##### Version 0.2.9
> 1. 为非正常状态下up主申请接口做防御
> 2. 优化api接口返回
##### Version 0.3.0
> 1. 优化up主稿件收入展示
##### Version 0.3.1
> 1. 新增最新公告接口
> 2. 修改稿件收入展示为最近30天
##### Version 0.3.2
> 1. 优化最新公告接口字段
##### Version 0.3.3
> 1. 修复up主统计跨月数据不统一的bug
##### Version 0.3.4
> 1. 优化up主稿件收入展示接口
##### Version 0.3.5
> 1. 优化up主稿件收入redis缓存
##### Version 0.3.6
> 1. 添加活动模版前台接口
> 2. 增加banner位展示
##### Version 0.3.7
> 1. 修复Banner获取bug
##### Version 0.3.8
> 1. 创作激励添加专栏
##### Version 0.3.9
> 1. 优化申请加入专栏
##### Version 0.4.1
> 1. 修复查询违规扣除失败的bug
##### Version 0.4.2
> 1. 优化业务总览的数据
##### Version 0.4.3
> 1. 优化up主总览查询,统一更新为T-2
##### Version 0.4.4
> 1. 优化up主主动退出
##### Version 0.4.5
> 1. 优化up主实时获取粉丝量
##### Version 0.4.6
> 1. 增加素材相关接口
##### Version 0.4.7
> 1. 修复素材量bug
##### Version 0.4.8
> 1. 专栏放开白名单
##### Version 0.4.9
> 1. 加入专栏放开白名单
##### Version 0.5.0
> 1. 专栏视频加入时判断限制条件
##### Version 0.5.8
> 1. 为h5提供业务类型
> 2. 添加半年账单接口
##### Version 0.5.9
> 1. 优化income查询
##### Version 0.6.0
> 1. 优化up summary返回
##### Version 0.6.1
> 1. 修改半年账单日期
##### Version 0.6.2
> 1. 修改半年账单流量王titel->激励101
##### Version 0.6.3
> 1. 修正额外收入因计算误差可能为负的问题
##### Version 0.6.4
> 1. 添加素材白名单判断
> 2. 添加激励内购接口
##### Version 0.6.5
> 1. 优化激励内购商品展示顺序
##### Version 0.6.6
> 1. 新手信功能
##### Version 0.6.8
> 1. 新手信对应的推荐up主获取不到的情况下随机获取
##### Version 0.6.9
> 1. 专项奖前台
> 2. 激励前台通知改版
> 3. 修正参数错误
> 4. 激励一周年

View File

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

View File

@@ -0,0 +1,12 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- gaopeng
labels:
- interface
- interface/main/growup
- main
options:
no_parent_owners: true
reviewers:
- gaopeng

View File

@@ -0,0 +1,10 @@
#### growup-interface
##### 项目简介
> growup-interface
##### 编译环境
> 请只用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 = ["growup-interface.toml"],
importpath = "go-common/app/interface/main/growup/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/growup/conf:go_default_library",
"//app/interface/main/growup/http:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/trace:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,158 @@
# This is a TOML document. Boom.
version = "1.0.0"
user = "nobody"
pid = "/tmp/growup-interface.pid"
dir = "./"
perf = "0.0.0.0:7422"
checkFile = "/data/www/growup-interface.html"
family = "growup-interface"
address = ""
[bm]
addr = "0.0.0.0:7420"
maxListen = 1000
timeout = "1s"
[log]
dir = "/data/log/growup-interface/"
# [log.agent]
# family = "growup-interface"
# taskID = "000057"
# proto = "unixgram"
# addr = "/var/run/lancer/collector.sock"
# chan = 10240
[db]
[db.growup]
dsn = "growup:test@tcp(172.16.33.205:3307)/bilibili_business_up?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 5
idleTimeout ="4h"
queryTimeout = "5s"
execTimeout = "5s"
tranTimeout = "10s"
[db.growup.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[db.allowance]
dsn = "growup:test@tcp(172.16.33.205:3307)/bilibili_business_up?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 5
idleTimeout = "4h"
queryTimeout = "5s"
execTimeout = "5s"
tranTimeout = "10s"
[db.allowance.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[multiHTTP]
[multiHTTP.inner]
addrs = ["0.0.0.0:7420"]
maxListen = 10
[multiHTTP.local]
addrs = ["0.0.0.0:7421"]
maxListen = 10
[appConf]
key = "345b38393c90f093"
secret = "598c2f3e826f36f6feb9c4f671e39adf"
[identify]
whiteAccessKey = "a2a1eb0ac97d6ba08b85aa0151528f34"
whiteMid = 23675773
csrf = true
[identify.app]
key = "7c7ac0db1aa05587"
secret = "9a6d62d93290c5f771ad381e9ca23f26"
[identify.memcache]
name = "go-business/identify"
proto = "unix"
addr = "/tmp/shd-platform-identify-web-mc.sock"
active = 1024
idle = 64
dialTimeout = "50ms"
readTimeout = "90ms"
writeTimeout = "80ms"
idleTimeout = "80s"
[identify.host]
auth = "http://passport.bilibili.co"
secret = "http://open.bilibili.co"
[identify.httpClient]
key = "7c7ac0db1aa05587"
secret = "9a6d62d93290c5f771ad381e9ca23f26"
dial = "50ms"
timeout = "100ms"
keepAlive = "60s"
[identify.httpClient.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[identify.httpClient.url]
"http://passport.bilibili.co/intranet/auth/tokenInfo" = {timeout = "100ms"}
"http://passport.bilibili.co/intranet/auth/cookieInfo" = {timeout = "100ms"}
"http://open.bilibili.co/api/getsecret" = {timeout = "500ms"}
[redis]
name = "growup-interface"
proto = "tcp"
addr = "127.0.0.1:6379"
idle = 100
active = 100
dialTimeout = "500ms"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
expire = "10m"
[httpClient]
[httpClient.read]
key = "a4bb50e6f2bc2e0f"
secret = "test"
dial = "1s"
timeout = "1s"
keepAlive = "60s"
timer = 1000
[httpClient.read.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[host]
archiveURI = "http://uat-api.bilibili.co/x/internal/v2/archive/archives"
accountURI = "http://uat-api.bilibili.co/x/internal/v3/account/infos"
uperURI = "http://uat-api.bilibili.co/x/internal/uper/all"
vipURI = "http://uat-api.bilibili.com/x/internal/big/useBatchInfo"
activitiesURI = "http://uat-www.bilibili.com/activity/list/"
relationsURI = "http://api.bilibili.co/x/internal/relation/relations"
videoUpURI = "http://uat-archive.api.bilibili.co/videoup/view"
categoriesURI = "http://uat-archive.api.bilibili.co/videoup/types"
[hbase]
master = ""
meta = ""
dialTimeout = "1s"
readTimeout = "150ms"
readsTimeout = "600ms"
writeTimeout = "200ms"
writesTimeout = "600ms"
[hbase.zookeeper]
root = ""
addrs = ["10.23.58.154:2181","10.23.58.141:2181","10.23.58.20:2181"]
timeout = "30s"
[threshold]
limitFanCnt = 3
limitTotalClick = 500000
limitArticleView = 1000

View File

@@ -0,0 +1,45 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"go-common/app/interface/main/growup/conf"
"go-common/app/interface/main/growup/http"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
// init conf,log,trace,stat,perf
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Log)
defer log.Close()
trace.Init(conf.Conf.Tracer)
defer trace.Close()
ecode.Init(nil)
http.Init(conf.Conf)
log.Info("growup-service start")
// signal handler
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("growup-service get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGINT:
log.Info("growup-service exit")
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,93 @@
# This is a TOML document. Boom.
[newbie]
defaultCover = "//i0.hdslb.com/bfs/icon/485664798f87607e76da437903fd6cf2cc15bea3.jpg"
defaultTalent = "潜力萌新"
RecommendUpCount = 3
RecommendUpPoolCount = 10
ActivityCount = 2
ActivityShotType = 16
[newbie.talents]
24 = "动画新星"
25 = "动画新星"
27 = "动画新星"
47 = "动画新星"
28 = "唱作新星"
195 = "唱作新星"
30 = "灵魂乐手"
59 = "灵魂乐手"
196 = "灵魂乐手"
31 = "实力唱将"
29 = "音乐鉴赏家"
54 = "音乐鉴赏家"
130 = "音乐鉴赏家"
17 = "头号玩家"
65 = "头号玩家"
136 = "头号玩家"
172 = "头号玩家"
173 = "头号玩家"
19 = "格斗新星"
121 = "潜力导演"
171 = "电竞达人"
71 = "综艺大咖"
131 = "韩圈达人"
137 = "头号粉丝"
39 = "博学多才"
95 = "数码狂人"
189 = "数码狂人"
191 = "数码狂人"
190 = "摄影新星"
96 = "心系天下"
98 = "见习机械师"
122 = "新进技术宅"
37 = "百科全书"
124 = "百科全书"
178 = "百科全书"
176 = "爱车一族"
22 = "鬼畜新星"
26 = "鬼畜新星"
126 = "鬼畜新星"
127 = "鬼畜新星"
20 = "宅舞新星"
154 = "不如斗舞"
156 = "不如斗舞"
157 = "时尚达人"
158 = "时尚达人"
159 = "时尚达人"
164 = "时尚达人"
193 = "时尚达人"
21 = "生活达人"
174 = "生活达人"
75 = "实习铲屎官"
76 = "吃货星人"
138 = "搞笑新星"
161 = "手工大触"
162 = "小画家"
163 = "体育达人"
166 = "广告达人"
153 = "国创之光"
168 = "国创之光"
169 = "国创之光"
179 = "资深军迷"
180 = "乐活达人"
85 = "影视新星"
86 = "影视新星"
182 = "影视新星"
183 = "影视新星"
184 = "影视新星"

View File

@@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/interface/main/growup/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/redis:go_default_library",
"//library/conf:go_default_library",
"//library/database/hbase.v2:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/net/trace:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,175 @@
package conf
import (
"errors"
"flag"
"path"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/rpc"
"go-common/library/net/rpc/warden"
"go-common/library/net/trace"
"go-common/library/time"
"go-common/library/database/hbase.v2"
"github.com/BurntSushi/toml"
)
var (
// ConfPath local config path
ConfPath string
// Conf config
Conf = &Config{}
client *conf.Client
)
// Config str
type Config struct {
// base
// channal len
ChanSize int64
// log
Log *log.Config
// http
BM *bm.ServerConfig
// identify
AppConf *bm.App
// tracer
Tracer *trace.Config
// tick load pgc
Tick time.Duration
// orm
DB *DB
//redis
Redis *Redis
// http client of search
HTTPClient *HTTPClient
// host
Host *Host
// rpc
ArticleRPC *rpc.ClientConfig
AccountRPC *rpc.ClientConfig
VipRPC *rpc.ClientConfig
AccCliConf *warden.ClientConfig
// threshold
Threshold *Threshold
// hbase
HBase *HBaseConfig
// newbie
Newbie Newbie
}
// DB def db struct
type DB struct {
Allowance *sql.Config
Growup *sql.Config
}
// Redis define redis conf.
type Redis struct {
*redis.Config
Expire time.Duration
}
// HTTPClient http client
type HTTPClient struct {
Read *bm.ClientConfig
}
// Host http host
type Host struct {
AccountURI string
ArchiveURI string
UperURI string
VipURI string
ActivitiesURI string
RelationsURI string
VideoUpURI string
CategoriesURI string
}
// HBaseConfig for new hbase client.
type HBaseConfig struct {
*hbase.Config
WriteTimeout time.Duration
ReadTimeout time.Duration
}
// Threshold up cretive threshold
type Threshold struct {
LimitFanCnt int64
LimitTotalClick int64
LimitArticleView int64
}
// Newbie newbie config
type Newbie struct {
Talents map[string]string
DefaultCover string
DefaultTalent string
RecommendUpCount int
RecommendUpPoolCount int
ActivityCount int
ActivityShotType int32
}
func init() {
flag.StringVar(&ConfPath, "conf", "", "default config path")
}
// Init init conf
func Init() (err error) {
if ConfPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(ConfPath, &Conf)
if err != nil {
return
}
var templateConfPath = path.Join(path.Dir(ConfPath), "newbie.toml")
_, err = toml.DecodeFile(templateConfPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,106 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"account_test.go",
"activity_test.go",
"archive_stat_test.go",
"av_breach_test.go",
"banner_test.go",
"bgm_test.go",
"column_income_test.go",
"dao_test.go",
"exchange_test.go",
"hbase_test.go",
"income_test.go",
"notice_test.go",
"redis_test.go",
"special_award_test.go",
"tool_test.go",
"up_bill_test.go",
"up_test.go",
"withdraw_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/growup/conf:go_default_library",
"//app/interface/main/growup/model:go_default_library",
"//library/net/metadata:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"account.go",
"activity.go",
"archive_stat.go",
"av_breach.go",
"banner.go",
"bgm.go",
"column_income.go",
"dao.go",
"exchange.go",
"hbase.go",
"income.go",
"notice.go",
"redis.go",
"special_award.go",
"tool.go",
"up.go",
"up_bill.go",
"up_year.go",
"withdraw.go",
],
importpath = "go-common/app/interface/main/growup/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/growup/conf:go_default_library",
"//app/interface/main/growup/model:go_default_library",
"//app/interface/openplatform/article/model:go_default_library",
"//app/interface/openplatform/article/rpc/client:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/account/rpc/client:go_default_library",
"//app/service/main/vip/model:go_default_library",
"//app/service/main/vip/rpc/client:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/hbase.v2:go_default_library",
"//library/database/sql: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",
"//library/xstr:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/tsuna/gohbase/hrpc:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/interface/main/growup/dao/newbiedao:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,79 @@
package dao
import (
"context"
"fmt"
"net/url"
"strconv"
"go-common/app/interface/main/growup/model"
account "go-common/app/service/main/account/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/xstr"
"github.com/pkg/errors"
)
// AccountInfos get account infos
func (d *Dao) AccountInfos(c context.Context, mids []int64) (infos map[int64]*model.ActUpInfo, err error) {
if len(mids) == 0 {
return
}
infos = make(map[int64]*model.ActUpInfo)
results := new(model.AccountInfosResult)
uv := url.Values{}
uv.Set("mids", xstr.JoinInts(mids))
if err = d.httpRead.Get(c, d.c.Host.AccountURI, "", uv, results); err != nil {
return
}
if results.Code != ecode.OK.Code() {
err = errors.Wrap(ecode.Int(results.Code), fmt.Sprintf("search account failed: %s?%s", d.c.Host.AccountURI, uv.Get("mids")))
return
}
for mid, account := range results.Data {
infos[mid] = &model.ActUpInfo{Nickname: account.Name, Face: account.Face}
}
return
}
// UpBusinessInfos get business infos
func (d *Dao) UpBusinessInfos(c context.Context, mid int64) (identify *model.UpIdentify, err error) {
identify = new(model.UpIdentify)
results := new(model.UperInfosResult)
uv := url.Values{}
uv.Set("mid", strconv.FormatInt(mid, 10))
if err = d.httpRead.Get(c, d.c.Host.UperURI, "", uv, results); err != nil {
return
}
if results.Code != ecode.OK.Code() {
err = errors.Wrap(ecode.Int(results.Code), fmt.Sprintf("search uper failed: %s?%s", d.c.Host.UperURI, uv.Get("mid")))
return
}
identify = results.Data["identify"]
return
}
// Card get account.
func (d *Dao) Card(c context.Context, mid int64) (res *account.Card, err error) {
var arg = &account.ArgMid{
Mid: mid,
}
if res, err = d.acc.Card3(c, arg); err != nil {
log.Error("d.acc.Card3() error(%v)", err)
err = ecode.CreativeAccServiceErr
}
return
}
// ProfileWithStat get account.
func (d *Dao) ProfileWithStat(c context.Context, mid int64) (res *account.ProfileStat, err error) {
var arg = &account.ArgMid{
Mid: mid,
}
if res, err = d.acc.ProfileWithStat3(c, arg); err != nil {
log.Error("d.acc.ProfileWithStat3() error(%v)", err)
err = ecode.CreativeAccServiceErr
}
return
}

View File

@@ -0,0 +1,70 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAccountInfos(t *testing.T) {
convey.Convey("AccountInfos", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1001}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
infos, err := d.AccountInfos(c, mids)
ctx.Convey("Then err should be nil.infos should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(infos, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpBusinessInfos(t *testing.T) {
convey.Convey("UpBusinessInfos", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.UpBusinessInfos(c, mid)
ctx.Convey("Then err should be nil.identify should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoCard(t *testing.T) {
convey.Convey("Card", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Card(c, mid)
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 TestDaoProfileWithStat(t *testing.T) {
convey.Convey("ProfileWithStat", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.ProfileWithStat(c, mid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,55 @@
package dao
import (
"context"
"go-common/app/interface/main/growup/model"
"go-common/library/log"
// "go-common/library/database/sql"
)
const (
_activitySQL = "SELECT id,name,signed_start,signed_end,sign_up_start,sign_up_end,sign_up,win_type,progress_start,progress_end,progress_sync,update_page,bonus_query,bonus_query_start,bonus_query_end,background,win_desc,unwin_desc,details FROM creative_activity WHERE id = ?"
_upActivitySQL = "SELECT mid,nickname,ranking,state FROM up_activity WHERE activity_id = ? AND is_deleted = 0"
_inUpActivitySQL = "INSERT INTO up_activity(mid,nickname,activity_id,state,sign_up_time) VALUES(?,?,?,?,?)"
)
// GetActivity get activity by query
func (d *Dao) GetActivity(c context.Context, id int64) (ac *model.CActivity, err error) {
ac = &model.CActivity{}
err = d.db.QueryRow(c, _activitySQL, id).Scan(&ac.ID, &ac.Name, &ac.SignedStart, &ac.SignedEnd, &ac.SignUpStart, &ac.SignUpEnd, &ac.SignUp, &ac.WinType, &ac.ProgressStart, &ac.ProgressEnd, &ac.ProgressSync, &ac.UpdatePage, &ac.BonusQuery, &ac.BonusQueryStart, &ac.BonusQueryEnd, &ac.Background, &ac.WinDesc, &ac.UnwinDesc, &ac.Details)
return
}
// ListUpActivity get up from up_activity
func (d *Dao) ListUpActivity(c context.Context, id int64) (ups []*model.UpBonus, err error) {
ups = make([]*model.UpBonus, 0)
rows, err := d.db.Query(c, _upActivitySQL, id)
if err != nil {
log.Error("ListUpActivity d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
up := &model.UpBonus{}
err = rows.Scan(&up.MID, &up.Nickname, &up.Rank, &up.State)
if err != nil {
log.Error("ListUpActivity rows.Scan error(%v)", err)
return
}
ups = append(ups, up)
}
err = rows.Err()
return
}
// SignUpActivity up sign up activity
func (d *Dao) SignUpActivity(c context.Context, up *model.UpBonus) (rows int64, err error) {
res, err := d.db.Exec(c, _inUpActivitySQL, up.MID, up.Nickname, up.ActivityID, up.State, up.SignUpTime)
if err != nil {
log.Error("SignUpActivity.Exec(%s) error(%v)", _inUpActivitySQL, err)
return
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,65 @@
package dao
import (
"context"
"go-common/app/interface/main/growup/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetActivity(t *testing.T) {
convey.Convey("GetActivity", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(1000)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO creative_activity(id, name) VALUES(1000, 'dao-test')")
ac, err := d.GetActivity(c, id)
ctx.Convey("Then err should be nil.ac should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ac, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListUpActivity(t *testing.T) {
convey.Convey("ListUpActivity", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(1000)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_activity(mid,activity_id,state) VALUES(1001, 1000, 2)")
ups, err := d.ListUpActivity(c, id)
ctx.Convey("Then err should be nil.ups should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ups, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSignUpActivity(t *testing.T) {
convey.Convey("SignUpActivity", t, func(ctx convey.C) {
var (
c = context.Background()
up = &model.UpBonus{
MID: 1002,
Nickname: "test",
ActivityID: 1000,
State: 2,
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "DELETE FROM up_activity WHERE mid = 1002")
rows, err := d.SignUpActivity(c, up)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,73 @@
package dao
import (
"context"
"encoding/json"
"fmt"
"strconv"
"go-common/app/interface/main/growup/model"
article "go-common/app/interface/openplatform/article/model"
"go-common/library/ecode"
"go-common/library/log"
)
// ArticleStat article stat
func (d *Dao) ArticleStat(c context.Context, mid int64, ip string) (res article.UpStat, err error) {
arg := &article.ArgMid{Mid: mid, RealIP: ip}
if res, err = d.art.CreationUpStat(c, arg); err != nil {
log.Error("d.art.CreationUpStat(%+v) error(%v)", arg, err)
if _, er := strconv.ParseInt(err.Error(), 10, 64); er != nil {
err = ecode.CreativeArticleRPCErr
}
}
return
}
func (d *Dao) getUpBaseStatCache(c context.Context, mid int64, date string) (data *model.UpBaseStat, err error) {
key := fmt.Sprintf("growup-up-status:%d-%s", mid, date)
res, err := d.getCacheVal(c, key)
if err != nil {
log.Error("d.getCacheVal error(%v)", err)
return
}
if res == nil {
return
}
err = json.Unmarshal(res, &data)
if err != nil {
log.Error("json.Unmarshal(%v) error(%v)", res, err)
}
return
}
// setUpBaseStatCache add stat cache.
func (d *Dao) setUpBaseStatCache(c context.Context, mid int64, date string, st *model.UpBaseStat) (err error) {
key := fmt.Sprintf("growup-up-status:%d-%s", mid, date)
v, err := json.Marshal(st)
if err != nil {
log.Error("json.Marshal error(%v)", err)
return
}
return d.setCacheKV(c, key, v, d.redisExpire)
}
// UpStat get up stat from hbase
func (d *Dao) UpStat(c context.Context, mid int64, dt string) (st *model.UpBaseStat, err error) {
// try cache
st, err = d.getUpBaseStatCache(c, mid, dt)
if err != nil {
log.Error("d.getUpBaseStatCache(%d) error(%v)", mid, err)
return
}
if st != nil {
return
}
// from hbase
if st, err = d.BaseUpStat(c, mid, dt); st != nil {
d.AddCache(func() {
d.setUpBaseStatCache(context.TODO(), mid, dt, st)
})
}
return
}

View File

@@ -0,0 +1,75 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
"go-common/app/interface/main/growup/model"
"go-common/library/net/metadata"
)
func TestDaoArticleStat(t *testing.T) {
convey.Convey("ArticleStat", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
ip = metadata.String(c, metadata.RemoteIP)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.ArticleStat(c, mid, ip)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestDaogetUpBaseStatCache(t *testing.T) {
convey.Convey("getUpBaseStatCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
date = "2018-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.getUpBaseStatCache(c, mid, date)
ctx.Convey("Then err should be nil.data should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestDaosetUpBaseStatCache(t *testing.T) {
convey.Convey("setUpBaseStatCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
date = "2018-01-01"
st = &model.UpBaseStat{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.setUpBaseStatCache(c, mid, date, st)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpStat(t *testing.T) {
convey.Convey("UpStat", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
dt = "20180101"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.UpStat(c, mid, dt)
ctx.Convey("Then err should be nil.st should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,87 @@
package dao
import (
"context"
"fmt"
"go-common/app/interface/main/growup/model"
"go-common/library/log"
xtime "go-common/library/time"
"go-common/library/xstr"
)
const (
// select
_avBreachSQL = "SELECT av_id, mid, cdate, money, ctype, reason FROM av_breach_record WHERE mid = ? AND cdate >= ? AND cdate <= ?"
_avBreachByAvIDSQL = "SELECT av_id, mid, cdate, money, reason FROM av_breach_record WHERE av_id in (%s) AND ctype = ?"
_avBreachByTypeSQL = "SELECT cdate, money FROM av_breach_record WHERE mid=? AND cdate >= ? AND cdate <= ? AND ctype in (%s)"
)
// ListAvBreach list av_breach_record by mid
func (d *Dao) ListAvBreach(c context.Context, mid int64, startTime, endTime string) (records []*model.AvBreach, err error) {
records = make([]*model.AvBreach, 0)
rows, err := d.db.Query(c, _avBreachSQL, mid, startTime, endTime)
if err != nil {
log.Error("ListAvBreach d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := &model.AvBreach{}
err = rows.Scan(&r.AvID, &r.MID, &r.CDate, &r.Money, &r.CType, &r.Reason)
if err != nil {
log.Error("ListAvBreach rows.Scan error(%v)", err)
return
}
records = append(records, r)
}
err = rows.Err()
return
}
// GetAvBreachByType get av breach record
func (d *Dao) GetAvBreachByType(c context.Context, mid int64, begin string, end string, typ []int64) (rs map[xtime.Time]int64, err error) {
if len(typ) == 0 {
typ = []int64{0, 1, 2, 3}
}
rows, err := d.db.Query(c, fmt.Sprintf(_avBreachByTypeSQL, xstr.JoinInts(typ)), mid, begin, end)
if err != nil {
log.Error("GetAvBreachByType d.db.Query error(%v)", err)
return
}
rs = make(map[xtime.Time]int64)
defer rows.Close()
for rows.Next() {
var cdate xtime.Time
var money int64
err = rows.Scan(&cdate, &money)
if err != nil {
log.Error("GetAvBreachByType rows.Scan error(%v)", err)
return
}
rs[cdate] += money
}
return
}
// GetAvBreachs get av_breach map by avids
func (d *Dao) GetAvBreachs(c context.Context, avs []int64, ctype int) (breachs map[int64]*model.AvBreach, err error) {
breachs = make(map[int64]*model.AvBreach)
rows, err := d.db.Query(c, fmt.Sprintf(_avBreachByAvIDSQL, xstr.JoinInts(avs)), ctype)
if err != nil {
log.Error("ListAvBreach d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := &model.AvBreach{}
if err = rows.Scan(&r.AvID, &r.MID, &r.CDate, &r.Money, &r.Reason); err != nil {
log.Error("ListAvBreach rows.Scan error(%v)", err)
return
}
breachs[r.AvID] = r
}
err = rows.Err()
return
}

View File

@@ -0,0 +1,65 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoListAvBreach(t *testing.T) {
convey.Convey("ListAvBreach", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
startTime = "2018-01-01"
endTime = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO av_breach_record(av_id, mid, cdate) VALUES(1000, 1001, '2018-06-01') ON DUPLICATE KEY UPDATE cdate = '2018-06-01'")
records, err := d.ListAvBreach(c, mid, startTime, endTime)
ctx.Convey("Then err should be nil.records should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(records, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetAvBreachByType(t *testing.T) {
convey.Convey("GetAvBreachByType", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1002)
begin = "2018-01-01"
end = "2019-01-01"
typ = []int64{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO av_breach_record(av_id, mid, cdate, ctype) VALUES(1001, 1002, '2018-06-01', 0) ON DUPLICATE KEY UPDATE cdate = '2018-06-01', ctype = 0")
rs, err := d.GetAvBreachByType(c, mid, begin, end, typ)
ctx.Convey("Then err should be nil.rs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetAvBreachs(t *testing.T) {
convey.Convey("GetAvBreachs", t, func(ctx convey.C) {
var (
c = context.Background()
avs = []int64{1000}
ctype = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO av_breach_record(av_id, mid, cdate, ctype) VALUES(1001, 1002, '2018-06-01', 0) ON DUPLICATE KEY UPDATE cdate = '2018-06-01', ctype = 0")
breachs, err := d.GetAvBreachs(c, avs, ctype)
ctx.Convey("Then err should be nil.breachs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(breachs, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,29 @@
package dao
import (
"context"
"database/sql"
"go-common/library/log"
"go-common/library/time"
"go-common/app/interface/main/growup/model"
)
const (
_bannerSQL = "SELECT id,image,link,start_at,end_at FROM banner WHERE start_at <= ? AND end_at >= ? LIMIT 1"
)
// Banner get banner
func (d *Dao) Banner(c context.Context, t int64) (b *model.Banner, err error) {
b = &model.Banner{}
row := d.db.QueryRow(c, _bannerSQL, time.Time(t), time.Time(t))
if err = row.Scan(&b.ID, &b.Image, &b.Link, &b.StartAt, &b.EndAt); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row scan error(%v)", err)
}
}
return
}

View File

@@ -0,0 +1,25 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoBanner(t *testing.T) {
convey.Convey("Banner", t, func(ctx convey.C) {
var (
c = context.Background()
no = int64(1541409804)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
b, err := d.Banner(c, no)
Exec(c, "INSERT INTO banner(id, start_at, end_at) VALUES(1000, '2018-01-01', '2019-01-01')")
ctx.Convey("Then err should be nil.b should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(b, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,111 @@
package dao
import (
"context"
"fmt"
"go-common/app/interface/main/growup/model"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_bgmCountSQL = "SELECT count(distinct sid) FROM background_music WHERE mid=?"
_bgmTitleSQL = "SELECT sid,title FROM background_music WHERE sid IN (%s)"
_bgmWhiteSQL = "SELECT COUNT(*) FROM bgm_white_list WHERE mid = ?"
_bgmIncomeByMIDSQL = "SELECT sid,income,total_income,date FROM bgm_income WHERE mid = ? AND date >= ? AND date <= ?"
_bgmIncomeBySIDSQL = "SELECT aid,income,date FROM bgm_income WHERE sid = ? AND date <= ?"
)
// BgmWhiteList bgm_white_list
func (d *Dao) BgmWhiteList(c context.Context, mid int64) (count int, err error) {
row := d.db.QueryRow(c, _bgmWhiteSQL, mid)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row scan error(%v)", err)
}
}
return
}
// BGMCount get up bgm count
func (d *Dao) BGMCount(c context.Context, mid int64) (count int, err error) {
row := d.db.QueryRow(c, _bgmCountSQL, mid)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row scan error(%v)", err)
}
}
return
}
// GetBgmTitle get bgm titles
func (d *Dao) GetBgmTitle(c context.Context, ids []int64) (titles map[int64]string, err error) {
titles = make(map[int64]string)
rows, err := d.db.Query(c, fmt.Sprintf(_bgmTitleSQL, xstr.JoinInts(ids)))
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
var sid int64
var title string
err = rows.Scan(&sid, &title)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
titles[sid] = title
}
return
}
// ListBgmIncome list bgm income
func (d *Dao) ListBgmIncome(c context.Context, mid int64, startTime, endTime string) (bgms []*model.ArchiveIncome, err error) {
bgms = make([]*model.ArchiveIncome, 0)
rows, err := d.db.Query(c, _bgmIncomeByMIDSQL, mid, startTime, endTime)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
bgm := &model.ArchiveIncome{}
err = rows.Scan(&bgm.ArchiveID, &bgm.Income, &bgm.TotalIncome, &bgm.Date)
if err != nil {
log.Error("ListColumnIncome rows.Scan error(%v)", err)
return
}
bgms = append(bgms, bgm)
}
err = rows.Err()
return
}
// ListBgmIncomeByID list bgm_income by sid
func (d *Dao) ListBgmIncomeByID(c context.Context, id int64, endTime string) (bgms []*model.ArchiveIncome, err error) {
bgms = make([]*model.ArchiveIncome, 0)
rows, err := d.db.Query(c, _bgmIncomeBySIDSQL, id, endTime)
if err != nil {
log.Error("ListBgmIncomeByID d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
bgm := &model.ArchiveIncome{}
err = rows.Scan(&bgm.ArchiveID, &bgm.Income, &bgm.Date)
if err != nil {
log.Error("ListBgmIncomeByID rows.Scan error(%v)", err)
return
}
bgms = append(bgms, bgm)
}
err = rows.Err()
return
}

View File

@@ -0,0 +1,79 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoBGMCount(t *testing.T) {
convey.Convey("BGMCount", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO background_music(sid, mid) VALUES(1000, 1001)")
count, err := d.BGMCount(c, mid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetBgmTitle(t *testing.T) {
convey.Convey("GetBgmTitle", t, func(ctx convey.C) {
var (
c = context.Background()
ids = []int64{1001}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO background_music(sid, mid, title) VALUES(1001, 1001, 'test')")
titles, err := d.GetBgmTitle(c, ids)
ctx.Convey("Then err should be nil.titles should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(titles, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListBgmIncome(t *testing.T) {
convey.Convey("ListBgmIncome", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
startTime = "2018-01-01"
endTime = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO bgm_income(sid, mid, total_income, date) VALUES(1000, 1001, 100, '2018-06-01')")
bgms, err := d.ListBgmIncome(c, mid, startTime, endTime)
ctx.Convey("Then err should be nil.bgms should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(bgms, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListBgmIncomeByID(t *testing.T) {
convey.Convey("ListBgmIncomeByID", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(1000)
endTime = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO bgm_income(sid, mid, total_income, date) VALUES(1000, 1001, 100, '2018-06-01')")
bgms, err := d.ListBgmIncomeByID(c, id, endTime)
ctx.Convey("Then err should be nil.bgms should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(bgms, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,85 @@
package dao
import (
"context"
"fmt"
"go-common/app/interface/main/growup/model"
"go-common/library/log"
"go-common/library/xstr"
)
const (
// select
_columnIncomeByMIDSQL = "SELECT aid, income, total_income, date FROM column_income WHERE mid = ? AND date >= ? AND date <= ?"
_columnIncomeByAvIDSQL = "SELECT income, date FROM column_income WHERE aid = ? AND date <= ?"
_columnStatisTitleSQL = "SELECT aid, title FROM column_income_statis WHERE aid in (%s)"
)
// ListColumnIncome list column_income by mid
func (d *Dao) ListColumnIncome(c context.Context, mid int64, startTime, endTime string) (columns []*model.ArchiveIncome, err error) {
columns = make([]*model.ArchiveIncome, 0)
rows, err := d.db.Query(c, _columnIncomeByMIDSQL, mid, startTime, endTime)
if err != nil {
log.Error("ListColumnIncome d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
column := &model.ArchiveIncome{}
err = rows.Scan(&column.ArchiveID, &column.Income, &column.TotalIncome, &column.Date)
if err != nil {
log.Error("ListColumnIncome rows.Scan error(%v)", err)
return
}
columns = append(columns, column)
}
err = rows.Err()
return
}
// ListColumnIncomeByID list column_income by aid
func (d *Dao) ListColumnIncomeByID(c context.Context, id int64, endTime string) (columns []*model.ArchiveIncome, err error) {
columns = make([]*model.ArchiveIncome, 0)
rows, err := d.db.Query(c, _columnIncomeByAvIDSQL, id, endTime)
if err != nil {
log.Error("ListColumnIncomeByID d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
column := &model.ArchiveIncome{}
err = rows.Scan(&column.Income, &column.Date)
if err != nil {
log.Error("ListColumnIncomeByID rows.Scan error(%v)", err)
return
}
columns = append(columns, column)
}
err = rows.Err()
return
}
// GetColumnTitle get column title by id
func (d *Dao) GetColumnTitle(c context.Context, ids []int64) (titles map[int64]string, err error) {
titles = make(map[int64]string)
rows, err := d.db.Query(c, fmt.Sprintf(_columnStatisTitleSQL, xstr.JoinInts(ids)))
if err != nil {
log.Error("GetColumnTitle d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var mid int64
var title string
err = rows.Scan(&mid, &title)
if err != nil {
log.Error("GetColumnTitle rows.Scan error(%v)", err)
return
}
titles[mid] = title
}
err = rows.Err()
return
}

View File

@@ -0,0 +1,62 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoListColumnIncome(t *testing.T) {
convey.Convey("ListColumnIncome", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
startTime = "2018-01-01"
endTime = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO column_income(aid, mid, total_income, date) VALUES(1000, 1001, 100, '2018-06-01')")
columns, err := d.ListColumnIncome(c, mid, startTime, endTime)
ctx.Convey("Then err should be nil.columns should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(columns, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListColumnIncomeByID(t *testing.T) {
convey.Convey("ListColumnIncomeByID", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(1000)
endTime = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO column_income(aid, mid, total_income, date) VALUES(1000, 1001, 100, '2018-06-01')")
columns, err := d.ListColumnIncomeByID(c, id, endTime)
ctx.Convey("Then err should be nil.columns should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(columns, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetColumnTitle(t *testing.T) {
convey.Convey("GetColumnTitle", t, func(ctx convey.C) {
var (
c = context.Background()
ids = []int64{1000}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO column_income_statis(aid, title) VALUES(1000, 'test')")
titles, err := d.GetColumnTitle(c, ids)
ctx.Convey("Then err should be nil.titles should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(titles, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,117 @@
package dao
import (
"context"
"time"
"go-common/app/interface/main/growup/conf"
article "go-common/app/interface/openplatform/article/rpc/client"
account "go-common/app/service/main/account/rpc/client"
vip "go-common/app/service/main/vip/rpc/client"
"go-common/library/cache/redis"
"go-common/library/database/hbase.v2"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
// Dao def dao struct
type Dao struct {
c *conf.Config
db *sql.DB
rddb *sql.DB
// redis
redis *redis.Pool
redisExpire int64
// search
httpRead *bm.Client
// rpc
acc *account.Service3
art *article.Service
vip *vip.Service
// hbase
hbase *hbase.Client
hbaseTimeOut time.Duration
// chan
missch chan func()
}
// New fn
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.DB.Growup),
rddb: sql.NewMySQL(c.DB.Allowance),
// redis
redis: redis.NewPool(c.Redis.Config),
redisExpire: int64(time.Duration(c.Redis.Expire) / time.Second),
// search
httpRead: bm.NewClient(c.HTTPClient.Read),
// rpc
acc: account.New3(c.AccountRPC),
art: article.New(c.ArticleRPC),
vip: vip.New(c.VipRPC),
// hbase
hbase: hbase.NewClient(c.HBase.Config),
hbaseTimeOut: time.Duration(time.Millisecond * 200),
// chan
missch: make(chan func(), 1024),
}
go d.cacheproc()
return d
}
// Ping ping db
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.db.Ping(c); err != nil {
log.Error("d.db.Ping error(%v)", err)
return
}
if err = d.pingRedis(c); err != nil {
log.Error("d.pingRedis error(%v)", err)
}
return
}
func (d *Dao) pingRedis(c context.Context) (err error) {
conn := d.redis.Get(c)
_, err = conn.Do("SET", "PING", "PONG")
conn.Close()
return
}
// Close close db conn
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
if d.redis != nil {
d.redis.Close()
}
if d.hbase != nil {
d.hbase.Close()
}
}
// BeginTran begin transcation
func (d *Dao) BeginTran(c context.Context) (tx *sql.Tx, err error) {
return d.db.Begin(c)
}
// AddCache add to chan for cache
func (d *Dao) AddCache(f func()) {
select {
case d.missch <- f:
default:
log.Warn("cacheproc chan full")
}
}
// cacheproc is a routine for execute closure.
func (d *Dao) cacheproc() {
for {
f := <-d.missch
f()
}
}

View File

@@ -0,0 +1,44 @@
package dao
import (
"context"
"flag"
"os"
"testing"
"go-common/app/interface/main/growup/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "mobile.studio.growup-interface")
flag.Set("conf_token", "c68ad4f01bc8c39a3fa6242623e79ffb")
flag.Set("tree_id", "13584")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/growup-interface.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}
func Exec(c context.Context, sql string) (rows int64, err error) {
res, err := d.db.Exec(c, sql)
if err != nil {
return
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,153 @@
package dao
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"net/url"
"strconv"
"go-common/app/interface/main/growup/model"
vip "go-common/app/service/main/vip/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
)
const (
_panelType = "incentive"
)
const (
_goodsInfoSQL = "SELECT ex_product_id,ex_resource_id,display_on_time,goods_type,discount FROM creative_goods WHERE is_display = ?"
_goodsResourceIDSQL = "SELECT ex_resource_id,discount,goods_type FROM creative_goods WHERE ex_product_id = ? AND goods_type = ? AND is_display = 2"
_goodsOrderSQL = "SELECT order_time,goods_name,goods_price,goods_cost FROM creative_order WHERE mid = ? ORDER BY order_time DESC LIMIT ?,?"
_goodsOrderCountSQL = "SELECT count(*) FROM creative_order WHERE mid = ?"
// insert
_txInGoodsOrderSQL = "INSERT INTO creative_order(mid,order_no,order_time,goods_type,goods_id,goods_name,goods_price,goods_cost) VALUES(?,?,?,?,?,?,?,?)"
)
// GetGoodsByProductID get goods by product id
func (d *Dao) GetGoodsByProductID(c context.Context, productID string, goodsType int) (goods *model.GoodsInfo, err error) {
goods = &model.GoodsInfo{}
err = d.db.QueryRow(c, _goodsResourceIDSQL, productID, goodsType).Scan(&goods.ResourceID, &goods.Discount, &goods.GoodsType)
if err == sql.ErrNoRows {
err = nil
}
return
}
// GetGoodsOrderCount get order count
func (d *Dao) GetGoodsOrderCount(c context.Context, mid int64) (count int, err error) {
err = d.db.QueryRow(c, _goodsOrderCountSQL, mid).Scan(&count)
if err == sql.ErrNoRows {
err = nil
}
return
}
// GetGoodsOrders get orders
func (d *Dao) GetGoodsOrders(c context.Context, mid int64, start, end int) (orders []*model.GoodsOrder, err error) {
orders = make([]*model.GoodsOrder, 0)
rows, err := d.db.Query(c, _goodsOrderSQL, mid, start, end)
if err != nil {
log.Error("d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
g := &model.GoodsOrder{}
err = rows.Scan(&g.OrderTime, &g.GoodsName, &g.GoodsPrice, &g.GoodsCost)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
orders = append(orders, g)
}
err = rows.Err()
return
}
// GetDisplayGoods get up from up_activity
func (d *Dao) GetDisplayGoods(c context.Context, isDisplay int) (goods []*model.GoodsInfo, err error) {
goods = make([]*model.GoodsInfo, 0)
rows, err := d.db.Query(c, _goodsInfoSQL, isDisplay)
if err != nil {
log.Error("d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
g := &model.GoodsInfo{}
err = rows.Scan(&g.ProductID, &g.ResourceID, &g.DisplayOnTime, &g.GoodsType, &g.Discount)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
goods = append(goods, g)
}
err = rows.Err()
return
}
// TxInsertGoodsOrder insert goods order
func (d *Dao) TxInsertGoodsOrder(tx *xsql.Tx, o *model.GoodsOrder) (rows int64, err error) {
res, err := tx.Exec(_txInGoodsOrderSQL, o.MID, o.OrderNo, o.OrderTime, o.GoodsType, o.GoodsID, o.GoodsName, o.GoodsPrice, o.GoodsCost)
if err != nil {
log.Error("d.db.Exec(%s) error(%v)", _txInGoodsOrderSQL, err)
return
}
return res.RowsAffected()
}
// ListVipProducts list vip products
func (d *Dao) ListVipProducts(c context.Context, mid int64) (r map[string]*model.GoodsInfo, err error) {
r = make(map[string]*model.GoodsInfo)
res, err := d.vip.VipPanelInfo5(c, &vip.ArgPanel{PanelType: _panelType, Mid: mid})
if err != nil {
log.Error("vipRPC.VipPanelInfo5 err(%v)", err)
return
}
if _, err = json.Marshal(res.Vps); err != nil {
log.Error("json.Marshal err(%v)", err)
return
}
for _, v := range res.Vps {
m := new(model.GoodsInfo)
m.ProductID = v.PdID
m.ProductName = v.PdName
// 大会员实时价格 = 激励兑换实时成本价; 单位元转换为单位分
m.OriginPrice = int64(Round(Mul(v.DPrice, float64(100)), 0))
m.Month = v.Month
r[v.PdID] = m
}
return
}
// ExchangeBigVIP exchange big vip
func (d *Dao) ExchangeBigVIP(c context.Context, mid, resourceID, orderNo int64, remark string) (err error) {
params := url.Values{}
params.Set("batchId", strconv.FormatInt(resourceID, 10))
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("orderNo", strconv.FormatInt(orderNo, 10))
params.Set("remark", remark)
var res struct {
Code int `json:"code"`
Message string `json:"message"`
}
url := d.c.Host.VipURI
if err = d.httpRead.Post(c, url, "", params, &res); err != nil {
log.Error("d.client.Post url(%s) error(%v)", url+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("ExchangeBigVIP code != 0. res.Code(%d) | url(%s) error(%v)", res.Code, url+"?"+params.Encode(), res.Message)
err = fmt.Errorf("ExchangeBigVIP error(%s)", res.Message)
}
return
}

View File

@@ -0,0 +1,110 @@
package dao
import (
"context"
"go-common/app/interface/main/growup/model"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetGoodsByProductID(t *testing.T) {
convey.Convey("GetGoodsByProductID", t, func(ctx convey.C) {
var (
c = context.Background()
productID = "aaaaa"
goodsType = int(1)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
Exec(c, "INSERT INTO creative_goods(ex_resource_id,discount,goods_type,is_display) values('aaaaa', 100, 1, 2)")
goods, err := d.GetGoodsByProductID(c, productID, goodsType)
ctx.Convey("Then err should be nil.goods should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(goods, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetDisplayGoods(t *testing.T) {
convey.Convey("GetDisplayGoods", t, func(ctx convey.C) {
var (
c = context.Background()
isDisplay = int(1)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
Exec(c, "INSERT INTO creative_goods(ex_resource_id,discount,goods_type,is_display) values('aaaaa', 100, 1, 2)")
goods, err := d.GetDisplayGoods(c, isDisplay)
ctx.Convey("Then err should be nil.goods should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(goods, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxInsertGoodsOrder(t *testing.T) {
convey.Convey("TxInsertGoodsOrder", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
o = &model.GoodsOrder{
MID: 253550886,
OrderNo: "DHY-20181122172812-1617825777068670976-253550886",
GoodsType: 1,
GoodsID: "incentive-1mon",
GoodsName: "月度大会员",
GoodsPrice: 100,
GoodsCost: 100,
}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
defer tx.Commit()
Exec(c, "DELETE FROM creative_order WHERE order_no = 'DHY-20181122172812-1617825777068670976-253550886'")
rows, err := d.TxInsertGoodsOrder(tx, o)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
ctx.Reset(func() {
tx.Commit()
})
})
}
func TestDaoListVipProducts(t *testing.T) {
convey.Convey("ListVipProducts", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(212312)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
r, err := d.ListVipProducts(c, mid)
ctx.Convey("Then err should be nil.r should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(r, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoExchangeBigVIP(t *testing.T) {
convey.Convey("ExchangeBigVIP", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(253550886)
resourceID = int64(16)
orderNo = time.Now().UnixNano()
remark = "creative"
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
err := d.ExchangeBigVIP(c, mid, resourceID, orderNo, remark)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,72 @@
package dao
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"strconv"
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/log"
"github.com/tsuna/gohbase/hrpc"
)
const (
// HBaseUpStatTablePrefix hbase up_stat_date
HBaseUpStatTablePrefix = "up_stats_"
)
func hbaseMd5Key(aid int64) string {
hasher := md5.New()
hasher.Write([]byte(strconv.Itoa(int(aid))))
return hex.EncodeToString(hasher.Sum(nil))
}
// BaseUpStat get base up stat.
func (d *Dao) BaseUpStat(c context.Context, mid int64, date string) (stat *model.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 = &model.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,38 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaohbaseMd5Key(t *testing.T) {
convey.Convey("hbaseMd5Key", t, func(ctx convey.C) {
var (
aid = int64(1000)
)
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 TestDaoBaseUpStat(t *testing.T) {
convey.Convey("BaseUpStat", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1000)
date = "2018-06-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, 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)
})
})
})
}

View File

@@ -0,0 +1,235 @@
package dao
import (
"context"
"database/sql"
"fmt"
"go-common/app/interface/main/growup/model"
"go-common/library/log"
"go-common/library/time"
"go-common/library/xstr"
)
const (
// select
_avIncomeByMIDSQL = "SELECT av_id, income, total_income, date FROM av_income WHERE mid = ? AND date >= ? AND date <= ?"
_avIncomeByAvIDSQL = "SELECT income, date FROM av_income WHERE av_id = ? AND date <= ?"
_blacklistByAvIDSQL = "SELECT av_id FROM av_black_list WHERE av_id in (%s) AND ctype = ? AND is_delete = 0"
_activityInfoByAvIDSQL = "SELECT archive_id, tag_id FROM activity_info WHERE archive_id in (%s)"
_tagInfoByTagIDSQL = "SELECT id, ratio, icon FROM tag_info WHERE id in (%s) and is_deleted = 0"
_upIncomeTableSQL = "SELECT mid,income,av_income,column_income,bgm_income,total_income,base_income,av_base_income,column_base_income,bgm_base_income,date FROM %s WHERE mid = ? AND date >= ? AND date <= ? AND is_deleted = 0"
_upAccountSQL = "SELECT mid, total_income, total_unwithdraw_income, withdraw_date_version, version FROM up_account WHERE mid = ? AND is_deleted = 0"
_upIncomeSQL = "SELECT mid,base_income,income,date FROM up_income WHERE mid=? AND date>=? AND date <=? ORDER BY date"
_firstUpIncomeSQL = "SELECT date FROM up_income WHERE mid = ? ORDER BY date LIMIT 1"
_upIncomeCountSQL = "SELECT count(*) FROM up_income WHERE date = ?"
_upDailyCharge = "SELECT inc_charge FROM up_daily_charge WHERE mid=? AND date>=?"
)
// GetUpDailyCharge get up daily charge
func (d *Dao) GetUpDailyCharge(c context.Context, mid int64, begin string) (incs []int, err error) {
rows, err := d.db.Query(c, _upDailyCharge, mid, begin)
if err != nil {
log.Error("GetUpDailyCharge d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var incCharge int
err = rows.Scan(&incCharge)
if err != nil {
log.Error("rows Scan error(%v)", err)
return
}
incs = append(incs, incCharge)
}
return
}
// ListAvIncome list av_income by mid
func (d *Dao) ListAvIncome(c context.Context, mid int64, startTime, endTime string) (avs []*model.ArchiveIncome, err error) {
avs = make([]*model.ArchiveIncome, 0)
rows, err := d.db.Query(c, _avIncomeByMIDSQL, mid, startTime, endTime)
if err != nil {
log.Error("ListAvIncome d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
av := &model.ArchiveIncome{}
err = rows.Scan(&av.ArchiveID, &av.Income, &av.TotalIncome, &av.Date)
if err != nil {
log.Error("ListAvIncome rows scan error(%v)", err)
return
}
avs = append(avs, av)
}
err = rows.Err()
return
}
// ListAvIncomeByID list av_income by av_id
func (d *Dao) ListAvIncomeByID(c context.Context, avID int64, endTime string) (avs []*model.ArchiveIncome, err error) {
avs = make([]*model.ArchiveIncome, 0)
rows, err := d.db.Query(c, _avIncomeByAvIDSQL, avID, endTime)
if err != nil {
log.Error("ListAvIncomeByID d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
av := &model.ArchiveIncome{}
err = rows.Scan(&av.Income, &av.Date)
if err != nil {
log.Error("ListAvIncomeByID rows scan error(%v)", err)
return
}
avs = append(avs, av)
}
err = rows.Err()
return
}
// ListAvBlackList list av_blakc_list by av_id
func (d *Dao) ListAvBlackList(c context.Context, avIds []int64, typ int) (avb map[int64]struct{}, err error) {
avb = make(map[int64]struct{})
rows, err := d.db.Query(c, fmt.Sprintf(_blacklistByAvIDSQL, xstr.JoinInts(avIds)), typ)
if err != nil {
log.Error("ListBlackList d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var avID int64
err = rows.Scan(&avID)
if err != nil {
log.Error("ListBlackList rows scan error(%v)", err)
return
}
avb[avID] = struct{}{}
}
err = rows.Err()
return
}
// ListActiveInfo list active_info by avid
func (d *Dao) ListActiveInfo(c context.Context, avIds []int64) (acM map[int64]int64, err error) {
acM = make(map[int64]int64)
rows, err := d.db.Query(c, fmt.Sprintf(_activityInfoByAvIDSQL, xstr.JoinInts(avIds)))
if err != nil {
log.Error("ListActiveInfo d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var avID, tagID int64
err = rows.Scan(&avID, &tagID)
if err != nil {
log.Error("ListActiveInfo rows scan error(%v)", err)
return
}
acM[avID] = tagID
}
err = rows.Err()
return
}
// ListTagInfo list tag_info by avid
func (d *Dao) ListTagInfo(c context.Context, tagIds []int64) (tagM map[int64]*model.TagInfo, err error) {
tagM = make(map[int64]*model.TagInfo)
rows, err := d.db.Query(c, fmt.Sprintf(_tagInfoByTagIDSQL, xstr.JoinInts(tagIds)))
if err != nil {
log.Error("ListTagInfo d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
tagInfo := model.TagInfo{}
err = rows.Scan(&tagInfo.ID, &tagInfo.Radio, &tagInfo.Icon)
if err != nil {
log.Error("ListTagInfo rows scan error(%v)", err)
return
}
if val, ok := tagM[tagInfo.ID]; !ok {
tagM[tagInfo.ID] = &tagInfo
} else {
if val.Radio < tagInfo.Radio {
tagM[tagInfo.ID] = &tagInfo
}
}
}
err = rows.Err()
return
}
// ListUpIncome list up_income by mid
func (d *Dao) ListUpIncome(c context.Context, mid int64, table, startTime, endTime string) (ups []*model.UpIncome, err error) {
ups = make([]*model.UpIncome, 0)
rows, err := d.db.Query(c, fmt.Sprintf(_upIncomeTableSQL, table), mid, startTime, endTime)
if err != nil {
log.Error("ListUpIncome d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
up := &model.UpIncome{}
err = rows.Scan(&up.MID, &up.Income, &up.AvIncome, &up.ColumnIncome, &up.BgmIncome, &up.TotalIncome, &up.BaseIncome, &up.AvBaseIncome, &up.ColumnBaseIncome, &up.BgmBaseIncome, &up.Date)
if err != nil {
log.Error("ListUpIncome rows scan error(%v)", err)
return
}
ups = append(ups, up)
}
err = rows.Err()
return
}
// ListUpAccount list up_account by mid
func (d *Dao) ListUpAccount(c context.Context, mid int64) (up *model.UpAccount, err error) {
up = &model.UpAccount{}
row := d.db.QueryRow(c, _upAccountSQL, mid)
if err = row.Scan(&up.MID, &up.TotalIncome, &up.TotalUnwithdrawIncome, &up.WithdrawDateVersion, &up.Version); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
log.Error("row.Scan error(%v)", err)
}
return
}
// GetUpIncome list up income by date
func (d *Dao) GetUpIncome(c context.Context, mid int64, begin string, end string) (result []*model.UpIncomeStat, err error) {
rows, err := d.db.Query(c, _upIncomeSQL, mid, begin, end)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
stat := &model.UpIncomeStat{}
err = rows.Scan(&stat.MID, &stat.BaseIncome, &stat.Income, &stat.Date)
if err != nil {
return
}
stat.ExtraIncome = stat.Income - stat.BaseIncome
result = append(result, stat)
}
return
}
// GetFirstUpIncome get first up income
func (d *Dao) GetFirstUpIncome(c context.Context, mid int64) (date time.Time, err error) {
err = d.db.QueryRow(c, _firstUpIncomeSQL, mid).Scan(&date)
if err == sql.ErrNoRows {
err = nil
date = time.Time(0)
}
return
}
// GetUpIncomeCount get up income count by date
func (d *Dao) GetUpIncomeCount(c context.Context, date string) (count int, err error) {
err = d.db.QueryRow(c, _upIncomeCountSQL, date).Scan(&count)
return
}

View File

@@ -0,0 +1,188 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetUpDailyCharge(t *testing.T) {
convey.Convey("GetUpDailyCharge", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
begin = "2018-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_daily_charge(mid, date, inc_charge) VALUES(1001, '2018-06-01', 100)")
incs, err := d.GetUpDailyCharge(c, mid, begin)
ctx.Convey("Then err should be nil.incs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(incs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListAvIncome(t *testing.T) {
convey.Convey("ListAvIncome", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
startTime = "2018-01-01"
endTime = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO av_income(av_id, mid, date, income) VALUES(1000, 1001, '2018-06-01', 100)")
avs, err := d.ListAvIncome(c, mid, startTime, endTime)
ctx.Convey("Then err should be nil.avs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(avs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListAvIncomeByID(t *testing.T) {
convey.Convey("ListAvIncomeByID", t, func(ctx convey.C) {
var (
c = context.Background()
avID = int64(1000)
endTime = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO av_income(av_id, mid, date, income) VALUES(1000, 1001, '2018-06-01', 100)")
avs, err := d.ListAvIncomeByID(c, avID, endTime)
ctx.Convey("Then err should be nil.avs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(avs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListAvBlackList(t *testing.T) {
convey.Convey("ListAvBlackList", t, func(ctx convey.C) {
var (
c = context.Background()
avIds = []int64{1000}
typ = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO av_black_list(av_id, ctype) VALUES(1000, 0) ON DUPLICATE KEY UPDATE ctype = 0")
avb, err := d.ListAvBlackList(c, avIds, typ)
ctx.Convey("Then err should be nil.avb should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(avb, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListActiveInfo(t *testing.T) {
convey.Convey("ListActiveInfo", t, func(ctx convey.C) {
var (
c = context.Background()
avIds = []int64{1000}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO activity_info(archive_id, tag_id) VALUES(1000, 1)")
acM, err := d.ListActiveInfo(c, avIds)
ctx.Convey("Then err should be nil.acM should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(acM, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListTagInfo(t *testing.T) {
convey.Convey("ListTagInfo", t, func(ctx convey.C) {
var (
c = context.Background()
tagIds = []int64{1000}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO tag_info(id, ratio, icon) VALUES(1000, 10, 'aaaaaa')")
tagM, err := d.ListTagInfo(c, tagIds)
ctx.Convey("Then err should be nil.tagM should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(tagM, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListUpIncome(t *testing.T) {
convey.Convey("ListUpIncome", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
table = "up_income"
startTime = "2018-01-01"
endTime = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_income(mid, date) VALUES(1001, '2018-06-01')")
ups, err := d.ListUpIncome(c, mid, table, startTime, endTime)
ctx.Convey("Then err should be nil.ups should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ups, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoListUpAccount(t *testing.T) {
convey.Convey("ListUpAccount", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_account(mid, is_deleted) VALUES(1001, 0) ON DUPLICATE KEY UPDATE is_deleted = 0")
up, err := d.ListUpAccount(c, mid)
ctx.Convey("Then err should be nil.up should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(up, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetUpIncome(t *testing.T) {
convey.Convey("GetUpIncome", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
begin = "2018-01-01"
end = "2019-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_income(mid, date) VALUES(1001, '2018-06-01')")
result, err := d.GetUpIncome(c, mid, begin, end)
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 TestDaoGetUpIncomeCount(t *testing.T) {
convey.Convey("GetUpIncomeCount", t, func(ctx convey.C) {
var (
c = context.Background()
date = "2018-06-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_income(mid, date) VALUES(1001, '2018-06-01')")
count, err := d.GetUpIncomeCount(c, date)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,69 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"account.go",
"activity.go",
"category.go",
"dao.go",
"recommend_up.go",
"relation.go",
"video_up.go",
],
importpath = "go-common/app/interface/main/growup/dao/newbiedao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/growup/conf:go_default_library",
"//app/interface/main/growup/model:go_default_library",
"//app/service/main/account/api:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_test",
srcs = [
"account_test.go",
"activity_test.go",
"category_test.go",
"dao_test.go",
"recommend_up_test.go",
"relation_test.go",
"video_up_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/interface/main/growup/conf:go_default_library",
"//app/interface/main/growup/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,38 @@
package newbiedao
import (
"context"
accApi "go-common/app/service/main/account/api"
"go-common/library/ecode"
"go-common/library/log"
)
// GetInfo get info
func (d *Dao) GetInfo(c context.Context, mid int64) (res *accApi.InfoReply, err error) {
res, err = d.accGRPC.Info3(c, &accApi.MidReq{Mid: mid})
if err != nil {
return
}
if res == nil || res.Info == nil {
err = ecode.GrowupUpInfoNotExist
log.Error("s.dao.GetInfo get up info is empty")
return
}
return
}
// GetInfos get infos
func (d *Dao) GetInfos(c context.Context, mids []int64) (res *accApi.InfosReply, err error) {
res, err = d.accGRPC.Infos3(c, &accApi.MidsReq{Mids: mids})
if err != nil {
return
}
if res == nil {
err = ecode.GrowupUpInfoNotExist
log.Error("s.dao.GetInfos get ups info are empty")
return
}
return
}

View File

@@ -0,0 +1,40 @@
package newbiedao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestNewbiedaoGetInfo(t *testing.T) {
convey.Convey("GetInfo", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(27515398)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.GetInfo(c, mid)
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 TestNewbiedaoGetInfos(t *testing.T) {
convey.Convey("GetInfo", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{27515398}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.GetInfos(c, mids)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,36 @@
package newbiedao
import (
"context"
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/log"
//"go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
"net/url"
)
// const text
const (
// ActivityTypeVideo type "videoall"
ActivityTypeVideo = "videoall"
)
// GetActivities get activities
func (d *Dao) GetActivities(c context.Context) (res []*model.Activity, err error) {
activitiesRes := new(model.ActivitiesRes)
err = d.httpRead.Get(c, d.c.Host.ActivitiesURI+ActivityTypeVideo, metadata.String(c, metadata.RemoteIP), url.Values{}, &activitiesRes)
if err != nil {
log.Error("s.dao.GetActivities error(%v)", err)
return
}
if activitiesRes.Code != ecode.OK.Code() {
err = ecode.Int(activitiesRes.Code)
log.Error("s.dao.GetActivities get activities failed, ecode: %d", activitiesRes.Code)
return
}
res = activitiesRes.Data
return
}

View File

@@ -0,0 +1,23 @@
package newbiedao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestNewbiedaoGetActivities(t *testing.T) {
convey.Convey("GetActivities", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.GetActivities(c)
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,32 @@
package newbiedao
import (
"context"
"github.com/pkg/errors"
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"net/url"
)
// GetCategories get categories
func (d *Dao) GetCategories(c context.Context) (err error) {
categoriesRes := new(model.CategoriesRes)
err = d.httpRead.Get(c, d.c.Host.CategoriesURI, metadata.String(c, metadata.RemoteIP), url.Values{}, categoriesRes)
if err != nil {
log.Error("s.dao.GetCategories error(%v)", err)
return
}
if categoriesRes.Code != ecode.OK.Code() || len(categoriesRes.Data) <= 0 {
err = errors.Wrap(ecode.Int(categoriesRes.Code), "get categories failed")
log.Error("s.dao.GetCategories failed, ecode: %d", categoriesRes.Code)
return
}
Categories = categoriesRes.Data
return
}

View File

@@ -0,0 +1,22 @@
package newbiedao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestNewbiedaoGetCategories(t *testing.T) {
convey.Convey("GetCategories", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.GetCategories(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,80 @@
package newbiedao
import (
"context"
"time"
"go-common/app/interface/main/growup/conf"
"go-common/app/interface/main/growup/model"
accApi "go-common/app/service/main/account/api"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
var (
// Categories cache categories
Categories map[int64]*model.Category
// RecommendUpList cache recommend up list
RecommendUpList map[int64]map[int64]*model.RecommendUp
)
// Dao def dao struct
type Dao struct {
c *conf.Config
db *sql.DB
// search
httpRead *bm.Client
// grpc
accGRPC accApi.AccountClient
}
// New fn
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.DB.Growup),
// search
httpRead: bm.NewClient(c.HTTPClient.Read),
}
var err error
if d.accGRPC, err = accApi.NewClient(c.AccCliConf); err != nil {
panic(err)
}
d.loadCache()
go func() {
t := time.Tick(10 * time.Minute)
for {
d.loadCache()
<-t
}
}()
return d
}
// Ping ping db
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.db.Ping(c); err != nil {
log.Error("d.db.Ping error(%v)", err)
return
}
return
}
// Close close db conn
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
}
// loodCache load cache
func (d *Dao) loadCache() {
_ = d.GetCategories(context.Background())
log.Info("refresh categories cache: %+v", Categories)
_ = d.GetRecommendUpList(context.Background())
log.Info("refresh recommend up list cache: %+v", RecommendUpList)
}

View File

@@ -0,0 +1,37 @@
package newbiedao
import (
"flag"
"go-common/app/interface/main/growup/conf"
"os"
"testing"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "mobile.studio.growup-interface")
flag.Set("conf_token", "c68ad4f01bc8c39a3fa6242623e79ffb")
flag.Set("tree_id", "13584")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../../cmd/growup-interface.toml")
}
if os.Getenv("UT_LOCAL_TEST") != "" {
flag.Set("conf", "../../cmd/growup-interface.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,37 @@
package newbiedao
import (
"context"
"go-common/app/interface/main/growup/model"
"go-common/library/log"
)
const _RecommendUpSql = "SELECT mid, tid FROM recommend_up_white"
// GetRecommendUpList get recommend up list
func (d *Dao) GetRecommendUpList(c context.Context) error {
recUps := make(map[int64]map[int64]*model.RecommendUp)
rows, err := d.db.Query(c, _RecommendUpSql)
if err != nil {
log.Error("d.db.Query recommend up error(%v)", err)
return err
}
defer rows.Close()
for rows.Next() {
recUp := new(model.RecommendUp)
err = rows.Scan(&recUp.Mid, &recUp.Tid)
if err != nil {
log.Error("rows scan error(%v)", err)
return err
}
if _, ok := recUps[recUp.Tid]; !ok {
recUps[recUp.Tid] = make(map[int64]*model.RecommendUp)
}
recUps[recUp.Tid][recUp.Mid] = recUp
}
RecommendUpList = recUps
return nil
}

View File

@@ -0,0 +1,22 @@
package newbiedao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestNewbiedaoGetRecommendUpList(t *testing.T) {
convey.Convey("GetRecommendUpList", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.GetRecommendUpList(c)
ctx.Convey("Then err should be nil.recUps should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,36 @@
package newbiedao
import (
"context"
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/library/xstr"
"net/url"
"strconv"
)
// GetRelations get relations
func (d *Dao) GetRelations(c context.Context, mid int64, fids []int64) (res map[int64]*model.Relation, err error) {
relationsRes := new(model.RelationsRes)
uv := url.Values{}
uv.Set("mid", strconv.FormatInt(mid, 10))
uv.Set("fids", xstr.JoinInts(fids))
err = d.httpRead.Get(c, d.c.Host.RelationsURI, metadata.String(c, metadata.RemoteIP), uv, relationsRes)
if err != nil {
log.Error("s.dao.GetRelations error(%v)", err)
return
}
if relationsRes.Code != ecode.OK.Code() {
err = ecode.Int(relationsRes.Code)
log.Error("s.dao.GetRelations get relations failed, ecode: %d", relationsRes.Code)
return
}
res = relationsRes.Data
return
}

View File

@@ -0,0 +1,25 @@
package newbiedao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestNewbiedaoGetRelations(t *testing.T) {
convey.Convey("GetRelations", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(27515398)
fids = []int64{389088, 6810019, 4578433}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.GetRelations(c, mid, fids)
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,37 @@
package newbiedao
import (
"context"
"github.com/pkg/errors"
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"net/url"
"strconv"
)
// GetVideoUp get video up
func (d *Dao) GetVideoUp(c context.Context, aid int64) (videoUpArchive *model.VideoUpArchive, err error) {
uv := url.Values{}
uv.Set("aid", strconv.FormatInt(aid, 10))
videoUpRes := new(model.VideoUpRes)
err = d.httpRead.Get(c, d.c.Host.VideoUpURI, metadata.String(c, metadata.RemoteIP), uv, videoUpRes)
if err != nil {
log.Error("s.dao.GetVideoUp error(%v)", err)
return
}
if videoUpRes.Code != ecode.OK.Code() {
err = errors.Wrap(ecode.Int(videoUpRes.Code), "get video up failed")
log.Error("s.dao.GetVideoUp get video up failed, ecode: %d", videoUpRes.Code)
return
}
if videoUpRes.Data == nil || videoUpRes.Data.Archive == nil {
err = errors.Wrap(ecode.Int(videoUpRes.Code), "get video up nil")
log.Error("s.dao.GetVideoUp get video up is empty")
return
}
videoUpArchive = videoUpRes.Data.Archive
return
}

View File

@@ -0,0 +1,25 @@
package newbiedao
import (
"context"
"go-common/app/interface/main/growup/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestNewbiedaoGetVideoUp(t *testing.T) {
convey.Convey("GetVideoUp", t, func(ctx convey.C) {
var (
c = context.Background()
req = &model.NewbieLetterReq{Aid: 10110467, Mid: 27515398}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
videoUpArchive, err := d.GetVideoUp(c, req.Aid)
ctx.Convey("Then err should be nil.videoUpArchive should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(videoUpArchive, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,60 @@
package dao
import (
"context"
"database/sql"
"fmt"
"go-common/library/log"
"go-common/app/interface/main/growup/model"
)
const (
_latestNoticeSQL = "SELECT title,link,type FROM notice WHERE status = 1 AND platform IN (?, 3) ORDER BY mtime DESC LIMIT 1"
_noticeSQL = "SELECT id,title,link,ctime,type FROM notice WHERE %s platform IN (?, 3) AND status=1 ORDER BY mtime DESC LIMIT ?,?"
_noticeCountSQL = "SELECT count(*) from notice WHERE %s platform IN (?, 3) AND status=1"
)
// LatestNotice latest notice
func (d *Dao) LatestNotice(c context.Context, platform int) (n *model.Notice, err error) {
row := d.rddb.QueryRow(c, _latestNoticeSQL, platform)
n = &model.Notice{}
if err = row.Scan(&n.Title, &n.Link, &n.Type); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row scan error(%v)", err)
}
}
return
}
// Notices notices
func (d *Dao) Notices(c context.Context, typ string, platform int, offset, limit int) (notices []*model.Notice, err error) {
rows, err := d.rddb.Query(c, fmt.Sprintf(_noticeSQL, typ), platform, offset, limit)
if err != nil {
log.Error("d.db.Query Notices error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
n := &model.Notice{}
err = rows.Scan(&n.ID, &n.Title, &n.Link, &n.CTime, &n.Type)
if err != nil {
log.Error("rows scan error(%v)", err)
return
}
notices = append(notices, n)
}
return
}
// NoticeCount notice count
func (d *Dao) NoticeCount(c context.Context, typ string, platform int) (count int64, err error) {
row := d.rddb.QueryRow(c, fmt.Sprintf(_noticeCountSQL, typ), platform)
if err = row.Scan(&count); err != nil {
log.Error("row scan error(%v)", err)
}
return
}

View File

@@ -0,0 +1,63 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoLatestNotice(t *testing.T) {
convey.Convey("LatestNotice", t, func(ctx convey.C) {
var (
c = context.Background()
platform = int(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO notice(status, platform, title, type) VALUES(1, 3, 'test', 0)")
n, err := d.LatestNotice(c, platform)
ctx.Convey("Then err should be nil.n should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(n, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoNotices(t *testing.T) {
convey.Convey("Notices", t, func(ctx convey.C) {
var (
c = context.Background()
typ = ""
platform = int(3)
offset = int(0)
limit = int(100)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO notice(status, platform, title, type) VALUES(1, 3, 'test', 0)")
notices, err := d.Notices(c, typ, platform, offset, limit)
ctx.Convey("Then err should be nil.notices should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(notices, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoNoticeCount(t *testing.T) {
convey.Convey("NoticeCount", t, func(ctx convey.C) {
var (
c = context.Background()
typ = ""
platform = int(3)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO notice(status, platform, title, type) VALUES(1, 3, 'test', 0)")
count, err := d.NoticeCount(c, typ, platform)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,99 @@
package dao
import (
"context"
"encoding/json"
"go-common/library/cache/redis"
"go-common/library/log"
)
// SetIncomeCache set income cache
func (d *Dao) SetIncomeCache(c context.Context, key string, value map[string]interface{}) (err error) {
v, err := json.Marshal(value)
if err != nil {
log.Error("json.Marshal error(%v)", err)
return
}
return d.setCacheKV(c, key, v, d.redisExpire)
}
// GetIncomeCache get income cache
func (d *Dao) GetIncomeCache(c context.Context, key string) (data map[string]interface{}, err error) {
res, err := d.getCacheVal(c, key)
if err != nil {
log.Error("d.getCacheVal error(%v)", err)
return
}
if res == nil {
return
}
err = json.Unmarshal(res, &data)
if err != nil {
log.Error("json.Unmarshal(%v) error(%v)", res, err)
}
return
}
// DelCacheKey del redis key
func (d *Dao) DelCacheKey(c context.Context, key string) (err error) {
return d.delCacheKey(c, key)
}
func (d *Dao) setCacheKV(c context.Context, key string, value []byte, expire int64) (err error) {
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("SET", key, value); err != nil {
log.Error("conn.Send(SET, %s, %s) error(%v)", key, value, err)
return
}
if err = conn.Send("EXPIRE", key, d.redisExpire); err != nil {
log.Error("conn.Send(Expire, %s, %d) error(%v)", key, d.redisExpire, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}
func (d *Dao) getCacheVal(c context.Context, key string) (res []byte, err error) {
conn := d.redis.Get(c)
defer conn.Close()
if res, err = redis.Bytes(conn.Do("GET", key)); err != nil {
if err == redis.ErrNil {
res, err = nil, nil
} else {
log.Error("conn.Do(GET, %s) error(%v)", key, err)
}
return
}
return
}
func (d *Dao) delCacheKey(c context.Context, key string) (err error) {
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("DEL", key); err != nil {
log.Error("conn.Send(DEL, %s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
}
return
}

View File

@@ -0,0 +1,73 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSetIncomeCache(t *testing.T) {
convey.Convey("SetIncomeCache", t, func(ctx convey.C) {
var (
c = context.Background()
key = "100"
value = map[string]interface{}{
"aa": "bb",
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetIncomeCache(c, key, value)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetIncomeCache(t *testing.T) {
convey.Convey("GetIncomeCache", t, func(ctx convey.C) {
var (
c = context.Background()
key = "100"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.GetIncomeCache(c, key)
ctx.Convey("Then err should be nil.data should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestDaosetCacheKV(t *testing.T) {
convey.Convey("setCacheKV", t, func(ctx convey.C) {
var (
c = context.Background()
key = "200"
value = []byte("aaaaaa")
expire = int64(100)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.setCacheKV(c, key, value, expire)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestDaogetCacheVal(t *testing.T) {
convey.Convey("getCacheVal", t, func(ctx convey.C) {
var (
c = context.Background()
key = "200"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.getCacheVal(c, key)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,305 @@
package dao
import (
"context"
"database/sql"
"fmt"
"go-common/app/interface/main/growup/model"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_openAwardsSQL = "SELECT award_id,award_name,cycle_start FROM special_award WHERE open_status=2"
_joinedAwardsSQL = "SELECT award_id,award_name,cycle_start,cycle_end,open_status FROM special_award WHERE award_id IN (%s)"
_awardScheSQL = "SELECT award_name,cycle_start,cycle_end,announce_date FROM special_award WHERE award_id=?"
_awardResourceSQL = "SELECT resource_type,content,resource_index FROM special_award_resource WHERE award_id=? AND is_deleted=0"
_awardWinnerSQL = "SELECT mid FROM special_award_winner WHERE award_id=? AND is_deleted=0"
_winnerIDsSQL = "SELECT award_id,prize_id FROM special_award_winner WHERE mid=? AND is_deleted=0"
_winnerDivisionSQL = "SELECT award_id,division_name FROM special_award_winner WHERE mid=? AND is_deleted=0"
_awardBonusSQL = "SELECT bonus FROM special_award_prize WHERE award_id=? AND prize_id=?"
_inSpecialAwardRecordSQL = "INSERT INTO special_award_record(mid,award_id) VALUES(?,?)"
_joinedCountSQL = "SELECT count(*) FROM special_award_record WHERE mid=? AND award_id=?"
_specialAwardsSQL = "SELECT award_id, award_name, cycle_start, cycle_end, announce_date FROM special_award WHERE display_status = 2 AND is_deleted = 0"
_awardDivisionSQL = "SELECT division_name FROM special_award_division WHERE award_id = ? AND is_deleted = 0"
_awardWinRecordSQL = "SELECT award_id FROM special_award_winner WHERE mid = ? AND is_deleted = 0"
_awardJoinRecordSQL = "SELECT award_id FROM special_award_record WHERE mid = ? AND is_deleted = 0"
)
// PastAwards get award basic info
func (d *Dao) PastAwards(c context.Context) (as []*model.SimpleSpecialAward, err error) {
rows, err := d.db.Query(c, _openAwardsSQL)
if err != nil {
return
}
defer rows.Close()
as = make([]*model.SimpleSpecialAward, 0)
for rows.Next() {
a := &model.SimpleSpecialAward{}
err = rows.Scan(&a.AwardID, &a.AwardName, &a.CycleStart)
if err != nil {
return
}
as = append(as, a)
}
err = rows.Err()
return
}
// JoinedSpecialAwards get joined awards
func (d *Dao) JoinedSpecialAwards(c context.Context, awardIDs []int64) (sas []*model.SpecialAward, err error) {
rows, err := d.db.Query(c, fmt.Sprintf(_joinedAwardsSQL, xstr.JoinInts(awardIDs)))
if err != nil {
return
}
defer rows.Close()
sas = make([]*model.SpecialAward, 0)
for rows.Next() {
sa := &model.SpecialAward{}
err = rows.Scan(&sa.AwardID, &sa.AwardName, &sa.CycleStart, &sa.CycleEnd, &sa.OpenStatus)
if err != nil {
log.Error("row scan error(%v)", err)
return
}
sas = append(sas, sa)
}
err = rows.Err()
return
}
// GetAwardSchedule get special award by award id
func (d *Dao) GetAwardSchedule(c context.Context, awardID int64) (award *model.SpecialAward, err error) {
award = &model.SpecialAward{}
row := d.db.QueryRow(c, _awardScheSQL, awardID)
if err = row.Scan(&award.AwardName, &award.CycleStart, &award.CycleEnd, &award.AnnounceDate); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row scan error(%v)", err)
}
}
return
}
// GetResources get special award resource map[type]map[index]content
func (d *Dao) GetResources(c context.Context, awardID int64) (res map[int]map[int]string, err error) {
rows, err := d.db.Query(c, _awardResourceSQL, awardID)
if err != nil {
log.Error("GetResources d.db.Query error(%v)", err)
return
}
defer rows.Close()
res = make(map[int]map[int]string)
for rows.Next() {
var rtype, index int
var content string
err = rows.Scan(&rtype, &content, &index)
if err != nil {
log.Error("GetDivisions rows.Scan error(%v)", err)
return
}
if cs, ok := res[rtype]; ok {
cs[index] = content
} else {
m := make(map[int]string)
m[index] = content
res[rtype] = m
}
}
err = rows.Err()
return
}
// GetWinners get winner mids by award_id
func (d *Dao) GetWinners(c context.Context, awardID int64) (mids []int64, err error) {
rows, err := d.db.Query(c, _awardWinnerSQL, awardID)
if err != nil {
log.Error("GetWinners d.db.Query error(%v)", err)
return
}
defer rows.Close()
mids = make([]int64, 0)
for rows.Next() {
var mid int64
err = rows.Scan(&mid)
if err != nil {
log.Error("GetWinners rows.Scan error(%v)", err)
return
}
mids = append(mids, mid)
}
err = rows.Err()
return
}
// AwardIDsByWinner get winner's record, am map[award_id]prize_id
func (d *Dao) AwardIDsByWinner(c context.Context, mid int64) (am map[int64]int64, err error) {
rows, err := d.db.Query(c, _winnerIDsSQL, mid)
if err != nil {
return
}
defer rows.Close()
am = make(map[int64]int64)
for rows.Next() {
var awardID, prizeID int64
err = rows.Scan(&awardID, &prizeID)
if err != nil {
log.Error("rows scan error(%v)", err)
return
}
am[awardID] = prizeID
}
err = rows.Err()
return
}
// DivisionName division name by mid, names map[award_id]division_name
func (d *Dao) DivisionName(c context.Context, mid int64) (names map[int64]string, err error) {
rows, err := d.db.Query(c, _winnerDivisionSQL, mid)
if err != nil {
return
}
defer rows.Close()
names = make(map[int64]string)
for rows.Next() {
var awardID int64
var name string
err = rows.Scan(&awardID, &name)
if err != nil {
log.Error("rows scan error(%v)", err)
return
}
names[awardID] = name
}
err = rows.Err()
return
}
// JoinedCount get signed up count by mid, award_id
func (d *Dao) JoinedCount(c context.Context, mid, awardID int64) (count int64, err error) {
row := d.db.QueryRow(c, _joinedCountSQL, mid, awardID)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row scan error(%v)", err)
}
}
return
}
// AwardBonus get bonus by award_id and prize_id
func (d *Dao) AwardBonus(c context.Context, awardID, prizeID int64) (bonus int64, err error) {
row := d.db.QueryRow(c, _awardBonusSQL, awardID, prizeID)
if err = row.Scan(&bonus); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row scan error(%v)", err)
}
}
return
}
// AddToAwardRecord add to award record
func (d *Dao) AddToAwardRecord(c context.Context, mid, awardID int64) (rows int64, err error) {
res, err := d.db.Exec(c, _inSpecialAwardRecordSQL, mid, awardID)
if err != nil {
return
}
return res.RowsAffected()
}
// GetSpecialAwards get all display sepcial award
func (d *Dao) GetSpecialAwards(c context.Context) (awards []*model.SpecialAward, err error) {
awards = make([]*model.SpecialAward, 0)
rows, err := d.db.Query(c, _specialAwardsSQL)
if err != nil {
log.Error("GetSpecialAwards d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
sa := &model.SpecialAward{}
err = rows.Scan(&sa.AwardID, &sa.AwardName, &sa.CycleStart, &sa.CycleEnd, &sa.AnnounceDate)
if err != nil {
log.Error("GetSpecialAwards rows.Scan error(%v)", err)
return
}
awards = append(awards, sa)
}
err = rows.Err()
return
}
// GetSpecialAwardDivision get special award division name
func (d *Dao) GetSpecialAwardDivision(c context.Context, awardID int64) (divisions []string, err error) {
divisions = make([]string, 0)
rows, err := d.db.Query(c, _awardDivisionSQL, awardID)
if err != nil {
log.Error("GetSpecialAwardDivision d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var name string
err = rows.Scan(&name)
if err != nil {
log.Error("GetSpecialAwardDivision rows.Scan error(%v)", err)
return
}
divisions = append(divisions, name)
}
err = rows.Err()
return
}
// GetAwardWinRecord get award win record
func (d *Dao) GetAwardWinRecord(c context.Context, mid int64) (awardIDs map[int64]bool, err error) {
awardIDs = make(map[int64]bool)
rows, err := d.db.Query(c, _awardWinRecordSQL, mid)
if err != nil {
log.Error("GetAwardWinRecord d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var id int64
err = rows.Scan(&id)
if err != nil {
log.Error("GetAwardWinRecord rows.Scan error(%v)", err)
return
}
awardIDs[id] = true
}
err = rows.Err()
return
}
// GetAwardJoinRecord get award join record
func (d *Dao) GetAwardJoinRecord(c context.Context, mid int64) (awardIDs map[int64]bool, err error) {
awardIDs = make(map[int64]bool)
rows, err := d.db.Query(c, _awardJoinRecordSQL, mid)
if err != nil {
log.Error("GetAwardJoinRecord d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var id int64
err = rows.Scan(&id)
if err != nil {
log.Error("GetAwardJoinRecord rows.Scan error(%v)", err)
return
}
awardIDs[id] = true
}
err = rows.Err()
return
}

View File

@@ -0,0 +1,242 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoPastAwards(t *testing.T) {
convey.Convey("PastAwards", t, func(convCtx convey.C) {
var (
c = context.Background()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "INSERT INTO special_award(award_id,award_name,open_status) VALUES(666,'test','2') ON DUPLICATE KEY UPDATE award_id=VALUES(award_id)")
as, err := d.PastAwards(c)
convCtx.Convey("Then err should be nil.as should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(as, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoJoinedSpecialAwards(t *testing.T) {
convey.Convey("JoinedSpecialAwards", t, func(convCtx convey.C) {
var (
c = context.Background()
awardIDs = []int64{666}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "INSERT INTO special_award(award_id,award_name,open_status) VALUES(666,'test','2') ON DUPLICATE KEY UPDATE award_id=VALUES(award_id)")
sas, err := d.JoinedSpecialAwards(c, awardIDs)
convCtx.Convey("Then err should be nil.sas should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(sas, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetAwardSchedule(t *testing.T) {
convey.Convey("GetAwardSchedule", t, func(convCtx convey.C) {
var (
c = context.Background()
awardID = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "INSERT INTO special_award(award_id,award_name,open_status) VALUES(666,'test','2') ON DUPLICATE KEY UPDATE award_id=VALUES(award_id)")
award, err := d.GetAwardSchedule(c, awardID)
convCtx.Convey("Then err should be nil.award should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(award, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetResources(t *testing.T) {
convey.Convey("GetResources", t, func(convCtx convey.C) {
var (
c = context.Background()
awardID = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "INSERT INTO special_award_resource(award_id,resource_type,content,resource_index) VALUES(666,1,'test',1) ON DUPLICATE KEY UPDATE award_id=VALUES(award_id)")
res, err := d.GetResources(c, awardID)
convCtx.Convey("Then err should be nil.res should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetWinners(t *testing.T) {
convey.Convey("GetWinners", t, func(convCtx convey.C) {
var (
c = context.Background()
awardID = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "INSERT INTO special_award_winner(award_id,mid,division_name) VALUES(666,2,'test') ON DUPLICATE KEY UPDATE award_id=VALUES(award_id)")
mids, err := d.GetWinners(c, awardID)
convCtx.Convey("Then err should be nil.mids should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(mids, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAwardIDsByWinner(t *testing.T) {
convey.Convey("AwardIDsByWinner", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(2)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
am, err := d.AwardIDsByWinner(c, mid)
convCtx.Convey("Then err should be nil.am should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(am, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoDivisionName(t *testing.T) {
convey.Convey("DivisionName", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(2)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
names, err := d.DivisionName(c, mid)
convCtx.Convey("Then err should be nil.names should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(names, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoJoinedCount(t *testing.T) {
convey.Convey("JoinedCount", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(2)
awardID = int64(666)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "INSERT INTO special_award_record(award_id,mid) VALUES(666,2) ON DUPLICATE KEY UPDATE award_id=VALUES(award_id)")
count, err := d.JoinedCount(c, mid, awardID)
convCtx.Convey("Then err should be nil.count should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAwardBonus(t *testing.T) {
convey.Convey("AwardBonus", t, func(convCtx convey.C) {
var (
c = context.Background()
awardID = int64(66)
prizeID = int64(2)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "INSERT INTO special_award_prize(award_id,prize_id, bonus) VALUES(66,2,100) ON DUPLICATE KEY UPDATE award_id=VALUES(award_id)")
bonus, err := d.AwardBonus(c, awardID, prizeID)
convCtx.Convey("Then err should be nil.bonus should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(bonus, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddToAwardRecord(t *testing.T) {
convey.Convey("AddToAwardRecord", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(2)
awardID = int64(666)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "DELETE FROM special_award_record WHERE mid=2")
rows, err := d.AddToAwardRecord(c, mid, awardID)
convCtx.Convey("Then err should be nil.rows should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetSpecialAwards(t *testing.T) {
convey.Convey("GetSpecialAwards", t, func(convCtx convey.C) {
var (
c = context.Background()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
awards, err := d.GetSpecialAwards(c)
convCtx.Convey("Then err should be nil.awards should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(awards, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetSpecialAwardDivision(t *testing.T) {
convey.Convey("GetSpecialAwardDivision", t, func(convCtx convey.C) {
var (
c = context.Background()
awardID = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
Exec(c, "INSERT INTO special_award_division(award_id,division_name) VALUES(666,'test') ON DUPLICATE KEY UPDATE award_id=VALUES(award_id)")
divisions, err := d.GetSpecialAwardDivision(c, awardID)
convCtx.Convey("Then err should be nil.divisions should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(divisions, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetAwardWinRecord(t *testing.T) {
convey.Convey("GetAwardWinRecord", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(2)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
awardIDs, err := d.GetAwardWinRecord(c, mid)
convCtx.Convey("Then err should be nil.awardIDs should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(awardIDs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetAwardJoinRecord(t *testing.T) {
convey.Convey("GetAwardJoinRecord", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(2)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
awardIDs, err := d.GetAwardJoinRecord(c, mid)
convCtx.Convey("Then err should be nil.awardIDs should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(awardIDs, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,56 @@
package dao
import (
"math"
"math/big"
)
// Div div
func Div(x, y float64) float64 {
a := big.NewFloat(x)
b := big.NewFloat(y)
c := new(big.Float).Quo(a, b)
d, _ := c.Float64()
return d
}
// Mul mul
func Mul(x, y float64) float64 {
a := big.NewFloat(x)
b := big.NewFloat(y)
c := new(big.Float).Mul(a, b)
d, _ := c.Float64()
return d
}
// DivWithRound div with round
func DivWithRound(x, y float64, places int) float64 {
a := big.NewFloat(x)
b := big.NewFloat(y)
c := new(big.Float).Quo(a, b)
d, _ := c.Float64()
return Round(d, places)
}
// MulWithRound mul with round
func MulWithRound(x, y float64, places int) float64 {
a := big.NewFloat(x)
b := big.NewFloat(y)
c := new(big.Float).Mul(a, b)
d, _ := c.Float64()
return Round(d, places)
}
// Round round
func Round(val float64, places int) float64 {
var round float64
pow := math.Pow(10, float64(places))
digit := pow * val
_, div := math.Modf(digit)
if div >= 0.5 {
round = math.Ceil(digit)
} else {
round = math.Floor(digit)
}
return round / pow
}

View File

@@ -0,0 +1,84 @@
package dao
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoDiv(t *testing.T) {
convey.Convey("Div", t, func(ctx convey.C) {
var (
x = float64(1)
y = float64(1)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := Div(x, y)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoMul(t *testing.T) {
convey.Convey("Mul", t, func(ctx convey.C) {
var (
x = float64(1)
y = float64(1)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := Mul(x, y)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoDivWithRound(t *testing.T) {
convey.Convey("DivWithRound", t, func(ctx convey.C) {
var (
x = float64(1)
y = float64(1)
places = int(2)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := DivWithRound(x, y, places)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoMulWithRound(t *testing.T) {
convey.Convey("MulWithRound", t, func(ctx convey.C) {
var (
x = float64(1)
y = float64(1)
places = int(2)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := MulWithRound(x, y, places)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoRound(t *testing.T) {
convey.Convey("Round", t, func(ctx convey.C) {
var (
val = float64(1)
places = int(2)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := Round(val, places)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,268 @@
package dao
import (
"context"
"fmt"
"go-common/app/interface/main/growup/model"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/time"
)
const (
// insert
_inUpsSQL = "INSERT INTO %s (mid,nickname,account_type,category_id,fans,account_state,sign_type,apply_at,%s,is_deleted) VALUES (?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE nickname=?,account_type=?,category_id=?,fans=?,account_state=?,sign_type=?,apply_at=?,%s=?,is_deleted=?"
_inUpBgmSQL = "INSERT INTO up_info_bgm(mid,nickname,bgms,account_type,fans,account_state,sign_type,signed_at,is_deleted) VALUES(?,?,?,?,?,3,?,?,0) ON DUPLICATE KEY UPDATE nickname=VALUES(nickname),bgms=VALUES(bgms),account_type=VALUES(account_type),fans=VALUES(fans),account_state=3,signed_at=VALUES(signed_at),sign_type=VALUES(sign_type),is_deleted=0"
_inCreditRecordSQL = "INSERT INTO credit_score_record (mid,operate_at,operator,reason,deducted,remaining) VALUES(?,?,?,?,?,?)"
_inCreditScoreSQL = "INSERT INTO credit_score(mid) VALUES(?) ON DUPLICATE KEY UPDATE mid=VALUES(mid)"
// select
_upsCateInfoSQL = "SELECT nick_name,main_category_id FROM up_category_info WHERE mid=?"
_upsStatInfoSQL = "SELECT fans FROM up_base_statistics WHERE mid=?"
_blockMIDSQL = "SELECT mid FROM up_blocked WHERE mid=? AND is_deleted=0"
_upNicknameSQL = "SELECT nickname FROM up_info_video WHERE mid = ?"
_upCreditScoreSQL = "SELECT score FROM credit_score WHERE mid = ?"
_accountStateSQL = "SELECT account_state FROM %s WHERE mid = ? AND is_deleted = 0"
_upSignedAtSQL = "SELECT signed_at FROM %s WHERE mid = ? AND account_state = 3 AND is_deleted = 0"
// will delete next version
_upWhiteListSQL = "SELECT type FROM up_white_list WHERE mid=? AND is_deleted=0"
// _upsArchiveSQL = "SELECT account_type,account_state,reason,expired_in,quit_at,ctime FROM up_info_video WHERE mid=? AND is_deleted=0"
_avAccountStateSQL = "SELECT account_type,account_state,reason,expired_in,quit_at,ctime FROM up_info_video WHERE mid=? AND is_deleted=0"
_bgmAccountStateSQL = "SELECT account_type,account_state,reason,expired_in,quit_at,ctime FROM up_info_bgm WHERE mid=? AND is_deleted=0"
_columnAccountStateSQL = "SELECT account_type,account_state,reason,expired_in,quit_at,ctime FROM up_info_column WHERE mid=? AND is_deleted=0"
_bgmUpCountSQL = "SELECT count(*) FROM background_music WHERE mid=?"
// update
_upQuitSQL = "UPDATE %s SET account_state=5,quit_at=?,expired_in=?,reason=? WHERE mid=? AND account_state=3 AND is_deleted=0"
_deductCreditScoreSQL = "UPDATE credit_score SET score=score-%d WHERE mid=?"
)
// GetAccountState account state
func (d *Dao) GetAccountState(c context.Context, table string, mid int64) (state int, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_accountStateSQL, table), mid)
if err = row.Scan(&state); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row scan error(%v)", err)
}
}
return
}
// GetUpSignedAt get up signed_at
func (d *Dao) GetUpSignedAt(c context.Context, table string, mid int64) (signedAt time.Time, err error) {
if err = d.db.QueryRow(c, fmt.Sprintf(_upSignedAtSQL, table), mid).Scan(&signedAt); err != nil {
if err == sql.ErrNoRows {
err = nil
signedAt = 0
} else {
log.Error("row scan error(%v)", err)
}
}
return
}
// InsertUpInfo add upinfo
func (d *Dao) InsertUpInfo(c context.Context, table string, totalCountField string, v *model.UpInfo) (rows int64, err error) {
res, err := d.db.Exec(c, fmt.Sprintf(_inUpsSQL, table, totalCountField, totalCountField), v.MID, v.Nickname, v.AccountType, v.MainCategory, v.Fans, v.AccountState, v.SignType, v.ApplyAt, v.TotalPlayCount, 0, v.Nickname, v.AccountType, v.MainCategory, v.Fans, v.AccountState, v.SignType, v.ApplyAt, v.TotalPlayCount, 0)
if err != nil {
log.Error("db.inUpsStmt.Exec(%s) error(%v)", _inUpsSQL, err)
return
}
return res.RowsAffected()
}
// TxInsertBgmUpInfo insert bgm up info
func (d *Dao) TxInsertBgmUpInfo(tx *sql.Tx, v *model.UpInfo) (rows int64, err error) {
res, err := tx.Exec(_inUpBgmSQL, v.MID, v.Nickname, v.Bgms, v.AccountType, v.Fans, v.SignType, v.SignedAt)
if err != nil {
log.Error("db.inBgmUpStmt.Exec(%s) error(%v)", _inUpsSQL, err)
return
}
return res.RowsAffected()
}
// TxInsertCreditScore insert credit score
func (d *Dao) TxInsertCreditScore(tx *sql.Tx, mid int64) (rows int64, err error) {
res, err := tx.Exec(_inCreditScoreSQL, mid)
if err != nil {
log.Error("db.Exec(%s) error(%v)", _inCreditScoreSQL, err)
return
}
return res.RowsAffected()
}
// Blocked query mid in blacklist
func (d *Dao) Blocked(c context.Context, mid int64) (id int64, err error) {
row := d.db.QueryRow(c, _blockMIDSQL, mid)
if err = row.Scan(&id); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// White map: key: type value: bool
func (d *Dao) White(c context.Context, mid int64) (m map[int]bool, err error) {
m = make(map[int]bool)
rows, err := d.db.Query(c, _upWhiteListSQL, mid)
if err != nil {
log.Error("row.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var typ int
err = rows.Scan(&typ)
if err != nil {
log.Error("rows.Scan error(%v)", err)
}
m[typ] = true
}
return
}
// AvUpStatus return av up status
func (d *Dao) AvUpStatus(c context.Context, mid int64) (status *model.BusinessStatus, err error) {
status = &model.BusinessStatus{}
row := d.db.QueryRow(c, _avAccountStateSQL, mid)
if err = row.Scan(&status.AccountType, &status.AccountState, &status.Reason, &status.ExpiredIn, &status.QuitAt, &status.CTime); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// BgmUpStatus return bgm up status
func (d *Dao) BgmUpStatus(c context.Context, mid int64) (status *model.BusinessStatus, err error) {
status = &model.BusinessStatus{}
row := d.db.QueryRow(c, _bgmAccountStateSQL, mid)
if err = row.Scan(&status.AccountType, &status.AccountState, &status.Reason, &status.ExpiredIn, &status.QuitAt, &status.CTime); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// ColumnUpStatus return bgm up status
func (d *Dao) ColumnUpStatus(c context.Context, mid int64) (status *model.BusinessStatus, err error) {
status = &model.BusinessStatus{}
row := d.db.QueryRow(c, _columnAccountStateSQL, mid)
if err = row.Scan(&status.AccountType, &status.AccountState, &status.Reason, &status.ExpiredIn, &status.QuitAt, &status.CTime); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// CategoryInfo return nickname & categoryID
func (d *Dao) CategoryInfo(c context.Context, mid int64) (nickname string, categoryID int, err error) {
row := d.rddb.QueryRow(c, _upsCateInfoSQL, mid)
if err = row.Scan(&nickname, &categoryID); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// Fans return fans count
func (d *Dao) Fans(c context.Context, mid int64) (fans int, err error) {
row := d.rddb.QueryRow(c, _upsStatInfoSQL, mid)
if err = row.Scan(&fans); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// TxQuit update up status
func (d *Dao) TxQuit(tx *sql.Tx, table string, mid int64, quitAt, expiredIn time.Time, reason string) (rows int64, err error) {
res, err := tx.Exec(fmt.Sprintf(_upQuitSQL, table), quitAt, expiredIn, reason, mid)
if err != nil {
log.Error("db.TxQuit.Exec() error(%v)", err)
return
}
return res.RowsAffected()
}
// TxInsertCreditRecord tx insert credit deduct record
func (d *Dao) TxInsertCreditRecord(tx *sql.Tx, cr *model.CreditRecord) (rows int64, err error) {
res, err := tx.Exec(_inCreditRecordSQL, cr.MID, cr.OperateAt, cr.Operator, cr.Reason, cr.Deducted, cr.Remaining)
if err != nil {
log.Error("db.TxInsertCreditRecord.Exec() error(%v)", err)
return
}
return res.RowsAffected()
}
// Nickname get nickname from up_info_video
func (d *Dao) Nickname(c context.Context, mid int64) (nickname string, err error) {
row := d.rddb.QueryRow(c, _upNicknameSQL, mid)
if err = row.Scan(&nickname); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// CreditScore get current credit score from up_info_video
func (d *Dao) CreditScore(c context.Context, mid int64) (score int, err error) {
row := d.rddb.QueryRow(c, _upCreditScoreSQL, mid)
if err = row.Scan(&score); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// BgmUpCount bgm up count in table background_music
func (d *Dao) BgmUpCount(c context.Context, mid int64) (count int, err error) {
row := d.db.QueryRow(c, _bgmUpCountSQL, mid)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
count = 0
} else {
log.Error("db.QueryRow(%s) error(%v)", _bgmUpCountSQL, err)
}
}
return
}
// TxDeductCreditScore tx update credit score
func (d *Dao) TxDeductCreditScore(tx *sql.Tx, score int, mid int64) (rows int64, err error) {
res, err := tx.Exec(fmt.Sprintf(_deductCreditScoreSQL, score), mid)
if err != nil {
log.Error("tx.Exec(%s) error(%v)", _deductCreditScoreSQL, err)
return
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,18 @@
package dao
import (
"context"
"go-common/app/interface/main/growup/model"
)
const (
_upBillSQL = "SELECT mid,first_income,max_income,total_income,av_count,av_max_income,av_id,quality_value,defeat_num,title,share_items,first_time,max_time,signed_at,end_at FROM up_bill WHERE mid = ?"
)
// GetUpBill get up bill by mid
func (d *Dao) GetUpBill(c context.Context, mid int64) (up *model.UpBill, err error) {
up = &model.UpBill{}
err = d.db.QueryRow(c, _upBillSQL, mid).Scan(&up.MID, &up.FirstIncome, &up.MaxIncome, &up.TotalIncome, &up.AvCount, &up.AvMaxIncome, &up.AvID, &up.QualityValue, &up.DefeatNum, &up.Title, &up.ShareItems, &up.FirstTime, &up.MaxTime, &up.SignedAt, &up.EndAt)
return
}

View File

@@ -0,0 +1,25 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetUpBill(t *testing.T) {
convey.Convey("GetUpBill", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_bill(mid) VALUES(1001)")
up, err := d.GetUpBill(c, mid)
ctx.Convey("Then err should be nil.up should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(up, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,343 @@
package dao
import (
"context"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
"go-common/app/interface/main/growup/model"
xtime "go-common/library/time"
)
func TestDaoGetAccountState(t *testing.T) {
convey.Convey("GetAccountState", t, func(ctx convey.C) {
var (
c = context.Background()
table = "up_info_video"
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_info_video(mid, account_state, is_deleted) VALUES(1001, 3, 0) ON DUPLICATE KEY UPDATE account_state = 3, is_deleted = 0")
state, err := d.GetAccountState(c, table, mid)
ctx.Convey("Then err should be nil.state should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(state, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetUpSignedAt(t *testing.T) {
convey.Convey("GetUpSignedAt", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_info_video(mid, account_state, is_deleted) VALUES(1001, 3, 0) ON DUPLICATE KEY UPDATE account_state = 3, is_deleted = 0")
signedAt, err := d.GetUpSignedAt(c, "up_info_video", mid)
ctx.Convey("Then err should be nil.signedAt should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(signedAt, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoInsertUpInfo(t *testing.T) {
convey.Convey("InsertUpInfo", t, func(ctx convey.C) {
var (
c = context.Background()
table = "up_info_video"
totalCountField = "total_play_count"
v = &model.UpInfo{
MID: 1002,
AccountState: 3,
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "DELETE FROM up_info_video WHERE mid = 1002")
rows, err := d.InsertUpInfo(c, table, totalCountField, v)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxInsertBgmUpInfo(t *testing.T) {
convey.Convey("TxInsertBgmUpInfo", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
v = &model.UpInfo{
MID: 1002,
AccountState: 3,
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
defer tx.Commit()
Exec(c, "DELETE FROM up_info_bgm WHERE mid = 1002")
rows, err := d.TxInsertBgmUpInfo(tx, v)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxInsertCreditScore(t *testing.T) {
convey.Convey("TxInsertCreditScore", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
defer tx.Commit()
rows, err := d.TxInsertCreditScore(tx, mid)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoBlocked(t *testing.T) {
convey.Convey("Blocked", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_blocked(mid) VALUES(1001)")
id, err := d.Blocked(c, mid)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoWhite(t *testing.T) {
convey.Convey("White", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_white_list(mid) VALUES(1001)")
m, err := d.White(c, mid)
ctx.Convey("Then err should be nil.m should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(m, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAvUpStatus(t *testing.T) {
convey.Convey("AvUpStatus", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_info_video(mid, account_state, is_deleted) VALUES(1001, 3, 0) ON DUPLICATE KEY UPDATE account_state = 3, is_deleted = 0")
status, err := d.AvUpStatus(c, mid)
ctx.Convey("Then err should be nil.status should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(status, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoBgmUpStatus(t *testing.T) {
convey.Convey("BgmUpStatus", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_info_bgm(mid, account_state, is_deleted) VALUES(1001, 3, 0) ON DUPLICATE KEY UPDATE account_state = 3, is_deleted = 0")
status, err := d.BgmUpStatus(c, mid)
ctx.Convey("Then err should be nil.status should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(status, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoColumnUpStatus(t *testing.T) {
convey.Convey("ColumnUpStatus", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_info_column(mid, account_state, is_deleted) VALUES(1001, 3, 0) ON DUPLICATE KEY UPDATE account_state = 3, is_deleted = 0")
status, err := d.ColumnUpStatus(c, mid)
ctx.Convey("Then err should be nil.status should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(status, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoCategoryInfo(t *testing.T) {
convey.Convey("CategoryInfo", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
nickname, categoryID, err := d.CategoryInfo(c, mid)
ctx.Convey("Then err should be nil.nickname,categoryID should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(categoryID, convey.ShouldNotBeNil)
ctx.So(nickname, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoFans(t *testing.T) {
convey.Convey("Fans", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_base_statistics(mid, fans) VALUES(1001, 100)")
fans, err := d.Fans(c, mid)
ctx.Convey("Then err should be nil.fans should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(fans, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxQuit(t *testing.T) {
convey.Convey("TxQuit", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
table = "up_info_video"
mid = int64(1003)
quitAt = xtime.Time(time.Now().Unix())
expiredIn = xtime.Time(time.Now().Unix())
reason = "test"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
defer tx.Commit()
Exec(c, "INSERT INTO up_info_video(mid, account_state, is_deleted) VALUES(1003, 3, 0) ON DUPLICATE KEY UPDATE account_state = 3, is_deleted = 0")
rows, err := d.TxQuit(tx, table, mid, quitAt, expiredIn, reason)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxInsertCreditRecord(t *testing.T) {
convey.Convey("TxInsertCreditRecord", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
cr = &model.CreditRecord{
MID: 1001,
Reason: 1,
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
defer tx.Commit()
Exec(c, "DELETE FROM credit_score_record WHERE mid = 1001")
rows, err := d.TxInsertCreditRecord(tx, cr)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoNickname(t *testing.T) {
convey.Convey("Nickname", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1004)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_info_video(mid, account_state, is_deleted, nickname) VALUES(1004, 3, 0, 'test') ON DUPLICATE KEY UPDATE account_state = 3, is_deleted = 0")
nickname, err := d.Nickname(c, mid)
ctx.Convey("Then err should be nil.nickname should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(nickname, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoCreditScore(t *testing.T) {
convey.Convey("CreditScore", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO credit_score(mid, score) VALUES(1001, 100)")
score, err := d.CreditScore(c, mid)
ctx.Convey("Then err should be nil.score should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(score, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoBgmUpCount(t *testing.T) {
convey.Convey("BgmUpCount", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO background_music(mid) VALUES(1001)")
count, err := d.BgmUpCount(c, mid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxDeductCreditScore(t *testing.T) {
convey.Convey("TxDeductCreditScore", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
score = int(10)
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
defer tx.Commit()
Exec(c, "INSERT INTO credit_score(mid, score) VALUES(1001, 100)")
rows, err := d.TxDeductCreditScore(tx, score, mid)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,20 @@
package dao
import (
"context"
"database/sql"
)
const (
_upTagYearSQL = "SELECT tag1, tag2, tag3, tag4, tag5, tag6, total_income FROM up_tag_year WHERE mid = ?"
)
// GetUpYearTag get up year tag income
func (d *Dao) GetUpYearTag(c context.Context, mid int64) (tags []int64, income int64, err error) {
tags = make([]int64, 6)
err = d.db.QueryRow(c, _upTagYearSQL, mid).Scan(&tags[0], &tags[1], &tags[2], &tags[3], &tags[4], &tags[5], &income)
if err == sql.ErrNoRows {
err = nil
}
return
}

View File

@@ -0,0 +1,205 @@
package dao
import (
"context"
"database/sql"
"fmt"
"time"
"go-common/app/interface/main/growup/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
const (
// get up_account withdraw count
_upAccountCount = "SELECT count(1) FROM up_account where is_deleted = 0 AND has_sign_contract = 1 AND total_unwithdraw_income > 0 AND withdraw_date_version != ?"
// query up_account by date
_queryUpAccountByDate = "SELECT mid, total_unwithdraw_income, withdraw_date_version FROM up_account WHERE is_deleted = 0 AND has_sign_contract = 1 AND total_unwithdraw_income > 0 AND withdraw_date_version != ? LIMIT ?,?"
// query up_account version by mid
_queryUpAccountVersion = "SELECT version FROM up_account WHERE is_deleted = 0 AND mid = ?"
// update up_account withdraw
_updateUpAccountWithdraw = "UPDATE up_account up SET up.total_unwithdraw_income = up.total_unwithdraw_income - %d, up.total_withdraw_income = up.total_withdraw_income + %d, up.last_withdraw_time = ? WHERE up.mid = ? AND up.total_unwithdraw_income > 0 AND is_deleted = 0"
// update up_account unwithdraw income
_updateUpAccountUnwithdrawIncome = "UPDATE up_account up SET up.total_unwithdraw_income = up.total_income - up.total_withdraw_income - up.exchange_income, up.withdraw_date_version = ?, up.version = up.version + 1 WHERE up.is_deleted = 0 AND up.mid = ? AND up.version = ?"
// update up_account exchange and unwithdraw income
_updateUpAccountExchangeIncome = "UPDATE up_account SET total_unwithdraw_income = total_unwithdraw_income - %d, exchange_income = exchange_income + %d, version = version + 1 WHERE is_deleted = 0 AND mid = ? AND version = ?"
// query up_income_withdraw by mid
_queryUpWithdrawByMID = "SELECT withdraw_income, date_version, state, ctime FROM up_income_withdraw WHERE mid = ? AND is_deleted = 0"
// query up_income_withdraw by mids and date_version
_queryUpWithdrawByMIDs = "SELECT id, mid, withdraw_income, date_version, state, ctime FROM up_income_withdraw WHERE is_deleted = 0 AND mid in (%s) AND date_version = ?"
// query up_income_withdraw by id
_queryUpWithdrawByID = "SELECT id, mid, withdraw_income, date_version, state, ctime FROM up_income_withdraw WHERE is_deleted = 0 AND id = ?"
// query up_income_withdraw max date_version by mid
_queryMaxUpWithdrawDateVersion = "SELECT MAX(date_version) FROM up_income_withdraw where is_deleted = 0 AND mid = ?"
// insert record into up_income_withdraw
_insertUpWithdrawRecord = "INSERT INTO up_income_withdraw(mid, withdraw_income, date_version, state) VALUES(?,?,?,?)"
// update up_income_withdraw
_updateUpWithdrawState = "UPDATE up_income_withdraw up SET up.state = ? WHERE up.id = ? AND is_deleted = 0"
)
// GetUpAccountCount get up account withdraw count
func (d *Dao) GetUpAccountCount(c context.Context, dateVersion string) (count int, err error) {
row := d.db.QueryRow(c, _upAccountCount, dateVersion)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
count = 0
} else {
log.Error("db.QueryRow(%s) error(%v)", _upAccountCount, err)
}
}
return
}
// QueryUpAccountByDate query up_account by date
func (d *Dao) QueryUpAccountByDate(c context.Context, dateVersion string, from, limit int) (upAccounts []*model.UpAccount, err error) {
upAccounts = make([]*model.UpAccount, 0)
rows, err := d.db.Query(c, _queryUpAccountByDate, dateVersion, from, limit)
if err != nil {
log.Error("d.db.Query(%s) error(%v)", _queryUpAccountByDate, err)
return
}
defer rows.Close()
for rows.Next() {
up := &model.UpAccount{}
err = rows.Scan(&up.MID, &up.TotalUnwithdrawIncome, &up.WithdrawDateVersion)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
upAccounts = append(upAccounts, up)
}
err = rows.Err()
return
}
// QueryUpWithdrawByMID query up_income_withdraw by mid
func (d *Dao) QueryUpWithdrawByMID(c context.Context, mid int64) (upWithdraws []*model.UpIncomeWithdraw, err error) {
upWithdraws = make([]*model.UpIncomeWithdraw, 0)
rows, err := d.db.Query(c, _queryUpWithdrawByMID, mid)
if err != nil {
log.Error("d.db.Query(%s) error(%v)", _queryUpWithdrawByMID, err)
return
}
defer rows.Close()
for rows.Next() {
upWithdraw := &model.UpIncomeWithdraw{}
err = rows.Scan(&upWithdraw.WithdrawIncome, &upWithdraw.DateVersion, &upWithdraw.State, &upWithdraw.CTime)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
upWithdraws = append(upWithdraws, upWithdraw)
}
err = rows.Err()
return
}
// QueryUpWithdrawByMids query up_income_withdraw by mids
func (d *Dao) QueryUpWithdrawByMids(c context.Context, mids []int64, dateVersion string) (upWithdraws map[int64]*model.UpIncomeWithdraw, err error) {
upWithdraws = make(map[int64]*model.UpIncomeWithdraw)
rows, err := d.db.Query(c, fmt.Sprintf(_queryUpWithdrawByMIDs, xstr.JoinInts(mids)), dateVersion)
if err != nil {
log.Error("d.db.Query(%s) error(%v)", _queryUpWithdrawByMIDs, err)
return
}
defer rows.Close()
for rows.Next() {
upWithdraw := &model.UpIncomeWithdraw{}
err = rows.Scan(&upWithdraw.ID, &upWithdraw.MID, &upWithdraw.WithdrawIncome, &upWithdraw.DateVersion, &upWithdraw.State, &upWithdraw.CTime)
if err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
upWithdraws[upWithdraw.MID] = upWithdraw
}
err = rows.Err()
return
}
// InsertUpWithdrawRecord insert record into up_income_withdraw
func (d *Dao) InsertUpWithdrawRecord(c context.Context, upWithdraw *model.UpIncomeWithdraw) (result int64, err error) {
res, err := d.db.Exec(c, _insertUpWithdrawRecord, upWithdraw.MID, upWithdraw.WithdrawIncome, upWithdraw.DateVersion, upWithdraw.State)
if err != nil {
log.Error("d.db.Exec(%s) error(%v)", _insertUpWithdrawRecord, err)
return
}
return res.RowsAffected()
}
// QueryUpWithdrawByID get up_income_withdraw by id
func (d *Dao) QueryUpWithdrawByID(c context.Context, id int64) (upWithdraw *model.UpIncomeWithdraw, err error) {
upWithdraw = &model.UpIncomeWithdraw{}
row := d.db.QueryRow(c, _queryUpWithdrawByID, id)
err = row.Scan(&upWithdraw.ID, &upWithdraw.MID, &upWithdraw.WithdrawIncome, &upWithdraw.DateVersion, &upWithdraw.State, &upWithdraw.CTime)
return
}
// TxUpdateUpWithdrawState update up_income_withdraw state
func (d *Dao) TxUpdateUpWithdrawState(tx *xsql.Tx, id int64, state int) (result int64, err error) {
res, err := tx.Exec(_updateUpWithdrawState, state, id)
if err != nil {
log.Error("d.db.Exec(%s) error(%v)", _updateUpWithdrawState)
return
}
return res.RowsAffected()
}
// TxUpdateUpAccountWithdraw update up_account withdraw
func (d *Dao) TxUpdateUpAccountWithdraw(tx *xsql.Tx, mid, thirdCoin int64) (result int64, err error) {
res, err := tx.Exec(fmt.Sprintf(_updateUpAccountWithdraw, thirdCoin, thirdCoin), time.Now(), mid)
if err != nil {
log.Error("d.db.Exec(%s) error(%v)", _updateUpAccountWithdraw)
return
}
return res.RowsAffected()
}
// TxQueryMaxUpWithdrawDateVersion query max date_version from up_income_withdraw by mid
func (d *Dao) TxQueryMaxUpWithdrawDateVersion(tx *xsql.Tx, mid int64) (dateVersion string, err error) {
row := tx.QueryRow(_queryMaxUpWithdrawDateVersion, mid)
if err = row.Scan(&dateVersion); err != nil {
if err == sql.ErrNoRows {
err = nil
dateVersion = ""
} else {
log.Error("db.QueryRow(%s) error(%v)", _queryMaxUpWithdrawDateVersion, err)
}
}
return
}
// TxQueryUpAccountVersion query up_account version
func (d *Dao) TxQueryUpAccountVersion(tx *xsql.Tx, mid int64) (version int64, err error) {
row := tx.QueryRow(_queryUpAccountVersion, mid)
err = row.Scan(&version)
return
}
// TxUpdateUpAccountUnwithdrawIncome update up_account unwithdraw and version
func (d *Dao) TxUpdateUpAccountUnwithdrawIncome(tx *xsql.Tx, mid int64, dateVersion string, version int64) (result int64, err error) {
res, err := tx.Exec(_updateUpAccountUnwithdrawIncome, dateVersion, mid, version)
if err != nil {
log.Error("d.db.Exec(%s) error(%v)", _updateUpAccountUnwithdrawIncome)
return
}
return res.RowsAffected()
}
// TxUpdateUpAccountExchangeIncome update up_account unwithdraw and exchange_income
func (d *Dao) TxUpdateUpAccountExchangeIncome(tx *xsql.Tx, mid, income, version int64) (result int64, err error) {
res, err := tx.Exec(fmt.Sprintf(_updateUpAccountExchangeIncome, income, income), mid, version)
if err != nil {
log.Error("d.db.Exec(%s) error(%v)", _updateUpAccountExchangeIncome, err)
return
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,227 @@
package dao
import (
"context"
"go-common/app/interface/main/growup/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetUpAccountCount(t *testing.T) {
convey.Convey("GetUpAccountCount", t, func(ctx convey.C) {
var (
c = context.Background()
dateVersion = "2017-01-01"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_account(mid, has_sign_contract, total_unwithdraw_income, withdraw_date_version, is_deleted) VALUES(1001, 1, 100, '2018-10', 0) ON DUPLICATE KEY UPDATE has_sign_contract = 1, is_deleted = 0")
count, err := d.GetUpAccountCount(c, dateVersion)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoQueryUpAccountByDate(t *testing.T) {
convey.Convey("QueryUpAccountByDate", t, func(ctx convey.C) {
var (
c = context.Background()
dateVersion = "2017-01-01"
from = int(0)
limit = int(10)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_account(mid, has_sign_contract, total_unwithdraw_income, withdraw_date_version, is_deleted) VALUES(1001, 1, 100, '2018-10', 0) ON DUPLICATE KEY UPDATE has_sign_contract = 1, is_deleted = 0")
upAccounts, err := d.QueryUpAccountByDate(c, dateVersion, from, limit)
ctx.Convey("Then err should be nil.upAccounts should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(upAccounts, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoQueryUpWithdrawByMID(t *testing.T) {
convey.Convey("QueryUpWithdrawByMID", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_income_withdraw(mid, date_version) VALUES(1001, '2018-08')")
upWithdraws, err := d.QueryUpWithdrawByMID(c, mid)
ctx.Convey("Then err should be nil.upWithdraws should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(upWithdraws, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoQueryUpWithdrawByMids(t *testing.T) {
convey.Convey("QueryUpWithdrawByMids", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1001}
dateVersion = "2018-08"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_income_withdraw(mid, date_version, is_deleted) VALUES(1001, '2018-08', 0) ON DUPLICATE KEY UPDATE is_deleted = 0")
upWithdraws, err := d.QueryUpWithdrawByMids(c, mids, dateVersion)
ctx.Convey("Then err should be nil.upWithdraws should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(upWithdraws, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoInsertUpWithdrawRecord(t *testing.T) {
convey.Convey("InsertUpWithdrawRecord", t, func(ctx convey.C) {
var (
c = context.Background()
upWithdraw = &model.UpIncomeWithdraw{
MID: 1002,
DateVersion: "2018-09",
State: 1,
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "DELETE FROM up_income_withdraw WHERE mid = 1002")
result, err := d.InsertUpWithdrawRecord(c, upWithdraw)
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 TestDaoQueryUpWithdrawByID(t *testing.T) {
convey.Convey("QueryUpWithdrawByID", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(100001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_income_withdraw(id, mid, date_version, is_deleted) VALUES(100001, 1006, '2018-08', 0) ON DUPLICATE KEY UPDATE is_deleted = 0")
upWithdraw, err := d.QueryUpWithdrawByID(c, id)
ctx.Convey("Then err should be nil.upWithdraw should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(upWithdraw, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxUpdateUpWithdrawState(t *testing.T) {
convey.Convey("TxUpdateUpWithdrawState", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
id = int64(100001)
state = int(2)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_income_withdraw(id, mid, date_version, is_deleted, state) VALUES(100001, 1001, '2018-08', 0, 1) ON DUPLICATE KEY UPDATE is_deleted = 0, state = 1")
result, err := d.TxUpdateUpWithdrawState(tx, id, 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)
})
})
ctx.Reset(func() {
tx.Commit()
})
})
}
func TestDaoTxUpdateUpAccountWithdraw(t *testing.T) {
convey.Convey("TxUpdateUpAccountWithdraw", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
mid = int64(1001)
thirdCoin = int64(10)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_account(mid, has_sign_contract, total_unwithdraw_income, withdraw_date_version, is_deleted) VALUES(1001, 1, 100, '2018-10', 0) ON DUPLICATE KEY UPDATE has_sign_contract = 1, is_deleted = 0")
result, err := d.TxUpdateUpAccountWithdraw(tx, mid, thirdCoin)
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)
})
})
ctx.Reset(func() {
tx.Commit()
})
})
}
func TestDaoTxQueryMaxUpWithdrawDateVersion(t *testing.T) {
convey.Convey("TxQueryMaxUpWithdrawDateVersion", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_income_withdraw(id, mid, date_version, is_deleted, state) VALUES(10001, 1001, '2018-08', 0, 1) ON DUPLICATE KEY UPDATE is_deleted = 0, state = 1")
dateVersion, err := d.TxQueryMaxUpWithdrawDateVersion(tx, mid)
ctx.Convey("Then err should be nil.dateVersion should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(dateVersion, convey.ShouldNotBeNil)
})
})
ctx.Reset(func() {
tx.Commit()
})
})
}
func TestDaoTxQueryUpAccountVersion(t *testing.T) {
convey.Convey("TxQueryUpAccountVersion", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
mid = int64(1001)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_account(mid, has_sign_contract, total_unwithdraw_income, withdraw_date_version, is_deleted) VALUES(1001, 1, 100, '2018-10', 0) ON DUPLICATE KEY UPDATE has_sign_contract = 1, is_deleted = 0")
version, err := d.TxQueryUpAccountVersion(tx, mid)
ctx.Convey("Then err should be nil.version should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(version, convey.ShouldNotBeNil)
})
})
ctx.Reset(func() {
tx.Commit()
})
})
}
func TestDaoTxUpdateUpAccountUnwithdrawIncome(t *testing.T) {
convey.Convey("TxUpdateUpAccountUnwithdrawIncome", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTran(c)
mid = int64(1005)
dateVersion = "2018-10"
version = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
Exec(c, "INSERT INTO up_account(mid, version, is_deleted) VALUES(1001, 1, 0) ON DUPLICATE KEY UPDATE version = 1, is_deleted = 0")
result, err := d.TxUpdateUpAccountUnwithdrawIncome(tx, mid, dateVersion, version)
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)
})
})
ctx.Reset(func() {
tx.Commit()
})
})
}

View File

@@ -0,0 +1,53 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"activity.go",
"column.go",
"exchange.go",
"http.go",
"income.go",
"join.go",
"local.go",
"newbie.go",
"notice.go",
"special_award.go",
"web.go",
"withdraw.go",
],
importpath = "go-common/app/interface/main/growup/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/growup/conf:go_default_library",
"//app/interface/main/growup/model:go_default_library",
"//app/interface/main/growup/service:go_default_library",
"//app/interface/main/growup/service/newbie: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/auth:go_default_library",
"//library/net/http/blademaster/render:go_default_library",
"//library/net/metadata: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,49 @@
package http
import (
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func showActivity(c *bm.Context) {
v := new(struct {
ActivityID int64 `form:"activity_id" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.ShowActivity(c, mid, v.ActivityID)
if err != nil {
log.Error("svc.ShowActivity error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func signUpActivity(c *bm.Context) {
var err error
v := new(struct {
ActivityID int64 `form:"activity_id" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
if err = svc.SignUpActivity(c, mid, v.ActivityID); err != nil {
log.Error("svc.SignUpActivity error(%v)", err)
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,29 @@
package http
import (
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func joinColumn(c *bm.Context) {
v := new(struct {
AccountType int `form:"account_type"`
SignType int `form:"sign_type"`
})
if err := c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
err := svc.JoinColumn(c, mid, v.AccountType, v.SignType)
if err != nil {
log.Error("svc.JoinColumn mid(%d) accountType(%d) signType(%d) error(%v)", mid, v.AccountType, v.SignType, err)
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1,93 @@
package http
import (
"net/http"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
)
func goodsState(c *bm.Context) {
data, err := svc.GoodsState(c)
if err != nil {
log.Error("growup svc.GoodsState error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func goodsShow(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.GoodsShow(c, mid)
if err != nil {
log.Error("growup svc.GoodsShow error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func goodsRecord(c *bm.Context) {
v := new(struct {
Page int `form:"page" default:"1" validate:"min=1"`
Size int `form:"size" default:"20" validate:"min=1"`
})
if err := c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, total, err := svc.GoodsRecord(c, mid, v.Page, v.Size)
if err != nil {
log.Error("growup svc.GoodsRecord error(%v)", err)
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": data,
"paging": map[string]int{
"page_size": v.Size,
"total": total,
},
}))
}
func goodsBuy(c *bm.Context) {
var err error
v := new(struct {
ProductID string `form:"product_id" validate:"required"`
GoodsType int `form:"goods_type" validate:"required"`
Price int64 `form:"price" validate:"required"`
})
if err = c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
if err = svc.GoodsBuy(c, mid, v.ProductID, v.GoodsType, v.Price); err != nil {
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 500,
"message": err.Error(),
}))
} else {
c.JSON(nil, nil)
}
}

View File

@@ -0,0 +1,116 @@
package http
import (
newbieService "go-common/app/interface/main/growup/service/newbie"
"net/http"
"go-common/app/interface/main/growup/conf"
"go-common/app/interface/main/growup/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/auth"
)
var (
svc *service.Service
authSvr *auth.Auth
newbieSvr *newbieService.Service
)
// Init http server
func Init(c *conf.Config) {
initService(c)
engine := bm.DefaultServer(c.BM)
setupInnerEngine(engine)
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
func initService(c *conf.Config) {
svc = service.New(c)
authSvr = auth.New(nil)
newbieSvr = newbieService.New(c)
}
func setupInnerEngine(e *bm.Engine) {
e.Ping(ping)
allowance := e.Group("/allowance/api/x/internal/growup")
allowanceUp := allowance.Group("/up")
{
// allowanceUp.GET("/status", getUpStatus)
allowanceUp.POST("/add", join)
allowanceUp.POST("/quit", quit)
allowanceUp.GET("/withdraw", getWithdraw)
allowanceUp.POST("/withdraw/success", withdrawSuccess)
}
studio := e.Group("/studio/growup/web", authSvr.User)
studioUp := studio.Group("/up")
{
studioUp.GET("/income/stat", upIncomeStat)
studioUp.GET("/summary", upSummary)
studioUp.GET("/archive/summary", archiveSummary)
studioUp.GET("/charge", upCharge)
studioUp.GET("/archive/income", archiveIncome)
studioUp.GET("/archive/detail", archiveDetail)
studioUp.GET("/archive/breach", archiveBreach)
studioUp.GET("/withdraw/detail", withdrawDetail)
studioUp.POST("/quit", quit1)
studioUp.GET("/status", getUpStatus)
studioUp.POST("/av/join", joinAv)
studioUp.POST("/bgm/join", joinBgm)
studioUp.POST("/column/join", joinColumn)
studioUp.GET("/bill", upBill)
studioUp.GET("/year", upYear)
// 新手信
studioUp.GET("/newbie/letter", upNewbieLetter)
exchange := studioUp.Group("/exchange")
{
exchange.GET("/state", goodsState)
exchange.GET("/show", goodsShow)
exchange.GET("/record", goodsRecord)
exchange.POST("/buy", goodsBuy)
}
}
studioActivity := studio.Group("/activity")
{
studioActivity.GET("/show", showActivity)
studioActivity.POST("/sign_up", signUpActivity)
}
specialAward := e.Group("/studio/growup/web/special/award", authSvr.Guest)
{
specialAward.GET("/info", sepcialAwardInfo)
specialAward.GET("/detail", specialAwardDetail)
specialAward.GET("/list", listSpecialAward)
specialAward.GET("/winner", specialAwardWinners)
}
specialAwardUser := e.Group("/studio/growup/web/special/award", authSvr.User)
{
specialAwardUser.GET("/record", specialAwardRecord)
specialAwardUser.GET("/record/poster", specialAwardPoster)
specialAwardUser.GET("/up/status", specialAwardUpStatus)
specialAwardUser.POST("/join", joinSpecialAward)
}
studio.GET("/notice/latest", latestNotice)
studio.GET("/notices", notices)
studio.GET("/banner", banner)
}
func ping(c *bm.Context) {
var err error
if err = svc.Ping(c); err != nil {
log.Error("service ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}

View File

@@ -0,0 +1,141 @@
package http
import (
"time"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func archiveIncome(c *bm.Context) {
v := new(struct {
Type int `form:"type"`
Page int `form:"page" default:"1" validate:"min=1"`
Size int `form:"size" default:"20" validate:"min=1"`
All int `form:"all" default:"0"`
})
if err := c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.ArchiveIncome(c, mid, v.Type, v.Page, v.Size, v.All)
if err != nil {
log.Error("growup svc.ArchiveIncome error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func upSummary(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.UpSummary(c, mid)
if err != nil {
log.Error("growup svc.UpSummary error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func archiveSummary(c *bm.Context) {
v := new(struct {
Type int `form:"type"`
})
if err := c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.ArchiveSummary(c, v.Type, mid)
if err != nil {
log.Error("growup svc.ArchiveSummary error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func archiveDetail(c *bm.Context) {
v := new(struct {
Type int `form:"type"`
ArchiveID int64 `form:"archive_id" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
data, err := svc.ArchiveDetail(c, v.Type, v.ArchiveID)
if err != nil {
log.Error("growup svc.ArchiveDetail error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func archiveBreach(c *bm.Context) {
v := new(struct {
Type int `form:"type"`
Page int `form:"page" default:"1" validate:"min=1"`
Size int `form:"size" default:"20" validate:"min=1"`
All int `form:"all" default:"0"`
})
if err := c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.ArchiveBreach(c, mid, v.Type, v.Page, v.Size, v.All)
if err != nil {
log.Error("growup svc.ArchiveBreach error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func upIncomeStat(c *bm.Context) {
v := new(struct {
Type int `form:"type"`
})
if err := c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.UpIncomeStat(c, v.Type, mid, time.Now())
if err != nil {
log.Error("growup svc.UpIncomeStat error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,49 @@
package http
import (
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func joinAv(c *bm.Context) {
v := new(struct {
AccountType int `form:"account_type"`
SignType int `form:"sign_type"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
if err = svc.JoinAv(c, v.AccountType, mid, v.SignType); err != nil {
log.Error("svc.Join accountType(%d) mid(%d) signType(%d) error(%v)", v.AccountType, mid, v.SignType, err)
}
c.JSON(nil, err)
}
func joinBgm(c *bm.Context) {
v := new(struct {
AccountType int `form:"account_type"`
SignType int `form:"sign_type"`
})
var err error
if err = c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
if err = svc.JoinBgm(c, mid, v.AccountType, v.SignType); err != nil {
log.Error("svc.JoinBgm accountType(%d) mid(%d) signType(%d) error(%v)", v.AccountType, mid, v.SignType, err)
}
c.JSON(nil, err)
}

View File

@@ -0,0 +1 @@
package http

View File

@@ -0,0 +1,29 @@
package http
import (
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/net/http/blademaster"
)
func upNewbieLetter(c *blademaster.Context) {
iMid, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
req := new(model.NewbieLetterReq)
if err := c.Bind(req); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
req.Mid = iMid.(int64)
res, err := newbieSvr.Letter(c, req)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(res, nil)
}

View File

@@ -0,0 +1,53 @@
package http
import (
"net/http"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
)
func notices(c *bm.Context) {
v := new(struct {
Type int `form:"type"`
Platform int `form:"platform"`
From int `form:"from" default:"0" validate:"min=0"`
Limit int `form:"limit" default:"20" validate:"min=1"`
})
if err := c.Bind(v); err != nil {
return
}
data, total, err := svc.GetNotices(c, v.Type, v.Platform, v.From, v.Limit)
if err != nil {
log.Error("growup svc.GetNotices error(%v)", err)
c.JSON(nil, err)
return
}
c.Render(http.StatusOK, render.MapJSON(map[string]interface{}{
"code": 0,
"message": "0",
"data": data,
"paging": map[string]int64{
"page_size": int64(v.Limit),
"total": total,
},
}))
}
func latestNotice(c *bm.Context) {
v := new(struct {
Platform int `form:"platform" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
notice, err := svc.LatestNotice(c, v.Platform)
if err != nil {
log.Error("svc.LatestNotice error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(notice, nil)
}

View File

@@ -0,0 +1,149 @@
package http
import (
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func sepcialAwardInfo(c *bm.Context) {
var mid int64
midI, ok := c.Get("mid")
if ok {
mid, _ = midI.(int64)
}
data, err := svc.SpecialAwardInfo(c, mid)
if err != nil {
log.Error("svc.SpecialAwardInfo error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func specialAwardDetail(c *bm.Context) {
v := new(struct {
AwardID int64 `form:"award_id" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
data, err := svc.AwardDetail(c, v.AwardID)
if err != nil {
log.Error("svc.AwardDetail error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func listSpecialAward(c *bm.Context) {
data, err := svc.AwardList(c)
if err != nil {
log.Error("svc.AwardDetail error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func specialAwardRecord(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.GetWinningRecord(c, mid)
if err != nil {
log.Error("svc.AwardDetail error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func specialAwardPoster(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
v := new(struct {
AwardID int64 `form:"award_id" validate:"required"`
PrizeID int64 `form:"prize_id" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
data, err := svc.GetWinningPoster(c, mid, v.AwardID, v.PrizeID)
if err != nil {
log.Error("svc.AwardDetail error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func joinSpecialAward(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
v := new(struct {
AwardID int64 `form:"award_id" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
err := svc.JoinAward(c, mid, v.AwardID)
if err != nil {
log.Error("svc.AwardDetail error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, err)
}
func specialAwardWinners(c *bm.Context) {
v := new(struct {
AwardID int64 `form:"award_id" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
data, err := svc.Winners(c, v.AwardID)
if err != nil {
log.Error("svc.AwardDetail error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func specialAwardUpStatus(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
v := new(struct {
AwardID int64 `form:"award_id" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
data, err := svc.GetAwardUpStatus(c, v.AwardID, mid)
if err != nil {
log.Error("svc.GetAwardUpStatus error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,187 @@
package http
import (
"strconv"
"time"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
)
//func getUpStatus(c *bm.Context) {
// params := c.Request.Form
// midStr := params.Get("mid")
// mid, err := strconv.ParseInt(midStr, 10, 64)
// if err != nil {
// log.Error("strconv.ParseInt mid(%s) error(%v)", midStr, err)
// c.JSON(nil, ecode.RequestErr)
// return
// }
// if mid <= 0 {
// log.Error("http.getUpStatus mid(%d) <= 0", mid)
// c.JSON(nil, ecode.RequestErr)
// return
// }
//
// data, err := svc.GetUpStatus(c, mid)
// if err != nil {
// log.Error("svc.GetUpStatus mid(%v), error(%v)", err)
// c.JSON(nil, err)
// return
// }
// c.JSON(data, nil)
//}
func getUpStatus(c *bm.Context) {
ip := metadata.String(c, metadata.RemoteIP)
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.GetUpStatus(c, mid, ip)
if err != nil {
log.Error("svc.GetUpStatus mid(%v), error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func join(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt mid(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
if mid <= 0 {
log.Error("http.getUpStatus mid(%d) <= 0", mid)
c.JSON(nil, ecode.RequestErr)
return
}
accountType, err := strconv.Atoi(params.Get("account_type"))
if err != nil {
log.Error("strconv.Atoi account_type(%s) error(%v)", accountType, err)
c.JSON(nil, ecode.RequestErr)
return
}
signType, err := strconv.Atoi(params.Get("sign_type"))
if err != nil {
log.Error("strconv.Atoi sign_type(%s) error(%v)", signType, err)
c.JSON(nil, ecode.RequestErr)
return
}
err = svc.JoinAv(c, accountType, mid, signType)
if err != nil {
log.Error("svc.AddUp accountType(%d) mid(%d) signType(%d) error(%v)", accountType, mid, signType, err)
}
c.JSON(nil, err)
}
func upCharge(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.GetUpCharge(c, mid, time.Now())
if err != nil {
log.Error("growup svc.GetUpCharge error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func quit(c *bm.Context) {
params := c.Request.Form
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt mid(%s) error(%v)", midStr, err)
c.JSON(nil, ecode.RequestErr)
return
}
if mid <= 0 {
log.Error("svc.quit mid(%d) <= 0", mid)
c.JSON(nil, ecode.RequestErr)
return
}
reason := params.Get("reason")
err = svc.Quit(c, mid, reason)
if err != nil {
log.Error("svc.Quit mid(%d) error(%v)", mid, err)
}
c.JSON(nil, err)
}
func quit1(c *bm.Context) {
v := new(struct {
Reason string `form:"reason"`
})
if err := c.Bind(v); err != nil {
return
}
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
err := svc.Quit(c, mid, v.Reason)
if err != nil {
log.Error("svc.Quit mid(%d) error(%v)", mid, err)
}
c.JSON(nil, err)
}
func banner(c *bm.Context) {
data, err := svc.GetBanner(c)
if err != nil {
log.Error("svc.Banner error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func upBill(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.UpBill(c, mid)
if err != nil {
log.Error("svc.UpBill mid(%d) error(%v)", mid, err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}
func upYear(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.UpYear(c, mid)
if err != nil {
log.Error("svc.UpYear mid(%d) error(%v)", mid, err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,90 @@
package http
import (
"sync"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
var (
mapLock sync.Mutex
// Lock withdraw lock
Lock map[int64]*sync.Mutex
)
func getWithdraw(c *bm.Context) {
v := new(struct {
DateVersion string `form:"dateVersion" validate:"required"`
Page int `form:"pageNo" default:"1" validate:"min=1"`
Size int `form:"size" default:"15" validate:"min=1"`
})
if err := c.Bind(v); err != nil {
return
}
from := (v.Page - 1) * v.Size
count, data, err := svc.GetWithdraw(c, v.DateVersion, from, v.Size)
if err != nil {
log.Error("growup svc.upWithdraw error(%v)", err)
c.JSON(nil, err)
return
}
Lock = make(map[int64]*sync.Mutex)
c.JSON(map[string]interface{}{
"page": v.Page,
"total_count": count,
"data": data,
}, nil)
}
func withdrawSuccess(c *bm.Context) {
v := new(struct {
OrderNo int64 `form:"order_no" validate:"required"`
TradeStatus int `form:"trade_status" validate:"required"`
})
if err := c.Bind(v); err != nil {
return
}
lock := getLock(v.OrderNo)
lock.Lock()
defer lock.Unlock()
err := svc.WithdrawSuccess(c, v.OrderNo, v.TradeStatus)
if err != nil {
log.Error("growup svc.WithdrawSuccess error(%v)", err)
}
c.JSON(nil, err)
}
func getLock(orderNo int64) *sync.Mutex {
mapLock.Lock()
defer mapLock.Unlock()
if Lock == nil {
Lock = make(map[int64]*sync.Mutex)
}
if _, ok := Lock[orderNo]; !ok {
Lock[orderNo] = new(sync.Mutex)
}
return Lock[orderNo]
}
func withdrawDetail(c *bm.Context) {
midI, ok := c.Get("mid")
if !ok {
c.JSON(nil, ecode.NoLogin)
return
}
mid, _ := midI.(int64)
data, err := svc.WithdrawDetail(c, mid)
if err != nil {
log.Error("growup svc.WithdrawDetail error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(data, nil)
}

View File

@@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"account.go",
"activity.go",
"archive_stat.go",
"av_breach.go",
"banner.go",
"exchange.go",
"income.go",
"newbie.go",
"notice.go",
"special_award.go",
"up.go",
"up_bill.go",
"withdraw.go",
],
importpath = "go-common/app/interface/main/growup/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//library/time:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,41 @@
package model
// ActUpInfo account up info
type ActUpInfo struct {
Nickname string `json:"nickname"`
Face string `json:"face"`
}
// Account Account
type Account struct {
Mid int64 `json:"mid"`
Name string `json:"name"`
Sex string `json:"sex"`
Face string `json:"face"`
Sign string `json:"sign"`
Rank int64 `json:"rank"`
}
// AccountInfosResult Account info result
type AccountInfosResult struct {
Code int `json:"code"`
Data map[int64]*Account `json:"data"`
Message string `json:"message"`
TTL int64 `json:"ttl"`
}
// UpIdentify up identify
type UpIdentify struct {
Article int `json:"article"`
Pic int `json:"pic"`
Archive int `json:"archive"`
Blink int `json:"blink"`
}
// UperInfosResult info result
type UperInfosResult struct {
Code int `json:"code"`
Data map[string]*UpIdentify `json:"data"`
Message string `json:"message"`
TTL int64 `json:"ttl"`
}

View File

@@ -0,0 +1,43 @@
package model
import (
"go-common/library/time"
)
// CActivity creative activity
type CActivity struct {
ID int64 `json:"id"`
Name string `json:"name"`
SignedStart time.Time `json:"-"`
SignedEnd time.Time `json:"-"`
SignUpStart time.Time `json:"-"`
SignUpEnd time.Time `json:"-"`
SignUp int `json:"sign_up"`
SignUpState int `json:"sign_up_state"` // 0可以报名,1已报名,2已获奖,3不能报名
WinType int `json:"win_type"`
ProgressStart time.Time `json:"-"`
ProgressEnd time.Time `json:"-"`
ProgressState int `json:"progress_state"` // 展示状态 0不展示 1展示
ProgressSync int `json:"progress_sync"`
UpdatePage int `json:"-"`
BonusQuery int `json:"bonus_query"`
BonusQueryStart time.Time `json:"-"`
BonusQueryEnd time.Time `json:"-"`
Background string `json:"background"`
WinDesc string `json:"win_desc"`
UnwinDesc string `json:"unwin_desc"`
Details string `json:"details"`
Enrollment int `json:"enrollment"`
WinNum int `json:"win_num"`
Ranking []*ActUpInfo `json:"ranking"`
}
// UpBonus up bonus
type UpBonus struct {
MID int64
ActivityID int64
Nickname string
Rank int
State int
SignUpTime time.Time
}

View File

@@ -0,0 +1,12 @@
package model
// UpBaseStat for up base.
type UpBaseStat struct {
View int64 `json:"view"`
Reply int64 `json:"reply"`
Dm int64 `json:"dm"`
Fans int64 `json:"fans"`
Fav int64 `json:"fav"`
Like int64 `json:"like"`
Share int64 `json:"share"`
}

View File

@@ -0,0 +1,16 @@
package model
import (
"go-common/library/time"
)
// AvBreach av breach
type AvBreach struct {
AvID int64 `json:"archive_id"`
MID int64 `json:"mid"`
CDate time.Time `json:"cdate"`
Money int64 `json:"money"`
CType int `json:"ctype"`
Reason string `json:"reason"`
Title string `json:"title"`
}

View File

@@ -0,0 +1,16 @@
package model
import (
"go-common/library/time"
)
// Banner banner
type Banner struct {
ID int64 `json:"id"`
Image string `json:"image"`
Link string `json:"link"`
StartAt time.Time `json:"start_at"`
EndAt time.Time `json:"end_at"`
CTime time.Time `json:"-"`
MTime time.Time `json:"-"`
}

View File

@@ -0,0 +1,32 @@
package model
import (
"go-common/library/time"
)
// GoodsInfo goods info
type GoodsInfo struct {
ID int64 `json:"-"`
ProductID string `json:"product_id"`
ResourceID int64 `json:"-"`
GoodsType int `json:"goods_type"`
Discount int `json:"discount"`
IsDisplay int `json:"-"`
DisplayOnTime time.Time `json:"-"`
ProductName string `json:"product_name"` // 商品名称
OriginPrice int64 `json:"origin_price"` // 实时成本, 单位分
CurrentPrice int64 `json:"current_price"` // 实时售价, 单位分
Month int32 `json:"month"` //有效期
}
// GoodsOrder goods order
type GoodsOrder struct {
MID int64 `json:"-"`
OrderNo string `json:"-"`
OrderTime time.Time `json:"order_time"`
GoodsType int `json:"-"`
GoodsID string `json:"-"`
GoodsName string `json:"goods_name"`
GoodsPrice int64 `json:"goods_price"`
GoodsCost int64 `json:"goods_cost"`
}

View File

@@ -0,0 +1,83 @@
package model
import (
"go-common/library/time"
)
// ArchiveIncome av income
type ArchiveIncome struct {
ID int64 `json:"id"`
ArchiveID int64 `json:"archive_id"`
Avs []int64 `json:"avs,omitempty"`
MID int64 `json:"mid"`
Income int64 `json:"income"`
MonthIncome int64 `json:"month_income"`
TotalIncome int64 `json:"total_income"`
Breach *AvBreach `json:"breach"`
Title string `json:"title"`
Icon string `json:"icon"`
Date time.Time `json:"date"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"mtime"`
IsDeleted int `json:"-"`
}
// Blacklist black list
type Blacklist struct {
ID int64 `json:"id" gorm:"column:id"`
AvID int64 `json:"av_id" gorm:"column:av_id"`
MID int64 `json:"mid" gorm:"column:mid"`
Reason int `json:"reason" gorm:"column:reason"`
CType int `json:"ctype" gorm:"column:ctype"`
HasSigned int `json:"has_signed" gorm:"column:has_signed"`
Nickname string `json:"nickname" gorm:"column:nickname"`
CTime time.Time `json:"ctime" gorm:"column:ctime"`
MTime time.Time `json:"mtime" gorm:"column:mtime"`
IsDeleted int `json:"-"`
}
// ArchiveRes archive response
type ArchiveRes struct {
Code int `json:"code"`
Data map[string]*Archive `json:"data"`
Message string `json:"message"`
}
// Archive archive
type Archive struct {
AID int64 `json:"aid"`
Title string `json:"title"`
}
// TagInfo tag_info
type TagInfo struct {
ID int64
Radio int64
Icon string
}
// UpIncome up_income
type UpIncome struct {
ID int64
MID int64
Income int64
AvIncome int64
ColumnIncome int64
BgmIncome int64
BaseIncome int64
AvBaseIncome int64
ColumnBaseIncome int64
BgmBaseIncome int64
TotalIncome int64
Date time.Time
}
// UpIncomeStat for up daily income analytics
type UpIncomeStat struct {
MID int64 `json:"-"`
Income int64 `json:"income"`
BaseIncome int64 `json:"base_income"`
ExtraIncome int64 `json:"extra_income"`
Breach int64 `json:"breach"`
Date time.Time `json:"date"`
}

View File

@@ -0,0 +1,129 @@
package model
import (
libTime "go-common/library/time"
)
// const text
const (
// TimeLayout time layout
TimeLayout = "2006-01-02 15:04:05"
)
// NewbieLetterReq newbie request
type NewbieLetterReq struct {
Aid int64 `form:"aid" validate:"required"`
Mid int64
}
// Category category
type Category struct {
ID int64 `json:"id"`
Pid int64 `json:"pid"`
Name string `json:"name"`
}
// CategoriesRes category result
type CategoriesRes struct {
Code int `json:"code"`
Data map[int64]*Category `json:"data"`
Message string `json:"message"`
}
// Activity activity
type Activity struct {
ID int64 `json:"-"`
AndroidUrl string `json:"-"`
H5Cover string `json:"-"`
ActUrl string `json:"act_url"`
IosUrl string `json:"-"`
Cover string `json:"cover"`
Type int32 `json:"type"`
}
// ActivitiesRes activities result
type ActivitiesRes struct {
Code int `json:"code"`
Data []*Activity `json:"data"`
Message string `json:"message"`
TTL int64 `json:"ttl"`
}
// VideoUpArchive video up archive
type VideoUpArchive struct {
Aid int64 `json:"aid"`
Mid int64 `json:"mid"`
Tid int64 `json:"tid"`
Title string `json:"title"`
PTime int64 `json:"ptime"`
}
// VideoUpVideo video up video
/*type VideoUpVideo struct {
}*/
// VideoUp video up
type VideoUp struct {
Archive *VideoUpArchive `json:"archive"`
//Videos []*VideoUpVideo `json:"videos"`
}
// VideoUpRes video up result
type VideoUpRes struct {
Code int `json:"code"`
Data *VideoUp `json:"data"`
Message string `json:"message"`
}
// Relation relation
type Relation struct {
Mid int64 `json:"mid"`
Attribute int `json:"attribute"`
Face string `json:"face"`
Name string `json:"name"`
}
// RelationsRes relation result
type RelationsRes struct {
Code int `json:"code"`
Data map[int64]*Relation `json:"data"`
Message string `json:"message"`
TTL int64 `json:"ttl"`
}
// RecommendUp table recommend up
type RecommendUp struct {
ID int64 `json:"id"`
Mid int64 `json:"mid"`
Tid int64 `json:"tid"`
SubTid int64 `json:"sub_tid"`
Reason string `json:"reason"`
Operator string `json:"operator"`
CTime libTime.Time `json:"ctime"`
MTime libTime.Time `json:"mtime"`
}
// NewbieLetterArchive newbie letter archive
type NewbieLetterArchive struct {
Mid int64 `json:"-"`
Tid int64 `json:"-"`
Title string `json:"title"`
PTime string `json:"ptime"`
}
// NewbieLetterUpInfo newbie letter up info
type NewbieLetterUpInfo struct {
Mid int64 `json:"mid"`
Name string `json:"name"`
}
// NewbieLetterRes newbie letter result
type NewbieLetterRes struct {
UperInfo *NewbieLetterUpInfo `json:"uper_info"`
Activities []*Activity `json:"activities"`
Relations []*Relation `json:"relations"`
Archive *NewbieLetterArchive `json:"archive"`
Talent string `json:"talent"`
Area string `json:"area"`
}

View File

@@ -0,0 +1,18 @@
package model
import (
"time"
)
// Notice notice
type Notice struct {
ID int64 `json:"id"`
Title string `json:"title"`
Type int `json:"type"`
Platform int `json:"-"`
Link string `json:"link"`
Status int `json:"-"`
IsDeleted int `json:"-"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"-"`
}

View File

@@ -0,0 +1,68 @@
package model
import (
"go-common/library/time"
)
// SpecialAward special award info
type SpecialAward struct {
AwardID int64 `json:"award_id"`
AwardName string `json:"award_name"`
Divisions []string `json:"divisions"`
CycleStart time.Time `json:"cycle_start"`
CycleEnd time.Time `json:"cycle_end"`
AnnounceDate time.Time `json:"announce_date"`
Duration int64 `json:"duration"`
OpenStatus int `json:"open_status"`
}
// Resource award resource
type Resource struct {
ResourceType int
ResourceIndex int
Content string
}
// WinningRecord winning record
type WinningRecord struct {
AwardID int64 `json:"award_id"`
AwardName string `json:"award_name"`
PrizeID int64 `json:"prize_id"`
State int `json:"state"`
}
// Poster poster
type Poster struct {
AwardName string `json:"award_name"`
Nickname string `json:"nickname"`
Face string `json:"face"`
PrizeName string `json:"prize_name"`
Date string `json:"date"`
Bonus int64 `json:"bonus"`
}
// SimpleSpecialAward simplify
type SimpleSpecialAward struct {
AwardName string `json:"award_name"`
AwardID int64 `json:"award_id"`
CycleStart time.Time `json:"cycle_start"`
}
// QA question & answer
type QA struct {
Question string `json:"question"`
Answer string `json:"answer"`
}
// UpAwardState up award state
type UpAwardState struct {
AwardID int64 `json:"-"`
AwardName string `json:"award_name"`
State int `json:"state"`
}
// AwardUpStatus up status
type AwardUpStatus struct {
Joined bool `json:"joined"`
Qualified bool `json:"qualified"`
}

View File

@@ -0,0 +1,64 @@
package model
import (
"time"
xtime "go-common/library/time"
)
// UpInfo is users of growup/video/column who applied for.
type UpInfo struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
Nickname string `json:"nickname"`
AccountType int `json:"account_type"`
OriginalArchiveCount int `json:"original_archive_count"`
MainCategory int `json:"category_id"`
Bgms int `json:"bgms"`
Fans int `json:"fans"`
TotalPlayCount int64 `json:"total_play_count"`
AccountState int `json:"account_state"`
SignType int `json:"sign_type,omitempty"`
Reason string `json:"reason"`
ApplyAt xtime.Time `json:"apply_at"`
SignedAt xtime.Time `json:"signed_at"`
RejectAt xtime.Time `json:"reject_at"`
ForbidAt xtime.Time `json:"forbid_at"`
QuitAt xtime.Time `json:"quit_at"`
DismissAt xtime.Time `json:"dismiss_at"`
ExpiredIn xtime.Time `json:"expired_in"`
IsDeleted int `json:"-"`
}
// UpStatus is user status of growup plan
type UpStatus struct {
Status []*BusinessStatus `json:"status"`
Blocked bool `json:"blocked"`
}
// BusinessStatus type: 1.视频 2.专栏 3.素材
type BusinessStatus struct {
IsWhite bool `json:"in_white_list"`
AccountState int `json:"account_state"`
AccountType int `json:"account_type"`
Type int `json:"type"`
Reason string `json:"reason"`
ShowPanel bool `json:"show_panel"`
ExpiredIn xtime.Time `json:"expired_in"`
QuitAt time.Time `json:"-"`
CTime time.Time `json:"-"`
}
// CreditRecord credit record
type CreditRecord struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
OperateAt xtime.Time `json:"operate_at"`
Operator string `json:"operator"`
Reason int `json:"reason"`
Deducted int `json:"deducted"`
Remaining int `json:"remaining"`
IsDeleted int `json:"recovered"`
CTime xtime.Time `json:"ctime"`
MTime xtime.Time `json:"mtime"`
}

View File

@@ -0,0 +1,28 @@
package model
import (
"go-common/library/time"
)
// UpBill up_bill
type UpBill struct {
MID int64 `json:"mid"`
Nickname string `json:"nickname"`
Face string `json:"face"`
FirstIncome int64 `json:"first_income"`
MaxIncome int64 `json:"max_income"`
TotalIncome int64 `json:"total_income"`
AvCount int64 `json:"av_count"`
AvMaxIncome int64 `json:"av_max_income"`
AvID int64 `json:"-"`
AvTitle string `json:"av_title"`
QualityValue int64 `json:"quality_value"`
DefeatNum int `json:"defeat_num"`
Title string `json:"title"`
ShareItems string `json:"share_items"`
FirstTime time.Time `json:"first_time"`
MaxTime time.Time `json:"max_time"`
SignedAt time.Time `json:"signed_at"`
EndAt time.Time `json:"end_at"`
Join bool `json:"join"`
}

View File

@@ -0,0 +1,45 @@
package model
import (
"go-common/library/time"
)
// UpAccount up account
type UpAccount struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
HasSignContract int `json:"has_sign_contract"`
State int `json:"state"`
TotalIncome int64 `json:"total_income"`
TotalUnwithdrawIncome int64 `json:"total_unwithdraw_income"`
TotalWithdrawIncome int64 `json:"total_withdraw_income"`
LastWithdrawTime time.Time `json:"last_withdraw_time"`
Version int64 `json:"version"`
IsDeleted int `json:"is_deleted"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"mtime"`
AllowanceState int `json:"allowance_state"`
Nickname string `json:"nick_name"`
WithdrawDateVersion string `json:"withdraw_date_version"`
}
// UpIncomeWithdraw up income withdraw
type UpIncomeWithdraw struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
WithdrawIncome int64 `json:"withdraw_income"`
DateVersion string `json:"date_version"`
State int `json:"state"`
IsDeleted int `json:"is_deleted"`
CTime time.Time `json:"ctime"`
MTime time.Time `json:"mtime"`
}
// WithdrawVo withdraw
type WithdrawVo struct {
MID int64 `json:"mid"`
ThirdOrderNo string `json:"third_order_no"`
ThirdCoin float64 `json:"third_coin"`
CTime string `json:"ctime"`
NotifyURL string `json:"notify_url"`
}

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 = [
"income_test.go",
"notice_test.go",
"service_test.go",
"withdraw_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/growup/conf:go_default_library",
"//app/interface/main/growup/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"activity.go",
"archive_stat.go",
"banner.go",
"bgm.go",
"column.go",
"exchange.go",
"income.go",
"notice.go",
"service.go",
"snow_flake.go",
"special_award.go",
"up_bill.go",
"up_status.go",
"up_year.go",
"withdraw.go",
],
importpath = "go-common/app/interface/main/growup/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/growup/conf:go_default_library",
"//app/interface/main/growup/dao:go_default_library",
"//app/interface/main/growup/model:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
"//library/time:go_default_library",
"//library/xstr:go_default_library",
"//vendor/golang.org/x/sync/errgroup:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/interface/main/growup/service/newbie:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,153 @@
package service
import (
"context"
"sort"
"time"
"go-common/app/interface/main/growup/model"
"go-common/library/log"
xtime "go-common/library/time"
)
const (
_canEnrol = iota // 未报名,可以报名
_hasEnrol // 已报名
_win // 中奖
_notEnrol // 不能报名
_enrolEnd // 报名已结束
)
// ShowActivity show creative_activity
func (s *Service) ShowActivity(c context.Context, mid, activityID int64) (ac *model.CActivity, err error) {
ac, err = s.dao.GetActivity(c, activityID)
if err != nil {
log.Error("s.dao.GetActivity error(%v)", err)
return
}
enrolNum, winNum, mids, upState, err := s.handleUpActivity(c, mid, activityID)
if err != nil {
log.Error("s.handleUpActivity error(%v)", err)
return
}
// 当前时间是否可以展示
now := xtime.Time(time.Now().Unix())
if ac.UpdatePage == 1 && now >= ac.ProgressStart && now <= ac.ProgressEnd {
ac.ProgressState = 1
ac.Enrollment = enrolNum
ac.WinNum = winNum
// 2: 中奖类型为排序型
if ac.WinType == 2 {
ac.Ranking, err = s.getActUpInfo(c, mids)
if err != nil {
log.Error("s.getActUpInfo error(%v)", err)
return
}
}
}
if !(ac.BonusQuery == 1 && now >= ac.BonusQueryStart && now <= ac.BonusQueryEnd) {
ac.BonusQuery = 0
}
// 获取up主当前状态
ac.SignUpState, err = s.getSignUpState(c, mid, upState, ac)
if err != nil {
log.Error("s.getSignUpState error(%v)", err)
}
return
}
// get mid name and face
func (s *Service) getActUpInfo(c context.Context, mids []int64) (upInfos []*model.ActUpInfo, err error) {
upInfoMap, err := s.dao.AccountInfos(c, mids)
if err != nil {
return
}
upInfos = make([]*model.ActUpInfo, len(upInfoMap))
for i := 0; i < len(mids); i++ {
upInfos[i] = upInfoMap[mids[i]]
}
return
}
func (s *Service) getSignUpState(c context.Context, mid int64, upState int, ac *model.CActivity) (signUpState int, err error) {
now := xtime.Time(time.Now().Unix())
// 报名未开始,不能报名
if now < ac.SignUpStart {
signUpState = _notEnrol
return
}
// 报名已结束并且未中奖
if now > ac.SignUpEnd && upState != _win {
upState = _enrolEnd
}
// 已报名
if upState >= _hasEnrol {
signUpState = upState
return
}
// 签约结束时间 >= 报名结束时间, 任何人都可以报名
if ac.SignedEnd >= ac.SignUpEnd {
signUpState = _canEnrol
} else {
var signedAt xtime.Time
signedAt, err = s.dao.GetUpSignedAt(c, "up_info_video", mid)
if err != nil {
return
}
if signedAt >= ac.SignedStart && signedAt <= ac.SignedEnd {
signUpState = _canEnrol
} else {
signUpState = _notEnrol
}
}
return
}
func (s *Service) handleUpActivity(c context.Context, mid, activityID int64) (enrol, win int, mids []int64, upState int, err error) {
ups, err := s.dao.ListUpActivity(c, activityID)
if err != nil {
return
}
sort.Slice(ups, func(i, j int) bool {
return ups[i].Rank < ups[j].Rank
})
mids = make([]int64, 0)
for _, up := range ups {
if up.State >= _win {
win++
enrol++
mids = append(mids, up.MID)
} else if up.State == _hasEnrol {
enrol++
}
if up.MID == mid {
upState = up.State
// 已发奖
if upState == 3 {
upState = 2
}
}
}
return
}
// SignUpActivity up sign up activity
func (s *Service) SignUpActivity(c context.Context, mid, activityID int64) (err error) {
nickname, _, err := s.dao.CategoryInfo(c, mid)
if err != nil {
log.Error("s.dao.CategoryInfo error(%v)", err)
return
}
upBonus := &model.UpBonus{
MID: mid,
ActivityID: activityID,
Nickname: nickname,
State: 1,
SignUpTime: xtime.Time(time.Now().Unix()),
}
if _, err = s.dao.SignUpActivity(c, upBonus); err != nil {
log.Error("s.dao.SignUpActivity error(%v)", err)
}
return
}

View File

@@ -0,0 +1,28 @@
package service
import (
"context"
"time"
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/log"
)
// avStat get stat from hbase.
func (s *Service) avStat(c context.Context, mid int64, ip string) (up *model.UpBaseStat, err error) {
hbaseDate := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
up, err = s.dao.UpStat(c, mid, hbaseDate)
if err != nil || up == nil {
log.Error("s.data.UpStat error(%v) mid(%d) up(%v) ip(%s)", err, mid, up, ip)
err = ecode.CreativeDataErr
return
}
pfl, err := s.dao.ProfileWithStat(c, mid)
if err != nil {
return
}
up.Fans = int64(pfl.Follower)
log.Info("s.data.UpStat hbaseDate(%+v) mid(%d)", up, mid)
return
}

View File

@@ -0,0 +1,13 @@
package service
import (
"context"
"time"
"go-common/app/interface/main/growup/model"
)
// GetBanner get banner for now
func (s *Service) GetBanner(c context.Context) (b *model.Banner, err error) {
return s.dao.Banner(c, time.Now().Unix())
}

View File

@@ -0,0 +1,102 @@
package service
import (
"context"
"time"
"go-common/app/interface/main/growup/model"
"go-common/library/database/sql"
"go-common/library/ecode"
"go-common/library/log"
xtime "go-common/library/time"
)
// JoinBgm join bgm
func (s *Service) JoinBgm(c context.Context, mid int64, accountType, signType int) (err error) {
id, err := s.dao.Blocked(c, mid)
if err != nil {
log.Error("s.dao.GetBlocked mid(%d) error(%v)", mid, err)
return
}
if id != 0 {
log.Info("mid(%d) is blocked", mid)
return ecode.GrowupDisabled
}
ok, err := s.checkBgmStat(c, mid)
if err != nil {
log.Info("s.checkBgmStat error(%v)", err)
return
}
if !ok {
return ecode.GrowupDisabled
}
count, err := s.dao.BGMCount(c, mid)
if err != nil {
log.Info("s.dao.BGMCount error(%v)", err)
return
}
avStat, err := s.dao.GetAccountState(c, "up_info_video", mid)
if err != nil {
return
}
if avStat >= 5 && avStat <= 7 {
return ecode.GrowupDisabled
}
columnStat, err := s.dao.GetAccountState(c, "up_info_column", mid)
if err != nil {
return
}
if columnStat >= 5 && columnStat <= 7 {
return ecode.GrowupDisabled
}
card, err := s.dao.Card(c, mid)
if err != nil {
log.Error("s.dao.Card(%d) error(%v)", mid, err)
return
}
fans, err := s.dao.Fans(c, mid)
if err != nil {
return
}
now := xtime.Time(time.Now().Unix())
// sign_type: 1.basic; 2.first publish; 0:default.
v := &model.UpInfo{
MID: mid,
Nickname: card.Name,
AccountType: accountType,
Fans: fans,
SignType: signType,
SignedAt: now,
Bgms: count,
}
var tx *sql.Tx
if tx, err = s.dao.BeginTran(c); err != nil {
return
}
if _, err = s.dao.TxInsertBgmUpInfo(tx, v); err != nil {
tx.Rollback()
return
}
if _, err = s.dao.TxInsertCreditScore(tx, mid); err != nil {
tx.Rollback()
return
}
err = tx.Commit()
if err != nil {
log.Error("tx.Commit error(%v)", err)
}
return
}

View File

@@ -0,0 +1,76 @@
package service
import (
"context"
"time"
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
xtime "go-common/library/time"
)
// JoinColumn join up to creative column
func (s *Service) JoinColumn(c context.Context, mid int64, accountType, signType int) (err error) {
id, err := s.dao.Blocked(c, mid)
if err != nil {
log.Error("s.dao.GetBlocked mid(%d) error(%v)", mid, err)
return
}
if id != 0 {
log.Info("mid(%d) is blocked", mid)
return ecode.GrowupDisabled
}
// get up view
ip := metadata.String(c, metadata.RemoteIP)
stat, err := s.dao.ArticleStat(c, mid, ip)
if err != nil {
log.Error("s.dao.ArticleStat mid(%d) error(%v)", mid, err)
return
}
if stat.View < s.conf.Threshold.LimitArticleView {
log.Info("mid(%d) view(%s) not reach standard", mid, stat.View)
return ecode.GrowupDisabled
}
// get up nickname
card, err := s.dao.Card(c, mid)
if err != nil {
log.Error("s.dao.Card(%d) error(%v)", mid, err)
return
}
fans, err := s.dao.Fans(c, mid)
if err != nil {
return
}
state, err := s.dao.GetAccountState(c, "up_info_column", mid)
if err != nil {
return
}
// if account state is 2 3 4 5 6 7 return
if state >= 2 && state < 8 {
return
}
now := xtime.Time(time.Now().Unix())
// sign_type: 1.basic; 2.first publish; 0:default.
v := &model.UpInfo{
MID: mid,
Nickname: card.Name,
AccountType: accountType,
MainCategory: 0,
Fans: fans,
AccountState: 2,
SignType: signType,
ApplyAt: now,
TotalPlayCount: stat.View,
}
_, err = s.dao.InsertUpInfo(c, "up_info_column", "total_view_count", v)
return
}

View File

@@ -0,0 +1,250 @@
package service
import (
"context"
"fmt"
"sort"
"time"
"go-common/app/interface/main/growup/dao"
"go-common/app/interface/main/growup/model"
"go-common/library/ecode"
"go-common/library/log"
xtime "go-common/library/time"
)
var (
_display = 2
_bigVipType = 1
_remark = "激励兑换"
)
// GoodsState get goods new state
func (s *Service) GoodsState(c context.Context) (data interface{}, err error) {
var newDisplay string
goods, err := s.dao.GetDisplayGoods(c, _display)
if err != nil {
log.Error("s.dao.GetDisplayGoods error(%v)", err)
return
}
if len(goods) > 0 {
sort.Slice(goods, func(i, j int) bool {
return goods[i].DisplayOnTime > goods[j].DisplayOnTime
})
newDisplay = fmt.Sprintf("%s+%d+%d", goods[0].ProductID, goods[0].GoodsType, goods[0].DisplayOnTime)
}
data = map[string]interface{}{
"new_display": newDisplay,
"open_exchange": time.Now().Day() >= 8, // 1-7号不开放兑换
}
return
}
// GoodsShow show goods
func (s *Service) GoodsShow(c context.Context, mid int64) (goods []*model.GoodsInfo, err error) {
goods, err = s.dao.GetDisplayGoods(c, _display)
if err != nil {
log.Error("s.dao.GetDisplayGoods error(%v)", err)
return
}
vips, err := s.dao.ListVipProducts(c, mid)
if err != nil {
log.Error("s.dao.ListVipProducts error(%v)", err)
return
}
// get vip price
for _, g := range goods {
if g.GoodsType != _bigVipType {
continue
}
if v, ok := vips[g.ProductID]; ok {
g.Month = v.Month
g.ProductName = v.ProductName
g.OriginPrice = v.OriginPrice
g.CurrentPrice = int64(dao.Round(dao.Mul(float64(v.OriginPrice), float64(g.Discount)/float64(100)), 0))
}
}
sort.Slice(goods, func(i, j int) bool {
return goods[i].Month < goods[j].Month
})
return
}
// GoodsRecord get goods record
func (s *Service) GoodsRecord(c context.Context, mid int64, page, size int) (monthOrder map[string][]*model.GoodsOrder, count int, err error) {
monthOrder = make(map[string][]*model.GoodsOrder)
if page == 0 {
page = 1
}
start, end := (page-1)*size, page*size
count, err = s.dao.GetGoodsOrderCount(c, mid)
if err != nil {
log.Error("s.dao.GetGoodsRecordCount error(%v)", err)
return
}
orders, err := s.dao.GetGoodsOrders(c, mid, start, end)
if err != nil {
log.Error("s.dao.GetGoodsOrders error(%v)", err)
return
}
for i := 0; i < len(orders); i++ {
month := orders[i].OrderTime.Time().Format("2006-01")
if _, ok := monthOrder[month]; !ok {
monthOrder[month] = make([]*model.GoodsOrder, 0)
}
monthOrder[month] = append(monthOrder[month], orders[i])
}
return
}
// GoodsBuy buy goods from creative
func (s *Service) GoodsBuy(c context.Context, mid int64, productID string, goodsType int, price int64) (err error) {
date := time.Now()
// 1-7号不开放兑换
if date.Day() < 8 {
err = ecode.GrowupGoodsTimeErr
return
}
p, err := s.getProduct(c, mid, productID, goodsType)
if err != nil {
log.Error("s.getProduct error(%v)", err)
return
}
p.CurrentPrice = int64(dao.Round(dao.Mul(float64(p.OriginPrice), float64(p.Discount)/float64(100)), 0))
if price != p.CurrentPrice {
err = ecode.GrowupPriceErr
return
}
// check upwithdraw_income
upAccount, totalUnwithdraw, err := s.getUpTotalUnwithdraw(c, mid)
if err != nil {
log.Error("s.getUpTotalUnwithdraw error(%v)", err)
return
}
if totalUnwithdraw < p.CurrentPrice {
err = ecode.GrowupPriceNotEnough
return
}
uuid, err := s.sf.Generate()
if err != nil {
return
}
order := &model.GoodsOrder{
MID: mid,
OrderNo: fmt.Sprintf("DHY-%s-%d-%d", date.Format("20060102150405"), uuid, mid),
OrderTime: xtime.Time(date.Unix()),
GoodsType: p.GoodsType,
GoodsID: productID,
GoodsName: p.ProductName,
GoodsPrice: p.CurrentPrice,
GoodsCost: p.OriginPrice,
}
// 清除up_summary redis缓存
if err = s.dao.DelCacheKey(c, fmt.Sprintf("growup-up-summary:%d", mid)); err != nil {
log.Error("s.dao.DelCacheKey error(%v)", err)
return
}
tx, err := s.dao.BeginTran(c)
if err != nil {
log.Error("s.dao.BeginTran error(%v)", err)
return
}
// update up account
rows, err := s.dao.TxUpdateUpAccountExchangeIncome(tx, mid, p.CurrentPrice, upAccount.Version)
if err != nil {
tx.Rollback()
log.Error("s.dao.TxUpdateUpAccountExchangeIncome error(%v)", err)
return
}
if rows != 1 {
tx.Rollback()
log.Error("s.dao.TxUpdateUpAccountExchangeIncome update rows(%d) != 1")
err = ecode.GrowupBuyErr
return
}
// generate order
rows, err = s.dao.TxInsertGoodsOrder(tx, order)
if err != nil {
tx.Rollback()
log.Error("s.dao.InsertGoodsOrder error(%v)", err)
return
}
if rows != 1 {
tx.Rollback()
log.Error("s.dao.InsertGoodsOrder insert rows(%d) != 1", rows)
err = ecode.GrowupBuyErr
return
}
// use vip batch info
if err = s.dao.ExchangeBigVIP(c, mid, p.ResourceID, uuid, _remark); err != nil {
tx.Rollback()
log.Error("s.dao.ExchangeBigVIP error(%v)", err)
err = ecode.GrowupBuyErr
return
}
if err = tx.Commit(); err != nil {
log.Error("tx.Commit error")
}
return
}
func (s *Service) getProduct(c context.Context, mid int64, productID string, goodsType int) (p *model.GoodsInfo, err error) {
p, err = s.dao.GetGoodsByProductID(c, productID, goodsType)
if err != nil {
log.Error("s.dao.GetGoodsByProductID error(%v)", err)
return
}
vips, err := s.dao.ListVipProducts(c, mid)
if err != nil {
log.Error("s.dao.ListVipProducts error(%v)", err)
return
}
// check ResourceID
if p.ResourceID == 0 || len(vips) == 0 {
err = ecode.GrowupGoodsNotExist
return
}
vip, ok := vips[productID]
if !ok {
err = ecode.GrowupGoodsNotExist
return
}
p.OriginPrice = vip.OriginPrice
p.ProductName = vip.ProductName
return
}
func (s *Service) getUpTotalUnwithdraw(c context.Context, mid int64) (upAccount *model.UpAccount, unwithdraw int64, err error) {
lastDay := time.Now().AddDate(0, 0, -1)
upIncomes, err := s.dao.ListUpIncome(c, mid, "up_income", lastDay.Format(_layout), lastDay.Format(_layout))
if err != nil {
log.Error("s.dao.ListUpIncome error(%v)", err)
return
}
var lastDayIncome int64
for _, up := range upIncomes {
if up.Date.Time().Format(_layout) == lastDay.Format(_layout) {
lastDayIncome = up.Income
}
}
upAccount, err = s.dao.ListUpAccount(c, mid)
if err != nil {
log.Error("s.dao.ListUpAccount error(%v)", err)
return
}
if upAccount == nil {
err = ecode.GrowupPriceNotEnough
return
}
unwithdraw = upAccount.TotalUnwithdrawIncome - lastDayIncome
return
}

View File

@@ -0,0 +1,834 @@
package service
import (
"context"
"crypto/md5"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"sort"
"strconv"
"time"
"go-common/app/interface/main/growup/model"
"go-common/library/log"
xtime "go-common/library/time"
"go-common/library/xstr"
)
const (
_video = iota
_audio
_column
_bgm
_up
)
var (
_layout = "2006-01-02"
)
// GetUpCharge get up daily sum(charge) last 30 days
func (s *Service) GetUpCharge(c context.Context, mid int64, t time.Time) (total int, err error) {
begin := t.AddDate(0, 0, -30).Format(_layout)
incs, err := s.dao.GetUpDailyCharge(c, mid, begin)
if err != nil {
return
}
for _, inc := range incs {
total += inc
}
total = int(float64(total) * float64(0.6))
return
}
// ArchiveIncome get archive income by mid
func (s *Service) ArchiveIncome(c context.Context, mid int64, typ, page, size, all int) (data map[string]interface{}, err error) {
redisKey := fmt.Sprintf("growup-archive-income:%d+%d+%d+%d+%d", typ, mid, all, page, size)
data, err = s.dao.GetIncomeCache(c, redisKey)
if err != nil {
log.Error("s.dao.GetIncomeCache error(%v)", err)
return
}
if data != nil {
return
}
data, err = s.archiveIncome(c, mid, typ, page, size, all)
if err != nil {
log.Error("s.archiveIncome error(%v)", err)
return
}
err = s.dao.SetIncomeCache(c, redisKey, data)
if err != nil {
log.Error("s.dao.SetIncomeCache error(%v)", err)
}
return
}
// archiveIncome get archive income by mid
func (s *Service) archiveIncome(c context.Context, mid int64, typ, page, size, all int) (data map[string]interface{}, err error) {
data = make(map[string]interface{})
if page == 0 {
page = 1
}
start, end := (page-1)*size, page*size
date := time.Now().AddDate(0, 0, -2)
startMonth := time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.Local).Format(_layout)
if all == 1 {
startMonth = "2017-12-01"
}
var (
archives []*model.ArchiveIncome
total int
)
switch typ {
case _video:
archives, total, err = s.listAvIncome(c, mid, startMonth, date.Format(_layout), start, end)
case _audio:
case _column:
archives, total, err = s.listColumnIncome(c, mid, startMonth, date.Format(_layout), start, end)
case _bgm:
archives, total, err = s.listBgmIncome(c, mid, startMonth, date.Format(_layout), start, end)
}
if err != nil {
log.Error("s.archiveIncome error(%v)", err)
return nil, err
}
data["data"] = archives
data["total_count"] = total
data["page"] = page
return
}
func (s *Service) listAvIncome(c context.Context, mid int64, startTime, endTime string, start, end int) (archiveList []*model.ArchiveIncome, total int, err error) {
avs, err := s.dao.ListAvIncome(c, mid, startTime, endTime)
if err != nil {
log.Error("s.dao.ListAvIncome error(%v)", err)
return
}
return s.handleArchiveIncome(c, avs, start, end, _video)
}
func (s *Service) listColumnIncome(c context.Context, mid int64, startTime, endTime string, start, end int) (archiveList []*model.ArchiveIncome, total int, err error) {
columns, err := s.dao.ListColumnIncome(c, mid, startTime, endTime)
if err != nil {
log.Error("s.dao.ListColumnIncome error(%v)", err)
return
}
return s.handleArchiveIncome(c, columns, start, end, _column)
}
func (s *Service) listBgmIncome(c context.Context, mid int64, startTime, endTime string, start, end int) (archiveList []*model.ArchiveIncome, total int, err error) {
bgms, err := s.dao.ListBgmIncome(c, mid, startTime, endTime)
if err != nil {
log.Error("s.dao.ListBgmIncome error(%v)", err)
return
}
return s.handleArchiveIncome(c, bgms, start, end, _bgm)
}
func calArchiveIncome(archives []*model.ArchiveIncome, avBMap map[int64]struct{}) (archiveMap map[int64]*model.ArchiveIncome) {
endTime := time.Now().AddDate(0, 0, -2)
archiveMap = make(map[int64]*model.ArchiveIncome)
archMonthIncome := make(map[int64]int64)
for _, arch := range archives {
if _, ok := avBMap[arch.ArchiveID]; ok {
continue
}
archiveDate := arch.Date.Time()
// cal month income
if archiveDate.Month() == endTime.Month() {
archMonthIncome[arch.ArchiveID] += arch.Income
}
if archiveDate.Format(_layout) != endTime.Format(_layout) {
arch.Income = 0
}
if old, ok := archiveMap[arch.ArchiveID]; !ok {
archiveMap[arch.ArchiveID] = arch
} else {
if old.Date < arch.Date {
archiveMap[arch.ArchiveID] = arch
}
}
archiveMap[arch.ArchiveID].MonthIncome = archMonthIncome[arch.ArchiveID]
}
return
}
func (s *Service) handleArchiveIncome(c context.Context, archives []*model.ArchiveIncome, start, end, typ int) (archiveList []*model.ArchiveIncome, total int, err error) {
archiveList = make([]*model.ArchiveIncome, 0)
if len(archives) == 0 {
return
}
aIDMap := make(map[int64]struct{})
aIDList := []int64{}
for _, arch := range archives {
if _, ok := aIDMap[arch.ArchiveID]; !ok {
aIDMap[arch.ArchiveID] = struct{}{}
aIDList = append(aIDList, arch.ArchiveID)
}
}
avBMap, err := s.dao.ListAvBlackList(c, aIDList, typ)
if err != nil {
log.Error("s.dao.ListAvBlackList error(%v)", err)
return
}
avsMap := calArchiveIncome(archives, avBMap)
for _, av := range avsMap {
archiveList = append(archiveList, av)
}
sort.Slice(archiveList, func(i, j int) bool {
if archiveList[i].Income == archiveList[j].Income {
if archiveList[i].MonthIncome == archiveList[j].MonthIncome {
return archiveList[i].TotalIncome > archiveList[j].TotalIncome
}
return archiveList[i].MonthIncome > archiveList[j].MonthIncome
}
return archiveList[i].Income > archiveList[j].Income
})
total = len(archiveList)
if end > total {
end = total
}
if start >= total || start > end {
return
}
archiveList = archiveList[start:end]
avIDs := []int64{}
for _, av := range archiveList {
avIDs = append(avIDs, av.ArchiveID)
}
titles := make(map[int64]string)
switch typ {
case _video:
titles, err = s.getAvTitle(c, avIDs)
if err != nil {
log.Error("s.getAvTitle error(%v)", err)
return
}
case _column:
titles, err = s.getColumnTitle(c, avIDs)
if err != nil {
log.Error("s.getColumnTitle error(%v)", err)
return
}
case _bgm:
titles, err = s.getBgmTitle(c, avIDs)
if err != nil {
log.Error("s.getBgmTitle error(%v)", err)
return
}
}
icons, err := s.getAvIcon(c, avIDs)
if err != nil {
log.Error("s.getAvIcon error(%v)", err)
return
}
breachs, err := s.getAvBreach(c, avIDs, typ)
if err != nil {
log.Error("s.getAvBreach error(%v)", err)
return
}
for _, av := range archiveList {
av.Title = titles[av.ArchiveID]
av.Icon = icons[av.ArchiveID]
av.Breach = breachs[av.ArchiveID]
}
return
}
func (s *Service) getColumnTitle(c context.Context, avs []int64) (titles map[int64]string, err error) {
return s.dao.GetColumnTitle(c, avs)
}
func (s *Service) getBgmTitle(c context.Context, avs []int64) (titles map[int64]string, err error) {
return s.dao.GetBgmTitle(c, avs)
}
func (s *Service) getAvTitle(c context.Context, avs []int64) (titles map[int64]string, err error) {
req, err := http.NewRequest("GET", s.conf.Host.ArchiveURI, nil)
if err != nil {
log.Error("http.NewRequest error(%v)", err)
return
}
q := req.URL.Query()
q.Add("aids", xstr.JoinInts(avs))
q.Add("appkey", s.conf.AppConf.Key)
now := time.Now().Unix()
q.Add("ts", strconv.FormatInt(now, 10))
sign := q.Encode() + s.conf.AppConf.Secret
q.Add("sign", fmt.Sprintf("%x", md5.Sum([]byte(sign))))
req.URL.RawQuery = q.Encode()
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Error("http.DefaultClient.Do error(%v)", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Error("ioutil.ReadAll error(%v)", err)
return
}
res := model.ArchiveRes{}
err = json.Unmarshal(body, &res)
if err != nil {
log.Error("json.Unmarshal body %s error(%v)", string(body), err)
return
}
titles = make(map[int64]string)
for _, archive := range res.Data {
titles[archive.AID] = archive.Title
}
return
}
func (s *Service) getAvIcon(c context.Context, avs []int64) (acM map[int64]string, err error) {
if len(avs) == 0 {
return
}
activeM, err := s.dao.ListActiveInfo(c, avs)
if err != nil {
log.Error("s.dao.ListActiveInfo error(%v)", err)
return
}
tagIDM := make(map[int64]struct{})
for _, tagID := range activeM {
tagIDM[tagID] = struct{}{}
}
tagIDList := make([]int64, 0)
for tagID := range tagIDM {
tagIDList = append(tagIDList, tagID)
}
if len(tagIDList) == 0 {
return
}
tagIconM, err := s.dao.ListTagInfo(c, tagIDList)
if err != nil {
log.Error("s.dao.ListTagInfo error(%v)", err)
return
}
acM = make(map[int64]string)
for avID, tagID := range activeM {
if _, ok := tagIconM[tagID]; ok {
acM[avID] = tagIconM[tagID].Icon
}
}
return
}
func (s *Service) getAvBreach(c context.Context, avs []int64, typ int) (breachs map[int64]*model.AvBreach, err error) {
if len(avs) == 0 {
return
}
return s.dao.GetAvBreachs(c, avs, typ)
}
// UpSummary summary up income
func (s *Service) UpSummary(c context.Context, mid int64) (data interface{}, err error) {
redisKey := fmt.Sprintf("growup-up-summary:%d", mid)
res, err := s.dao.GetIncomeCache(c, redisKey)
if err != nil {
log.Error("s.dao.GetIncomeCache error(%v)", err)
return
}
if res != nil {
data = res["data"]
return
}
data, err = s.upSummary(c, mid)
if err != nil {
log.Error("s.upSummary error(%v)", err)
return
}
err = s.dao.SetIncomeCache(c, redisKey, map[string]interface{}{"data": data})
if err != nil {
log.Error("s.dao.SetIncomeCache error(%v)", err)
}
return
}
func (s *Service) upSummary(c context.Context, mid int64) (data interface{}, err error) {
summary := new(struct {
DayIncome string `json:"day_income"`
Date string `json:"date"`
Income string `json:"income"`
TotalIncome string `json:"total_income"`
WaitWithdraw string `json:"wait_withdraw"`
BreachMoney string `json:"breach_money"`
UnwithdrawDate string `json:"unwithdraw_date"`
})
summary.DayIncome, summary.Income, summary.TotalIncome, summary.WaitWithdraw, summary.BreachMoney = "0", "0", "0", "0", "0"
now := time.Now().AddDate(0, 0, -2)
nowMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
count, err := s.dao.GetUpIncomeCount(c, now.Format(_layout))
if err != nil {
log.Error("s.dao.GetUpIncomeCount error(%v)", err)
return
}
if count <= 0 {
summary.DayIncome, summary.Income, summary.TotalIncome, summary.WaitWithdraw, summary.BreachMoney = "-1", "-1", "-1", "-1", "-1"
data = summary
return
}
upIncomes, err := s.dao.ListUpIncome(c, mid, "up_income", nowMonth.Format(_layout), now.AddDate(0, 0, 1).Format(_layout))
if err != nil {
log.Error("s.dao.ListUpIncome error(%v)", err)
return
}
var monthIncome, lastDayIncome, dayIncome int64
for _, up := range upIncomes {
if up.Date.Time().Format(_layout) == now.Format(_layout) {
dayIncome = up.Income
}
if up.Date.Time().Format(_layout) == now.AddDate(0, 0, 1).Format(_layout) {
lastDayIncome = up.Income
}
monthIncome += up.Income
}
upAccount, err := s.dao.ListUpAccount(c, mid)
if err != nil {
log.Error("s.dao.ListUpAccount error(%v)", err)
return
}
if upAccount == nil {
data = summary
return
}
breachs, err := s.dao.ListAvBreach(c, mid, nowMonth.Format(_layout), time.Now().Format(_layout))
if err != nil {
log.Error("s.dao.ListAvBreach error(%v)", err)
return
}
var breachMoney int64
for _, b := range breachs {
breachMoney += b.Money
}
summary.DayIncome = fmt.Sprintf("%.2f", fromYuanToFen(dayIncome))
summary.BreachMoney = fmt.Sprintf("%.2f", fromYuanToFen(breachMoney))
summary.TotalIncome = fmt.Sprintf("%.2f", fromYuanToFen(upAccount.TotalIncome-lastDayIncome))
summary.Date = now.Format(_layout)
wdv, err := time.Parse("2006-01", upAccount.WithdrawDateVersion)
if err != nil {
log.Error("time.Parse error(%v)", err)
return
}
summary.UnwithdrawDate = time.Date(wdv.Year(), wdv.Month()+1, 1, 0, 0, 0, 0, time.Local).Format("2006-01")
// 如果T-1的month不等于T-2的month 当月新增不需要减去那一天的收入:lastDayIncome = 0
if now.AddDate(0, 0, 1).Month() == now.Month() {
monthIncome -= lastDayIncome
}
summary.Income = fmt.Sprintf("%.2f", fromYuanToFen(monthIncome))
// 当月未提现,待结算不能减去昨天收入,当月已提现,需要减去昨日收入
preMonth := time.Date(nowMonth.Year(), nowMonth.Month()-1, 1, 0, 0, 0, 0, time.Local).Format("2006-01")
if preMonth != upAccount.WithdrawDateVersion || now.AddDate(0, 0, 1).Month() != now.Month() {
lastDayIncome = 0
}
summary.WaitWithdraw = fmt.Sprintf("%.2f", fromYuanToFen(upAccount.TotalUnwithdrawIncome-lastDayIncome))
data = summary
return
}
func fromYuanToFen(income int64) float64 {
return float64(income) / float64(100)
}
// ArchiveSummary get archive summary
func (s *Service) ArchiveSummary(c context.Context, typ int, mid int64) (data interface{}, err error) {
redisKey := fmt.Sprintf("growup-archive-summary:%d+%d", typ, mid)
res, err := s.dao.GetIncomeCache(c, redisKey)
if err != nil {
log.Error("s.dao.GetIncomeCache error(%v)", err)
return
}
if res != nil {
data = res["data"]
return
}
data, err = s.archiveSummary(c, typ, mid)
if err != nil {
log.Error("s.archiveSummary error(%v)", err)
return
}
err = s.dao.SetIncomeCache(c, redisKey, map[string]interface{}{"data": data})
if err != nil {
log.Error("s.dao.SetIncomeCache error(%v)", err)
}
return
}
func (s *Service) archiveSummary(c context.Context, typ int, mid int64) (data interface{}, err error) {
date := time.Now().AddDate(0, 0, -2)
startMonth := xtime.Time(time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.Local).Unix())
upIncomes, err := s.dao.ListUpIncome(c, mid, "up_income", "2017-12-01", date.Format(_layout))
if err != nil {
log.Error("s.dao.ListUpIncome error(%v)", err)
return
}
summary := new(struct {
DayIncome int64 `json:"day_income"`
Date string `json:"date"`
MonthIncome int64 `json:"income"`
TotalIncome int64 `json:"total_income"`
Breach int64 `json:"breach_money"`
})
if len(upIncomes) == 0 {
data = summary
return
}
sort.Slice(upIncomes, func(i, j int) bool {
return upIncomes[i].Date > upIncomes[j].Date
})
summary.Date = date.Format(_layout)
if upIncomes[0].Date.Time().Format(_layout) == summary.Date {
switch typ {
case _video:
summary.DayIncome = upIncomes[0].AvIncome
case _column:
summary.DayIncome = upIncomes[0].ColumnIncome
case _bgm:
summary.DayIncome = upIncomes[0].BgmIncome
}
}
var breachType []int64
for _, up := range upIncomes {
if up.Date >= startMonth {
switch typ {
case _video:
summary.MonthIncome += up.AvIncome
case _column:
summary.MonthIncome += up.ColumnIncome
case _bgm:
summary.MonthIncome += up.BgmIncome
}
}
switch typ {
case _video:
breachType = []int64{0}
summary.TotalIncome += up.AvIncome
case _column:
breachType = []int64{2}
summary.TotalIncome += up.ColumnIncome
case _bgm:
breachType = []int64{3}
summary.TotalIncome += up.BgmIncome
}
}
breach, err := s.dao.GetAvBreachByType(c, mid, "2017-12-01", time.Now().Format(_layout), breachType)
if err != nil {
log.Error("s.dao.GetAvBreachByType error(%v)", err)
return
}
for d, money := range breach {
if d >= startMonth {
summary.Breach += money
}
summary.TotalIncome -= money
}
if summary.TotalIncome < 0 {
summary.TotalIncome = 0
}
data = summary
return
}
// ArchiveDetail cal archive detail
func (s *Service) ArchiveDetail(c context.Context, typ int, archiveID int64) (data interface{}, err error) {
redisKey := fmt.Sprintf("growup-archive-detail:%d+%d", typ, archiveID)
res, err := s.dao.GetIncomeCache(c, redisKey)
if err != nil {
log.Error("s.dao.GetIncomeCache error(%v)", err)
return
}
if res != nil {
data = res["data"]
return
}
data, err = s.archiveDetail(c, typ, archiveID)
if err != nil {
log.Error("s.archiveDetail error(%v)", err)
return
}
err = s.dao.SetIncomeCache(c, redisKey, map[string]interface{}{"data": data})
if err != nil {
log.Error("s.dao.SetIncomeCache error(%v)", err)
}
return
}
func (s *Service) archiveDetail(c context.Context, typ int, archiveID int64) (archives []*model.ArchiveIncome, err error) {
archives = make([]*model.ArchiveIncome, 0)
endTime := time.Now().AddDate(0, 0, -2).Format(_layout)
switch typ {
case _video:
archives, err = s.dao.ListAvIncomeByID(c, archiveID, endTime)
if err != nil {
log.Error("s.dao.ListAvIncomeByID error(%v)", err)
return
}
case _audio:
case _column:
archives, err = s.dao.ListColumnIncomeByID(c, archiveID, endTime)
if err != nil {
log.Error("s.dao.ListColumnIncomeByID error(%v)", err)
return
}
case _bgm:
archives, err = s.listBgmIncomeByID(c, archiveID, endTime)
if err != nil {
return
}
}
sort.Slice(archives, func(i, j int) bool {
return archives[i].Date > archives[j].Date
})
return
}
func (s *Service) listBgmIncomeByID(c context.Context, archiveID int64, endTime string) (archives []*model.ArchiveIncome, err error) {
as, err := s.dao.ListBgmIncomeByID(c, archiveID, endTime)
if err != nil {
log.Error("s.dao.ListBgmIncomeByID error(%v)", err)
return
}
am := make(map[xtime.Time][]*model.ArchiveIncome)
for _, a := range as {
if _, ok := am[a.Date]; ok {
am[a.Date] = append(am[a.Date], a)
} else {
am[a.Date] = []*model.ArchiveIncome{a}
}
}
archives = make([]*model.ArchiveIncome, 0)
for date, ars := range am {
a := &model.ArchiveIncome{}
a.Date = date
for _, ar := range ars {
a.Income += ar.Income
a.Avs = append(a.Avs, ar.ArchiveID)
}
archives = append(archives, a)
}
return
}
// ArchiveBreach get av_breach_record
func (s *Service) ArchiveBreach(c context.Context, mid int64, typ, page, size, all int) (data interface{}, err error) {
if page == 0 {
page = 1
}
start, end := (page-1)*size, page*size
date := time.Now().AddDate(0, 0, -2)
startMonth := time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.Local).Format(_layout)
if all == 1 {
startMonth = "2017-12-01"
}
archives, err := s.dao.ListAvBreach(c, mid, startMonth, date.Format(_layout))
if err != nil {
log.Error("s.dao.ListAvBreach error(%v)", err)
return
}
typBreach := make([]*model.AvBreach, 0)
for _, arch := range archives {
if arch.CType == typ {
typBreach = append(typBreach, arch)
}
}
if len(typBreach) == 0 {
return
}
breachs, err := s.breachInBlacklist(c, typBreach, typ)
if err != nil {
log.Error("s.breachInBlacklist error(%v)", err)
return
}
sort.Slice(breachs, func(i, j int) bool {
return breachs[i].CDate > breachs[j].CDate
})
if end > len(breachs) {
end = len(breachs)
}
list := breachs[start:end]
aIDs := make([]int64, 0)
for _, b := range list {
aIDs = append(aIDs, b.AvID)
}
var titles map[int64]string
switch typ {
case _video:
titles, err = s.getAvTitle(c, aIDs)
if err != nil {
log.Error("s.getAvTitle error(%v)", err)
return
}
case _column:
titles, err = s.getColumnTitle(c, aIDs)
if err != nil {
log.Error("s.getColumnTitle error(%v)", err)
return
}
case _bgm:
titles, err = s.getBgmTitle(c, aIDs)
if err != nil {
log.Error("s.getBgmTitle error(%v)", err)
return
}
}
for _, b := range list {
b.Title = titles[b.AvID]
}
data = map[string]interface{}{
"data": list,
"total_count": len(breachs),
"page": page,
}
return
}
func (s *Service) breachInBlacklist(c context.Context, avs []*model.AvBreach, typ int) (breachs []*model.AvBreach, err error) {
aIDList := make([]int64, 0)
for _, a := range avs {
aIDList = append(aIDList, a.AvID)
}
avBMap, err := s.dao.ListAvBlackList(c, aIDList, typ)
if err != nil {
return
}
breachs = make([]*model.AvBreach, 0)
for _, av := range avs {
if _, ok := avBMap[av.AvID]; ok {
breachs = append(breachs, av)
}
}
return
}
// UpIncomeStat get up income stat by month
func (s *Service) UpIncomeStat(c context.Context, typ int, mid int64, date time.Time) (data interface{}, err error) {
redisKey := fmt.Sprintf("growup-income-stat:%d+%d", typ, mid)
res, err := s.dao.GetIncomeCache(c, redisKey)
if err != nil {
log.Error("s.dao.GetIncomeCache error(%v)", err)
return
}
if res != nil {
data = res["data"]
return
}
data, err = s.upIncomeStat(c, typ, mid, date)
if err != nil {
return
}
err = s.dao.SetIncomeCache(c, redisKey, map[string]interface{}{"data": data})
if err != nil {
log.Error("s.dao.SetIncomeCache error(%v)", err)
}
return
}
func (s *Service) upIncomeStat(c context.Context, typ int, mid int64, date time.Time) (stats []*model.UpIncomeStat, err error) {
et := date.AddDate(0, 0, -2)
end := et.Format(_layout)
// last 30 days
begin := et.AddDate(0, 0, -30).Format(_layout)
upIncomes, err := s.dao.ListUpIncome(c, mid, "up_income", begin, end)
if err != nil {
log.Error("s.dao.ListUpIncome error(%v)", err)
return
}
stats = make([]*model.UpIncomeStat, 0)
if len(upIncomes) == 0 {
return
}
var breachType []int64
for _, up := range upIncomes {
var income, baseIncome int64
switch typ {
case _video:
income, baseIncome = up.AvIncome, up.AvBaseIncome
breachType = []int64{0}
case _column:
income, baseIncome = up.ColumnIncome, up.ColumnBaseIncome
breachType = []int64{2}
case _bgm:
income, baseIncome = up.BgmIncome, up.BgmBaseIncome
breachType = []int64{3}
case _up:
income, baseIncome = up.Income, up.BaseIncome
breachType = []int64{0, 1, 2, 3}
}
extra := income - baseIncome
if extra < 0 {
extra = 0
}
stats = append(stats, &model.UpIncomeStat{
MID: up.MID,
Income: income,
BaseIncome: baseIncome,
ExtraIncome: extra,
Date: up.Date,
})
}
rs, err := s.dao.GetAvBreachByType(c, mid, begin, end, breachType)
if err != nil {
log.Error("s.dao.GetAvBreachByType error(%v)", err)
return
}
for _, stat := range stats {
if _, ok := rs[stat.Date]; ok {
stat.Breach = rs[stat.Date]
delete(rs, stat.Date)
}
}
for date, breach := range rs {
stats = append(stats, &model.UpIncomeStat{
MID: mid,
Date: date,
Breach: breach,
})
}
sort.Slice(stats, func(i, j int) bool {
return stats[i].Date < stats[j].Date
})
return
}

View File

@@ -0,0 +1,29 @@
package service
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func Test_ArchiveIncome(t *testing.T) {
var (
mid = int64(1011)
typ = 0
page, size = 0, 10
all = 0
)
Convey("ArchiveIncome", t, WithService(func(s *Service) {
_, err := s.ArchiveIncome(context.Background(), mid, typ, page, size, all)
So(err, ShouldBeNil)
}))
}
func Test_UpSummary(t *testing.T) {
Convey("UpSummary", t, WithService(func(s *Service) {
var mid int64 = 1011
_, err := s.UpSummary(context.Background(), mid)
So(err, ShouldBeNil)
}))
}

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