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/esports/cmd:all-srcs",
"//app/interface/main/esports/conf:all-srcs",
"//app/interface/main/esports/dao:all-srcs",
"//app/interface/main/esports/http:all-srcs",
"//app/interface/main/esports/model:all-srcs",
"//app/interface/main/esports/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,63 @@
### esports
#### Version 1.3.0
##### Features
> 1.接雷达积分数据
#### Version 1.2.9
##### Features
> 1.bug fix fav list
#### Version 1.2.8
##### Features
> 1.修复积分赛API倒序排序错误
#### Version 1.2.7
##### Features
> 1.电竞赛事库1.2 增加H5配置
#### Version 1.2.6
##### Features
> 1.活动赛事顶部赛程接口 fix time
#### Version 1.2.4
##### Features
> 1.电竞赛事库1.2
#### Version 1.2.3
##### Features
> 1.订阅赛选接口fix null
#### Version 1.2.2
##### Features
> 1.添加APP订阅列表接口
#### Version 1.2.1
##### Features
> 1.add internal
#### Version 1.2.0
##### Features
> 1.添加订阅和取消订阅
> 2.添加app赛程、赛季接口
#### Version 1.1.2
##### Features
> 1.修改remoteip方法
#### Version 1.1.1
##### Features
> 1.赛程加比赛中状态
#### Version 1.1.0
##### Features
> 1.筛选联动
#### Version 1.0.1
##### Features
> 1.筛选联动
#### Version 1.0.0
##### Features
> 1.初始化项目
> 2.新增赛事库相关接口

View File

@@ -0,0 +1,10 @@
# Owner
liweijia
zhapuyu
# Author
guanyanliang
# Reviewer
liweijia
wuhao02

View File

@@ -0,0 +1,16 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- guanyanliang
- liweijia
- zhapuyu
labels:
- interface
- interface/main/esports
- main
options:
no_parent_owners: true
reviewers:
- guanyanliang
- liweijia
- wuhao02

View File

@@ -0,0 +1,17 @@
#### esports
##### 项目简介
> 1.提供web端小功能接口
##### 编译环境
> 请使用golang v1.8.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common
##### 编译执行
> 在主目录执行go build。
> 编译后可执行 ./cmd/cmd -conf esports-test.toml 使用项目本地配置文件启动服务。
##### 特别说明
> http接口文档可参考 http://info.bilibili.co/pages/viewpage.action?pageId=8742472

View File

@@ -0,0 +1,44 @@
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 = ["esports-test.toml"],
importpath = "go-common/app/interface/main/esports/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/esports/conf:go_default_library",
"//app/interface/main/esports/http:go_default_library",
"//app/interface/main/esports/service: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,101 @@
[identify]
whiteAccessKey = ""
whiteMid = 0
[identify.app]
key = "7c7ac0db1aa05587"
secret = "9a6d62d93290c5f771ad381e9ca23f26"
[identify.memcache]
name = "go-app/identify"
proto = "tcp"
addr = "172.16.33.54:11211"
active = 5
idle = 1
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[identify.host]
auth = "http://passport.bilibili.com"
secret = "http://open.bilibili.com"
[identify.httpClient]
key = "7c7ac0db1aa05587"
secret = "9a6d62d93290c5f771ad381e9ca23f26"
dial = "30ms"
timeout = "150ms"
keepAlive = "60s"
[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"}
[log]
dir = "/data/log/esports/"
[app]
key = "7c7ac0db1aa05587"
secret = "9a6d62d93290c5f771ad381e9ca23f26"
[BM]
addr = "0.0.0.0:7791"
timeout = "1s"
[archiveRPC]
timeout = "1s"
[filterRPC]
timeout = "1s"
[mysql]
addr = "172.16.33.205:3308"
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_esports?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
idleTimeout = "4h"
queryTimeout = "100ms"
execTimeout = "100ms"
tranTimeout = "200ms"
[mysql.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[redis]
name = "esports-interface"
proto = "tcp"
addr = "172.18.33.60:6894"
idle = 10
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
filterExpire = "5m"
listExpire = "1s"
[httpClient]
key = "7c7ac0db1aa05587"
secret = "9a6d62d93290c5f771ad381e9ca23f26"
dial = "1s"
timeout = "1s"
keepAlive = "60s"
[host]
search = "http://s.search.bilibili.co"
[rule]
knockTree="30s"
[leidata]
timeout = "15s"
afterSleep = "3m"
endSleep = "30m"
retry = 5
url = "http://47.95.28.113/nesport/index.php/Api"
key = "d076eef519773c5954081e6a352c726d"
lolPlayersCron = "0 0 2 * * ?"
dotaPlayersCron = "0 0 3 * * ?"
infoCron = "0 0 4 * * ?"

View File

@@ -0,0 +1,6 @@
#!/bin/bash
command -v goconvey >/dev/null 2>&1 || { echo >&2 "required goconvey but it's not installed."; echo "Aborting."; echo "Please run commond: go get github.com/smartystreets/goconvey"; exit 1; }
cd ../
goconvey -excludedDirs "vendor" -packages 1

View File

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

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 = ["conf.go"],
importpath = "go-common/app/interface/main/esports/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/redis:go_default_library",
"//library/conf:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode/tip: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/middleware/verify: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,147 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/sql"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/auth"
"go-common/library/net/http/blademaster/middleware/verify"
"go-common/library/net/rpc"
"go-common/library/net/rpc/warden"
"go-common/library/net/trace"
"go-common/library/time"
"github.com/BurntSushi/toml"
)
// global var
var (
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
// Config config set
type Config struct {
// base
// elk
Log *log.Config
// App
App *bm.App
// rpc server2
RPCServer2 *rpc.ServerConfig
// tracer
Tracer *trace.Config
// bm
BM *bm.ServerConfig
// Ecode
Ecode *ecode.Config
// rpc
FavoriteRPC *rpc.ClientConfig
// grpc
ArcClient *warden.ClientConfig
// Mysql
Mysql *sql.Config
// Redis
Redis *Redis
// HTTP client
HTTPClient *bm.ClientConfig
// Host
Host *Host
// Auth
Auth *auth.Config
// verify
Verify *verify.Config
// reload
Rule *Rule
// leidata
Leidata *Leidata
}
// Host hosts.
type Host struct {
Search string
}
// Redis redis struct
type Redis struct {
*redis.Config
FilterExpire time.Duration
ListExpire time.Duration
}
// Rule rule .
type Rule struct {
KnockTree time.Duration
}
// Leidata lei da data .
type Leidata struct {
Timeout time.Duration
AfterSleep time.Duration
EndSleep time.Duration
Retry int
URL string
Key string
LolPlayersCron string
DotaPlayersCron string
InfoCron string
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init init conf
func Init() error {
if confPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,76 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"cache.go",
"dao.cache.go",
"dao.go",
"mysql.go",
"pointdata.go",
"redis.go",
"search.go",
],
importpath = "go-common/app/interface/main/esports/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/esports/conf:go_default_library",
"//app/interface/main/esports/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/elastic: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/stat/prom:go_default_library",
"//library/sync/pipeline/fanout: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 = [
"cache_test.go",
"dao.cache_test.go",
"dao_test.go",
"mysql_test.go",
"pointdata_test.go",
"redis_test.go",
"search_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/esports/conf:go_default_library",
"//app/interface/main/esports/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,19 @@
package dao
import (
"context"
"go-common/app/interface/main/esports/model"
)
//go:generate $GOPATH/src/go-common/app/tool/cache/gen
type _cache interface {
// cache
EpContests(c context.Context, ids []int64) (map[int64]*model.Contest, error)
// cache
EpSeasons(c context.Context, ids []int64) (map[int64]*model.Season, error)
// cache
EpTeams(c context.Context, ids []int64) (map[int64]*model.Team, error)
// cache
EpContestsData(c context.Context, ids []int64) (map[int64][]*model.ContestsData, error)
}

View File

@@ -0,0 +1 @@
package dao

View File

@@ -0,0 +1,156 @@
// Code generated by $GOPATH/src/go-common/app/tool/cache/gen. DO NOT EDIT.
/*
Package dao is a generated cache proxy package.
It is generated from:
type _cache interface {
// cache
EpContests(c context.Context, ids []int64) (map[int64]*model.Contest, error)
// cache
EpSeasons(c context.Context, ids []int64) (map[int64]*model.Season, error)
// cache
EpTeams(c context.Context, ids []int64) (map[int64]*model.Team, error)
// cache
EpContestsData(c context.Context, ids []int64) (map[int64][]*model.ContestsData, error)
}
*/
package dao
import (
"context"
"go-common/app/interface/main/esports/model"
"go-common/library/stat/prom"
)
var _ _cache
// EpContests get data from cache if miss will call source method, then add to cache.
func (d *Dao) EpContests(c context.Context, keys []int64) (res map[int64]*model.Contest, err error) {
if len(keys) == 0 {
return
}
addCache := true
if res, err = d.CacheEpContests(c, keys); err != nil {
addCache = false
res = nil
err = nil
}
var miss []int64
for _, key := range keys {
if (res == nil) || (res[key] == nil) {
miss = append(miss, key)
}
}
prom.CacheHit.Add("EpContests", int64(len(keys)-len(miss)))
missLen := len(miss)
if missLen == 0 {
return
}
var missData map[int64]*model.Contest
prom.CacheMiss.Add("EpContests", int64(len(miss)))
missData, err = d.RawEpContests(c, miss)
if res == nil {
res = make(map[int64]*model.Contest, len(keys))
}
for k, v := range missData {
res[k] = v
}
if err != nil {
return
}
if !addCache {
return
}
d.cache.Do(c, func(c context.Context) {
d.AddCacheEpContests(c, missData)
})
return
}
// EpSeasons get data from cache if miss will call source method, then add to cache.
func (d *Dao) EpSeasons(c context.Context, keys []int64) (res map[int64]*model.Season, err error) {
if len(keys) == 0 {
return
}
addCache := true
if res, err = d.CacheEpSeasons(c, keys); err != nil {
addCache = false
res = nil
err = nil
}
var miss []int64
for _, key := range keys {
if (res == nil) || (res[key] == nil) {
miss = append(miss, key)
}
}
prom.CacheHit.Add("EpSeasons", int64(len(keys)-len(miss)))
missLen := len(miss)
if missLen == 0 {
return
}
var missData map[int64]*model.Season
prom.CacheMiss.Add("EpSeasons", int64(len(miss)))
missData, err = d.RawEpSeasons(c, miss)
if res == nil {
res = make(map[int64]*model.Season, len(keys))
}
for k, v := range missData {
res[k] = v
}
if err != nil {
return
}
if !addCache {
return
}
d.cache.Do(c, func(c context.Context) {
d.AddCacheEpSeasons(c, missData)
})
return
}
// EpTeams get data from cache if miss will call source method, then add to cache.
func (d *Dao) EpTeams(c context.Context, keys []int64) (res map[int64]*model.Team, err error) {
if len(keys) == 0 {
return
}
addCache := true
if res, err = d.CacheEpTeams(c, keys); err != nil {
addCache = false
res = nil
err = nil
}
var miss []int64
for _, key := range keys {
if (res == nil) || (res[key] == nil) {
miss = append(miss, key)
}
}
prom.CacheHit.Add("EpTeams", int64(len(keys)-len(miss)))
missLen := len(miss)
if missLen == 0 {
return
}
var missData map[int64]*model.Team
prom.CacheMiss.Add("EpTeams", int64(len(miss)))
missData, err = d.RawEpTeams(c, miss)
if res == nil {
res = make(map[int64]*model.Team, len(keys))
}
for k, v := range missData {
res[k] = v
}
if err != nil {
return
}
if !addCache {
return
}
d.cache.Do(c, func(c context.Context) {
d.AddCacheEpTeams(c, missData)
})
return
}

View File

@@ -0,0 +1,51 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoEpContests(t *testing.T) {
var (
c = context.Background()
keys = []int64{1, 2, 3}
)
convey.Convey("EpContests", t, func(ctx convey.C) {
res, err := d.EpContests(c, keys)
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 TestDaoEpSeasons(t *testing.T) {
var (
c = context.Background()
keys = []int64{1, 2, 3}
)
convey.Convey("EpSeasons", t, func(ctx convey.C) {
res, err := d.EpSeasons(c, keys)
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 TestDaoEpTeams(t *testing.T) {
convey.Convey("EpTeams", t, func(convCtx convey.C) {
var (
c = context.Background()
keys = []int64{1, 2, 3}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
res, err := d.EpTeams(c, keys)
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)
})
})
})
}

View File

@@ -0,0 +1,61 @@
package dao
import (
"context"
"net/http"
"time"
"go-common/app/interface/main/esports/conf"
"go-common/library/cache/redis"
"go-common/library/database/elastic"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
"go-common/library/sync/pipeline/fanout"
)
const (
_searchURL = "/esports/search"
)
// Dao dao struct.
type Dao struct {
// config
c *conf.Config
// db
db *sql.DB
// redis
redis *redis.Pool
filterExpire, listExpire int32
// http client
http *bm.Client
ldClient *http.Client
searchURL string
ela *elastic.Elastic
cache *fanout.Fanout
}
// New new dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// config
c: c,
db: sql.NewMySQL(c.Mysql),
redis: redis.NewPool(c.Redis.Config),
filterExpire: int32(time.Duration(c.Redis.FilterExpire) / time.Second),
listExpire: int32(time.Duration(c.Redis.ListExpire) / time.Second),
http: bm.NewClient(c.HTTPClient),
ldClient: http.DefaultClient,
searchURL: c.Host.Search + _searchURL,
ela: elastic.NewElastic(nil),
cache: fanout.New("fanout"),
}
return
}
// Ping ping dao
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.db.Ping(c); err != nil {
return
}
return
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"flag"
"os"
"testing"
"go-common/app/interface/main/esports/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.web-svr.esports")
flag.Set("conf_token", "a144f51d7157d638749686d63b13c693")
flag.Set("tree_id", "38395")
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/esports-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}

View File

@@ -0,0 +1,628 @@
package dao
import (
"context"
"database/sql"
"fmt"
"strconv"
"strings"
"go-common/app/interface/main/esports/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_matchsSQL = "SELECT id,title,sub_title,logo,rank FROM es_matchs WHERE status=0 order by rank DESC , ID ASC"
_gamesSQL = "SELECT id,title,sub_title,logo FROM es_games WHERE status=0 order by id ASC"
_teamsSQL = "SELECT id,title,sub_title,logo FROM es_teams WHERE is_deleted=0 order by id ASC"
_tagsSQL = "SELECT id,name FROM es_tags WHERE status=0 order by id ASC"
_yearsSQL = "SELECT distinct year as id, year FROM es_year_map WHERE is_deleted=0 order by id ASC"
_dayContestSQL = "SELECT FROM_UNIXTIME(stime, '%Y-%m-%d') as s,count(1) as c FROM `es_contests` WHERE status=0 AND stime >= ? and stime <= ? GROUP BY s ORDER BY stime"
_seasonSQL = "SELECT id,mid,title,sub_title,stime,etime,sponsor,logo,dic,ctime,mtime,status,rank,is_app,url,data_focus,focus_url FROM es_seasons WHERE status = 0 ORDER BY stime DESC"
_epSeasonSQL = "SELECT id,mid,title,sub_title,stime,etime,sponsor,logo,dic,ctime,mtime,status,rank,is_app,url,data_focus,focus_url FROM es_seasons WHERE status = 0 and id in (%s) ORDER BY stime DESC"
_seasonMSQL = "SELECT id,mid,title,sub_title,stime,etime,sponsor,logo,dic,ctime,mtime,status,rank,is_app,url,data_focus,focus_url FROM es_seasons WHERE status = 0 AND is_app = 1 ORDER BY rank DESC,stime DESC"
_seasonsSQL = "SELECT id,title,sub_title,logo,url,data_focus,focus_url FROM es_seasons WHERE status = 0 ORDER BY stime DESC"
_contestSQL = "SELECT id,game_stage,stime,etime,home_id,away_id,home_score,away_score,live_room,aid,collection,game_state,dic,ctime,mtime,status,sid,mid,special,special_name,special_tips,success_team,special_image,playback,collection_url,live_url,data_type,match_id FROM `es_contests` WHERE id= ?"
_contestsSQL = "SELECT id,game_stage,stime,etime,home_id,away_id,home_score,away_score,live_room,aid,collection,game_state,dic,ctime,mtime,status,sid,mid,special,special_name,special_tips,success_team,special_image,playback,collection_url,live_url,data_type,match_id FROM `es_contests` WHERE id in (%s) ORDER BY ID ASC"
_contestLeidaSQL = "SELECT id,game_stage,stime,etime,home_id,away_id,home_score,away_score,live_room,aid,collection,game_state,dic,ctime,mtime,status,sid,mid,special,special_name,special_tips,success_team,special_image,playback,collection_url,live_url,data_type,match_id FROM `es_contests` WHERE match_id > 0 and status = 0"
_moduleSQL = "SELECT id,ma_id,name,oids FROM `es_matchs_module` WHERE id = ? AND status = 0"
_activeSQL = "SELECT id,mid,sid,background,live_id,intr,focus,url,back_color,color_step,h5_background,h5_back_color,intr_logo,intr_title,intr_text,h5_focus,h5_url FROM es_matchs_active WHERE id = ? AND `status`= 0"
_modulesSQL = "SELECT id,ma_id,name,oids FROM `es_matchs_module` WHERE ma_id = ? AND status = 0 ORDER BY ID ASC"
_pDetailSQL = "SELECT ma_id,game_type,stime,etime FROM es_matchs_detail WHERE id = ? AND `status` = 0"
_actDetail = "SELECT id,ma_id,game_type,stime,etime,score_id,game_stage,knockout_type,winner_type,online FROM es_matchs_detail WHERE ma_id = ? AND status = 0"
_treeSQL = "SELECT id,ma_id,mad_id,pid,root_id,game_rank,mid FROM es_matchs_tree WHERE mad_id = ? AND is_deleted=0 ORDER BY root_id ASC,pid ASC,game_rank ASC"
_teamsInSQL = "SELECT id,title,sub_title,logo FROM es_teams WHERE is_deleted=0 AND id in (%s)"
_kDetailsSQL = "SELECT id,ma_id,game_type,stime,etime,online FROM es_matchs_detail WHERE `status` = 0 AND game_type = 2"
_contestDataSQL = "SELECT id,cid,url,point_data FROM `es_contests_data` WHERE cid = ? AND is_deleted = 0"
_contestRecent = "SELECT id,game_stage,stime,etime,home_id,away_id,home_score,away_score,live_room,aid,collection,game_state,dic,ctime,mtime,status,sid,mid,special,special_name,special_tips,success_team,special_image,playback,collection_url,live_url,data_type FROM es_contests WHERE ( `status` = 0 AND home_id = ? AND away_id = ? ) OR ( `status` = 0 AND home_id = ? AND away_id = ? ) ORDER BY stime DESC LIMIT ?"
)
// logoURL convert logo url to full url.
func logoURL(uri string) (logo string) {
if uri == "" {
return
}
logo = uri
if strings.Index(uri, "http://") == 0 || strings.Index(uri, "//") == 0 {
return
}
if len(uri) >= 10 && uri[:10] == "/templets/" {
return
}
if strings.HasPrefix(uri, "group1") {
logo = "//i0.hdslb.com/" + uri
return
}
if pos := strings.Index(uri, "/uploads/"); pos != -1 && (pos == 0 || pos == 3) {
logo = uri[pos+8:]
}
logo = strings.Replace(logo, "{IMG}", "", -1)
logo = "//i0.hdslb.com" + logo
return
}
// Matchs filter matchs.
func (d *Dao) Matchs(c context.Context) (res []*model.Filter, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _matchsSQL); err != nil {
log.Error("Match:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Filter)
if err = rows.Scan(&r.ID, &r.Title, &r.SubTitle, &r.Logo, &r.Rank); err != nil {
log.Error("Match:row.Scan() error(%v)", err)
return
}
r.Logo = logoURL(r.Logo)
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// Games filter games.
func (d *Dao) Games(c context.Context) (res []*model.Filter, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _gamesSQL); err != nil {
log.Error("Games:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Filter)
if err = rows.Scan(&r.ID, &r.Title, &r.SubTitle, &r.Logo); err != nil {
log.Error("Games:row.Scan() error(%v)", err)
return
}
r.Logo = logoURL(r.Logo)
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// Teams filter teams.
func (d *Dao) Teams(c context.Context) (res []*model.Filter, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _teamsSQL); err != nil {
log.Error("Teams:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Filter)
if err = rows.Scan(&r.ID, &r.Title, &r.SubTitle, &r.Logo); err != nil {
log.Error("Teams:row.Scan() error(%v)", err)
return
}
r.Logo = logoURL(r.Logo)
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// Tags filter Tags.
func (d *Dao) Tags(c context.Context) (res []*model.Filter, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _tagsSQL); err != nil {
log.Error("Tags:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Filter)
if err = rows.Scan(&r.ID, &r.Title); err != nil {
log.Error("Tags:row.Scan() error(%v)", err)
return
}
r.Logo = logoURL(r.Logo)
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// Years filter years.
func (d *Dao) Years(c context.Context) (res []*model.Filter, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _yearsSQL); err != nil {
log.Error("Years:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Year)
if err = rows.Scan(&r.ID, &r.Year); err != nil {
log.Error("Years:row.Scan() error(%v)", err)
return
}
res = append(res, &model.Filter{ID: r.ID, Title: strconv.FormatInt(r.Year, 10)})
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// Calendar calendar count.
func (d *Dao) Calendar(c context.Context, stime, etime int64) (res []*model.Calendar, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _dayContestSQL, stime, etime); err != nil {
log.Error("Calendar:d.db.Query(%d,%d) error(%v)", stime, etime, err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Calendar)
if err = rows.Scan(&r.Stime, &r.Count); err != nil {
log.Error("Calendar:row.Scan() error(%v)", err)
return
}
res = append(res, r)
}
return
}
// Season season list.
func (d *Dao) Season(c context.Context) (res []*model.Season, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _seasonSQL); err != nil {
log.Error("Contest:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Season)
if err = rows.Scan(&r.ID, &r.Mid, &r.Title, &r.SubTitle, &r.Stime, &r.Etime, &r.Sponsor, &r.Logo, &r.Dic, &r.Ctime,
&r.Mtime, &r.Status, &r.Rank, &r.IsApp, &r.URL, &r.DataFocus, &r.FocusURL); err != nil {
log.Error("Contest:row.Scan() error(%v)", err)
return
}
r.Logo = logoURL(r.Logo)
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// Module active module
func (d *Dao) Module(c context.Context, mmid int64) (mod *model.Module, err error) {
mod = &model.Module{}
row := d.db.QueryRow(c, _moduleSQL, mmid)
if err = row.Scan(&mod.ID, &mod.MAid, &mod.Name, &mod.Oids); err != nil {
if err == sql.ErrNoRows {
mod = nil
err = nil
} else {
log.Error("Esport dao Module:row.Scan error(%v)", err)
}
}
return
}
// Modules active module
func (d *Dao) Modules(c context.Context, aid int64) (mods []*model.Module, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _modulesSQL, aid); err != nil {
log.Error("Esport dao Modules:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Module)
if err = rows.Scan(&r.ID, &r.MAid, &r.Name, &r.Oids); err != nil {
log.Error("Esport dao Modules:row.Scan() error(%v)", err)
return
}
mods = append(mods, r)
}
if err = rows.Err(); err != nil {
log.Error("Esport dao Modules.Err() error(%v)", err)
}
return
}
// Trees match tree
func (d *Dao) Trees(c context.Context, madID int64) (mods []*model.Tree, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _treeSQL, madID); err != nil {
log.Error("Esport dao Trees:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Tree)
if err = rows.Scan(&r.ID, &r.MaID, &r.MadID, &r.Pid, &r.RootID, &r.GameRank, &r.Mid); err != nil {
log.Error("Esport dao Trees:row.Scan() error(%v)", err)
return
}
mods = append(mods, r)
}
if err = rows.Err(); err != nil {
log.Error("Esport dao Trees.Err() error(%v)", err)
}
return
}
// Active matchs active
func (d *Dao) Active(c context.Context, aid int64) (mod *model.Active, err error) {
mod = &model.Active{}
row := d.db.QueryRow(c, _activeSQL, aid)
if err = row.Scan(&mod.ID, &mod.Mid, &mod.Sid, &mod.Background, &mod.Liveid, &mod.Intr, &mod.Focus, &mod.URL, &mod.BackColor, &mod.ColorStep, &mod.H5Background, &mod.H5BackColor, &mod.IntrLogo, &mod.IntrTitle, &mod.IntrText, &mod.H5Focus, &mod.H5Url); err != nil {
if err == sql.ErrNoRows {
mod = nil
err = nil
} else {
log.Error("Esport dao Active:row.Scan error(%v)", err)
}
}
return
}
// PActDetail poin match detail
func (d *Dao) PActDetail(c context.Context, id int64) (mod *model.ActiveDetail, err error) {
mod = &model.ActiveDetail{}
row := d.db.QueryRow(c, _pDetailSQL, id)
if err = row.Scan(&mod.Maid, &mod.GameType, &mod.STime, &mod.ETime); err != nil {
if err == sql.ErrNoRows {
mod = nil
err = nil
} else {
log.Error("Esport dao Contest:row.Scan error(%v)", err)
}
}
return
}
// ActDetail data module
func (d *Dao) ActDetail(c context.Context, aid int64) (actDetail []*model.ActiveDetail, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _actDetail, aid); err != nil {
log.Error("Esport dao Modules:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.ActiveDetail)
if err = rows.Scan(&r.ID, &r.Maid, &r.GameType, &r.STime, &r.ETime, &r.ScoreID, &r.GameStage, &r.KnockoutType, &r.WinnerType, &r.Online); err != nil {
log.Error("Esport dao ActDetail:row.Scan() error(%v)", err)
return
}
actDetail = append(actDetail, r)
}
if err = rows.Err(); err != nil {
log.Error("Esport dao ActDetail.Err() error(%v)", err)
}
return
}
// AppSeason season match list.
func (d *Dao) AppSeason(c context.Context) (res []*model.Season, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _seasonMSQL); err != nil {
log.Error("Contest:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Season)
if err = rows.Scan(&r.ID, &r.Mid, &r.Title, &r.SubTitle, &r.Stime, &r.Etime, &r.Sponsor, &r.Logo,
&r.Dic, &r.Ctime, &r.Mtime, &r.Status, &r.Rank, &r.IsApp, &r.URL, &r.DataFocus, &r.FocusURL); err != nil {
log.Error("Contest:row.Scan() error(%v)", err)
return
}
r.Logo = logoURL(r.Logo)
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// SeasonAll all season list.
func (d *Dao) SeasonAll(c context.Context) (res []*model.Filter, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _seasonsSQL); err != nil {
log.Error("SeasonAll:d.db.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.Filter)
if err = rows.Scan(&r.ID, &r.Title, &r.SubTitle, &r.Logo, &r.URL, &r.DataFocus, &r.FocusURL); err != nil {
log.Error("SeasonAll:row.Scan() error(%v)", err)
return
}
r.Logo = logoURL(r.Logo)
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// Contest get contest by id.
func (d *Dao) Contest(c context.Context, cid int64) (res *model.Contest, err error) {
res = &model.Contest{}
row := d.db.QueryRow(c, _contestSQL, cid)
if err = row.Scan(&res.ID, &res.GameStage, &res.Stime, &res.Etime, &res.HomeID, &res.AwayID, &res.HomeScore, &res.AwayScore,
&res.LiveRoom, &res.Aid, &res.Collection, &res.GameState, &res.Dic, &res.Ctime, &res.Mtime, &res.Status, &res.Sid, &res.Mid,
&res.Special, &res.SpecialName, &res.SpecialTips, &res.SuccessTeam, &res.SpecialImage, &res.Playback, &res.CollectionURL,
&res.LiveURL, &res.DataType, &res.MatchID); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("Contest:row.Scan error(%v)", err)
}
}
return
}
// ContestRecent get recent contest
func (d *Dao) ContestRecent(c context.Context, homeid, awayid, contestid, ps int64) (res []*model.Contest, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _contestRecent, homeid, awayid, awayid, homeid, ps+1); err != nil {
log.Error("ContestRecent: db.Exec(%s) error(%v)", _contestRecent, err)
return
}
defer rows.Close()
res = make([]*model.Contest, 0)
for rows.Next() {
r := new(model.Contest)
if err = rows.Scan(&r.ID, &r.GameStage, &r.Stime, &r.Etime, &r.HomeID, &r.AwayID, &r.HomeScore, &r.AwayScore,
&r.LiveRoom, &r.Aid, &r.Collection, &r.GameState, &r.Dic, &r.Ctime, &r.Mtime, &r.Status, &r.Sid, &r.Mid,
&r.Special, &r.SpecialName, &r.SpecialTips, &r.SuccessTeam, &r.SpecialImage, &r.Playback, &r.CollectionURL, &r.LiveURL, &r.DataType); err != nil {
log.Error("Contests:row.Scan() error(%v)", err)
return
}
if r.ID != contestid && len(res) != int(ps) {
res = append(res, r)
}
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// ContestData get contest by id.
func (d *Dao) ContestData(c context.Context, cid int64) (res []*model.ContestsData, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _contestDataSQL, cid); err != nil {
log.Error("ContestsData: db.Exec(%s) error(%v)", _contestDataSQL, err)
return
}
defer rows.Close()
for rows.Next() {
data := new(model.ContestsData)
if err = rows.Scan(&data.ID, &data.Cid, &data.URL, &data.PointData); err != nil {
log.Error("ContestsData:row.Scan() error(%v)", err)
return
}
res = append(res, data)
}
if err = rows.Err(); err != nil {
log.Error("ContestssData rows.Err() error(%v)", err)
}
return
}
// ContestDatas contest datas.
func (d *Dao) ContestDatas(c context.Context) (res []*model.Contest, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _contestLeidaSQL); err != nil {
log.Error("Contests: db.Exec(%s) error(%v)", _contestLeidaSQL, err)
return
}
defer rows.Close()
res = make([]*model.Contest, 0)
for rows.Next() {
r := new(model.Contest)
if err = rows.Scan(&r.ID, &r.GameStage, &r.Stime, &r.Etime, &r.HomeID, &r.AwayID, &r.HomeScore, &r.AwayScore,
&r.LiveRoom, &r.Aid, &r.Collection, &r.GameState, &r.Dic, &r.Ctime, &r.Mtime, &r.Status, &r.Sid, &r.Mid,
&r.Special, &r.SpecialName, &r.SpecialTips, &r.SuccessTeam, &r.SpecialImage, &r.Playback, &r.CollectionURL, &r.LiveURL, &r.DataType, &r.MatchID); err != nil {
log.Error("Contests:row.Scan() error(%v)", err)
return
}
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// RawEpContests get contests by ids.
func (d *Dao) RawEpContests(c context.Context, cids []int64) (res map[int64]*model.Contest, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, fmt.Sprintf(_contestsSQL, xstr.JoinInts(cids))); err != nil {
log.Error("Contests: db.Exec(%s) error(%v)", xstr.JoinInts(cids), err)
return
}
defer rows.Close()
res = make(map[int64]*model.Contest, len(cids))
for rows.Next() {
r := new(model.Contest)
if err = rows.Scan(&r.ID, &r.GameStage, &r.Stime, &r.Etime, &r.HomeID, &r.AwayID, &r.HomeScore, &r.AwayScore,
&r.LiveRoom, &r.Aid, &r.Collection, &r.GameState, &r.Dic, &r.Ctime, &r.Mtime, &r.Status, &r.Sid, &r.Mid,
&r.Special, &r.SpecialName, &r.SpecialTips, &r.SuccessTeam, &r.SpecialImage, &r.Playback, &r.CollectionURL,
&r.LiveURL, &r.DataType, &r.MatchID); err != nil {
log.Error("Contests:row.Scan() error(%v)", err)
return
}
res[r.ID] = r
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// RawEpSeasons get seasons by ids.
func (d *Dao) RawEpSeasons(c context.Context, sids []int64) (res map[int64]*model.Season, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, fmt.Sprintf(_epSeasonSQL, xstr.JoinInts(sids))); err != nil {
log.Error("Contests: db.Exec(%s) error(%v)", xstr.JoinInts(sids), err)
return
}
defer rows.Close()
res = make(map[int64]*model.Season, len(sids))
for rows.Next() {
r := new(model.Season)
if err = rows.Scan(&r.ID, &r.Mid, &r.Title, &r.SubTitle, &r.Stime, &r.Etime, &r.Sponsor, &r.Logo, &r.Dic, &r.Ctime,
&r.Mtime, &r.Status, &r.Rank, &r.IsApp, &r.URL, &r.DataFocus, &r.FocusURL); err != nil {
log.Error("Contest:row.Scan() error(%v)", err)
return
}
res[r.ID] = r
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// ActTeams get teams by ids in
func (d *Dao) ActTeams(c context.Context, tids []int64) (res []*model.Team, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, fmt.Sprintf(_teamsInSQL, xstr.JoinInts(tids))); err != nil {
log.Error("ActTeams: db.Exec(%s) error(%v)", xstr.JoinInts(tids), err)
return
}
defer rows.Close()
res = make([]*model.Team, len(tids))
for rows.Next() {
r := new(model.Team)
if err = rows.Scan(&r.ID, &r.Title, &r.SubTitle, &r.Logo); err != nil {
log.Error("ActTeams:row.Scan() error(%v)", err)
return
}
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("ActTeams rows.Err() error(%v)", err)
}
return
}
// RawEpTeams get seasons by ids.
func (d *Dao) RawEpTeams(c context.Context, tids []int64) (res map[int64]*model.Team, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, fmt.Sprintf(_teamsInSQL, xstr.JoinInts(tids))); err != nil {
log.Error("RawEpTeams: db.Exec(%s) error(%v)", xstr.JoinInts(tids), err)
return
}
defer rows.Close()
res = make(map[int64]*model.Team, len(tids))
for rows.Next() {
r := new(model.Team)
if err = rows.Scan(&r.ID, &r.Title, &r.SubTitle, &r.Logo); err != nil {
log.Error("RawEpTeams:row.Scan() error(%v)", err)
return
}
res[r.ID] = r
}
if err = rows.Err(); err != nil {
log.Error("RawEpTeams.Err() error(%v)", err)
}
return
}
// KDetails knockout detail
func (d *Dao) KDetails(c context.Context) (res []*model.ActiveDetail, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _kDetailsSQL); err != nil {
log.Error("ActPDetails: db.Exec(%s) error(%v)", _kDetailsSQL, err)
return
}
defer rows.Close()
for rows.Next() {
detail := new(model.ActiveDetail)
if err = rows.Scan(&detail.ID, &detail.Maid, &detail.GameType, &detail.STime, &detail.ETime, &detail.Online); err != nil {
log.Error("KDetails:row.Scan() error(%v)", err)
return
}
res = append(res, detail)
}
if err = rows.Err(); err != nil {
log.Error("KDetails rows.Err() error(%v)", err)
}
return
}

View File

@@ -0,0 +1,368 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaologoURL(t *testing.T) {
convey.Convey("logoURL", t, func(ctx convey.C) {
var (
uri = "/bfs/archive/ad22dba8f05bb7dee6889492d3bb544413ee42c1.jpg"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
logo := logoURL(uri)
ctx.Convey("Then logo should not be nil.", func(ctx convey.C) {
ctx.So(logo, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoMatchs(t *testing.T) {
convey.Convey("Matchs", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Matchs(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)
})
})
})
}
func TestDaoGames(t *testing.T) {
convey.Convey("Games", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Games(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)
})
})
})
}
func TestDaoTeams(t *testing.T) {
convey.Convey("Teams", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Teams(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)
})
})
})
}
func TestDaoTags(t *testing.T) {
convey.Convey("Tags", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Tags(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)
})
})
})
}
func TestDaoYears(t *testing.T) {
convey.Convey("Years", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Years(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)
})
})
})
}
func TestDaoCalendar(t *testing.T) {
convey.Convey("Calendar", t, func(ctx convey.C) {
var (
c = context.Background()
stime = int64(0)
etime = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Calendar(c, stime, etime)
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 TestDaoSeason(t *testing.T) {
convey.Convey("Season", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Season(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)
})
})
})
}
func TestDaoModule(t *testing.T) {
convey.Convey("Module", t, func(ctx convey.C) {
var (
c = context.Background()
mmid = int64(69)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
mod, err := d.Module(c, mmid)
ctx.Convey("Then err should be nil.mod should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(mod, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoModules(t *testing.T) {
convey.Convey("Modules", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
mods, err := d.Modules(c, aid)
ctx.Convey("Then err should be nil.mods should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(mods, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTrees(t *testing.T) {
convey.Convey("Trees", t, func(ctx convey.C) {
var (
c = context.Background()
madID = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
mods, err := d.Trees(c, madID)
ctx.Convey("Then err should be nil.mods should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(mods, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoActive(t *testing.T) {
convey.Convey("Active", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
mod, err := d.Active(c, aid)
ctx.Convey("Then err should be nil.mod should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(mod, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoPActDetail(t *testing.T) {
convey.Convey("PActDetail", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(2)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.PActDetail(c, id)
ctx.Convey("Then err should be nil.mod should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoActData(t *testing.T) {
convey.Convey("ActDetail", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
actData, err := d.ActDetail(c, aid)
ctx.Convey("Then err should be nil.actData should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(actData, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAppSeason(t *testing.T) {
convey.Convey("AppSeason", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.AppSeason(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)
})
})
})
}
func TestDaoSeasonAll(t *testing.T) {
convey.Convey("SeasonAll", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.SeasonAll(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)
})
})
})
}
func TestDaoContest(t *testing.T) {
convey.Convey("Contest", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Contest(c, cid)
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 TestDaoContestRecent(t *testing.T) {
convey.Convey("ContestRecent", t, func(ctx convey.C) {
var (
c = context.Background()
homeid = int64(1)
awayid = int64(2)
contestid = int64(1)
ps = int64(2)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
res, err := d.ContestRecent(c, homeid, awayid, contestid, ps)
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 TestDaoContestData(t *testing.T) {
convey.Convey("ContestData", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(458)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
res, err := d.ContestData(c, cid)
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 TestDaoRawEpSeasons(t *testing.T) {
convey.Convey("RawEpSeasons", t, func(ctx convey.C) {
var (
c = context.Background()
sids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.RawEpSeasons(c, sids)
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 TestDaoActTeams(t *testing.T) {
convey.Convey("ActTeams", t, func(ctx convey.C) {
var (
c = context.Background()
tids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.ActTeams(c, tids)
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 TestDaoKDetails(t *testing.T) {
convey.Convey("KDetails", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.KDetails(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)
})
})
})
}
func TestDaoRawEpContests(t *testing.T) {
convey.Convey("RawEpContests", t, func(ctx convey.C) {
var (
c = context.Background()
cids = []int64{1, 2, 3, 4, 5, 6}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
res, err := d.RawEpContests(c, cids)
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,47 @@
package dao
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"time"
"go-common/library/log"
"github.com/pkg/errors"
)
// Leida get leidata.
func (d *Dao) Leida(c context.Context, url string) (rs []byte, err error) {
if rs, err = d.ThirdGet(c, url); err != nil {
log.Error("d.ThirdGet url(%s) error(%+v)", url, err)
}
return
}
// ThirdGet get.
func (d *Dao) ThirdGet(c context.Context, url string) (res []byte, err error) {
var (
req *http.Request
resp *http.Response
)
if req, err = http.NewRequest("GET", url, nil); err != nil {
err = errors.Wrapf(err, "ThirdGet http.NewRequest(%s)", url)
return
}
ctx, cancel := context.WithTimeout(c, time.Duration(d.c.Leidata.Timeout))
defer cancel()
req = req.WithContext(ctx)
if resp, err = d.ldClient.Do(req); err != nil {
err = errors.Wrapf(err, "ThirdGet d.ldClient.Do(%s)", url)
return
}
defer resp.Body.Close()
if resp.StatusCode >= http.StatusBadRequest {
err = fmt.Errorf("ThirdGet url(%s) resp.StatusCode(%v)", url, resp.StatusCode)
return
}
res, err = ioutil.ReadAll(resp.Body)
return
}

View File

@@ -0,0 +1,40 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoLeida(t *testing.T) {
convey.Convey("Leida", t, func(convCtx convey.C) {
var (
c = context.Background()
url = "http://47.95.28.113/nesport/index.php/Api/lol/games?match_id=328266&key=d076eef519773c5954081e6a352c726d"
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
rs, err := d.Leida(c, url)
convCtx.Convey("Then err should be nil.rs should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(rs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoThirdGet(t *testing.T) {
convey.Convey("ThirdGet", t, func(convCtx convey.C) {
var (
c = context.Background()
url = "http://47.95.28.113/nesport/index.php/Api/lol/games?match_id=328266&key=d076eef519773c5954081e6a352c726d"
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
res, err := d.ThirdGet(c, url)
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)
})
})
})
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,893 @@
package dao
import (
"context"
"go-common/app/interface/main/esports/model"
arcmdl "go-common/app/service/main/archive/api"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaokeyCale(t *testing.T) {
convey.Convey("keyCale", t, func(ctx convey.C) {
var (
stime = ""
etime = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyCale(stime, etime)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyCont(t *testing.T) {
convey.Convey("keyCont", t, func(ctx convey.C) {
var (
ps = int(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyCont(ps)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyVideo(t *testing.T) {
convey.Convey("keyVideo", t, func(ctx convey.C) {
var (
ps = int(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyVideo(ps)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyContID(t *testing.T) {
convey.Convey("keyContID", t, func(ctx convey.C) {
var (
cid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyContID(cid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyCoFav(t *testing.T) {
convey.Convey("keyCoFav", t, func(ctx convey.C) {
var (
mid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyCoFav(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyCoAppFav(t *testing.T) {
convey.Convey("keyCoAppFav", t, func(ctx convey.C) {
var (
mid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyCoAppFav(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeySID(t *testing.T) {
convey.Convey("keySID", t, func(ctx convey.C) {
var (
sid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keySID(sid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyMatchAct(t *testing.T) {
convey.Convey("keyMatchAct", t, func(ctx convey.C) {
var (
aid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyMatchAct(aid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyMatchModule(t *testing.T) {
convey.Convey("keyMatchModule", t, func(ctx convey.C) {
var (
mmid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyMatchModule(mmid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyKnock(t *testing.T) {
convey.Convey("keyKnock", t, func(ctx convey.C) {
var (
mdID = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyKnock(mdID)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyTop(t *testing.T) {
convey.Convey("keyTop", t, func(ctx convey.C) {
var (
aid = int64(1)
ps = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyTop(aid, ps)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyPoint(t *testing.T) {
convey.Convey("keyPoint", t, func(ctx convey.C) {
var (
aid = int64(1)
mdID = int64(1)
ps = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyPoint(aid, mdID, ps)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoFMatCache(t *testing.T) {
convey.Convey("FMatCache", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.FMatCache(c)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoFVideoCache(t *testing.T) {
convey.Convey("FVideoCache", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.FVideoCache(c)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaofilterCache(t *testing.T) {
convey.Convey("filterCache", t, func(ctx convey.C) {
var (
c = context.Background()
key = "1"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.filterCache(c, key)
ctx.Convey("Then err should be nil.rs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetFMatCache(t *testing.T) {
convey.Convey("SetFMatCache", t, func(ctx convey.C) {
var (
c = context.Background()
fs map[string][]*model.Filter
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetFMatCache(c, fs)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetFVideoCache(t *testing.T) {
convey.Convey("SetFVideoCache", t, func(ctx convey.C) {
var (
c = context.Background()
fs map[string][]*model.Filter
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetFVideoCache(c, fs)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaosetFilterCache(t *testing.T) {
convey.Convey("setFilterCache", t, func(ctx convey.C) {
var (
c = context.Background()
key = ""
fs map[string][]*model.Filter
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.setFilterCache(c, key, fs)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoContestCache(t *testing.T) {
convey.Convey("ContestCache", t, func(ctx convey.C) {
var (
c = context.Background()
ps = int(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.ContestCache(c, ps)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoFavCoCache(t *testing.T) {
convey.Convey("FavCoCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.FavCoCache(c, mid)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoFavCoAppCache(t *testing.T) {
convey.Convey("FavCoAppCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.FavCoAppCache(c, mid)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaocosCache(t *testing.T) {
convey.Convey("cosCache", t, func(ctx convey.C) {
var (
c = context.Background()
key = "1"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.cosCache(c, key)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetContestCache(t *testing.T) {
convey.Convey("SetContestCache", t, func(ctx convey.C) {
var (
c = context.Background()
ps = int(1)
con = &model.Contest{}
contests = []*model.Contest{con}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetContestCache(c, ps, contests, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetFavCoCache(t *testing.T) {
convey.Convey("SetFavCoCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
con = &model.Contest{}
contests = []*model.Contest{con}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetFavCoCache(c, mid, contests, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetAppFavCoCache(t *testing.T) {
convey.Convey("SetAppFavCoCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
con = &model.Contest{}
contests = []*model.Contest{con}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetAppFavCoCache(c, mid, contests, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoDelFavCoCache(t *testing.T) {
convey.Convey("DelFavCoCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelFavCoCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaosetCosCache(t *testing.T) {
convey.Convey("setCosCache", t, func(ctx convey.C) {
var (
c = context.Background()
key = ""
con = &model.Contest{}
contests = []*model.Contest{con}
total = int(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.setCosCache(c, key, contests, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoCalendarCache(t *testing.T) {
convey.Convey("CalendarCache", t, func(ctx convey.C) {
var (
c = context.Background()
p = &model.ParamFilter{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.CalendarCache(c, p)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetCalendarCache(t *testing.T) {
convey.Convey("SetCalendarCache", t, func(ctx convey.C) {
var (
c = context.Background()
p = &model.ParamFilter{}
cal = &model.Calendar{}
cales = []*model.Calendar{cal}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetCalendarCache(c, p, cales)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoVideoCache(t *testing.T) {
convey.Convey("VideoCache", t, func(ctx convey.C) {
var (
c = context.Background()
ps = int(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.VideoCache(c, ps)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetVideoCache(t *testing.T) {
convey.Convey("SetVideoCache", t, func(ctx convey.C) {
var (
c = context.Background()
ps = int(0)
arc = &arcmdl.Arc{}
videos = []*arcmdl.Arc{arc}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetVideoCache(c, ps, videos, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoseasonsCache(t *testing.T) {
convey.Convey("seasonsCache", t, func(ctx convey.C) {
var (
c = context.Background()
key = "1"
start = int(0)
end = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.seasonsCache(c, key, start, end)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaosetSeasonsCache(t *testing.T) {
convey.Convey("setSeasonsCache", t, func(ctx convey.C) {
var (
c = context.Background()
key = "1"
seasons = []*model.Season{}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.setSeasonsCache(c, key, seasons, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSeasonCache(t *testing.T) {
convey.Convey("SeasonCache", t, func(ctx convey.C) {
var (
c = context.Background()
start = int(0)
end = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.SeasonCache(c, start, end)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetSeasonCache(t *testing.T) {
convey.Convey("SetSeasonCache", t, func(ctx convey.C) {
var (
c = context.Background()
seasons = []*model.Season{}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetSeasonCache(c, seasons, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSeasonMCache(t *testing.T) {
convey.Convey("SeasonMCache", t, func(ctx convey.C) {
var (
c = context.Background()
start = int(0)
end = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.SeasonMCache(c, start, end)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetSeasonMCache(t *testing.T) {
convey.Convey("SetSeasonMCache", t, func(ctx convey.C) {
var (
c = context.Background()
seasons = []*model.Season{}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetSeasonMCache(c, seasons, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaofrom(t *testing.T) {
convey.Convey("from", t, func(ctx convey.C) {
var (
i = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := from(i)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaocombine(t *testing.T) {
convey.Convey("combine", t, func(ctx convey.C) {
var (
sort = int64(0)
count = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := combine(sort, count)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoCacheEpContests(t *testing.T) {
convey.Convey("CacheEpContests", t, func(ctx convey.C) {
var (
c = context.Background()
ids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.CacheEpContests(c, ids)
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 TestDaoAddCacheEpContests(t *testing.T) {
convey.Convey("AddCacheEpContests", t, func(ctx convey.C) {
var (
c = context.Background()
data map[int64]*model.Contest
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddCacheEpContests(c, data)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoCacheEpSeasons(t *testing.T) {
convey.Convey("CacheEpSeasons", t, func(ctx convey.C) {
var (
c = context.Background()
ids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.CacheEpSeasons(c, ids)
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 TestDaoAddCacheEpSeasons(t *testing.T) {
convey.Convey("AddCacheEpSeasons", t, func(ctx convey.C) {
var (
c = context.Background()
data map[int64]*model.Season
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddCacheEpSeasons(c, data)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGetActPageCache(t *testing.T) {
convey.Convey("GetActPageCache", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.GetActPageCache(c, id)
ctx.Convey("Then err should be nil.act should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoAddActPageCache(t *testing.T) {
convey.Convey("AddActPageCache", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
act = &model.ActivePage{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddActPageCache(c, aid, act)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGetActModuleCache(t *testing.T) {
convey.Convey("GetActModuleCache", t, func(ctx convey.C) {
var (
c = context.Background()
mmid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.GetActModuleCache(c, mmid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoAddActModuleCache(t *testing.T) {
convey.Convey("AddActModuleCache", t, func(ctx convey.C) {
var (
c = context.Background()
mmid = int64(0)
module []*arcmdl.Arc
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddActModuleCache(c, mmid, module)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGetActTopCache(t *testing.T) {
convey.Convey("GetActTopCache", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
ps = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.GetActTopCache(c, aid, ps)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddActTopCache(t *testing.T) {
convey.Convey("AddActTopCache", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
ps = int64(0)
con = &model.Contest{}
tops = []*model.Contest{con}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddActTopCache(c, aid, ps, tops, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGetActPointsCache(t *testing.T) {
convey.Convey("GetActPointsCache", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
mdID = int64(0)
ps = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, total, err := d.GetActPointsCache(c, aid, mdID, ps)
ctx.Convey("Then err should be nil.res,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddActPointsCache(t *testing.T) {
convey.Convey("AddActPointsCache", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
mdID = int64(0)
ps = int64(0)
con = &model.Contest{}
points = []*model.Contest{con}
total = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddActPointsCache(c, aid, mdID, ps, points, total)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGetActKnockoutCache(t *testing.T) {
convey.Convey("GetActKnockoutCache", t, func(ctx convey.C) {
var (
c = context.Background()
mdID = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.GetActKnockoutCache(c, mdID)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoAddActKnockoutCache(t *testing.T) {
convey.Convey("AddActKnockoutCache", t, func(ctx convey.C) {
var (
c = context.Background()
mdID = int64(0)
knock = [][]*model.TreeList{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddActKnockoutCache(c, mdID, knock)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoAddActKnockCacheTime(t *testing.T) {
convey.Convey("AddActKnockCacheTime", t, func(convCtx convey.C) {
var (
c = context.Background()
mdID = int64(1)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.AddActKnockCacheTime(c, mdID)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGetMActCache(t *testing.T) {
convey.Convey("GetMActCache", t, func(convCtx convey.C) {
var (
c = context.Background()
aid = int64(1)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
res, err := d.GetMActCache(c, aid)
convCtx.Convey("Then err should be nil.res should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
println(res)
})
})
})
}
func TestDaoAddMActCache(t *testing.T) {
convey.Convey("AddMActCache", t, func(convCtx convey.C) {
var (
c = context.Background()
aid = int64(1)
act = &model.Active{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.AddMActCache(c, aid, act)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,377 @@
package dao
import (
"context"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/interface/main/esports/model"
arcMdl "go-common/app/service/main/archive/model/archive"
"go-common/library/database/elastic"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
)
const (
_esports = "esports"
_contest = "esports_contests"
_videomap = "esports_map"
_matchmap = "esports_contests_map"
_calendar = "esports_contests_date"
_contestFav = "esports_fav"
_searchPlatform = "web"
_fromSource = "esports_search"
_searchType = "vesports"
_searchVer = "v3"
_orderRank = "totalrank"
_orderHot = "hot"
_orderPub = "pubdate"
_active = 1
_pageNum = 1
_pageSize = 1000
)
// Search search api.
func (d *Dao) Search(c context.Context, mid int64, p *model.ParamSearch, buvid string) (rs *model.SearchEsp, err error) {
var (
params = url.Values{}
ip = metadata.String(c, metadata.RemoteIP)
)
params.Set("keyword", p.Keyword)
params.Set("platform", _searchPlatform)
params.Set("from_source", _fromSource)
params.Set("search_type", _searchType)
params.Set("main_ver", _searchVer)
params.Set("clientip", ip)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("buvid", buvid)
params.Set("page", strconv.Itoa(p.Pn))
params.Set("pagesize", strconv.Itoa(p.Ps))
if p.Sort == 0 {
params.Set("order", _orderRank)
} else if p.Sort == 1 {
params.Set("order", _orderPub)
} else if p.Sort == 2 {
params.Set("order", _orderHot)
}
if err = d.http.Get(c, d.searchURL, ip, params, &rs); err != nil {
log.Error("Search接口错误 Search d.http.Get(%s) error(%v)", d.searchURL+"?"+params.Encode(), err)
return
}
if rs.Code != ecode.OK.Code() {
log.Error("Search接口code错误 Search d.http.Do(%s) code error(%d)", d.searchURL, rs.Code)
err = ecode.Int(rs.Code)
}
return
}
// SearchVideo search video.
func (d *Dao) SearchVideo(c context.Context, p *model.ParamVideo) (rs []*model.SearchVideo, total int, err error) {
var res struct {
Page model.Page `json:"page"`
Result []*model.SearchVideo `json:"result"`
}
states := []int64{arcMdl.StateForbidFixed, arcMdl.StateOpen, arcMdl.StateOrange}
r := d.ela.NewRequest(_esports).WhereIn("state", states).WhereEq("is_deleted", 0).Fields("aid").Index(_esports).Pn(p.Pn).Ps(p.Ps)
if p.Gid > 0 {
r.WhereEq("gid", p.Gid)
}
if p.Mid > 0 {
r.WhereEq("matchs", p.Mid)
}
if p.Year > 0 {
r.WhereEq("year", p.Year)
}
if p.Tid > 0 {
r.WhereEq("teams", p.Tid)
}
if p.Tag > 0 {
r.WhereEq("tags", p.Tag)
}
if p.Sort == 0 {
r.Order("score", elastic.OrderDesc)
} else if p.Sort == 1 {
r.Order("pubtime", elastic.OrderDesc)
} else if p.Sort == 2 {
r.Order("click", elastic.OrderDesc)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
total = res.Page.Total
rs = res.Result
return
}
// SearchContest search contest.
func (d *Dao) SearchContest(c context.Context, p *model.ParamContest) (rs []*model.Contest, total int, err error) {
var res struct {
Page model.Page `json:"page"`
Result []*model.Contest `json:"result"`
}
r := d.ela.NewRequest(_contest).Index(_contest).WhereEq("status", 0).Pn(p.Pn).Ps(p.Ps)
r.Fields("id", "game_stage", "stime", "etime", "home_id", "away_id", "home_score", "away_score", "live_room", "aid", "collection", "game_state", "dic", "ctime", "mtime", "status", "sid", "mid")
if p.Sort == 1 {
r.Order("stime", elastic.OrderDesc)
} else {
r.Order("stime", elastic.OrderAsc)
}
if p.Gid > 0 {
r.WhereEq("gid", p.Gid)
}
if p.Mid > 0 {
r.WhereEq("mid", p.Mid)
}
if p.Tid > 0 {
r.WhereOr("home_id", p.Tid).WhereOr("away_id", p.Tid)
}
if p.Stime != "" && p.Etime != "" {
start, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Stime+" 00:00:00", time.Local)
end, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Etime+" 23:59:59", time.Local)
r.WhereRange("stime", start.Unix(), end.Unix(), elastic.RangeScopeLcRc)
} else if p.Stime != "" && p.Etime == "" {
start, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Stime+" 00:00:00", time.Local)
r.WhereRange("stime", start.Unix(), "", elastic.RangeScopeLcRo)
} else if p.Stime == "" && p.Etime != "" {
end, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Etime+" 23:59:59", time.Local)
r.WhereRange("stime", "", end.Unix(), elastic.RangeScopeLoRc)
}
if p.GState != "" {
r.WhereIn("game_state", strings.Split(p.GState, ","))
}
if len(p.Sids) > 0 {
r.WhereIn("sid", p.Sids)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
total = res.Page.Total
rs = res.Result
return
}
// SearchContestQuery search contest.
func (d *Dao) SearchContestQuery(c context.Context, p *model.ParamContest) (rs []*model.Contest, total int, err error) {
var res struct {
Page model.Page `json:"page"`
Result []*model.Contest `json:"result"`
}
r := d.ela.NewRequest(_contest).Index(_contest).WhereEq("status", 0).Pn(p.Pn).Ps(p.Ps)
r.Fields("id", "game_stage", "stime", "etime", "home_id", "away_id", "home_score", "away_score", "live_room", "aid", "collection", "game_state", "dic", "ctime", "mtime", "status", "sid", "mid")
if p.Sort == 1 {
r.Order("stime", elastic.OrderDesc)
} else {
r.Order("stime", elastic.OrderAsc)
}
if p.Gid > 0 {
r.WhereEq("gid", p.Gid)
}
if p.Mid > 0 {
r.WhereEq("mid", p.Mid)
}
if p.Tid > 0 {
r.WhereOr("home_id", p.Tid).WhereOr("away_id", p.Tid)
}
if p.Stime != "" && p.Etime != "" {
start, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Stime, time.Local)
end, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Etime, time.Local)
r.WhereRange("stime", start.Unix(), end.Unix(), elastic.RangeScopeLcRc)
} else if p.Stime != "" && p.Etime == "" {
start, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Stime, time.Local)
r.WhereRange("stime", start.Unix(), "", elastic.RangeScopeLcRo)
} else if p.Stime == "" && p.Etime != "" {
end, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Etime, time.Local)
r.WhereRange("stime", "", end.Unix(), elastic.RangeScopeLoRc)
}
if p.GState != "" {
r.WhereIn("game_state", strings.Split(p.GState, ","))
}
if len(p.Sids) > 0 {
r.WhereIn("sid", p.Sids)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
total = res.Page.Total
rs = res.Result
return
}
// FilterVideo video filter.
func (d *Dao) FilterVideo(c context.Context, p *model.ParamFilter) (rs *model.FilterES, err error) {
var res struct {
Page model.Page `json:"page"`
Result *model.FilterES `json:"result"`
}
r := d.ela.NewRequest(_videomap).Index(_videomap).Pn(_pageNum).Ps(_pageSize)
r.WhereEq("active", _active).GroupBy("group_by", "gid", nil).GroupBy("group_by", "match", nil).GroupBy("group_by", "tag", nil).GroupBy("group_by", "team", nil).GroupBy("group_by", "year", nil)
if p.Gid > 0 {
r.WhereEq("gid", p.Gid).WhereEq("active", _active)
}
if p.Mid > 0 {
r.WhereEq("match", p.Mid).WhereEq("active", _active)
}
if p.Tid > 0 {
r.WhereOr("team", p.Tid).WhereEq("active", _active)
}
if p.Tag > 0 {
r.WhereEq("tag", p.Tag).WhereEq("active", _active)
}
if p.Year > 0 {
r.WhereEq("year", p.Year).WhereEq("active", _active)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
rs = res.Result
return
}
// FilterMatch match filter.
func (d *Dao) FilterMatch(c context.Context, p *model.ParamFilter) (rs *model.FilterES, err error) {
var res struct {
Page model.Page `json:"page"`
Result *model.FilterES `json:"result"`
}
r := d.ela.NewRequest(_matchmap).Index(_matchmap).Pn(_pageNum).Ps(_pageSize)
r.WhereEq("active", _active).GroupBy("group_by", "match", nil).GroupBy("group_by", "gid", nil).GroupBy("group_by", "team", nil)
if p.Mid > 0 {
r.WhereEq("match", p.Mid).WhereEq("active", _active)
}
if p.Gid > 0 {
r.WhereEq("gid", p.Gid).WhereEq("active", _active)
}
if p.Tid > 0 {
r.WhereOr("team", p.Tid).WhereEq("active", _active)
}
if p.Stime != "" {
r.WhereOr("stime", p.Stime).WhereEq("active", _active)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
rs = res.Result
return
}
// FilterCale Calendar filter.
func (d *Dao) FilterCale(c context.Context, p *model.ParamFilter) (rs map[string]int64, err error) {
var res struct {
Page model.Page `json:"page"`
Result map[string]int64 `json:"result"`
}
r := d.ela.NewRequest(_calendar).Index(_matchmap).Pn(_pageNum).Ps(_pageSize).WhereEq("active", _active).WhereRange("stime", p.Stime, p.Etime, elastic.RangeScopeLcRc)
r.GroupBy("group_by", "stime", nil)
if p.Mid > 0 {
r.WhereEq("match", p.Mid).WhereEq("active", _active)
}
if p.Gid > 0 {
r.WhereEq("gid", p.Gid).WhereEq("active", _active)
}
if p.Tid > 0 {
r.WhereOr("team", p.Tid).WhereEq("active", _active)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
rs = res.Result
return
}
// SearchFav search app fav contest.
func (d *Dao) SearchFav(c context.Context, mid int64, p *model.ParamFav) (rs []int64, total int, err error) {
var res struct {
Page model.Page `json:"page"`
Result []*model.ElaSub `json:"result"`
}
r := d.ela.NewRequest(_contestFav).Index(_contestFav).WhereEq("mid", mid).WhereEq("state", 0).Pn(p.Pn).Ps(p.Ps).Fields("oid")
if p.Sort == 1 {
r.Order("stime", elastic.OrderDesc)
} else {
r.Order("stime", elastic.OrderAsc)
}
if p.Stime != "" && p.Etime != "" {
start, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Stime+" 00:00:00", time.Local)
end, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Etime+" 23:59:59", time.Local)
r.WhereRange("stime", start.Unix(), end.Unix(), elastic.RangeScopeLcRc)
} else if p.Stime != "" && p.Etime == "" {
start, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Stime+" 00:00:00", time.Local)
r.WhereRange("stime", start.Unix(), "", elastic.RangeScopeLcRo)
} else if p.Stime == "" && p.Etime != "" {
end, _ := time.ParseInLocation("2006-01-02 15:04:05", p.Etime+" 23:59:59", time.Local)
r.WhereRange("stime", "", end.Unix(), elastic.RangeScopeLoRc)
}
if len(p.Sids) > 0 {
r.WhereIn("sid", p.Sids)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
total = res.Page.Total
if total == 0 {
return
}
for _, contest := range res.Result {
rs = append(rs, contest.Oid)
}
return
}
// SeasonFav fav season list.
func (d *Dao) SeasonFav(c context.Context, mid int64, p *model.ParamSeason) (rs []*model.ElaSub, total int, err error) {
var res struct {
Page model.Page `json:"page"`
Result []*model.ElaSub `json:"result"`
}
r := d.ela.NewRequest(_contestFav).Index(_contestFav).WhereEq("mid", mid).WhereEq("state", 0).Pn(p.Pn).Ps(p.Ps).Fields("sid", "oid")
if p.Sort == 1 {
r.Order("season_stime", elastic.OrderDesc)
} else {
r.Order("season_stime", elastic.OrderAsc)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
total = res.Page.Total
if total == 0 {
return
}
rs = res.Result
return
}
// StimeFav fav contest stime list.
func (d *Dao) StimeFav(c context.Context, mid int64, p *model.ParamSeason) (rs []*model.ElaSub, total int, err error) {
var res struct {
Page model.Page `json:"page"`
Result []*model.ElaSub `json:"result"`
}
r := d.ela.NewRequest(_contestFav).Index(_contestFav).WhereEq("mid", mid).WhereEq("state", 0).Pn(p.Pn).Ps(p.Ps).Fields("stime", "oid")
if p.Sort == 1 {
r.Order("stime", elastic.OrderDesc)
} else {
r.Order("stime", elastic.OrderAsc)
}
if err = r.Scan(c, &res); err != nil {
log.Error("r.Scan error(%v)", err)
return
}
total = res.Page.Total
if total == 0 {
return
}
rs = res.Result
return
}

View File

@@ -0,0 +1,146 @@
package dao
import (
"context"
"testing"
"go-common/app/interface/main/esports/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSearch(t *testing.T) {
var (
c = context.Background()
mid = int64(111)
p = &model.ParamSearch{Keyword: "test", Pn: 1, Ps: 100, Sort: 0}
buvid = ""
)
convey.Convey("Search", t, func(ctx convey.C) {
rs, err := d.Search(c, mid, p, buvid)
ctx.Convey("Then err should be nil.rs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
println(rs)
})
})
}
func TestDaoSearchVideo(t *testing.T) {
var (
c = context.Background()
p = &model.ParamVideo{Pn: 1, Ps: 30}
)
convey.Convey("SearchVideo", t, func(ctx convey.C) {
rs, total, err := d.SearchVideo(c, p)
ctx.Convey("Then err should be nil.rs,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
ctx.So(len(rs), convey.ShouldBeGreaterThanOrEqualTo, 0)
})
})
}
func TestDaoSearchContest(t *testing.T) {
var (
c = context.Background()
p = &model.ParamContest{Pn: 1, Ps: 30}
)
convey.Convey("SearchContest", t, func(ctx convey.C) {
rs, total, err := d.SearchContest(c, p)
ctx.Convey("Then err should be nil.rs,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
ctx.So(len(rs), convey.ShouldBeGreaterThanOrEqualTo, 0)
})
})
}
func TestDaoFilterVideo(t *testing.T) {
var (
c = context.Background()
p = &model.ParamFilter{Mid: 2}
)
convey.Convey("FilterVideo", t, func(ctx convey.C) {
rs, err := d.FilterVideo(c, p)
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 TestDaoFilterMatch(t *testing.T) {
var (
c = context.Background()
p = &model.ParamFilter{}
)
convey.Convey("FilterMatch", t, func(ctx convey.C) {
rs, err := d.FilterMatch(c, p)
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 TestDaoFilterCale(t *testing.T) {
var (
c = context.Background()
p = &model.ParamFilter{}
)
convey.Convey("FilterCale", t, func(ctx convey.C) {
rs, err := d.FilterCale(c, p)
ctx.Convey("Then err should be nil.rs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(len(rs), convey.ShouldBeGreaterThanOrEqualTo, 0)
})
})
}
func TestDaoSearchFav(t *testing.T) {
var (
c = context.Background()
mid = int64(111)
p = &model.ParamFav{Pn: 1, Ps: 30}
)
convey.Convey("SearchFav", t, func(ctx convey.C) {
rs, total, err := d.SearchFav(c, mid, p)
ctx.Convey("Then err should be nil.rs,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
ctx.So(len(rs), convey.ShouldBeGreaterThanOrEqualTo, 0)
})
})
}
func TestDaoSeasonFav(t *testing.T) {
var (
c = context.Background()
mid = int64(111)
p = &model.ParamSeason{Pn: 1, Ps: 30}
)
convey.Convey("SeasonFav", t, func(ctx convey.C) {
rs, total, err := d.SeasonFav(c, mid, p)
ctx.Convey("Then err should be nil.rs,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
ctx.So(len(rs), convey.ShouldBeGreaterThanOrEqualTo, 0)
})
})
}
func TestDaoStimeFav(t *testing.T) {
var (
c = context.Background()
mid = int64(111)
p = &model.ParamSeason{Pn: 1, Ps: 30}
)
convey.Convey("StimeFav", t, func(ctx convey.C) {
rs, total, err := d.StimeFav(c, mid, p)
ctx.Convey("Then err should be nil.rs,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
ctx.So(len(rs), convey.ShouldBeGreaterThanOrEqualTo, 0)
})
})
}

View File

@@ -0,0 +1,44 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"favorite.go",
"http.go",
"match.go",
"pointdata.go",
],
importpath = "go-common/app/interface/main/esports/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/esports/conf:go_default_library",
"//app/interface/main/esports/model:go_default_library",
"//app/interface/main/esports/service:go_default_library",
"//app/service/main/archive/api: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/middleware/verify: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,193 @@
package http
import (
"time"
"go-common/app/interface/main/esports/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func addFav(c *bm.Context) {
midStr, _ := c.Get("mid")
mid := midStr.(int64)
v := new(struct {
Cid int64 `form:"cid" validate:"min=1"`
})
if err := c.Bind(v); err != nil {
return
}
c.JSON(nil, switchCode(eSvc.AddFav(c, mid, v.Cid)))
}
func delFav(c *bm.Context) {
midStr, _ := c.Get("mid")
mid := midStr.(int64)
v := new(struct {
Cid int64 `form:"cid" validate:"min=1"`
})
if err := c.Bind(v); err != nil {
return
}
c.JSON(nil, switchCode(eSvc.DelFav(c, mid, v.Cid)))
}
func listFav(c *bm.Context) {
var (
mid int64
total int
contest []*model.Contest
err error
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
v := new(struct {
VMID int64 `form:"vmid"`
Pn int `form:"pn" default:"1" validate:"min=1"`
Ps int `form:"ps" default:"5" validate:"min=1"`
})
if err = c.Bind(v); err != nil {
return
}
if contest, total, err = eSvc.ListFav(c, mid, v.VMID, v.Pn, v.Ps); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": v.Pn,
"size": v.Ps,
"total": total,
}
data["page"] = page
data["list"] = contest
c.JSON(data, nil)
}
func appListFav(c *bm.Context) {
var (
mid int64
total int
contest []*model.Contest
err error
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
v := new(model.ParamFav)
if err = c.Bind(v); err != nil {
return
}
if mid == 0 && v.VMID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if v.Stime != "" {
if _, err = time.Parse("2006-01-02", v.Stime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
if v.Etime != "" {
if _, err = time.Parse("2006-01-02", v.Etime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
if contest, total, err = eSvc.ListAppFav(c, mid, v); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": v.Pn,
"size": v.Ps,
"total": total,
}
data["page"] = page
data["list"] = contest
c.JSON(data, nil)
}
func seasonFav(c *bm.Context) {
var (
mid int64
total int
seasons []*model.Season
err error
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
v := new(model.ParamSeason)
if err = c.Bind(v); err != nil {
return
}
if mid == 0 && v.VMID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if seasons, total, err = eSvc.SeasonFav(c, mid, v); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": v.Pn,
"size": v.Ps,
"total": total,
}
data["page"] = page
data["list"] = seasons
c.JSON(data, nil)
}
func stimeFav(c *bm.Context) {
var (
mid int64
total int
stimes []string
err error
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
v := new(model.ParamSeason)
if err = c.Bind(v); err != nil {
return
}
if mid == 0 && v.VMID == 0 {
c.JSON(nil, ecode.RequestErr)
return
}
if stimes, total, err = eSvc.StimeFav(c, mid, v); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": v.Pn,
"size": v.Ps,
"total": total,
}
data["page"] = page
data["list"] = stimes
c.JSON(data, nil)
}
func switchCode(err error) error {
if err == nil {
return err
}
switch ecode.Cause(err) {
case ecode.FavResourceOverflow:
err = ecode.EsportsContestMaxCount
case ecode.FavResourceAlreadyDel:
err = ecode.EsportsContestFavDel
case ecode.FavResourceExist:
err = ecode.EsportsContestFavExist
case ecode.FavFolderNotExist:
err = ecode.EsportsContestNotExist
}
return err
}

View File

@@ -0,0 +1,121 @@
package http
import (
"net/http"
"go-common/app/interface/main/esports/conf"
"go-common/app/interface/main/esports/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/auth"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
authn *auth.Auth
vfySvr *verify.Verify
eSvc *service.Service
)
// Init init http server
func Init(c *conf.Config, s *service.Service) {
authn = auth.New(c.Auth)
vfySvr = verify.New(c.Verify)
eSvc = s
engine := bm.DefaultServer(c.BM)
outerRouter(engine)
internalRouter(engine)
if err := engine.Start(); err != nil {
log.Error("httpx.Serve error(%v)", err)
panic(err)
}
}
// outerRouter init outer router api path.
func outerRouter(e *bm.Engine) {
e.Ping(ping)
group := e.Group("/x/esports", bm.CORS())
{
group.GET("/season", season)
group.GET("/app/season", appSeason)
matGroup := group.Group("/matchs")
{
matGroup.GET("/filter", filterMatch)
matGroup.GET("/list", authn.Guest, listContest)
matGroup.GET("/app/list", authn.Guest, appContest)
matGroup.GET("/calendar", calendar)
matGroup.GET("/active", authn.Guest, active)
matGroup.GET("/videos", authn.Guest, actVideos)
matGroup.GET("/points", authn.Guest, actPoints)
matGroup.GET("/top", authn.Guest, actTop)
matGroup.GET("/knockout", authn.Guest, actKnockout)
matGroup.GET("/info", authn.Guest, contest)
matGroup.GET("/recent", authn.Guest, recent)
}
videoGroup := group.Group("/video")
{
videoGroup.GET("/filter", filterVideo)
videoGroup.GET("/list", listVideo)
videoGroup.GET("/search", authn.Guest, search)
}
favGroup := group.Group("/fav")
{
favGroup.GET("", authn.Guest, listFav)
favGroup.GET("/season", authn.Guest, seasonFav)
favGroup.GET("/stime", authn.Guest, stimeFav)
favGroup.GET("/list", authn.Guest, appListFav)
favGroup.POST("/add", authn.User, addFav)
favGroup.POST("/del", authn.User, delFav)
}
pointGroup := group.Group("/leida")
{
pointGroup.GET("/game", game)
pointGroup.GET("/items", items)
pointGroup.GET("/heroes", heroes)
pointGroup.GET("/abilities", abilities)
pointGroup.GET("/players", players)
}
}
}
func internalRouter(e *bm.Engine) {
group := e.Group("/x/internal/esports")
{
group.GET("/season", vfySvr.Verify, season)
group.GET("/app/season", vfySvr.Verify, appSeason)
matGroup := group.Group("/matchs")
{
matGroup.GET("/filter", vfySvr.Verify, filterMatch)
matGroup.GET("/list", vfySvr.Verify, listContest)
matGroup.GET("/app/list", vfySvr.Verify, appContest)
matGroup.GET("/calendar", vfySvr.Verify, calendar)
matGroup.GET("/active", vfySvr.Verify, active)
matGroup.GET("/videos", vfySvr.Verify, actVideos)
matGroup.GET("/points", vfySvr.Verify, actPoints)
matGroup.GET("/top", vfySvr.Verify, actTop)
matGroup.GET("/knockout", vfySvr.Verify, actKnockout)
matGroup.GET("/info", vfySvr.Verify, contest)
matGroup.GET("/recent", vfySvr.Verify, recent)
}
videoGroup := group.Group("/video")
{
videoGroup.GET("/filter", vfySvr.Verify, filterVideo)
videoGroup.GET("/list", vfySvr.Verify, listVideo)
videoGroup.GET("/search", vfySvr.Verify, search)
}
favGroup := group.Group("/fav")
{
favGroup.GET("", vfySvr.Verify, listFav)
favGroup.GET("/season", vfySvr.Verify, seasonFav)
favGroup.GET("/stime", vfySvr.Verify, stimeFav)
favGroup.GET("/list", vfySvr.Verify, appListFav)
}
}
}
func ping(c *bm.Context) {
if err := eSvc.Ping(c); err != nil {
log.Error("esports interface ping error")
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}

View File

@@ -0,0 +1,359 @@
package http
import (
"time"
"go-common/app/interface/main/esports/model"
arcmdl "go-common/app/service/main/archive/api"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func filterMatch(c *bm.Context) {
p := new(model.ParamFilter)
if err := c.Bind(p); err != nil {
return
}
if p.Stime != "" {
if _, err := time.Parse("2006-01-02", p.Stime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
c.JSON(eSvc.FilterMatch(c, p))
}
func listContest(c *bm.Context) {
var (
mid int64
err error
total int
list []*model.Contest
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
p := new(model.ParamContest)
if err = c.Bind(p); err != nil {
return
}
if p.Stime != "" {
if _, err = time.Parse("2006-01-02", p.Stime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
if p.Etime != "" {
if _, err = time.Parse("2006-01-02", p.Etime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
if list, total, err = eSvc.ListContest(c, mid, p); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": p.Pn,
"size": p.Ps,
"total": total,
}
data["page"] = page
data["list"] = list
c.JSON(data, nil)
}
func appContest(c *bm.Context) {
var (
mid int64
err error
total int
list []*model.Contest
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
p := new(model.ParamContest)
if err = c.Bind(p); err != nil {
return
}
if p.Stime != "" {
if _, err = time.Parse("2006-01-02", p.Stime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
p.Etime = p.Stime
}
if list, total, err = eSvc.ListContest(c, mid, p); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": p.Pn,
"size": p.Ps,
"total": total,
}
data["page"] = page
data["list"] = list
c.JSON(data, nil)
}
func calendar(c *bm.Context) {
var err error
p := new(model.ParamFilter)
if err = c.Bind(p); err != nil {
return
}
if _, err = time.Parse("2006-01-02", p.Stime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if _, err = time.Parse("2006-01-02", p.Etime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(eSvc.Calendar(c, p))
}
func filterVideo(c *bm.Context) {
p := new(model.ParamFilter)
if err := c.Bind(p); err != nil {
return
}
c.JSON(eSvc.FilterVideo(c, p))
}
func listVideo(c *bm.Context) {
var (
err error
total int
list []*arcmdl.Arc
)
p := new(model.ParamVideo)
if err = c.Bind(p); err != nil {
return
}
if list, total, err = eSvc.ListVideo(c, p); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": p.Pn,
"size": p.Ps,
"total": total,
}
data["page"] = page
data["list"] = list
c.JSON(data, nil)
}
func actVideos(c *bm.Context) {
var (
err error
)
param := new(struct {
MmID int64 `form:"mm_id" validate:"gt=0"`
})
if err = c.Bind(param); err != nil {
return
}
c.JSON(eSvc.ActModules(c, param.MmID))
}
func active(c *bm.Context) {
var (
err error
)
param := new(struct {
Aid int64 `form:"aid" validate:"gt=0"`
})
if err = c.Bind(param); err != nil {
return
}
c.JSON(eSvc.ActPage(c, param.Aid))
}
func actPoints(c *bm.Context) {
var (
mid int64
err error
total int
list []*model.Contest
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
p := new(model.ParamActPoint)
if err = c.Bind(p); err != nil {
return
}
if list, total, err = eSvc.ActPoints(c, mid, p); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": p.Pn,
"size": p.Ps,
"total": total,
}
data["page"] = page
data["list"] = list
c.JSON(data, nil)
}
func actKnockout(c *bm.Context) {
var (
err error
)
param := new(struct {
MdID int64 `form:"md_id" validate:"gt=0"`
})
if err = c.Bind(param); err != nil {
return
}
c.JSON(eSvc.ActKnockout(c, param.MdID))
}
func actTop(c *bm.Context) {
var (
mid int64
err error
total int
list []*model.Contest
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
p := new(model.ParamActTop)
if err = c.Bind(p); err != nil {
return
}
if p.Stime != "" {
if _, err = time.Parse("2006-01-02", p.Stime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
if p.Etime != "" {
if _, err = time.Parse("2006-01-02", p.Etime); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
}
if list, total, err = eSvc.ActTop(c, mid, p); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": p.Pn,
"size": p.Ps,
"total": total,
}
data["page"] = page
data["list"] = list
c.JSON(data, nil)
}
func search(c *bm.Context) {
var (
mid int64
buvid string
err error
)
p := new(model.ParamSearch)
if err = c.Bind(p); err != nil {
return
}
if ck, err := c.Request.Cookie("buvid3"); err == nil {
buvid = ck.Value
}
if midInter, ok := c.Get("mid"); ok {
mid = midInter.(int64)
}
c.JSON(eSvc.Search(c, mid, p, buvid))
}
func season(c *bm.Context) {
var (
err error
total int
list []*model.Season
)
p := new(model.ParamSeason)
if err = c.Bind(p); err != nil {
return
}
if list, total, err = eSvc.Season(c, p); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": p.Pn,
"size": p.Ps,
"total": total,
}
data["page"] = page
data["list"] = list
c.JSON(data, nil)
}
func appSeason(c *bm.Context) {
var (
err error
total int
list []*model.Season
)
p := new(model.ParamSeason)
if err = c.Bind(p); err != nil {
return
}
if list, total, err = eSvc.AppSeason(c, p); err != nil {
c.JSON(nil, err)
return
}
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": p.Pn,
"size": p.Ps,
"total": total,
}
data["page"] = page
data["list"] = list
c.JSON(data, nil)
}
func contest(c *bm.Context) {
var (
mid int64
err error
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
param := new(struct {
Cid int64 `form:"cid" validate:"gt=0"`
})
if err = c.Bind(param); err != nil {
return
}
c.JSON(eSvc.Contest(c, mid, param.Cid))
}
func recent(c *bm.Context) {
var (
mid int64
err error
)
if midStr, ok := c.Get("mid"); ok {
mid = midStr.(int64)
}
param := &model.ParamCDRecent{}
if err = c.Bind(param); err != nil {
return
}
c.JSON(eSvc.Recent(c, mid, param))
}

View File

@@ -0,0 +1,45 @@
package http
import (
"go-common/app/interface/main/esports/model"
bm "go-common/library/net/http/blademaster"
)
func game(c *bm.Context) {
p := new(model.ParamGame)
if err := c.Bind(p); err != nil {
return
}
c.JSON(eSvc.Game(c, p))
}
func items(c *bm.Context) {
p := new(model.ParamLeidas)
if err := c.Bind(p); err != nil {
return
}
c.JSON(eSvc.Items(c, p))
}
func heroes(c *bm.Context) {
p := new(model.ParamLeidas)
if err := c.Bind(p); err != nil {
return
}
c.JSON(eSvc.Heroes(c, p))
}
func abilities(c *bm.Context) {
p := new(model.ParamLeidas)
if err := c.Bind(p); err != nil {
return
}
c.JSON(eSvc.Abilities(c, p))
}
func players(c *bm.Context) {
p := new(model.ParamLeidas)
if err := c.Bind(p); err != nil {
return
}
c.JSON(eSvc.Players(c, p))
}

View File

@@ -0,0 +1,37 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"match.go",
"params.go",
"pointdata.go",
"search.go",
],
importpath = "go-common/app/interface/main/esports/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/archive/api:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,207 @@
package model
import (
arcmdl "go-common/app/service/main/archive/api"
"go-common/library/time"
)
// Filter filter struct
type Filter struct {
ID int64 `json:"id"`
Title string `json:"title"`
SubTitle string `json:"sub_title"`
Logo string `json:"logo"`
Rank int `json:"rank"`
URL string `json:"url"`
DataFocus string `json:"data_focus"`
FocusURL string `json:"focus_url"`
}
// Year year struct
type Year struct {
ID int64 `json:"id"`
Year int64 `json:"year"`
Aid int64 `json:"aid"`
}
// Calendar calendar struct
type Calendar struct {
Stime string `json:"stime"`
Count int64 `json:"count"`
}
// Season season struct
type Season struct {
ID int64 `json:"id"`
Mid int64 `json:"mid"`
Title string `json:"title"`
SubTitle string `json:"sub_title"`
Stime int64 `json:"stime"`
Etime int64 `json:"etime"`
Sponsor string `json:"sponsor"`
Logo string `json:"logo"`
Dic string `json:"dic"`
Status int64 `json:"status"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
Rank int64 `json:"rank"`
IsApp int64 `json:"is_app"`
URL string `json:"url"`
DataFocus string `json:"data_focus"`
FocusURL string `json:"focus_url"`
}
// Contest contest struct
type Contest struct {
ID int64 `json:"id"`
GameStage string `json:"game_stage"`
Stime int64 `json:"stime"`
Etime int64 `json:"etime"`
HomeID int64 `json:"home_id"`
AwayID int64 `json:"away_id"`
HomeScore int64 `json:"home_score"`
AwayScore int64 `json:"away_score"`
LiveRoom int64 `json:"live_room"`
Aid int64 `json:"aid"`
Collection int64 `json:"collection"`
GameState int64 `json:"game_state"`
Dic string `json:"dic"`
Ctime string `json:"ctime"`
Mtime string `json:"mtime"`
Status int64 `json:"status"`
Sid int64 `json:"sid"`
Mid int64 `json:"mid"`
Season interface{} `json:"season"`
HomeTeam interface{} `json:"home_team"`
AwayTeam interface{} `json:"away_team"`
Special int `json:"special"`
SuccessTeam int64 `json:"success_team"`
SuccessTeaminfo interface{} `json:"success_teaminfo"`
SpecialName string `json:"special_name"`
SpecialTips string `json:"special_tips"`
SpecialImage string `json:"special_image"`
Playback string `json:"playback"`
CollectionURL string `json:"collection_url"`
LiveURL string `json:"live_url"`
DataType int64 `json:"data_type"`
MatchID int64 `json:"match_id"`
}
// ContestsData contest data struct
type ContestsData struct {
ID int64 `json:"id"`
Cid int64 `json:"cid"`
URL string `json:"url"`
PointData int64 `json:"point_data"`
GameStatus int64 `json:"game_status"`
DataType int64 `json:"-"`
}
//ContestDataPage contest data pager
type ContestDataPage struct {
Contest *Contest `json:"contest"`
Detail []*ContestsData `json:"detail"`
}
// ElaSub elasticsearch sub contest.
type ElaSub struct {
SeasonStime int64 `json:"season_stime"`
Mid int64 `json:"mid"`
Stime int64 `json:"stime"`
Oid int64 `json:"oid"`
State int64 `json:"state"`
Sid int64 `json:"sid"`
}
// Tree match Active
type Tree struct {
ID int64 `json:"id" form:"id"`
MaID int64 `json:"ma_id,omitempty" form:"ma_id" validate:"required"`
MadID int64 `json:"mad_id,omitempty" form:"mad_id" validate:"required"`
Pid int64 `json:"pid" form:"pid"`
RootID int64 `json:"root_id" form:"root_id"`
GameRank int64 `json:"game_rank,omitempty" form:"game_rank" validate:"required"`
Mid int64 `json:"mid" form:"mid"`
IsDeleted int `json:"is_deleted,omitempty" form:"is_deleted"`
}
// Team .
type Team struct {
ID int64 `json:"id" form:"id"`
Title string `json:"title" form:"title" validate:"required"`
SubTitle string `json:"sub_title" form:"sub_title"`
ETitle string `json:"e_title" form:"e_title"`
CreateTime int64 `json:"create_time" form:"create_time"`
Area string `json:"area" form:"area"`
Logo string `json:"logo" form:"logo" validate:"required"`
UID int64 `json:"uid" form:"uid" gorm:"column:uid"`
Members string `json:"members" form:"members"`
Dic string `json:"dic" form:"dic"`
IsDeleted int `json:"is_deleted" form:"is_deleted"`
}
// ContestInfo .
type ContestInfo struct {
*Contest
HomeName string `json:"home_name"`
AwayName string `json:"away_name"`
SuccessName string `json:"success_name" form:"success_name"`
}
// TreeList .
type TreeList struct {
*Tree
*ContestInfo
}
// Active match Active
type Active struct {
ID int64 `json:"id"`
Mid int64 `json:"mid"`
Sid int64 `json:"sid"`
Background string `json:"background"`
Liveid int64 `json:"live_id"`
Intr string `json:"intr"`
Focus string `json:"focus"`
URL string `json:"url"`
BackColor string `json:"back_color"`
ColorStep string `json:"color_step"`
H5Background string `json:"h5_background"`
H5BackColor string `json:"h5_back_color"`
IntrLogo string `json:"intr_logo"`
IntrTitle string `json:"intr_title"`
IntrText string `json:"intr_text"`
H5Focus string `json:"h5_focus"`
H5Url string `json:"h5_url"`
}
// Module match module
type Module struct {
ID int64 `json:"id"`
MAid int64 `json:"ma_id"`
Name string `json:"name"`
Oids string `json:"oids"`
}
//ActiveDetail 活动页数据模块
type ActiveDetail struct {
ID int64 `json:"id"`
Maid int64 `json:"ma_id"`
GameType int `json:"game_type"`
STime int64 `json:"stime"`
ETime int64 `json:"etime"`
ScoreID int64 `json:"score_id"`
GameStage string `json:"game_stage"`
KnockoutType int `json:"knockout_type"`
WinnerType int `json:"winner_type"`
Online int `json:"online"`
}
//ActivePage 活动页
type ActivePage struct {
Active *Active `json:"active,omitempty"`
Videos []*arcmdl.Arc `json:"video_first,omitempty"`
Modules []*Module `json:"video_module,omitempty"`
ActiveDetail []*ActiveDetail `json:"active_detail,omitempty"`
Season *Season `json:"season,omitempty"`
}

View File

@@ -0,0 +1,116 @@
package model
// ParamCale calendar params.
type ParamCale struct {
Stime int64 `form:"stime" validate:"required"`
Etime int64 `form:"etime" validate:"required"`
}
// ParamContest matchs params.
type ParamContest struct {
Mid int64 `form:"mid" validate:"gte=0"`
Gid int64 `form:"gid" validate:"gte=0"`
Tid int64 `form:"tid" validate:"gte=0"`
Stime string `form:"stime"`
Etime string `form:"etime"`
GState string `form:"g_state"`
Sids []int64 `form:"sids,split"`
Sort int `form:"sort"`
Pn int `form:"pn" validate:"gt=0"`
Ps int `form:"ps" validate:"gt=0,lte=50"`
}
// ParamVideo video params
type ParamVideo struct {
Mid int64 `form:"mid" validate:"gte=0"`
Gid int64 `form:"gid" validate:"gte=0"`
Tid int64 `form:"tid" validate:"gte=0"`
Year int64 `form:"year" validate:"gte=0"`
Tag int64 `form:"tag" validate:"gte=0"`
Sort int64 `form:"sort" validate:"gte=0"`
Pn int `form:"pn" validate:"gt=0"`
Ps int `form:"ps" validate:"gt=0,lte=50"`
}
// ParamSearch search video params
type ParamSearch struct {
Pn int `form:"pn" validate:"gt=0"`
Ps int `form:"ps" validate:"gt=0"`
Keyword string `form:"keyword" validate:"required"`
Sort int64 `form:"sort" validate:"gte=0"`
}
// ParamSeason season params.
type ParamSeason struct {
VMID int64 `form:"vmid"`
Sort int64 `form:"sort"`
Pn int `form:"pn" validate:"gt=0"`
Ps int `form:"ps" validate:"gt=0,lte=50"`
}
// ParamFilter filter video params
type ParamFilter struct {
Mid int64 `form:"mid" validate:"gte=0"`
Gid int64 `form:"gid" validate:"gte=0"`
Tid int64 `form:"tid" validate:"gte=0"`
Year int64 `form:"year" validate:"gte=0"`
Tag int64 `form:"tag" validate:"gte=0"`
Stime string `form:"stime" `
Etime string `form:"etime" `
}
// ParamActPoint matchs params.
type ParamActPoint struct {
Aid int64 `form:"aid" validate:"gt=0"`
MdID int64 `form:"md_id" validate:"gt=0"`
Sort int `form:"sort"`
Pn int `form:"pn" validate:"gt=0"`
Ps int `form:"ps" validate:"gt=0,lte=50"`
}
// ParamActTop matchs params.
type ParamActTop struct {
Aid int64 `form:"aid" validate:"gt=0"`
Sort int `form:"sort"`
Stime string `form:"stime" `
Etime string `form:"etime" `
Pn int `form:"pn" validate:"gt=0"`
Ps int `form:"ps" validate:"gt=0,lte=50"`
}
// ParamFav app fav list.
type ParamFav struct {
VMID int64 `form:"vmid"`
Sids []int64 `form:"sids,split"`
Stime string `form:"stime"`
Etime string `form:"etime"`
Sort int `form:"sort"`
Pn int `form:"pn" default:"1" validate:"min=1"`
Ps int `form:"ps" default:"50" validate:"min=1"`
}
// ParamLd leidata param
type ParamLd struct {
Route string `form:"route"`
}
// ParamCDRecent contest recently match
type ParamCDRecent struct {
HomeID int64 `form:"home_id" validate:"gt=0"`
AwayID int64 `form:"away_id" validate:"gt=0"`
CID int64 `form:"cid" validate:"gt=0"`
Ps int64 `form:"ps" default:"8" validate:"lte=10"`
}
// ParamGame game
type ParamGame struct {
MatchID int64 `form:"match_id" validate:"required"`
GameIDs []int64 `form:"game_ids,split" validate:"required"`
Tp int64 `form:"tp" default:"1" validate:"min=1"`
}
// ParamLeidas .
type ParamLeidas struct {
IDs []int64 `form:"ids,split" validate:"required"`
Tp int64 `form:"tp" default:"1" validate:"min=1"`
}

View File

@@ -0,0 +1,117 @@
package model
import (
"encoding/json"
"sync"
)
//Item .
type Item struct {
PercentMovementSpeedMod interface{} `json:"percent_movement_speed_mod"`
PercentLifeStealMod interface{} `json:"percent_life_steal_mod"`
PercentAttackSpeedMod interface{} `json:"percent_attack_speed_mod"`
Name string `json:"name"`
ImageURL string `json:"image_url"`
ID int64 `json:"id"`
GoldTotal interface{} `json:"gold_total"`
GoldSell interface{} `json:"gold_sell"`
GoldPurchasable bool `json:"gold_purchasable"`
GoldBase interface{} `json:"gold_base"`
FlatSpellBlockMod interface{} `json:"flat_spell_block_mod"`
FlatPhysicalDamageMod interface{} `json:"flat_physical_damage_mod"`
FlatMpRegenMod interface{} `json:"flat_mp_regen_mod"`
FlatMpPoolMod interface{} `json:"flat_mp_pool_mod"`
FlatMovementSpeedMod interface{} `json:"flat_movement_speed_mod"`
FlatMagicDamageMod interface{} `json:"flat_magic_damage_mod"`
FlatHpRegenMod interface{} `json:"flat_hp_regen_mod"`
FlatHpPoolMod interface{} `json:"flat_hp_pool_mod"`
FlatCritChanceMod interface{} `json:"flat_crit_chance_mod"`
FlatArmorMod interface{} `json:"flat_armor_mod"`
}
//Game .
type Game struct {
WinnerType string `json:"winner_type"`
Winner json.RawMessage `json:"winner"`
Teams json.RawMessage `json:"teams"`
Position int64 `json:"position"`
Players json.RawMessage `json:"players"`
MatchID int64 `json:"match_id"`
Match json.RawMessage `json:"match"`
Length int64 `json:"length"`
ID int64 `json:"id"`
Finished interface{} `json:"finished"`
BeginAt interface{} `json:"begin_at"`
}
//Champion .
type Champion struct {
VideogameVersions []string `json:"videogame_versions"`
Spellblockperlevel float64 `json:"spellblockperlevel"`
Spellblock float64 `json:"spellblock"`
Name string `json:"name"`
Mpregenperlevel float64 `json:"mpregenperlevel"`
Mpregen float64 `json:"mpregen"`
Mpperlevel interface{} `json:"mpperlevel"`
Mp float64 `json:"mp"`
Movespeed interface{} `json:"movespeed"`
ImageURL string `json:"image_url"`
ID int64 `json:"id"`
Hpregenperlevel float64 `json:"hpregenperlevel"`
Hpregen interface{} `json:"hpregen"`
Hpperlevel interface{} `json:"hpperlevel"`
Hp interface{} `json:"hp"`
Critperlevel interface{} `json:"critperlevel"`
Crit interface{} `json:"crit"`
BigImageURL string `json:"big_image_url"`
Attackspeedperlevel float64 `json:"attackspeedperlevel"`
Attackspeedoffset interface{} `json:"attackspeedoffset"`
Attackrange interface{} `json:"attackrange"`
Attackdamageperlevel float64 `json:"attackdamageperlevel"`
Attackdamage float64 `json:"attackdamage"`
Armorperlevel float64 `json:"armorperlevel"`
Armor interface{} `json:"armor"`
}
//Hero .
type Hero struct {
*LdInfo
LocalizedName string `json:"localized_name"`
}
// LdInfo .
type LdInfo struct {
Name string `json:"name"`
ImageURL string `json:"image_url"`
ID int64 `json:"id"`
}
// SyncGame store leida game list
type SyncGame struct {
Data map[int64][]*Game
sync.Mutex
}
// SyncItem store item list
type SyncItem struct {
Data map[int64]*Item
sync.Mutex
}
// SyncChampion store champion list
type SyncChampion struct {
Data map[int64]*Champion
sync.Mutex
}
// SyncHero store hero list
type SyncHero struct {
Data map[int64]*Hero
sync.Mutex
}
// SyncInfo store leida base info list
type SyncInfo struct {
Data map[int64]*LdInfo
sync.Mutex
}

View File

@@ -0,0 +1,50 @@
package model
import "encoding/json"
// Page es page
type Page struct {
Num int `json:"num"`
Size int `json:"size"`
Total int `json:"total"`
}
// SearchVideo search video.
type SearchVideo struct {
AID int64 `json:"aid"`
}
// SearchEsp big search esports.
type SearchEsp struct {
Code int `json:"code,omitempty"`
Seid string `json:"seid"`
Page int `json:"page"`
PageSize int `json:"pagesize"`
NumResults int `json:"numResults"`
NumPages int `json:"numPages"`
Result json.RawMessage `json:"result"`
}
// FilterES filter ES video and match
type FilterES struct {
GroupByGid []struct {
DocCount int `json:"doc_count"`
Key string `json:"key"`
} `json:"group_by_gid"`
GroupByMatch []struct {
DocCount int `json:"doc_count"`
Key string `json:"key"`
} `json:"group_by_match"`
GroupByTag []struct {
DocCount int `json:"doc_count"`
Key string `json:"key"`
} `json:"group_by_tag"`
GroupByTeam []struct {
DocCount int `json:"doc_count"`
Key string `json:"key"`
} `json:"group_by_team"`
GroupByYear []struct {
DocCount int `json:"doc_count"`
Key string `json:"key"`
} `json:"group_by_year"`
}

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 = [
"favorite.go",
"match.go",
"match_active.go",
"pointdata.go",
"search.go",
"service.go",
],
importpath = "go-common/app/interface/main/esports/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/esports/conf:go_default_library",
"//app/interface/main/esports/dao:go_default_library",
"//app/interface/main/esports/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/favorite/api/gorpc:go_default_library",
"//app/service/main/favorite/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/sync/pipeline/fanout:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/robfig/cron: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 = [
"favorite_test.go",
"match_test.go",
"search_test.go",
"service_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/esports/conf:go_default_library",
"//app/interface/main/esports/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,375 @@
package service
import (
"context"
"time"
"go-common/app/interface/main/esports/model"
favmdl "go-common/app/service/main/favorite/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/library/sync/errgroup"
)
const (
_firstPs = 5
_firstAppPs = 50
_favDay = 15
)
var _empStime = make([]string, 0)
// AddFav add favorite contest.
func (s *Service) AddFav(c context.Context, mid, cid int64) (err error) {
var (
contest *model.Contest
mapC map[int64]*model.Contest
ip = metadata.String(c, metadata.RemoteIP)
)
if mapC, err = s.dao.EpContests(c, []int64{cid}); err != nil {
return
}
contest = mapC[cid]
if contest == nil || contest.ID == 0 {
err = ecode.EsportsContestNotExist
return
}
if contest.LiveRoom <= 0 {
err = ecode.EsportsContestFavNot
return
}
nowTime := time.Now().Unix()
if contest.Etime > 0 && nowTime >= contest.Etime {
err = ecode.EsportsContestEnd
return
}
if contest.Stime == 0 || nowTime >= contest.Stime {
err = ecode.EsportsContestStart
return
}
subDay := timeSub(contest.Stime)
if subDay > _favDay {
err = ecode.EsportsContestNotDay
return
}
arg := &favmdl.ArgAdd{Type: favmdl.TypeEsports, Mid: mid, Oid: cid, Fid: 0, RealIP: ip}
if err = s.fav.Add(c, arg); err != nil {
log.Error("AddFav s.fav.Add(%+v) error(%v)", arg, err)
return
}
if err = s.dao.DelFavCoCache(c, mid); err != nil {
log.Error("AddFav s.dao.DelFavCoCache mid(%d) error(%v)", mid, err)
return
}
return
}
func timeSub(stime int64) int {
var (
nowTime, endTime time.Time
)
nowTime = time.Now()
endTime = time.Unix(stime, 0)
nowTime = time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local)
endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, time.Local)
return int(endTime.Sub(nowTime).Hours() / 24)
}
// DelFav delete favorite contest.
func (s *Service) DelFav(c context.Context, mid, cid int64) (err error) {
var (
contest *model.Contest
mapC map[int64]*model.Contest
ip = metadata.String(c, metadata.RemoteIP)
)
if mapC, err = s.dao.EpContests(c, []int64{cid}); err != nil {
return
}
contest = mapC[cid]
if contest == nil || contest.ID == 0 {
err = ecode.EsportsContestNotExist
return
}
arg := &favmdl.ArgDel{Type: favmdl.TypeEsports, Mid: mid, Oid: cid, Fid: 0, RealIP: ip}
if err = s.fav.Del(c, arg); err != nil {
log.Error("DelFav s.fav.Del(%+v) error(%v)", arg, err)
return
}
if err = s.dao.DelFavCoCache(c, mid); err != nil {
log.Error("DelFav s.dao.DelFavCoCache mid(%d) error(%v)", mid, err)
return
}
return
}
// ListFav list favorite contests.
func (s *Service) ListFav(c context.Context, mid, vmid int64, pn, ps int) (rs []*model.Contest, count int, err error) {
var (
isFirst bool
uid int64
favRes *favmdl.Favorites
cids []int64
ip = metadata.String(c, metadata.RemoteIP)
teams, seasons []*model.Filter
cData map[int64]*model.Contest
favContest []*model.Contest
group *errgroup.Group
contErr, teamErr, seasonErr error
)
if vmid > 0 {
uid = vmid
} else {
uid = mid
}
isFirst = pn == 1 && ps == _firstPs
if isFirst {
if rs, count, err = s.dao.FavCoCache(c, uid); err != nil {
err = nil
}
if len(rs) > 0 {
s.fmtContest(c, rs, mid)
return
}
}
arg := &favmdl.ArgFavs{Type: favmdl.TypeEsports, Mid: mid, Vmid: vmid, Fid: 0, Pn: pn, Ps: ps, RealIP: ip}
if favRes, err = s.fav.Favorites(c, arg); err != nil {
log.Error("ListFav s.fav.Favorites(%+v) error(%v)", arg, err)
return
}
count = favRes.Page.Count
if favRes == nil || len(favRes.List) == 0 || count == 0 {
rs = _emptContest
return
}
for _, fav := range favRes.List {
cids = append(cids, fav.Oid)
}
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if cData, contErr = s.dao.EpContests(c, cids); contErr != nil {
log.Error("s.dao.Contest error(%v)", contErr)
}
return contErr
})
group.Go(func() error {
if teams, teamErr = s.dao.Teams(errCtx); teamErr != nil {
log.Error("s.dao.Teams error %v", teamErr)
}
return nil
})
group.Go(func() error {
if seasons, seasonErr = s.dao.SeasonAll(errCtx); seasonErr != nil {
log.Error("s.dao.SeasonAll error %v", seasonErr)
}
return nil
})
err = group.Wait()
if err != nil {
return
}
for _, fav := range favRes.List {
if contest, ok := cData[fav.Oid]; ok {
favContest = append(favContest, contest)
}
}
rs = s.ContestInfo(c, cids, favContest, teams, seasons, mid)
if isFirst {
s.cache.Do(c, func(c context.Context) {
s.dao.SetFavCoCache(c, uid, rs, count)
})
}
return
}
// SeasonFav list favorite season.
func (s *Service) SeasonFav(c context.Context, mid int64, p *model.ParamSeason) (rs []*model.Season, count int, err error) {
var (
uid int64
elaContest []*model.ElaSub
mapSeasons map[int64]*model.Season
cids []int64
sids []int64
dbContests map[int64]*model.Contest
)
if p.VMID > 0 {
uid = p.VMID
} else {
uid = mid
}
if elaContest, count, err = s.dao.SeasonFav(c, uid, p); err != nil {
log.Error("s.dao.StimeFav error(%v)", err)
return
}
for _, contest := range elaContest {
cids = append(cids, contest.Oid)
sids = append(sids, contest.Sid)
}
if len(cids) > 0 {
if dbContests, err = s.dao.EpContests(c, cids); err != nil {
log.Error("s.dao.EpContests error(%v)", err)
return
}
} else {
rs = _emptSeason
return
}
if mapSeasons, err = s.dao.EpSeasons(c, sids); err != nil {
log.Error("s.dao.EpSeasons error(%v)", err)
return
}
ms := make(map[int64]struct{}, len(cids))
for _, contest := range elaContest {
if _, ok := ms[contest.Sid]; ok {
continue
}
// del over contest stime.
if contest, ok := dbContests[contest.Oid]; ok {
if contest.Etime > 0 && time.Now().Unix() > contest.Etime {
continue
}
}
ms[contest.Sid] = struct{}{}
if season, ok := mapSeasons[contest.Sid]; ok {
rs = append(rs, season)
}
}
if len(rs) == 0 {
rs = _emptSeason
}
return
}
// StimeFav list favorite contests stime.
func (s *Service) StimeFav(c context.Context, mid int64, p *model.ParamSeason) (rs []string, count int, err error) {
var (
uid int64
elaContest []*model.ElaSub
cids []int64
dbContests map[int64]*model.Contest
)
if p.VMID > 0 {
uid = p.VMID
} else {
uid = mid
}
if elaContest, count, err = s.dao.StimeFav(c, uid, p); err != nil {
log.Error("s.dao.StimeFav error(%v)", err)
}
for _, contest := range elaContest {
cids = append(cids, contest.Oid)
}
if len(cids) > 0 {
if dbContests, err = s.dao.EpContests(c, cids); err != nil {
log.Error("s.dao.EpContests error(%v)", err)
return
}
} else {
rs = _empStime
return
}
ms := make(map[string]struct{}, len(cids))
for _, contest := range elaContest {
tm := time.Unix(contest.Stime, 0)
stime := tm.Format("2006-01-02")
if _, ok := ms[stime]; ok {
continue
}
ms[stime] = struct{}{}
// del over contest stime.
if contest, ok := dbContests[contest.Oid]; ok {
if contest.Etime > 0 && time.Now().Unix() > contest.Etime {
continue
}
}
rs = append(rs, stime)
}
if len(rs) == 0 {
rs = _empStime
}
return
}
// ListAppFav list favorite contests.
func (s *Service) ListAppFav(c context.Context, mid int64, p *model.ParamFav) (rs []*model.Contest, count int, err error) {
var (
uid int64
cids []int64
isFirst bool
teams, seasons []*model.Filter
cData map[int64]*model.Contest
favContest []*model.Contest
group *errgroup.Group
contErr, teamErr, seasonErr error
)
if p.VMID > 0 {
uid = p.VMID
} else {
uid = mid
}
isFirst = p.Pn == 1 && p.Ps == _firstAppPs && p.Stime == "" && p.Etime == "" && len(p.Sids) == 0 && p.Sort == 0
if isFirst {
if rs, count, err = s.dao.FavCoAppCache(c, uid); err != nil {
err = nil
}
if len(rs) > 0 {
s.fmtContest(c, rs, uid)
return
}
}
if cids, count, err = s.dao.SearchFav(c, uid, p); err != nil {
log.Error("s.dao.SearchFav error(%v)", err)
return
}
if len(cids) == 0 || count == 0 {
rs = _emptContest
return
}
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if cData, contErr = s.dao.EpContests(c, cids); contErr != nil {
log.Error("s.dao.Contest error(%v)", contErr)
}
return contErr
})
group.Go(func() error {
if teams, teamErr = s.dao.Teams(errCtx); teamErr != nil {
log.Error("s.dao.Teams error %v", teamErr)
}
return nil
})
group.Go(func() error {
if seasons, seasonErr = s.dao.SeasonAll(errCtx); seasonErr != nil {
log.Error("s.dao.SeasonAll error %v", seasonErr)
}
return nil
})
err = group.Wait()
if err != nil {
return
}
for _, cid := range cids {
if contest, ok := cData[cid]; ok {
favContest = append(favContest, contest)
}
}
rs = s.ContestInfo(c, cids, favContest, teams, seasons, uid)
if isFirst {
s.cache.Do(c, func(c context.Context) {
s.dao.SetAppFavCoCache(c, uid, rs, count)
})
}
return
}
func (s *Service) isFavs(c context.Context, mid int64, cids []int64) (res map[int64]bool, err error) {
if mid > 0 {
ip := metadata.String(c, metadata.RemoteIP)
if res, err = s.fav.IsFavs(c, &favmdl.ArgIsFavs{Type: favmdl.TypeEsports, Mid: mid, Oids: cids, RealIP: ip}); err != nil {
log.Error("s.fav.IsFavs(%d,%+v) error(%d)", mid, cids, err)
err = nil
}
}
return
}

View File

@@ -0,0 +1,31 @@
package service
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_AddFav(t *testing.T) {
Convey("test service addfav", t, WithService(func(s *Service) {
err := s.AddFav(context.Background(), 180, 3)
So(err, ShouldBeNil)
}))
}
func TestService_DelFav(t *testing.T) {
Convey("test service delfav", t, WithService(func(s *Service) {
err := s.DelFav(context.Background(), 180, 0)
So(err, ShouldBeNil)
}))
}
func TestService_ListFav(t *testing.T) {
Convey("test service listfav", t, WithService(func(s *Service) {
res, count, err := s.ListFav(context.Background(), 10, 10, 1, 10)
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan)
println(count)
}))
}

View File

@@ -0,0 +1,816 @@
package service
import (
"context"
"sort"
"strconv"
"time"
"go-common/app/interface/main/esports/model"
arcmdl "go-common/app/service/main/archive/api"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
const (
_gameNoSub = 6
_gameSub = 3
_gameIn = 5
_gameLive = 4
_gameOver = 1
_caleDay = 3
_typeMatch = "matchs"
_typeGame = "games"
_typeTeam = "teams"
_typeYear = "years"
_typeTag = "tags"
_downline = 0
)
var (
_emptContest = make([]*model.Contest, 0)
_emptCalendar = make([]*model.Calendar, 0)
_emptFilter = make([]*model.Filter, 0)
_emptVideoList = make([]*arcmdl.Arc, 0)
_emptSeason = make([]*model.Season, 0)
_emptContestDetail = make([]*model.ContestsData, 0)
)
// FilterMatch filter match.
func (s *Service) FilterMatch(c context.Context, p *model.ParamFilter) (rs map[string][]*model.Filter, err error) {
var (
tmpRs map[string][]*model.Filter
fm *model.FilterES
fMap map[string]map[int64]*model.Filter
matchs, games, teams []*model.Filter
)
isAll := p.Tid == 0 && p.Gid == 0 && p.Mid == 0 && p.Stime == ""
if rs, err = s.dao.FMatCache(c); err != nil {
err = nil
}
if isAll && len(rs) > 0 {
return
}
matchs, games, teams = s.filterLeft(c)
tmpRs = make(map[string][]*model.Filter, 3)
tmpRs[_typeMatch] = matchs
tmpRs[_typeGame] = games
tmpRs[_typeTeam] = teams
if fm, err = s.dao.FilterMatch(c, p); err != nil {
log.Error("s.dao.FilterMatch error(%v)", err)
return
}
fMap = s.filterMap(tmpRs)
if tmpRs, err = s.fmtES(fm, fMap); err != nil {
log.Error("FilterMatch s.filterES error(%v)", err)
}
rs = make(map[string][]*model.Filter, 3)
rs[_typeMatch] = tmpRs[_typeMatch]
rs[_typeGame] = tmpRs[_typeGame]
rs[_typeTeam] = tmpRs[_typeTeam]
if isAll {
s.cache.Do(c, func(c context.Context) {
s.dao.SetFMatCache(c, rs)
})
} else {
if len(rs[_typeMatch]) == 0 && len(rs[_typeGame]) == 0 && len(rs[_typeTeam]) == 0 {
if tmpRs, err = s.dao.FMatCache(c); err != nil {
err = nil
}
if len(tmpRs) > 0 {
rs = tmpRs
}
}
}
return
}
func (s *Service) filterLeft(c context.Context) (matchs, games, teams []*model.Filter) {
var (
matchErr, gameErr, teamErr error
)
group := &errgroup.Group{}
group.Go(func() error {
if matchs, matchErr = s.dao.Matchs(context.Background()); matchErr != nil {
log.Error("s.dao.Matchs error %v", matchErr)
}
return nil
})
group.Go(func() error {
if games, gameErr = s.dao.Games(context.Background()); gameErr != nil {
log.Error("s.dao.Games error %v", gameErr)
}
return nil
})
group.Go(func() error {
if teams, teamErr = s.dao.Teams(context.Background()); teamErr != nil {
log.Error("s.dao.Teams error %v", teamErr)
}
return nil
})
group.Wait()
if len(matchs) == 0 {
matchs = _emptFilter
}
if len(games) == 0 {
games = _emptFilter
}
if len(teams) == 0 {
teams = _emptFilter
}
return
}
// Calendar contest calendar count
func (s *Service) Calendar(c context.Context, p *model.ParamFilter) (rs []*model.Calendar, err error) {
var fc map[string]int64
before3 := time.Now().AddDate(0, 0, -_caleDay).Format("2006-01-02")
after3 := time.Now().AddDate(0, 0, _caleDay).Format("2006-01-02")
todayAll := p.Mid == 0 && p.Gid == 0 && p.Tid == 0 && p.Stime == before3 && p.Etime == after3
if todayAll {
if rs, err = s.dao.CalendarCache(c, p); err != nil {
err = nil
}
if len(rs) > 0 {
return
}
}
if fc, err = s.dao.FilterCale(c, p); err != nil {
log.Error("s.dao.FilterCale error(%v)", err)
return
}
if len(fc) == 0 {
rs = _emptCalendar
return
}
for d, c := range fc {
rs = append(rs, &model.Calendar{Stime: d, Count: c})
}
if todayAll {
s.cache.Do(c, func(c context.Context) {
s.dao.SetCalendarCache(c, p, rs)
})
}
return
}
func (s *Service) fmtContest(c context.Context, contests []*model.Contest, mid int64) {
cids := s.contestIDs(contests)
favContest, _ := s.isFavs(c, mid, cids)
for _, contest := range contests {
if contest.Etime > 0 && time.Now().Unix() > contest.Etime {
contest.GameState = _gameOver
} else if contest.Stime <= time.Now().Unix() && (contest.Etime >= time.Now().Unix() || contest.Etime == 0) {
if contest.LiveRoom == 0 {
contest.GameState = _gameIn
} else {
contest.GameState = _gameLive
}
} else if contest.LiveRoom > 0 {
if v, ok := favContest[contest.ID]; ok && v && mid > 0 {
contest.GameState = _gameSub
} else {
contest.GameState = _gameNoSub
}
}
}
}
// ListContest contest list.
func (s *Service) ListContest(c context.Context, mid int64, p *model.ParamContest) (rs []*model.Contest, total int, err error) {
var (
teams, seasons []*model.Filter
cData, tmpRs []*model.Contest
dbContests map[int64]*model.Contest
group *errgroup.Group
cids []int64
contErr, teamErr, seasonErr error
)
// get from cache.
isFirst := p.Mid == 0 && p.Gid == 0 && p.Tid == 0 && p.Stime == "" && p.GState == "" && p.Pn == 1 && len(p.Sids) == 0 && p.Sort == 0
if isFirst {
if rs, total, err = s.dao.ContestCache(c, p.Ps); err != nil {
err = nil
} else if len(rs) > 0 {
s.fmtContest(c, rs, mid)
return
}
}
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if cData, total, contErr = s.dao.SearchContest(errCtx, p); contErr != nil {
log.Error("s.dao.SearchContest error(%v)", contErr)
}
return contErr
})
group.Go(func() error {
if teams, teamErr = s.dao.Teams(errCtx); teamErr != nil {
log.Error("s.dao.Teams error(%v)", teamErr)
}
return nil
})
group.Go(func() error {
if seasons, seasonErr = s.dao.SeasonAll(errCtx); seasonErr != nil {
log.Error("s.dao.SeasonAll error %v", seasonErr)
}
return nil
})
err = group.Wait()
if err != nil {
return
}
if total == 0 || len(cData) == 0 {
rs = _emptContest
return
}
cids = s.contestIDs(cData)
if len(cids) > 0 {
if dbContests, err = s.dao.EpContests(c, cids); err != nil {
log.Error("s.dao.EpContests error(%v)", err)
return
}
}
for _, c := range cData {
if contest, ok := dbContests[c.ID]; ok {
tmpRs = append(tmpRs, contest)
}
}
rs = s.ContestInfo(c, cids, tmpRs, teams, seasons, mid)
if isFirst {
s.cache.Do(c, func(c context.Context) {
s.dao.SetContestCache(c, p.Ps, rs, total)
})
}
return
}
func (s *Service) contestIDs(cData []*model.Contest) (rs []int64) {
for _, contest := range cData {
rs = append(rs, contest.ID)
}
return
}
// ContestInfo contest add team season.
func (s *Service) ContestInfo(c context.Context, cids []int64, cData []*model.Contest, teams, seasons []*model.Filter, mid int64) (rs []*model.Contest) {
var (
mapTeam, mapSeason map[int64]*model.Filter
)
mapTeam = make(map[int64]*model.Filter, len(teams))
for _, team := range teams {
mapTeam[team.ID] = team
}
mapSeason = make(map[int64]*model.Filter, len(seasons))
for _, season := range seasons {
mapSeason[season.ID] = season
}
favContest, _ := s.isFavs(c, mid, cids)
for _, contest := range cData {
if contest == nil {
continue
}
if v, ok := mapTeam[contest.HomeID]; ok && v != nil {
contest.HomeTeam = v
} else {
contest.HomeTeam = struct{}{}
}
if v, ok := mapTeam[contest.AwayID]; ok && v != nil {
contest.AwayTeam = v
} else {
contest.AwayTeam = struct{}{}
}
if v, ok := mapTeam[contest.SuccessTeam]; ok && v != nil {
contest.SuccessTeaminfo = v
} else {
contest.SuccessTeaminfo = struct{}{}
}
if v, ok := mapSeason[contest.Sid]; ok && v != nil {
contest.Season = v
} else {
contest.Season = struct{}{}
}
if contest.Etime > 0 && time.Now().Unix() > contest.Etime {
contest.GameState = _gameOver
} else if contest.Stime <= time.Now().Unix() && (contest.Etime >= time.Now().Unix() || contest.Etime == 0) {
if contest.LiveRoom == 0 {
contest.GameState = _gameIn
} else {
contest.GameState = _gameLive
}
} else if contest.LiveRoom > 0 {
if v, ok := favContest[contest.ID]; ok && v && mid > 0 {
contest.GameState = _gameSub
} else {
contest.GameState = _gameNoSub
}
}
rs = append(rs, contest)
}
return
}
// ListVideo video list.
func (s *Service) ListVideo(c context.Context, p *model.ParamVideo) (rs []*arcmdl.Arc, total int, err error) {
var (
vData []*model.SearchVideo
aids []int64
arcsReply *arcmdl.ArcsReply
)
isFirst := p.Mid == 0 && p.Gid == 0 && p.Tid == 0 && p.Year == 0 && p.Tag == 0 && p.Sort == 0 && p.Pn == 1
if isFirst {
// get from cache.
if rs, total, err = s.dao.VideoCache(c, p.Ps); err != nil {
err = nil
} else if len(rs) > 0 {
return
}
}
if vData, total, err = s.dao.SearchVideo(c, p); err != nil {
log.Error("s.dao.SearchVideo(%v) error(%v)", p, err)
return
}
if total == 0 {
rs = _emptVideoList
return
}
for _, arc := range vData {
aids = append(aids, arc.AID)
}
if arcsReply, err = s.arcClient.Arcs(c, &arcmdl.ArcsRequest{Aids: aids}); err != nil {
log.Error("ListVideo s.arc.Archives3 error(%v)", err)
return
}
for _, aid := range aids {
if arc, ok := arcsReply.Arcs[aid]; ok && arc.IsNormal() {
rs = append(rs, arc)
}
}
if isFirst {
s.cache.Do(c, func(c context.Context) {
s.dao.SetVideoCache(c, p.Ps, rs, total)
})
}
return
}
// FilterVideo filter video.
func (s *Service) FilterVideo(c context.Context, p *model.ParamFilter) (rs map[string][]*model.Filter, err error) {
var (
tmpRs map[string][]*model.Filter
fv *model.FilterES
fMap map[string]map[int64]*model.Filter
matchs, games, teams, tags, years []*model.Filter
)
isAll := p.Year == 0 && p.Tag == 0 && p.Tid == 0 && p.Gid == 0 && p.Mid == 0
if rs, err = s.dao.FVideoCache(c); err != nil {
err = nil
}
if isAll && len(rs) > 0 {
return
}
matchs, games, teams, tags, years = s.filterTop(c)
tmpRs = make(map[string][]*model.Filter, 3)
tmpRs[_typeMatch] = matchs
tmpRs[_typeGame] = games
tmpRs[_typeTeam] = teams
tmpRs[_typeYear] = years
tmpRs[_typeTag] = tags
if fv, err = s.dao.FilterVideo(c, p); err != nil {
log.Error("s.dao.FilterVideo error(%v)", err)
return
}
fMap = s.filterMap(tmpRs)
if rs, err = s.fmtES(fv, fMap); err != nil {
log.Error("FilterVideo s.filterES error(%v)", err)
}
if isAll {
s.cache.Do(c, func(c context.Context) {
s.dao.SetFVideoCache(c, rs)
})
} else {
if len(rs[_typeMatch]) == 0 && len(rs[_typeGame]) == 0 && len(rs[_typeTeam]) == 0 && len(rs[_typeYear]) == 0 && len(rs[_typeTag]) == 0 {
if tmpRs, err = s.dao.FVideoCache(c); err != nil {
err = nil
}
if len(tmpRs) > 0 {
rs = tmpRs
}
}
}
return
}
func (s *Service) filterTop(c context.Context) (matchs, games, teams, tags, years []*model.Filter) {
var (
matchErr, gameErr, teamErr, tagErr, yearErr error
)
group := &errgroup.Group{}
group.Go(func() error {
if matchs, matchErr = s.dao.Matchs(context.Background()); matchErr != nil {
log.Error("s.dao.Matchs error %v", matchErr)
}
return nil
})
group.Go(func() error {
if games, gameErr = s.dao.Games(context.Background()); gameErr != nil {
log.Error("s.dao.Games error %v", gameErr)
}
return nil
})
group.Go(func() error {
if teams, teamErr = s.dao.Teams(context.Background()); teamErr != nil {
log.Error("s.dao.Teams error %v", teamErr)
}
return nil
})
group.Go(func() error {
if tags, tagErr = s.dao.Tags(context.Background()); tagErr != nil {
log.Error("s.dao.tags error %v", tagErr)
}
return nil
})
group.Go(func() error {
if years, yearErr = s.dao.Years(context.Background()); yearErr != nil {
log.Error("s.dao.Years error %v", yearErr)
}
return nil
})
group.Wait()
if len(matchs) == 0 {
matchs = _emptFilter
}
if len(games) == 0 {
games = _emptFilter
}
if len(teams) == 0 {
teams = _emptFilter
}
if len(years) == 0 {
years = _emptFilter
}
if len(tags) == 0 {
tags = _emptFilter
}
return
}
func (s *Service) fmtES(fv *model.FilterES, fMap map[string]map[int64]*model.Filter) (rs map[string][]*model.Filter, err error) {
var (
intMid, intGid, intTeam, intTag, intYear int64
matchs, games, teams, tags, years []*model.Filter
)
group := &errgroup.Group{}
group.Go(func() error {
for _, midGroup := range fv.GroupByMatch {
if intMid, err = strconv.ParseInt(midGroup.Key, 10, 64); err != nil {
err = nil
continue
}
if match, ok := fMap[_typeMatch][intMid]; ok {
matchs = append(matchs, match)
}
}
return nil
})
group.Go(func() error {
for _, gidGroup := range fv.GroupByGid {
if intGid, err = strconv.ParseInt(gidGroup.Key, 10, 64); err != nil {
err = nil
continue
}
if game, ok := fMap[_typeGame][intGid]; ok {
games = append(games, game)
}
}
return nil
})
group.Go(func() error {
for _, teamGroup := range fv.GroupByTeam {
if intTeam, err = strconv.ParseInt(teamGroup.Key, 10, 64); err != nil {
err = nil
continue
}
if team, ok := fMap[_typeTeam][intTeam]; ok {
teams = append(teams, team)
}
}
return nil
})
group.Go(func() error {
for _, tagGroup := range fv.GroupByTag {
if intTag, err = strconv.ParseInt(tagGroup.Key, 10, 64); err != nil {
err = nil
continue
}
if tag, ok := fMap[_typeTag][intTag]; ok {
tags = append(tags, tag)
}
}
return nil
})
group.Go(func() error {
for _, yearGroup := range fv.GroupByYear {
if intYear, err = strconv.ParseInt(yearGroup.Key, 10, 64); err != nil {
err = nil
continue
}
if year, ok := fMap[_typeYear][intYear]; ok {
years = append(years, year)
}
}
return nil
})
group.Wait()
rs = make(map[string][]*model.Filter, 5)
if len(matchs) == 0 {
matchs = _emptFilter
} else {
sort.Slice(matchs, func(i, j int) bool {
return matchs[i].Rank > matchs[j].Rank || (matchs[i].Rank == matchs[j].Rank && matchs[i].ID < matchs[j].ID)
})
}
if len(games) == 0 {
games = _emptFilter
} else {
sort.Slice(games, func(i, j int) bool { return games[i].ID < games[j].ID })
}
if len(teams) == 0 {
teams = _emptFilter
} else {
sort.Slice(teams, func(i, j int) bool { return teams[i].ID < teams[j].ID })
}
if len(years) == 0 {
years = _emptFilter
} else {
sort.Slice(years, func(i, j int) bool { return years[i].ID < years[j].ID })
}
if len(tags) == 0 {
tags = _emptFilter
} else {
sort.Slice(tags, func(i, j int) bool { return tags[i].ID < tags[j].ID })
}
rs[_typeMatch] = matchs
rs[_typeGame] = games
rs[_typeTeam] = teams
rs[_typeTag] = tags
rs[_typeYear] = years
return
}
func (s *Service) filterMap(f map[string][]*model.Filter) (rs map[string]map[int64]*model.Filter) {
var (
match, game, team, tag, year *model.Filter
mapMatch, mapGame, mapTeam, mapTag, mapYear map[int64]*model.Filter
)
group := &errgroup.Group{}
group.Go(func() error {
mapMatch = make(map[int64]*model.Filter, len(f[_typeMatch]))
for _, match = range f[_typeMatch] {
if match != nil {
mapMatch[match.ID] = match
}
}
return nil
})
group.Go(func() error {
mapGame = make(map[int64]*model.Filter, len(f[_typeGame]))
for _, game = range f[_typeGame] {
if game != nil {
mapGame[game.ID] = game
}
}
return nil
})
group.Go(func() error {
mapTeam = make(map[int64]*model.Filter, len(f[_typeTeam]))
for _, team = range f[_typeTeam] {
if team != nil {
mapTeam[team.ID] = team
}
}
return nil
})
group.Go(func() error {
mapTag = make(map[int64]*model.Filter, len(f[_typeTag]))
for _, tag = range f[_typeTag] {
if tag != nil {
mapTag[tag.ID] = tag
}
}
return nil
})
group.Go(func() error {
mapYear = make(map[int64]*model.Filter, len(f[_typeYear]))
for _, year = range f[_typeYear] {
if year != nil {
mapYear[year.ID] = year
}
}
return nil
})
group.Wait()
rs = make(map[string]map[int64]*model.Filter, 5)
rs[_typeMatch] = mapMatch
rs[_typeGame] = mapGame
rs[_typeTeam] = mapTeam
rs[_typeTag] = mapTag
rs[_typeYear] = mapYear
return
}
// Season season list.
func (s *Service) Season(c context.Context, p *model.ParamSeason) (rs []*model.Season, count int, err error) {
var (
seasons []*model.Season
start = (p.Pn - 1) * p.Ps
end = start + p.Ps - 1
)
if rs, count, err = s.dao.SeasonCache(c, start, end); err != nil || len(rs) == 0 {
err = nil
if seasons, err = s.dao.Season(c); err != nil {
log.Error("s.dao.Season error(%v)", err)
return
}
count = len(seasons)
if count == 0 || count < start {
rs = _emptSeason
return
}
s.cache.Do(c, func(c context.Context) {
s.dao.SetSeasonCache(c, seasons, count)
})
if count > end+1 {
rs = seasons[start : end+1]
} else {
rs = seasons[start:]
}
}
return
}
// AppSeason app season list.
func (s *Service) AppSeason(c context.Context, p *model.ParamSeason) (rs []*model.Season, count int, err error) {
var (
seasons []*model.Season
start = (p.Pn - 1) * p.Ps
end = start + p.Ps - 1
)
if rs, count, err = s.dao.SeasonMCache(c, start, end); err != nil || len(rs) == 0 {
err = nil
if seasons, err = s.dao.AppSeason(c); err != nil {
log.Error("s.dao.AppSeason error(%v)", err)
return
}
count = len(seasons)
if count == 0 || count < start {
rs = _emptSeason
return
}
s.cache.Do(c, func(c context.Context) {
s.dao.SetSeasonMCache(c, seasons, count)
})
if count > end+1 {
rs = seasons[start : end+1]
} else {
rs = seasons[start:]
}
}
sort.Slice(rs, func(i, j int) bool {
return rs[i].Rank > rs[j].Rank || (rs[i].Rank == rs[j].Rank && rs[i].Stime > rs[j].Stime)
})
return
}
// Contest contest data.
func (s *Service) Contest(c context.Context, mid, cid int64) (res *model.ContestDataPage, err error) {
var (
contest *model.Contest
contestData []*model.ContestsData
teams map[int64]*model.Team
season map[int64]*model.Season
teamErr, contestErr error
games []*model.Game
gameMap map[int64]*model.Game
)
if res, err = s.dao.GetCSingleData(c, cid); err != nil || res == nil {
err = nil
res = &model.ContestDataPage{}
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if contest, contestErr = s.dao.Contest(errCtx, cid); contestErr != nil {
log.Error("SingleData.dao.Contest error(%v)", teamErr)
}
return contestErr
})
group.Go(func() error {
if contestData, _ = s.dao.ContestData(errCtx, cid); err != nil {
log.Error("SingleData.dao.ContestData error(%v)", teamErr)
}
return nil
})
err = group.Wait()
if err != nil {
return
}
if contest.ID == 0 {
err = ecode.NothingFound
return
}
if len(contestData) == 0 {
contestData = _emptContestDetail
}
if teams, err = s.dao.EpTeams(c, []int64{contest.HomeID, contest.AwayID}); err != nil {
log.Error("SingleData.dao.Teams error(%v)", err)
err = nil
}
if season, err = s.dao.EpSeasons(c, []int64{contest.Sid}); err != nil {
log.Error("SingleData.dao.EpSeasons error(%v)", err)
err = nil
}
s.ContestInfos(contest, teams, season)
res.Contest = contest
res.Detail = contestData
s.cache.Do(c, func(c context.Context) {
s.dao.AddCSingleData(c, cid, res)
})
}
if res.Contest.DataType == _lolType {
games = s.lolGameMap.Data[res.Contest.MatchID]
} else if res.Contest.DataType == _dotaType {
games = s.dotaGameMap.Data[res.Contest.MatchID]
}
if len(games) > 0 {
gameMap = make(map[int64]*model.Game, len(games))
for _, game := range games {
gameMap[game.ID] = game
}
for _, data := range res.Detail {
if g, ok := gameMap[data.PointData]; ok {
if g.Finished == true || (res.Contest.Etime > 0 && time.Now().Unix() > res.Contest.Etime) {
data.GameStatus = 1
} else if g.Finished == false {
data.GameStatus = 2
}
}
}
}
tmp := []*model.Contest{res.Contest}
s.fmtContest(c, tmp, mid)
return
}
// ContestInfos contest infos.
func (s *Service) ContestInfos(contest *model.Contest, teams map[int64]*model.Team, season map[int64]*model.Season) {
if homeTeam, ok := teams[contest.HomeID]; ok {
contest.HomeTeam = homeTeam
} else {
contest.HomeTeam = struct{}{}
}
if awayTeam, ok := teams[contest.AwayID]; ok {
contest.AwayTeam = awayTeam
} else {
contest.AwayTeam = struct{}{}
}
if sea, ok := season[contest.Sid]; ok {
contest.Season = sea
} else {
contest.Season = struct{}{}
}
}
// Recent contest recents.
func (s *Service) Recent(c context.Context, mid int64, param *model.ParamCDRecent) (res []*model.Contest, err error) {
var (
teams map[int64]*model.Team
season map[int64]*model.Season
)
if res, err = s.dao.GetCRecent(c, param); err != nil || len(res) == 0 {
err = nil
if res, err = s.dao.ContestRecent(c, param.HomeID, param.AwayID, param.CID, param.Ps); err != nil {
log.Error("ContestRecent.dao.ContestRecent error(%v)", err)
return
}
if len(res) == 0 {
res = _emptContest
return
}
for _, contest := range res {
if teams, err = s.dao.EpTeams(c, []int64{contest.HomeID, contest.AwayID}); err != nil {
log.Error("SingleData.dao.Teams error(%v)", err)
err = nil
}
if season, err = s.dao.EpSeasons(c, []int64{contest.Sid}); err != nil {
log.Error("SingleData.dao.EpSeasons error(%v)", err)
err = nil
}
s.ContestInfos(contest, teams, season)
contest.SuccessTeaminfo = struct{}{}
}
s.cache.Do(c, func(c context.Context) {
s.dao.AddCRecent(c, param, res)
})
}
s.fmtContest(c, res, mid)
return
}

View File

@@ -0,0 +1,537 @@
package service
import (
"context"
"time"
"go-common/app/interface/main/esports/model"
arcmdl "go-common/app/service/main/archive/api"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
)
var (
_emptActDetail = make([]*model.ActiveDetail, 0)
_emptActModule = make([]*model.Module, 0)
_emptActVideos = make([]*arcmdl.Arc, 0)
_emptTreeList = make([][]*model.TreeList, 0)
)
//ArcsInfo archive info
func (s *Service) ArcsInfo(c context.Context, aids []int64) (arc []*arcmdl.Arc, err error) {
var (
arcsReply *arcmdl.ArcsReply
res map[int64]*arcmdl.Arc
)
if arcsReply, err = s.arcClient.Arcs(c, &arcmdl.ArcsRequest{Aids: aids}); err != nil {
log.Error("s.arcClient.Arcs(%v) error(%v)", aids, err)
return
}
if arcsReply == nil {
return
}
res = make(map[int64]*arcmdl.Arc)
for k, v := range arcsReply.Arcs {
if v != nil && v.IsNormal() {
res[k] = v
}
}
for _, aid := range aids {
if v, ok := res[aid]; ok {
arc = append(arc, v)
}
}
return
}
// ActModules matchs active videos
func (s *Service) ActModules(c context.Context, mmid int64) (res []*arcmdl.Arc, err error) {
var (
mModule *model.Module
aids []int64
)
if res, err = s.dao.GetActModuleCache(c, mmid); err != nil || res == nil {
if mModule, err = s.dao.Module(c, mmid); err != nil {
return
}
if mModule == nil {
err = ecode.EsportsActVideoNotExist
return
}
if aids, err = xstr.SplitInts(mModule.Oids); err != nil {
return
}
if res, err = s.ArcsInfo(c, aids); err != nil {
return
}
if res == nil {
res = _emptActVideos
return
}
s.cache.Do(c, func(c context.Context) {
s.dao.AddActModuleCache(c, mmid, res)
})
}
return
}
//MatchAct match act
func (s *Service) MatchAct(c context.Context, aid int64) (act *model.Active, err error) {
if act, err = s.dao.GetMActCache(c, aid); err != nil || act == nil {
if act, err = s.dao.Active(c, aid); err != nil {
log.Error("s.dao.Active error(%v)", err)
return
}
if act != nil {
s.cache.Do(c, func(c context.Context) {
s.dao.AddMActCache(c, aid, act)
})
}
}
return
}
// ActPage matchs active page info
func (s *Service) ActPage(c context.Context, aid int64) (res *model.ActivePage, err error) {
var (
act *model.Active
modules []*model.Module
aids []int64
actDetail []*model.ActiveDetail
videos []*arcmdl.Arc
moduleErr, actDetailError, actError error
mapSeasons map[int64]*model.Season
)
if res, err = s.dao.GetActPageCache(c, aid); err != nil || res == nil {
res = &model.ActivePage{}
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if act, actError = s.MatchAct(errCtx, aid); actError != nil {
log.Error("s.dao.Active error(%v)", moduleErr)
}
return actError
})
group.Go(func() error {
if modules, moduleErr = s.dao.Modules(errCtx, aid); moduleErr != nil {
log.Error("s.dao.Modules error(%v)", moduleErr)
return nil
}
if len(modules) > 0 && modules[0].Oids != "" {
if aids, moduleErr = xstr.SplitInts(modules[0].Oids); moduleErr != nil {
log.Error("s.ActPage.SplitInts oids error(%v) error(%v)", modules[0].Oids, moduleErr)
return nil
}
if videos, moduleErr = s.ArcsInfo(c, aids); moduleErr != nil {
log.Error("s.ActPage.ArcsInfo aids(%v) error(%v)", aids, moduleErr)
}
}
return nil
})
group.Go(func() error {
if actDetail, actDetailError = s.dao.ActDetail(errCtx, aid); actDetailError != nil {
log.Error("s.dao.ActDetail error(%v)", actDetailError)
}
return nil
})
err = group.Wait()
if err != nil {
return
}
if act == nil {
err = ecode.EsportsActNotExist
return
}
res.Active = act
if len(actDetail) == 0 {
res.ActiveDetail = _emptActDetail
} else {
res.ActiveDetail = actDetail
}
if len(modules) == 0 {
res.Modules = _emptActModule
} else {
res.Modules = modules
}
if len(videos) == 0 {
res.Videos = _emptActVideos
} else {
res.Videos = videos
}
if mapSeasons, err = s.dao.EpSeasons(c, []int64{act.Sid}); err != nil {
log.Error("s.dao.EpSeasons error(%v)", err)
err = nil
}
if season, ok := mapSeasons[act.Sid]; ok {
res.Season = season
} else {
res.Season = &model.Season{}
}
s.cache.Do(c, func(c context.Context) {
s.dao.AddActPageCache(c, aid, res)
})
}
return
}
//ContestCommon act match same deal logic
func (s *Service) ContestCommon(c context.Context, mid int64, p *model.ParamContest) (rs []*model.Contest, total int, err error) {
var (
cData, tmpRs []*model.Contest
contErr, teamErr, seasonErr error
teams, seasons []*model.Filter
cids []int64
dbContests map[int64]*model.Contest
)
group, errCtx := errgroup.WithContext(c)
group.Go(func() error {
if cData, total, contErr = s.dao.SearchContestQuery(errCtx, p); contErr != nil {
log.Error("s.dao.SearchContest error(%v)", contErr)
}
return contErr
})
group.Go(func() error {
if teams, teamErr = s.dao.Teams(errCtx); teamErr != nil {
log.Error("s.dao.Teams error(%v)", teamErr)
}
return nil
})
group.Go(func() error {
if seasons, seasonErr = s.dao.SeasonAll(errCtx); seasonErr != nil {
log.Error("s.dao.SeasonAll error %v", seasonErr)
}
return nil
})
err = group.Wait()
if err != nil {
return
}
if total == 0 || len(cData) == 0 {
rs = _emptContest
return
}
cids = s.contestIDs(cData)
if len(cids) > 0 {
if dbContests, err = s.dao.EpContests(c, cids); err != nil {
log.Error("s.dao.Contest error(%v)", err)
return
}
}
for _, c := range cData {
if contest, ok := dbContests[c.ID]; ok {
tmpRs = append(tmpRs, contest)
}
}
rs = s.ContestInfo(c, cids, tmpRs, teams, seasons, mid)
return
}
// ActTop act match top data
func (s *Service) ActTop(c context.Context, mid int64, param *model.ParamActTop) (res []*model.Contest, total int, err error) {
var (
act *model.Active
sids []int64
mapSeasons map[int64]*model.Season
sTime, eTime time.Time
season *model.Season
ok bool
)
isFirst := param.Pn == 1 && param.Sort == 0 && param.Stime == ""
if isFirst {
if res, total, err = s.dao.GetActTopCache(c, param.Aid, int64(param.Ps)); err != nil {
err = nil
} else if len(res) > 0 {
s.fmtContest(c, res, mid)
return
}
}
if act, err = s.MatchAct(c, param.Aid); err != nil {
log.Error("s.MatchAct error(%v)", err)
return
}
if act == nil || act.Sid <= 0 {
err = ecode.EsportsActNotExist
return
}
sids = []int64{act.Sid}
if mapSeasons, err = s.dao.EpSeasons(c, sids); err != nil {
log.Error("MatchAct s.dao.EpSeasons error(%v)", err)
return
}
season, ok = mapSeasons[act.Sid]
if !ok {
log.Error("s.ActTop sid(%d) not exists", act.Sid)
return
}
if param.Stime != "" {
sTime, _ = time.ParseInLocation("2006-01-02", param.Stime, time.Local)
if sTime.Unix() <= season.Stime {
param.Stime = time.Unix(season.Stime, 0).Format("2006-01-02 15:04:05")
} else {
sTime, _ = time.ParseInLocation("2006-01-02", param.Stime, time.Local)
param.Stime = time.Unix(sTime.Unix(), 0).Format("2006-01-02") + " 00:00:00"
}
} else {
param.Stime = time.Unix(season.Stime, 0).Format("2006-01-02 15:04:05")
}
if param.Etime != "" {
if season.Etime != 0 {
eTime, _ = time.ParseInLocation("2006-01-02", param.Etime, time.Local)
if eTime.Unix() >= season.Etime {
param.Etime = time.Unix(season.Etime, 0).Format("2006-01-02 15:04:05")
} else {
eTime, _ = time.ParseInLocation("2006-01-02", param.Etime, time.Local)
param.Etime = time.Unix(eTime.Unix(), 0).Format("2006-01-02") + " 23:59:59"
}
} else {
eTime, _ = time.ParseInLocation("2006-01-02", param.Etime, time.Local)
param.Etime = time.Unix(eTime.Unix(), 0).Format("2006-01-02") + " 23:59:59"
}
} else {
if season.Etime != 0 {
param.Etime = time.Unix(season.Etime, 0).Format("2006-01-02 15:04:05")
}
}
p := &model.ParamContest{
Mid: act.Mid,
Sids: []int64{act.Sid},
Sort: param.Sort,
Stime: param.Stime,
Etime: param.Etime,
Pn: param.Pn,
Ps: param.Ps,
}
if res, total, err = s.ContestCommon(c, mid, p); err != nil {
return
}
if len(res) == 0 {
res = _emptContest
return
}
if isFirst {
s.cache.Do(c, func(c context.Context) {
s.dao.AddActTopCache(c, param.Aid, int64(param.Ps), res, total)
})
}
return
}
// ActPoints act match point match
func (s *Service) ActPoints(c context.Context, mid int64, param *model.ParamActPoint) (res []*model.Contest, total int, err error) {
var (
act *model.Active
detail *model.ActiveDetail
)
isFirst := param.Pn == 1 && param.Sort == 0
if isFirst {
if res, total, err = s.dao.GetActPointsCache(c, param.Aid, param.MdID, int64(param.Ps)); err != nil {
err = nil
} else if len(res) > 0 {
s.fmtContest(c, res, mid)
return
}
}
if act, err = s.MatchAct(c, param.Aid); err != nil {
log.Error("s.dao.Active error(%v)", err)
return
}
if act == nil || act.Sid <= 0 {
err = ecode.EsportsActNotExist
return
}
p := &model.ParamContest{
Mid: act.Mid,
Sids: []int64{act.Sid},
Sort: param.Sort,
Pn: param.Pn,
Ps: param.Ps,
}
detail, err = s.dao.PActDetail(c, param.MdID)
if err != nil {
log.Error("s.dao.PActDetail error(%v)", err)
return
}
if detail != nil {
if detail.STime != 0 {
p.Stime = time.Unix(detail.STime, 0).Format("2006-01-02 15:04:05")
}
if detail.ETime != 0 {
p.Etime = time.Unix(detail.ETime, 0).Format("2006-01-02 15:04:05")
}
} else {
err = ecode.EsportsActPointNotExist
return
}
if res, total, err = s.ContestCommon(c, mid, p); err != nil {
return
}
if len(res) == 0 {
res = _emptContest
return
}
if isFirst {
s.cache.Do(c, func(c context.Context) {
s.dao.AddActPointsCache(c, param.Aid, param.MdID, int64(param.Ps), res, total)
})
}
return
}
//contestTeam get contest team
func (s *Service) contestTeam(c context.Context, contests map[int64]*model.Contest, teams map[int64]*model.Filter) (list []*model.ContestInfo, err error) {
for _, v := range contests {
contest := &model.ContestInfo{Contest: v}
if v.HomeID > 0 {
if team, ok := teams[v.HomeID]; ok {
contest.HomeName = team.Title
contest.HomeTeam = team
} else {
contest.HomeName = ""
contest.HomeTeam = struct{}{}
}
} else {
contest.HomeName = ""
contest.HomeTeam = struct{}{}
}
if v.AwayID > 0 {
if team, ok := teams[v.AwayID]; ok {
contest.AwayName = team.Title
contest.AwayTeam = team
} else {
contest.AwayName = ""
contest.AwayTeam = struct{}{}
}
} else {
contest.AwayName = ""
contest.AwayTeam = struct{}{}
}
if v.SuccessTeam > 0 {
if team, ok := teams[v.SuccessTeam]; ok {
contest.SuccessName = team.Title
} else {
contest.SuccessName = ""
}
} else {
contest.SuccessName = ""
}
contest.Season = struct{}{}
contest.SuccessTeaminfo = struct{}{}
list = append(list, contest)
}
return
}
//TeamMap get team and map team id to team
func (s *Service) TeamMap(ctx context.Context) (res map[int64]*model.Filter, err error) {
var (
teams []*model.Filter
)
if teams, err = s.dao.Teams(ctx); err != nil {
log.Error("LoadKnockoutTree s.dao.Teams error(%v)", err)
return
}
res = make(map[int64]*model.Filter)
for _, v := range teams {
res[v.ID] = v
}
return
}
// BuildKnockTree knock tree.
func (s *Service) BuildKnockTree(c context.Context) {
var (
trees []*model.Tree
sTree []*model.TreeList
mids []int64
contests map[int64]*model.Contest
cInfos []*model.ContestInfo
mapContests map[int64]*model.ContestInfo
treeList [][]*model.TreeList
err error
details []*model.ActiveDetail
teamMap map[int64]*model.Filter
)
if teamMap, err = s.TeamMap(c); err != nil {
log.Error("LoadKnockoutTree TeamMap error(%v)", err)
return
}
if details, err = s.dao.KDetails(c); err != nil {
log.Error("LoadKnockoutTree s.dao.KDetails error(%v)", err)
return
}
//build tree
for _, detail := range details {
if detail.Online == _downline {
//edit status; must add cache time
if s.dao.AddActKnockCacheTime(c, detail.ID); err != nil {
log.Error("LoadKnockoutTree s.dao.AddActKnockCacheTime error(%v)", err)
continue
}
} else {
treeList = _emptTreeList
sTree = make([]*model.TreeList, 0)
if trees, err = s.dao.Trees(c, detail.ID); err != nil {
log.Error("s.dao.Trees error(%v)", err)
return
}
for _, tree := range trees {
mids = append(mids, tree.Mid)
}
if len(mids) == 0 {
continue
} else {
count := len(mids)
if contests, err = s.dao.EpContests(c, mids); err != nil {
log.Error("s.dao.RawEpContests error(%v)", err)
continue
}
if cInfos, err = s.contestTeam(c, contests, teamMap); err != nil {
log.Error("s.contestTeam Error (%v)", err)
continue
}
mapContests = make(map[int64]*model.ContestInfo, count)
for _, info := range cInfos {
mapContests[info.ID] = info
}
for _, tree := range trees {
if tree.Pid == 0 {
if len(sTree) > 0 {
treeList = append(treeList, sTree)
}
sTree = nil
if cInfo, ok := mapContests[tree.Mid]; ok {
sTree = append(sTree, &model.TreeList{Tree: tree, ContestInfo: cInfo})
} else {
sTree = append(sTree, &model.TreeList{Tree: tree})
}
} else {
if cInfo, ok := mapContests[tree.Mid]; ok {
sTree = append(sTree, &model.TreeList{Tree: tree, ContestInfo: cInfo})
} else {
sTree = append(sTree, &model.TreeList{Tree: tree})
}
}
}
if len(sTree) > 0 {
treeList = append(treeList, sTree)
}
if len(treeList) > 0 {
go s.dao.AddActKnockoutCache(context.Background(), detail.ID, treeList)
}
}
}
}
}
// ActKnockout knockout tree
func (s *Service) ActKnockout(c context.Context, madID int64) (res [][]*model.TreeList, err error) {
if res, err = s.dao.GetActKnockoutCache(c, madID); err != nil {
return
}
if len(res) == 0 {
res = _emptTreeList
err = ecode.EsportsActKnockNotExist
}
return
}

View File

@@ -0,0 +1,80 @@
package service
import (
"context"
"testing"
"go-common/app/interface/main/esports/model"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_Calendar(t *testing.T) {
Convey("test service calendar", t, WithService(func(s *Service) {
res, err := s.Calendar(context.Background(), &model.ParamFilter{Stime: "2018-07-27", Etime: "2018-08-02"})
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
}))
}
func TestService_FilterMatch(t *testing.T) {
Convey("test service filterMatch", t, WithService(func(s *Service) {
res, err := s.FilterMatch(context.Background(), &model.ParamFilter{Mid: 0})
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
}))
}
func TestService_FilterVideo(t *testing.T) {
Convey("test service filterVideo", t, WithService(func(s *Service) {
res, err := s.FilterVideo(context.Background(), &model.ParamFilter{Mid: 0})
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
}))
}
func TestService_ListVideo(t *testing.T) {
Convey("test service listVideo", t, WithService(func(s *Service) {
arg := &model.ParamVideo{
Mid: int64(0),
Gid: int64(0),
Tid: int64(0),
Year: int64(2018),
Tag: int64(1),
Pn: 1,
Ps: 30,
}
res, total, err := s.ListVideo(context.Background(), arg)
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
println(total)
}))
}
func TestService_ListContest(t *testing.T) {
Convey("test service listContest", t, WithService(func(s *Service) {
arg := &model.ParamContest{
Mid: int64(0),
GState: "0,3,4",
Pn: 1,
Ps: 10,
}
mid := int64(12309)
res, total, err := s.ListContest(context.Background(), mid, arg)
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
println(total)
}))
}
func TestService_Season(t *testing.T) {
Convey("test service Season", t, WithService(func(s *Service) {
arg := &model.ParamSeason{
Pn: 1,
Ps: 5,
}
res, count, err := s.Season(context.Background(), arg)
So(err, ShouldBeNil)
So(count, ShouldBeGreaterThan, 0)
So(len(res), ShouldBeGreaterThan, 0)
}))
}

View File

@@ -0,0 +1,127 @@
package service
import (
"context"
"go-common/app/interface/main/esports/model"
)
// Game get game.
func (s *Service) Game(c context.Context, p *model.ParamGame) (rs map[int64]*model.Game, err error) {
var (
ok bool
games []*model.Game
gameMap map[int64]*model.Game
)
rs = make(map[int64]*model.Game, len(p.GameIDs))
if p.Tp == _lolType {
if games, ok = s.lolGameMap.Data[p.MatchID]; !ok {
return
}
} else if p.Tp == _dotaType {
if games, ok = s.dotaGameMap.Data[p.MatchID]; !ok {
return
}
}
count := len(games)
if count == 0 {
return
}
gameMap = make(map[int64]*model.Game, count)
for _, game := range games {
gameMap[game.ID] = game
}
for _, id := range p.GameIDs {
if game, ok := gameMap[id]; ok {
rs[id] = game
}
}
return
}
// Items get items.
func (s *Service) Items(c context.Context, p *model.ParamLeidas) (rs map[int64]*model.Item, err error) {
rs = make(map[int64]*model.Item, len(p.IDs))
if p.Tp == _lolType {
for _, id := range p.IDs {
if item, ok := s.lolItemsMap.Data[id]; ok {
rs[id] = item
}
}
} else if p.Tp == _dotaType {
for _, id := range p.IDs {
if item, ok := s.dotaItemsMap.Data[id]; ok {
rs[id] = item
}
}
}
return
}
// Heroes lol:champions ; dota2 heroes.
func (s *Service) Heroes(c context.Context, p *model.ParamLeidas) (rs interface{}, err error) {
var (
champions map[int64]*model.Champion
dotaHeroes map[int64]*model.Hero
)
if p.Tp == _lolType {
champions = make(map[int64]*model.Champion, len(p.IDs))
for _, id := range p.IDs {
if item, ok := s.lolChampions.Data[id]; ok {
champions[id] = item
}
}
rs = champions
} else if p.Tp == _dotaType {
dotaHeroes = make(map[int64]*model.Hero, len(p.IDs))
for _, id := range p.IDs {
if item, ok := s.dotaHeroes.Data[id]; ok {
dotaHeroes[id] = item
}
}
rs = dotaHeroes
}
return
}
// Abilities lol:spells;dota2:abilities.
func (s *Service) Abilities(c context.Context, p *model.ParamLeidas) (rs interface{}, err error) {
infos := make(map[int64]*model.LdInfo, len(p.IDs))
if p.Tp == _lolType {
for _, id := range p.IDs {
if info, ok := s.lolSpells.Data[id]; ok {
infos[id] = info
}
}
rs = infos
} else if p.Tp == _dotaType {
for _, id := range p.IDs {
if info, ok := s.dotaAbilities.Data[id]; ok {
infos[id] = info
}
}
rs = infos
}
return
}
// Players get players.
func (s *Service) Players(c context.Context, p *model.ParamLeidas) (rs interface{}, err error) {
infos := make(map[int64]*model.LdInfo, len(p.IDs))
if p.Tp == _lolType {
for _, id := range p.IDs {
if info, ok := s.lolPlayers.Data[id]; ok {
infos[id] = info
}
}
rs = infos
} else if p.Tp == _dotaType {
for _, id := range p.IDs {
if info, ok := s.dotaPlayers.Data[id]; ok {
infos[id] = info
}
}
rs = infos
}
return
}

View File

@@ -0,0 +1,13 @@
package service
import (
"context"
"go-common/app/interface/main/esports/model"
)
// Search search video list.
func (s *Service) Search(c context.Context, mid int64, p *model.ParamSearch, buvid string) (rs *model.SearchEsp, err error) {
rs, err = s.dao.Search(c, mid, p, buvid)
return
}

View File

@@ -0,0 +1,23 @@
package service
import (
"context"
"testing"
"go-common/app/interface/main/esports/model"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_Search(t *testing.T) {
Convey("test service Search", t, WithService(func(s *Service) {
arg := &model.ParamSearch{
Keyword: "dota",
Pn: 1,
Ps: 30,
}
res, err := s.Search(context.Background(), 0, arg, "")
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
}))
}

View File

@@ -0,0 +1,364 @@
package service
import (
"context"
"encoding/json"
"math"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/interface/main/esports/conf"
"go-common/app/interface/main/esports/dao"
"go-common/app/interface/main/esports/model"
arcclient "go-common/app/service/main/archive/api"
favrpc "go-common/app/service/main/favorite/api/gorpc"
"go-common/library/log"
"go-common/library/sync/pipeline/fanout"
"github.com/robfig/cron"
)
const (
_perPage = 100
_lolType = 1
_dotaType = 2
_firstPage = "1"
_lolGame = "lol/games"
_dotaGame = "dota2/games"
_lolItems = "lol/items"
_dotaItems = "dota2/items"
_lolChampions = "lol/champions"
_lolHeroes = "dota2/heroes"
_lolSpells = "lol/spells"
_dotaAbilities = "dota2/abilities"
_lolPlayers = "lol/players"
_dotaPlayers = "dota2/players"
)
// Service service struct.
type Service struct {
c *conf.Config
dao *dao.Dao
// rpc
fav *favrpc.Service
// cache proc
cache *fanout.Fanout
arcClient arcclient.ArchiveClient
lolGameMap, dotaGameMap *model.SyncGame
lolItemsMap, dotaItemsMap *model.SyncItem
lolChampions *model.SyncChampion
dotaHeroes *model.SyncHero
lolSpells, dotaAbilities *model.SyncInfo
lolPlayers, dotaPlayers *model.SyncInfo
// cron
cron *cron.Cron
}
// New new service.
func New(c *conf.Config) *Service {
s := &Service{
c: c,
dao: dao.New(c),
fav: favrpc.New2(c.FavoriteRPC),
cache: fanout.New("cache"),
lolGameMap: &model.SyncGame{
Data: make(map[int64][]*model.Game),
},
dotaGameMap: &model.SyncGame{
Data: make(map[int64][]*model.Game),
},
lolItemsMap: &model.SyncItem{
Data: make(map[int64]*model.Item),
},
dotaItemsMap: &model.SyncItem{
Data: make(map[int64]*model.Item),
},
lolChampions: &model.SyncChampion{
Data: make(map[int64]*model.Champion),
},
dotaHeroes: &model.SyncHero{
Data: make(map[int64]*model.Hero),
},
lolSpells: &model.SyncInfo{
Data: make(map[int64]*model.LdInfo),
},
dotaAbilities: &model.SyncInfo{
Data: make(map[int64]*model.LdInfo),
},
lolPlayers: &model.SyncInfo{
Data: make(map[int64]*model.LdInfo),
},
dotaPlayers: &model.SyncInfo{
Data: make(map[int64]*model.LdInfo),
},
cron: cron.New(),
}
var err error
if s.arcClient, err = arcclient.NewClient(c.ArcClient); err != nil {
panic(err)
}
go s.loadKnockTreeCache()
go s.loadLdGame()
go s.createCron()
return s
}
// Ping ping service.
func (s *Service) Ping(c context.Context) (err error) {
if err = s.dao.Ping(c); err != nil {
log.Error("s.dao.Ping error(%v)", err)
}
return
}
// loadCache load cache
func (s *Service) loadKnockTreeCache() {
for {
s.BuildKnockTree(context.Background())
time.Sleep(time.Duration(conf.Conf.Rule.KnockTree))
}
}
func (s *Service) loadLdGame() {
var (
contestDatas []*model.Contest
err error
)
for {
if contestDatas, err = s.dao.ContestDatas(context.Background()); err != nil {
log.Error("loadLeida s.dao.ContestDatas error(%v)", err)
time.Sleep(time.Second)
continue
}
for _, data := range contestDatas {
tmp := data
go s.setGamesMap(tmp)
}
time.Sleep(time.Duration(conf.Conf.Leidata.AfterSleep))
}
}
func (s *Service) createCron() {
go s.lolPlayersCron()
go s.dotaPlayersCron()
go s.infoCron()
s.cron.AddFunc(s.c.Leidata.LolPlayersCron, s.lolPlayersCron)
s.cron.AddFunc(s.c.Leidata.DotaPlayersCron, s.dotaPlayersCron)
s.cron.AddFunc(s.c.Leidata.InfoCron, s.infoCron)
s.cron.Start()
}
func (s *Service) lolPlayersCron() {
go s.loadLdPages(_lolPlayers)
log.Info("createCron lolPlayersCron start")
}
func (s *Service) dotaPlayersCron() {
go s.loadLdPages(_dotaPlayers)
log.Info("createCron dotaPlayersCron start")
}
func (s *Service) infoCron() {
go s.loadLdPages(_lolItems)
go s.loadLdPages(_dotaItems)
go s.loadLdPages(_lolSpells)
go s.loadLdPages(_dotaAbilities)
go s.loadLdPages(_lolChampions)
go s.loadLdPages(_lolHeroes)
log.Info("createCron infoCron start")
}
func (s *Service) setGamesMap(data *model.Contest) {
var (
err error
params url.Values
rs json.RawMessage
games []*model.Game
endTime time.Time
isTime bool
)
params = url.Values{}
params.Set("match_id", strconv.FormatInt(data.MatchID, 10))
if data.Etime > 0 {
endTime = time.Unix(data.Etime, 0).Add(time.Duration(s.c.Leidata.EndSleep))
if time.Now().Unix() > endTime.Unix() {
isTime = true
}
}
if !isTime && data.Stime > 0 && time.Now().Unix() < data.Stime {
isTime = true
}
if data.DataType == _lolType {
if _, ok := s.lolGameMap.Data[data.MatchID]; ok && isTime {
return
}
if rs, _, err = s.leida(params, _lolGame); err == nil {
if err = json.Unmarshal(rs, &games); err == nil {
s.lolGameMap.Lock()
s.lolGameMap.Data[data.MatchID] = games
s.lolGameMap.Unlock()
}
}
} else if data.DataType == _dotaType {
if _, ok := s.dotaGameMap.Data[data.MatchID]; ok && isTime {
return
}
if rs, _, err = s.leida(params, _dotaGame); err == nil {
if err = json.Unmarshal(rs, &games); err == nil {
s.dotaGameMap.Lock()
s.dotaGameMap.Data[data.MatchID] = games
s.dotaGameMap.Unlock()
}
}
}
}
func (s *Service) loadLdPages(tp string) {
var (
err error
params url.Values
count int
)
params = url.Values{}
params.Set("page", _firstPage)
params.Set("per_page", strconv.Itoa(_perPage))
if count, err = s.setPages(tp, params); err != nil {
return
}
for i := 2; i <= count; i++ {
time.Sleep(time.Second)
params.Set("page", strconv.Itoa(i))
params.Set("per_page", strconv.Itoa(_perPage))
s.setPages(tp, params)
}
}
func (s *Service) setPages(tp string, params url.Values) (count int, err error) {
var (
rs json.RawMessage
items []*model.Item
infos []*model.LdInfo
champions []*model.Champion
heroes []*model.Hero
)
switch tp {
case _lolItems:
if rs, count, err = s.leida(params, _lolItems); err == nil {
if err = json.Unmarshal(rs, &items); err == nil {
for _, item := range items {
s.lolItemsMap.Lock()
s.lolItemsMap.Data[item.ID] = item
s.lolItemsMap.Unlock()
}
}
}
case _dotaItems:
if rs, count, err = s.leida(params, _dotaItems); err == nil {
if err = json.Unmarshal(rs, &items); err == nil {
for _, item := range items {
s.dotaItemsMap.Lock()
s.dotaItemsMap.Data[item.ID] = item
s.dotaItemsMap.Unlock()
}
}
}
case _lolSpells:
if rs, count, err = s.leida(params, _lolSpells); err == nil {
if err = json.Unmarshal(rs, &infos); err == nil {
for _, info := range infos {
s.lolSpells.Lock()
s.lolSpells.Data[info.ID] = info
s.lolSpells.Unlock()
}
}
}
case _dotaAbilities:
if rs, count, err = s.leida(params, _dotaAbilities); err == nil {
if err = json.Unmarshal(rs, &infos); err == nil {
for _, info := range infos {
s.dotaAbilities.Lock()
s.dotaAbilities.Data[info.ID] = info
s.dotaAbilities.Unlock()
}
}
}
case _lolPlayers:
if rs, count, err = s.leida(params, _lolPlayers); err == nil {
if err = json.Unmarshal(rs, &infos); err == nil {
for _, info := range infos {
s.lolPlayers.Lock()
s.lolPlayers.Data[info.ID] = info
s.lolPlayers.Unlock()
}
}
}
case _dotaPlayers:
if rs, count, err = s.leida(params, _dotaPlayers); err == nil {
if err = json.Unmarshal(rs, &infos); err == nil {
for _, info := range infos {
s.dotaPlayers.Lock()
s.dotaPlayers.Data[info.ID] = info
s.dotaPlayers.Unlock()
}
}
}
case _lolChampions:
if rs, count, err = s.leida(params, _lolChampions); err == nil {
if err = json.Unmarshal(rs, &champions); err == nil {
for _, champion := range champions {
s.lolChampions.Lock()
s.lolChampions.Data[champion.ID] = champion
s.lolChampions.Unlock()
}
}
}
case _lolHeroes:
if rs, count, err = s.leida(params, _lolHeroes); err == nil {
if err = json.Unmarshal(rs, &heroes); err == nil {
for _, hero := range heroes {
s.dotaHeroes.Lock()
s.dotaHeroes.Data[hero.ID] = hero
s.dotaHeroes.Unlock()
}
}
}
}
return
}
func (s *Service) leida(params url.Values, route string) (rs []byte, count int, err error) {
var body, orginBody []byte
params.Del("route")
params.Set("key", s.c.Leidata.Key)
url := s.c.Leidata.URL + "/" + route + "?" + params.Encode()
for i := 0; i < s.c.Leidata.Retry; i++ {
if body, err = s.dao.Leida(context.Background(), url); err != nil {
time.Sleep(time.Second)
continue
}
bodyStr := string(body[:])
if bodyStr == "" {
time.Sleep(time.Second)
continue
}
rsPos := strings.Index(bodyStr, "[")
if rsPos > -1 {
orginBody = body
body = []byte(bodyStr[rsPos:])
} else {
time.Sleep(time.Second)
continue
}
rs = body
totalPos := strings.Index(bodyStr, "X-Total:")
if totalPos > 0 {
s := string(orginBody[totalPos+9 : rsPos-4])
if t, e := strconv.ParseFloat(s, 64); e == nil {
count = int(math.Ceil(t / float64(_perPage)))
}
}
break
}
if err != nil {
log.Error("json.Unmarshal url(%s) body(%s) error(%v)", url, string(body), err)
}
return
}

View File

@@ -0,0 +1,28 @@
package service
import (
"flag"
"path/filepath"
"time"
"go-common/app/interface/main/esports/conf"
)
var (
svr *Service
)
func init() {
dir, _ := filepath.Abs("../cmd/esports-test.toml")
flag.Set("conf", dir)
conf.Init()
svr = New(conf.Conf)
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(svr)
}
}