Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

21
app/admin/main/tv/BUILD Normal file
View File

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

View File

@@ -0,0 +1,206 @@
### tv端视频审核
##### Version 1.7.1
> 1. UGC审核查询和内容库result=1即过审迁移到ES对接ES的SDK删除原有的DB逻辑
> 2. UP主管理列表增加"干预昵称"字段、搜索昵称改为搜索UP主原名
> 3. UGC内容库增加可按UP主原名或者MID搜索稿件
##### Version 1.7.0
> 1. 新增tv admin tv会员 订单列表查询接口
> 2. 新增tv admin tv会员 价格面板创建接口
> 3. 新增tv admin tv会员 价格面板列表查询接口
> 4. 新增tv admin tv会员 价格面板根据id删除接口
> 5. 新增tv admin tv会员 价格面板根据id查询接口
> 6. 新增tv admin tv会员 用户根据mid查询接口
##### Version 1.6.2
> 1. 合拍影视的地区为多个如"中国,美国",所以将area字段由int型改为string型用于接收此类信息
##### Version 1.6.1
> 1. 允许season的total_num为0未完结的番剧修改其参数int型为string型
##### Version 1.6.0
> 1. 允许ep的length为0去掉form中该字段的validate
##### Version 1.5.9
> 1. ugc付费禁止手动添加进tv库
##### Version 1.5.8
> 1. 新增索引标签排序接口修改position字段
> 2. 索引标签列表接口排序改为使用position字段排序
##### Version 1.5.7
> 1. 修改模块发布bug
##### Version 1.5.6
> 1. 添加动态标签接口
##### Version 1.5.5
> 1. 修复新页面添加新模块的问题
##### Version 1.5.4
> 1. 修改modules的添加和编辑接口使得其支持传入类型moretype2新pgc索引3新ugc索引morepage传入pgc或者ugc的一级分区id
##### Version 1.5.3
> 1. 修改模块配置页面 err为nil的bug
##### Version 1.5.2
> 1. 渠道闪屏改版需求,增加筛选条件
##### Version 1.5.1
> 1. PGC的season列表和UGC的archive列表增加主站发布时间字段
> 2. 干预列表增加主站发布时间字段判断PGC或UGC读取相应字段展示
> 3. pgc的category翻译成中文的逻辑改为走配置不再写死在代码中
##### Version 1.5.0
> 1. 新增索引页干预类型list和publish接口发布时验证ugc稿件或pgc剧集属于所提交的分区否则认为失败
> 2. 对于模块页和精选页的干预进行优化收敛差异化操作至model中。修改路由使得三种干预操作放入同一group中清真的味道~
##### Version 1.4.9
> 1. 动态分区配置
##### Version 1.4.8
> 1. 添加tv版1.13的索引标签管理模块
> 2. 添加索引标签自动同步pgc cond接口及稿件的分区的机制自动添加"全部"标签
##### Version 1.4.7
> 1. 修复ep导入时state为0的问题
##### Version 1.4.6
> 1. createSeason接口修改
- 新增参数version、producer
- 改用bind的required进行参数校验
- season的update使用反射进行更新字段检测只更新有变更的字段如无变更则不更新
> 2. online和hidden冗余代码优化
> 3. pgc过审保持逻辑优化不再更新state=7进行过渡
##### Version 1.4.5
> 1. 修复ugc审核查询的rows未close的问题
##### Version 1.4.4
> 1. 增加ugc审核查询相关接口由于ES暂不支持按照title搜索所以title搜索暂时还是走DB其他搜索走ES
> 2. 补齐tv-admin的UT并修正无法通过的UT
> 3. pgc审核查询接口改版合并审核中的2种状态、增加ep和season的结果中增加ctime字段
> 4. 增加批量删除媒资接口用于进行PGC/UGC资料的软删除
> 5. 增加ugc异常cid已提交转码一定时间仍未返回值的的列表导出功能
##### Version 1.4.3
> 1. 添加pgc转码查询后台接口
##### Version 1.4.2
> 1. archive-service和account-service改为grpc
> 2. 配合archive-service的grpc将typeid从int16改为int32
##### Version 1.4.1
> 1. 芒果推荐位接口:新增、删除、展示、编辑、发布
##### Version 1.4.0
> 1. 手动提审视频时,转载的视为无效,不允许添加
##### Version 1.3.13
> 1. 干预发布支持老的无分类的数据无分类默认为PGC干预
##### Version 1.3.12
> 1. 两套干预接口统一为一套逻辑新增支持UGC干预逻辑
> 2. 模块数据源支持ugc5个pgc的category+5个ugc的一级分区及其下属的二级分区
> 3. 增加接口,用于吐出模块化所支持的数据源
##### Version 1.3.11
> 1. 按照视频云要求ugc playurl接口新增参数"platform" = "tvproj"
##### Version 1.3.10
> 1. UGC内容库
##### Version 1.3.9
> 1. cms中新增up主管理干预、上下架等
##### Version 1.3.8
> 1. ugc 视频分区过滤
##### Version 1.3.7
> 1. 模块化干预默认取100条数据
##### Version 1.3.6
> 1. 修复分页参数错误
##### Version 1.3.5
> 1. 修复权限错误
##### Version 1.3.4
> 1. 模块化
##### Version 1.3.3
> 1. 修复bm参数映射错误问题
##### Version 1.3.2
> 1. 水印管理
> 2. fix bazel file
##### Version 1.3.1
> 1. 修复pgc数据bind的问题
##### Version 1.3.0
> 1. TV四期需求——UGC相关功能up主管理接口添加、删除、导入历史数据等等
> 2. 批量手动添加稿件接口
##### Version 1.2.12
> 1. 修改MC 找不到key 报500错误
> 2. 修复方法错误问题
##### Version 1.2.11
> 1. 搜索热词干预
##### Version 1.2.10
> 1. 干预列表和干预发布增加对"最新更新"即category=3的支持
> 2. pgc下架ep或者season时添加过审保持逻辑保证鉴权报错准确性
> 3. 避免pgc接口更新时多次打更新将原先过审的ep/season更新成未过审
##### Version 1.2.9
> 2. 修改默认配置
##### Version 1.2.8
> 1. Bazel Update
##### Version 1.2.7
> 1. 迁移bm框架
> 2. 审核查询接口支持manager权限点控制
##### Version 1.2.6
> 1, 修复pgc数据无法上架问题
##### Version 1.2.5
> 1, 修复season添加时的报错问题分开searepo和season/create使用的结构体
##### Version 1.2.4
> 1.修正添加干预的时候时间排序问题
> 2.修正ep添加的时候title可以为空
> 3.修正升级管理添加版本的时候灰度更新失效问题
##### Version 1.2.3
> 1.双写内容库tv_content/tv_ep_content表, 原因interface读表和admin写表不一致有bug
##### Version 1.2.2
> 1.修正升级管理是否推送/强制推送勾选问题
> 2.修正dao层dbshow日志记录问题
> 3.修正剧集标题模糊搜索
##### Version 1.2.1
> 1.预览功能对接playurl接口增加qn=16逻辑
> 2.修复剧集无法显示全部的问题
> 3.封装bfs接口
##### Version 1.2.0
> 1.修改route为verify route
##### Version 1.1.1
> 1.预览功能对接playurl
##### Version 1.0.0
> 1.新增审核通过列表接口
> 2.新增上下线接口
##### Version 1.1.0
> 1.新增干预列表展示,可搜索筛选。在展示时会检验所有干预的有效性,对于无效干预进行接口吐出展示,并且进行删除操作。
> 2.新增干预列表发布接口,发布后删除之前所有干预,添加新干预。
> 3. 新增审核结果查询接口ep接口和season接口
> 4. 新增内容库/升级管理

View File

@@ -0,0 +1,15 @@
# Owner
liweijia
renwei
zhaogangtao
# Author
gukai
zhaoshichen
shenpeng
# Reviewer
renwei
wuhao
guanyanliang
liweijia

23
app/admin/main/tv/OWNERS Normal file
View File

@@ -0,0 +1,23 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- gukai
- liweijia
- renwei
- zhaogangtao
- zhaoshichen
labels:
- admin
- admin/main/tv
- main
options:
no_parent_owners: true
reviewers:
- guanyanliang
- gukai
- liweijia
- renwei
- shenpeng
- wuhao
- zhaogangtao
- zhaoshichen

View File

@@ -0,0 +1,10 @@
#### tv-admin
##### 项目简介
> 1.提供tv端视频审核服务
##### 编译环境
> 请只用golang v1.7.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common

View File

@@ -0,0 +1,46 @@
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 = ["tv-admin-test.toml"],
importpath = "go-common/app/admin/main/tv/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/tv/conf:go_default_library",
"//app/admin/main/tv/http:go_default_library",
"//app/admin/main/tv/service:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/trace:go_default_library",
"//library/os/signal:go_default_library",
"//library/syscall: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,60 @@
package main
import (
"flag"
"os"
"time"
"go-common/app/admin/main/tv/conf"
"go-common/app/admin/main/tv/http"
"go-common/app/admin/main/tv/service"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
"go-common/library/net/trace"
"go-common/library/os/signal"
"go-common/library/syscall"
)
var (
s *service.Service
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
log.Error("conf.Init() error(%v)", err)
panic(err)
}
log.Init(conf.Conf.Log)
defer log.Close()
trace.Init(conf.Conf.Tracer)
defer trace.Close()
// service init
s = service.New(conf.Conf)
ecode.Init(conf.Conf.Ecode)
http.Init(conf.Conf, s)
log.Info("tv-admin start")
signalHandler()
}
func signalHandler() {
var (
ch = make(chan os.Signal, 1)
)
signal.Notify(ch, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT, syscall.SIGSTOP)
for {
si := <-ch
switch si {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGINT:
time.Sleep(time.Second * 2)
log.Info("get a signal %s, stop the tv-admin process", si.String())
s.Close()
s.Wait()
time.Sleep(time.Second)
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@@ -0,0 +1,222 @@
version = "1.0.0"
user = "nobody"
dir = "./"
family = "tv-admin"
trace = false
debug = false
env = "uat"
[cfg]
playpath = "upos-hz-tvshenhe.acgvideo.com"
playurlAPI = "http://videodispatch-pgc.bilibili.co/v2/playurl"
UPlayurlAPI = "http://uat-tv-ugc.bilibili.co/v2/playurl"
auditRSize = 20
intervLimit = 100
SearInterMax = 20
PGCTypes = ["番剧","电视剧","电影","纪录片",]
PgcNames = {1 = "番剧",2="电影",3="纪录片",4="国创",5="电视剧"}
ModIntMaxSize = 100
TypesLoad = "2h"
MangoErr = "以下内容因下架被删除推荐:"
LoadSnFre = "30m"
[cfg.RefLabel]
Fre = "24h"
PGCApi = "http://bangumi.bilibili.com/media/web_api/search/v2/condition"
UgcType = "二级分区"
UgcTime = "时间"
AllValue = "-1"
AllName = "全部"
[cfg.Abnormal]
CriticalCid = 12780000
AbnormHours = 24
ReloadFre = "5m"
ExportTitles = ["cid","video_title","ctime","aid","arc_title","pub_time"]
[cfg.SupportCat]
PGCTypes = [1,2,3,4,5]
UGCTypes = [3,4,36,155,160]
ReloadFre = "10m"
[cfg.AuditConsult]
LikeLimit = 50
UnshelveNb = 10
MatchPS = 50000
[cfg.Hosts]
ESUgc = "http://uat-manager.bilibili.co/x/admin/search/query"
Manager = "http://uat-manager.bilibili.co"
[cfg.EsIdx]
[cfg.EsIdx.UgcIdx]
Business = "tv_ugc_archive"
Index = "tv_ugc_archive"
[log]
dir = "/data/log/tv-admin/"
[orm]
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_tv?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 5
idleTimeout = "4h"
[HTTPServer]
addr = "0.0.0.0:6683"
timeout = "1s"
[ormshow]
dsn = "test:test@tcp(172.16.33.205:3308)/bilibili_show?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 5
idleTimeout = "4h"
[httpSearch]
fullURL = "http://android-apk.bilibili.co/api/v1/archive/pack/apk"
key = "89ffc6e896106fd3"
secret = "1359cdbaf9ff6e2f9b6251579d966101"
dial = "1s"
timeout = "8s"
keepAlive = "60s"
timer = 1000
[httpSearch.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[identify]
whiteAccessKey = ""
whiteMid = 0
csrfOn = true
[identify.app]
key = "9cfc54570033cd61"
secret = "9d63835fa38fe58a62d9f49ef5da296f"
[identify.memcache]
name = "go-business/identify"
proto = "tcp"
addr = "172.16.33.54:11211"
active = 100
idle = 100
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[identify.host]
auth = "http://passport.bilibili.co"
secret = "http://open.bilibili.co"
[identify.httpClient]
key = "3c4e41f926e51656"
secret = "26a2095b60c24154521d24ae62b885bb"
dial = "30ms"
timeout = "100ms"
keepAlive = "60s"
[identify.httpClient.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[identify.httpClient.url]
"http://passport.bilibili.co/intranet/auth/tokenInfo" = {timeout = "100ms"}
"http://passport.bilibili.co/intranet/auth/cookieInfo" = {timeout = "100ms"}
"http://open.bilibili.co/api/getsecret" = {timeout = "500ms"}
[auth]
managerHost = "http://uat-manager.bilibili.co"
dashboardHost = "http://dashboard-mng.bilibili.co"
dashboardCaller = "manager-go"
[auth.DsHTTPClient]
key = "manager-go"
secret = "949bbb2dd3178252638c2407578bc7ad"
dial = "1s"
timeout = "1s"
keepAlive = "60s"
[auth.DsHTTPClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[auth.MaHTTPClient]
key = "f6433799dbd88751"
secret = "36f8ddb1806207fe07013ab6a77a3935"
dial = "1s"
timeout = "1s"
keepAlive = "60s"
[auth.MaHTTPClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[auth.session]
sessionIDLength = 32
cookieLifeTime = 1800
cookieName = "mng-go"
domain = ".bilibili.co"
[auth.session.Memcache]
name = "go-business/auth"
proto = "tcp"
addr = "172.16.33.54:11211"
active = 10
idle = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[httpClient]
key = "cadf599ba8b3796a"
secret = "42fbb979aa742013d713a088f912673b"
dial = "500ms"
timeout = "2s"
keepAlive = "60s"
timer = 10
[httpClient.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[URLConf]
getRemotePanelUrl = "https://gwboss.test.atianqi.com:443/boss/inter/bili/getBiliProduct"
syncPanelUrl = "https://gwboss.test.atianqi.com:443/boss/inter/bili/editBiliProd"
[YSTParam]
queryPanelType = "allvod"
insertPanelType = "svod"
source = "snm_bilibili"
insert = "1"
update = "2"
[bfs]
host = "http://uat-bfs.bilibili.co"
bucket = "test"
key = "221bce6492eba70f"
secret = "6eb80603e85842542f9736eb13b7e3"
timeout = 1000
[archiveRPC]
timeout = "500ms"
[archiveRPC.conf]
domain = "api.bilibili.co"
key = "53e2fa226f5ad348"
secret = "3cf6bd1b0ff671021da5f424fea4b04a"
[accountRPC]
timeout = "500ms"
[accountRPC.conf]
domain = "api.bilibili.co"
key = "53e2fa226f5ad348"
secret = "3cf6bd1b0ff671021da5f424fea4b04a"
[memcache]
name = "feed-admin"
proto = "tcp"
addr = "172.18.33.60:11236"
active = 10
idle = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
cmsExpire = "36h"

View File

@@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/admin/main/tv/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/memcache:go_default_library",
"//library/conf:go_default_library",
"//library/database/orm: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/permit: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,220 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/conf"
"go-common/library/database/orm"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
"go-common/library/net/rpc/warden"
"go-common/library/net/trace"
xtime "go-common/library/time"
"github.com/BurntSushi/toml"
)
var (
confPath string
client *conf.Client
// Conf of config
Conf = &Config{}
)
// Memcache memcache.
type Memcache struct {
*memcache.Config
CmsExpire xtime.Duration
}
// Config def.
type Config struct {
// base
// http
HTTPServer *bm.ServerConfig
// auth
Auth *permit.Config
// db
ORM *orm.Config
// dbshow
ORMShow *orm.Config
// log
Log *log.Config
// tracer
Tracer *trace.Config
// httpsearch
HTTPSearch *HTTPSearch
// Cfg
Cfg *Cfg
// HTTPClient .
HTTPClient *bm.ClientConfig
// URLConf
URLConf *URLConf
// YSTParam
YSTParam *YSTParam
// Bfs
Bfs *Bfs
// grpc
ArcClient *warden.ClientConfig
AccClient *warden.ClientConfig
// Ecode Cfg
Ecode *ecode.Config
//mc
Memcache *Memcache
}
// Cfg def
type Cfg struct {
Playpath string // playurl
AuditRSize int // page size for audit result checking
PlayurlAPI string // pgc playurl api
SearInterMax int
IntervLimit int
PGCTypes []string // pgc types that need to filter archives
PgcNames map[string]string // pgc category name in CN
ModIntMaxSize int // ModIntMaxSize module intervene max size
TypesLoad xtime.Duration // reloading type duratio
UPlayurlAPI string // ugc playurl api
SupportCat *SupportCat
MangoErr string // mango error indication message
LoadSnFre xtime.Duration
RefLabel *RefLabel // refresh label original data frequency
AuditConsult *AuditConsult // audit consult cfg
Hosts *Hosts
Abnormal *Abnormal // abnormal cid export related cfg
EsIdx *EsIdx // es index cfg
}
// EsIdx def.
type EsIdx struct {
UgcIdx *EsCfg
}
// EsCfg def.
type EsCfg struct {
Business string
Index string
}
// RefLabel def.
type RefLabel struct {
Fre xtime.Duration
PgcAPI string // pgc api host
UgcType string
UgcTime string
AllValue string
AllName string
}
// Hosts def.
type Hosts struct {
ESUgc string // ESUgc api
Manager string // manager host
}
// AuditConsult related cfg
type AuditConsult struct {
LikeLimit int
UnshelveNb int
MatchPS int64
}
// Abnormal cid export def
type Abnormal struct {
CriticalCid int64 // 12780000, critical cid for transcoding
AbnormHours int // ugc abnormal cid interval hour
ReloadFre xtime.Duration
ExportTitles []string // export titles
}
// SupportCat means the pgc&ugc types that we support to fill the modules
type SupportCat struct {
PGCTypes []int32
UGCTypes []int32
ReloadFre xtime.Duration
}
// URLConf url conf
type URLConf struct {
GetRemotePanelUrl string
SyncPanelUrl string
}
// YSTParam yst config param
type YSTParam struct {
QueryPanelType string
InsertPanelType string
Source string
Insert string
Update string
}
// Bfs struct
type Bfs struct {
Key string
Secret string
Host string
Timeout int
Bucket string
}
// HTTPSearch http client of search
type HTTPSearch struct {
*bm.ClientConfig
FullURL string
}
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
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init int config
func Init() error {
if confPath != "" {
return local()
}
return remote()
}

View File

@@ -0,0 +1,84 @@
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"archive_test.go",
"audit_result_test.go",
"dao_test.go",
"full_test.go",
"modules_test.go",
"panel_test.go",
"pgc_cond_test.go",
"playurl_test.go",
"region_test.go",
"sear_inter_test.go",
"upbfs_test.go",
"upper_test.go",
"user_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/tv/conf:go_default_library",
"//app/admin/main/tv/model:go_default_library",
"//library/log:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"archive.go",
"audit_result.go",
"dao.go",
"full.go",
"mango.go",
"modules.go",
"panel.go",
"pgc_cond.go",
"playurl.go",
"region.go",
"sear_inter.go",
"upbfs.go",
"upper.go",
"user.go",
],
importpath = "go-common/app/admin/main/tv/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/tv/conf:go_default_library",
"//app/admin/main/tv/model:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/elastic:go_default_library",
"//library/database/orm:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,12 @@
package dao
const (
_setManual = "REPLACE INTO ugc_archive (aid, manual, deleted) VALUES (?,?,?)"
_needImport = 1
_notDeleted = 0
)
// NeedImport sets the archive as manual, if it's deleted, we recover it
func (d *Dao) NeedImport(aid int64) (err error) {
return d.DB.Exec(_setManual, aid, _needImport, _notDeleted).Error
}

View File

@@ -0,0 +1,14 @@
package dao
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_ArchiveAdd(t *testing.T) {
Convey("TestDao_ArchiveAdd", t, WithDao(func(d *Dao) {
err := d.NeedImport(123)
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,53 @@
package dao
import (
"context"
"fmt"
"go-common/app/admin/main/tv/model"
"go-common/library/database/elastic"
"go-common/library/log"
)
// ArcES treats the ugc index request and call the ES to get the result
func (d *Dao) ArcES(c context.Context, req *model.ReqArcES) (data *model.EsUgcResult, err error) {
var (
cfg = d.c.Cfg.EsIdx.UgcIdx
r = d.esClient.NewRequest(cfg.Business).Index(cfg.Index).WhereEq("deleted", 0)
)
if req.Valid != "" {
r = r.WhereEq("valid", req.Valid)
}
if req.AID != "" {
r = r.WhereEq("aid", req.AID)
}
if req.Result != "" {
r = r.WhereEq("result", req.Result)
}
if len(req.Typeids) != 0 {
r = r.WhereIn("typeid", req.Typeids)
}
if req.Title != "" {
r = r.WhereLike([]string{"title"}, []string{req.Title}, true, elastic.LikeLevelMiddle)
}
if len(req.Mids) != 0 {
r = r.WhereIn("mid", req.Mids)
}
r.Ps(req.Ps).Pn(int(req.Pn))
if req.MtimeOrder != "" {
r = r.Order("mtime", req.MtimeSort())
}
if req.PubtimeOrder != "" {
r = r.Order("pubtime", req.PubtimeSort())
}
if err = r.Scan(c, &data); err != nil {
log.Error("ArcES:Scan params(%s) error(%v)", r.Params(), err)
return
}
if data == nil || data.Page == nil {
err = fmt.Errorf("data or data.Page nil")
log.Error("ArcES params(%s) error(%v)", r.Params(), err)
return
}
return
}

View File

@@ -0,0 +1,31 @@
package dao
import (
"context"
"go-common/app/admin/main/tv/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoArcES(t *testing.T) {
var (
c = context.Background()
req = &model.ReqArcES{
AID: "10110475",
Valid: "1",
Result: "1",
Mids: []int64{477132},
Typeids: []int32{24},
MtimeOrder: "1",
PubtimeOrder: "1",
}
)
convey.Convey("ArcES", t, func(ctx convey.C) {
data, err := d.ArcES(c, req)
ctx.Convey("Then err should be nil.data should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(data, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,61 @@
package dao
import (
"net/http"
"time"
"go-common/app/admin/main/tv/conf"
"go-common/library/cache/memcache"
"go-common/library/database/elastic"
"go-common/library/database/orm"
httpx "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
// Dao struct user of Dao.
type Dao struct {
c *conf.Config
// db
DB *gorm.DB
// dbshow
DBShow *gorm.DB
fullURL string
httpSearch *httpx.Client
client *httpx.Client
bfsClient *http.Client
esClient *elastic.Elastic
// memcache
mc *memcache.Pool
cmsExpire int32
}
// New create a instance of Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// conf
c: c,
// db
DB: orm.NewMySQL(c.ORM),
// dbshow
DBShow: orm.NewMySQL(c.ORMShow),
// http client
fullURL: c.HTTPSearch.FullURL,
httpSearch: httpx.NewClient(c.HTTPSearch.ClientConfig),
client: httpx.NewClient(c.HTTPClient),
bfsClient: &http.Client{Timeout: time.Duration(c.Bfs.Timeout) * time.Millisecond},
esClient: elastic.NewElastic(&elastic.Config{
Host: c.Cfg.Hosts.Manager,
HTTPClient: c.HTTPClient,
}),
mc: memcache.NewPool(c.Memcache.Config),
cmsExpire: int32(time.Duration(c.Memcache.CmsExpire) / time.Second),
}
d.initORM()
return
}
func (d *Dao) initORM() {
d.DB.LogMode(true)
d.DBShow.LogMode(true)
}

View File

@@ -0,0 +1,75 @@
package dao
import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"testing"
"go-common/app/admin/main/tv/conf"
"flag"
. "github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
var d *Dao
func init() {
// dir, _ := filepath.Abs("../cmd/tv-admin-test.toml")
// flag.Set("conf", dir)
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.web-svr.tv-admin")
flag.Set("conf_token", "3d446a004187a6572d656bab1dbff1b0")
flag.Set("tree_id", "15310")
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")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
}
func WithDao(f func(d *Dao)) func() {
return func() {
Reset(func() {})
f(d)
}
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
d.client.SetTransport(gock.DefaultTransport)
d.httpSearch.SetTransport(gock.DefaultTransport)
d.bfsClient.Transport = gock.DefaultTransport
return r
}
func TestDao_MaxOrder(t *testing.T) {
Convey("TestDao_MaxOrder", t, WithDao(func(d *Dao) {
order := d.MaxOrder(context.Background())
So(order, ShouldBeGreaterThan, 0)
fmt.Println(order)
}))
}
func TestDao_MangoRecom(t *testing.T) {
Convey("TestDao_MangoRecom", t, WithDao(func(d *Dao) {
err := d.MangoRecom(context.Background(), []int64{3, 4, 5})
So(err, ShouldBeNil)
res, err2 := d.GetMRecom(context.Background())
So(err2, ShouldBeNil)
data, _ := json.Marshal(res)
fmt.Println(string(data))
}))
}

View File

@@ -0,0 +1,38 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
)
type msgReturn struct {
Code int `json:"code"`
Message string `json:"message"`
Data []*model.APKInfo `json:"data"`
}
// FullImport .
func (d *Dao) FullImport(c context.Context, build int) (result []*model.APKInfo, err error) {
var (
res = &msgReturn{}
fullURL = d.fullURL
)
params := url.Values{}
params.Set("version_code", fmt.Sprintf("%d", build))
err = d.httpSearch.Get(c, fullURL, "", params, res)
if err != nil {
log.Error("d.httpSearch.Get(%s) error(%v)", fullURL+"?"+params.Encode(), err)
return
}
result = res.Data
if res.Code != ecode.OK.Code() {
err = fmt.Errorf("return code:%d", res.Code)
log.Error("d.httpSearch.Get(%s) error(%v)", fullURL+"?"+params.Encode(), err)
}
return
}

View File

@@ -0,0 +1,33 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoFullImport(t *testing.T) {
var (
c = context.Background()
build = int(0)
)
convey.Convey("FullImport", t, func(ctx convey.C) {
ctx.Convey("Http code err", func(ctx convey.C) {
httpMock("GET", d.fullURL).Reply(-400).JSON(``)
_, err := d.FullImport(c, build)
ctx.So(err, convey.ShouldNotBeNil)
})
ctx.Convey("Business code err", func(ctx convey.C) {
httpMock("GET", d.fullURL).Reply(200).JSON(`{"code":-400}`)
_, err := d.FullImport(c, build)
ctx.So(err, convey.ShouldNotBeNil)
})
ctx.Convey("Everything goes well", func(ctx convey.C) {
httpMock("GET", d.fullURL).Reply(200).JSON(`{"code":0,"data":[{"id":1}]}`)
data, err := d.FullImport(c, build)
ctx.So(err, convey.ShouldBeNil)
ctx.So(data, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,72 @@
package dao
import (
"context"
"encoding/json"
"time"
"go-common/app/admin/main/tv/model"
"go-common/library/cache/memcache"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
xtime "go-common/library/time"
)
const (
_mangoKey = "mango_cms_recom"
_delRecom = "UPDATE mango_recom SET deleted = 1 WHERE id = ?"
_maxOrder = "SELECT MAX(rorder) AS ord FROM mango_recom WHERE deleted = 0"
)
//MangoRecom is used to set mango recom cache in MC
func (d *Dao) MangoRecom(c context.Context, ids []int64) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
mcItem := &model.MRecomMC{
RIDs: ids,
Pubtime: xtime.Time(time.Now().Unix()),
}
itemJSON := &memcache.Item{
Key: _mangoKey,
Object: mcItem,
Flags: memcache.FlagJSON,
Expiration: 0,
}
if err = conn.Set(itemJSON); err != nil {
log.Error("MangoRecom Ids %v, Err %v", ids, err)
}
return
}
// GetMRecom get mango recom mc data
func (d *Dao) GetMRecom(c context.Context) (res *model.MRecomMC, err error) {
var item *memcache.Item
conn := d.mc.Get(c)
defer conn.Close()
if item, err = conn.Get(_mangoKey); err != nil {
log.Error("GetMRecom MangoKey, Err %v", _mangoKey, err)
return
}
err = json.Unmarshal(item.Value, &res)
return
}
// DelMRecom deletes an mango recom position
func (d *Dao) DelMRecom(c *bm.Context, id int64) (err error) {
if err = d.DB.Exec(_delRecom, id).Error; err != nil {
log.Error("DelMRecom Error %v", err)
}
return
}
// MaxOrder picks the max rorder from the table
func (d *Dao) MaxOrder(ctx context.Context) int {
var maxR = new(struct {
Ord int
})
if err := d.DB.Raw(_maxOrder).Scan(&maxR).Error; err != nil {
log.Error("MaxOrder Error %v", err)
return 0
}
return maxR.Ord
}

View File

@@ -0,0 +1,44 @@
package dao
import (
"context"
"go-common/app/admin/main/tv/model"
"go-common/library/cache/memcache"
)
//ModulePublish is used for module status MC key
const ModulePublish = "ModulePublish"
//SetModPub is used for set module publish status to MC
func (d *Dao) SetModPub(c context.Context, pageID string, p model.ModPub) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
itemJSON := &memcache.Item{
Key: ModulePublish + pageID,
Object: p,
Flags: memcache.FlagJSON,
Expiration: 0,
}
if err = conn.Set(itemJSON); err != nil {
return
}
return
}
//GetModPub is used for getting module publish status
func (d *Dao) GetModPub(c context.Context, pageID string) (p model.ModPub, err error) {
var (
conn memcache.Conn
item *memcache.Item
)
conn = d.mc.Get(c)
defer conn.Close()
k := ModulePublish + pageID
if item, err = conn.Get(k); err != nil {
return
}
if err = conn.Scan(item, &p); err != nil {
return
}
return
}

View File

@@ -0,0 +1,43 @@
package dao
import (
"go-common/app/admin/main/tv/model"
"testing"
"time"
"context"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSetModulePublishCache(t *testing.T) {
var (
c = context.Background()
pageID = "18"
p = model.ModPub{
Time: time.Now().Format("2006-01-02 15:04:05"),
State: 1,
}
)
convey.Convey("SetModPub", t, func(ctx convey.C) {
err := d.SetModPub(c, pageID, p)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoGetModulePublishCache(t *testing.T) {
var (
c = context.Background()
pageID = "18"
)
convey.Convey("GetModPub", t, func(ctx convey.C) {
p, err := d.GetModPub(c, pageID)
ctx.Convey("Then err should be nil.p should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,52 @@
package dao
import (
"go-common/app/admin/main/tv/model"
"go-common/library/log"
)
const (
_configTableName = "tv_price_config"
_valid = 0
_invalid = 1
)
// GetById select panel info by id
func (d *Dao) GetById(id int64) (panelInfo *model.TvPriceConfigResp, err error) {
panelInfo = &model.TvPriceConfigResp{}
if err = d.DB.Table(_configTableName).Where("id = ? and status in (?, ?)", id, _valid, _invalid).First(panelInfo).Error; err != nil {
log.Error("GetById (%v) error(%v)", panelInfo, err)
}
return
}
// PanelStatus update panel status info by id
func (d *Dao) PanelStatus(id, status int64) (err error) {
if err = d.DB.Table(_configTableName).Where("id = ? and status in (?, ?)", id, _valid, _invalid).Update("status", status).Error; err != nil {
log.Error("PanelStatus (%v) error(%v)", id, err)
}
return
}
// SavePanel update or add panel info
func (d *Dao) SavePanel(panel *model.TvPriceConfig) (err error) {
if err = d.DB.Save(panel).Error; err != nil {
log.Error("SavePanel (%v) error(%v)", panel, err)
return err
}
return
}
// ExistProduct check duplicated productId, productName
func (d *Dao) ExistProduct(productID string) (flag bool) {
panel := []model.TvPriceConfig{}
if err := d.DB.Table(_configTableName).Where("status in (?, ?) and product_id = ?", _valid, _invalid, productID).Find(&panel).Error; err != nil {
log.Error("HasDiscount %v, Err %v", productID, err)
return false
}
return !(len(panel) == 0)
}

View File

@@ -0,0 +1,67 @@
package dao
import (
"testing"
"go-common/app/admin/main/tv/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSavePanel(t *testing.T) {
convey.Convey("SavePanel", t, func(ctx convey.C) {
var (
panel = &model.TvPriceConfig{ID: 100000000}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
err := d.SavePanel(panel)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGetById(t *testing.T) {
convey.Convey("GetById", t, func(ctx convey.C) {
var (
id = int64(100000000)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
panelInfo, err := d.GetById(id)
ctx.Convey("Then err should be nil.panelInfo should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(panelInfo, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoPanelStatus(t *testing.T) {
convey.Convey("PanelStatus", t, func(ctx convey.C) {
var (
id = int64(100000000)
status = int64(2)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
err := d.PanelStatus(id, status)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoExistProduct(t *testing.T) {
convey.Convey("ExistProduct", t, func(ctx convey.C) {
var (
productID = ""
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
flag := d.ExistProduct(productID)
ctx.Convey("Then flag should not be nil.", func(ctx convey.C) {
ctx.So(flag, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,31 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"github.com/pkg/errors"
)
// PgcCond picks pgc condition
func (d *Dao) PgcCond(c context.Context, snType int32) (result *model.PgcCond, err error) {
var (
host = d.c.Cfg.RefLabel.PgcAPI
params = url.Values{}
resp = model.PgcCondResp{}
)
params.Set("season_type", fmt.Sprintf("%d", snType))
if err = d.client.Get(c, host, "", params, &resp); err != nil {
return
}
if resp.Code != ecode.OK.Code() {
err = errors.Wrapf(ecode.Int(resp.Code), resp.Message)
return
}
result = resp.Result
return
}

View File

@@ -0,0 +1,23 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoPgcCond(t *testing.T) {
var (
c = context.Background()
snType = int32(1)
)
convey.Convey("PgcCond", t, func(ctx convey.C) {
httpMock("GET", d.c.Cfg.RefLabel.PgcAPI).Reply(200).JSON(`{"code":0,"message":"success","result":{"filter":[{"id":"area","name":"地区","value":[{"id":"-1","name":"全部"},{"id":"1","name":"中国大陆"},{"id":"6,7","name":"中国港台"},{"id":"3","name":"美国"},{"id":"2","name":"日本"},{"id":"8","name":"韩国"},{"id":"9","name":"法国"},{"id":"4","name":"英国"},{"id":"15","name":"德国"},{"id":"10","name":"泰国"},{"id":"35","name":"意大利"},{"id":"13","name":"西班牙"},{"id":"5,11,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52","name":"其他国家"}]},{"id":"style_id","name":"风格","value":[{"id":"-1","name":"全部"},{"id":"460","name":"剧情"},{"id":"480","name":"喜剧"},{"id":"490","name":"爱情"},{"id":"500","name":"动作"},{"id":"510","name":"恐怖"},{"id":"520","name":"科幻"},{"id":"530","name":"犯罪"},{"id":"540","name":"惊悚"},{"id":"550","name":"悬疑"},{"id":"560","name":"奇幻"},{"id":"600","name":"战争"},{"id":"610","name":"动画"},{"id":"620","name":"传记"},{"id":"630","name":"家庭"},{"id":"640","name":"歌舞"},{"id":"650","name":"历史"},{"id":"730","name":"漫画改"}]},{"id":"year","name":"年份","value":[{"id":"-1","name":"全部"},{"id":"2018","name":"2018"},{"id":"2017","name":"2017"},{"id":"2016","name":"2016"},{"id":"2015","name":"2015"},{"id":"2014","name":"2014"},{"id":"2013-2010","name":"2013-2010"},{"id":"2009-2005","name":"2009-2005"},{"id":"2004-2000","name":"2004-2000"},{"id":"90年代","name":"90年代"},{"id":"80年代","name":"80年代"},{"id":"更早","name":"更早"}]},{"id":"season_status","name":"付费","value":[{"id":"-1","name":"全部"},{"id":"1","name":"免费"},{"id":"2,6","name":"付费"},{"id":"4,6","name":"大会员"}]}],"order":{"name":"排序","value":[{"id":"2","name":"播放数量","sort":"0,1"},{"id":"0","name":"更新时间","sort":"0,1"},{"id":"6","name":"上映时间","sort":"0,1"}]}}}`)
result, err := d.PgcCond(c, snType)
ctx.Convey("Then err should be nil.result should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(result, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,72 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/app/admin/main/tv/model"
"go-common/library/log"
)
const _type = "mp4"
const _maxBackup = 0
const _otype = "json"
const _qn = "16"
// Playurl Def.
func (d *Dao) Playurl(ctx context.Context, cid int) (playurl string, err error) {
var (
result = model.PlayurlResp{}
params = url.Values{}
api = d.c.Cfg.PlayurlAPI
)
params.Set("cid", fmt.Sprintf("%d", cid))
params.Set("type", _type) // to get one piece
params.Set("max_backup", fmt.Sprintf("%d", _maxBackup)) // no backup url needed
params.Set("otype", _otype) // json format response
params.Set("qn", _qn) // json format response
if err = d.client.Get(ctx, api, "", params, &result); err != nil {
log.Error("ClientGet error[%v]", err)
return
}
if result.Code != 0 { // logic error
err = fmt.Errorf("Resp Code:[%v], Message:[%v]", result.Code, result.Message)
return
}
if len(result.Durl) < 1 { // result empty
err = fmt.Errorf("Playurl Result is Empty! Resp (%v)", result)
return
}
playurl = result.Durl[0].URL
return
}
//UPlayurl ugc play url
func (d *Dao) UPlayurl(ctx context.Context, cid int) (playurl string, err error) {
var (
result = model.UPlayURLR{}
params = url.Values{}
api = d.c.Cfg.UPlayurlAPI
)
params.Set("cid", fmt.Sprintf("%d", cid))
params.Set("type", "mp4")
params.Set("max_backup", fmt.Sprintf("%d", 0))
params.Set("otype", "json")
params.Set("qn", "16")
params.Set("platform", "tvproj")
if err = d.client.Get(ctx, api, "", params, &result); err != nil {
log.Error("UPlayurl ClientGet error[%v]", err)
return
}
if result.Code != 0 { // logic error
err = fmt.Errorf("UPlayurl Resp Code:[%v], Message:[%v], Result:[%v]", result.Code, result.Message, result.Result)
return
}
if len(result.Durl) < 1 { // result empty
err = fmt.Errorf("UPlayurl Result is Empty! Resp (%v)", result)
return
}
playurl = result.Durl[0].URL
return
}

View File

@@ -0,0 +1,64 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoPlayurl(t *testing.T) {
var (
ctx = context.Background()
cid = int(0)
normalStr = `{"Code":0,"Durl":[{"URL":"test"}]}`
httpStr = `{"Code":-400,"Durl":[{"URL":"test"}]}`
emptyStr = `{"Code":0,"Durl":[]}`
)
convey.Convey("Playurl", t, func(cx convey.C) {
cx.Convey("Normal Situation. Then err should be nil.playurl should not be nil.", func(cx convey.C) {
httpMock("GET", d.c.Cfg.PlayurlAPI).Reply(200).JSON(normalStr)
playurl, err := d.Playurl(ctx, cid)
cx.So(err, convey.ShouldBeNil)
cx.So(playurl, convey.ShouldNotBeNil)
})
cx.Convey("Http Err Situation. Then err should be nil.playurl should not be nil.", func(cx convey.C) {
httpMock("GET", d.c.Cfg.PlayurlAPI).Reply(200).JSON(httpStr)
_, err := d.Playurl(ctx, cid)
cx.So(err, convey.ShouldNotBeNil)
})
cx.Convey("Empty Durl Situation. Then err should be nil.playurl should not be nil.", func(cx convey.C) {
httpMock("GET", d.c.Cfg.PlayurlAPI).Reply(200).JSON(emptyStr)
_, err := d.Playurl(ctx, cid)
cx.So(err, convey.ShouldNotBeNil)
})
})
}
func TestDaoUPlayurl(t *testing.T) {
var (
ctx = context.Background()
cid = int(0)
normalStr = `{"Code":0,"Durl":[{"URL":"test"}]}`
httpStr = `{"Code":-400,"Durl":[{"URL":"test"}]}`
emptyStr = `{"Code":0,"Durl":[]}`
)
convey.Convey("UPlayurl", t, func(cx convey.C) {
cx.Convey("Normal Situation. Then err should be nil.playurl should not be nil.", func(cx convey.C) {
httpMock("GET", d.c.Cfg.UPlayurlAPI).Reply(200).JSON(normalStr)
playurl, err := d.UPlayurl(ctx, cid)
cx.So(err, convey.ShouldBeNil)
cx.So(playurl, convey.ShouldNotBeNil)
})
cx.Convey("Http Err Situation. Then err should be nil.playurl should not be nil.", func(cx convey.C) {
httpMock("GET", d.c.Cfg.UPlayurlAPI).Reply(200).JSON(httpStr)
_, err := d.UPlayurl(ctx, cid)
cx.So(err, convey.ShouldNotBeNil)
})
cx.Convey("Empty Durl Situation. Then err should be nil.playurl should not be nil.", func(cx convey.C) {
httpMock("GET", d.c.Cfg.UPlayurlAPI).Reply(200).JSON(emptyStr)
_, err := d.UPlayurl(ctx, cid)
cx.So(err, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,84 @@
package dao
import (
"context"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_addRegSQL = `INSERT INTO tv_pages (page_id,title,index_type,index_tid,rank) VALUES (?,?,?,?,?)`
_editRegSQL = `UPDATE tv_pages SET title=?,index_type=?,index_tid=? WHERE page_id=?`
_del = 0
_firpid = 1
)
// RegList region list .
func (d *Dao) RegList(ctx context.Context, arg *model.Param) (res []*model.RegDB, err error) {
if arg.PageID != "" {
if err = d.DB.Where("page_id=? AND deleted=?", arg.PageID, _del).Find(&res).Error; err != nil {
log.Error("d.DB.Where error(%v)", err)
}
} else {
if arg.State == "2" {
if err = d.DB.Order("rank ASC", true).Where("title LIKE ? AND deleted=?", "%"+arg.Title+"%", _del).Find(&res).Error; err != nil {
log.Error("d.DB.Where error(%v)", err)
}
return
}
if err = d.DB.Order("rank ASC", true).Where("title LIKE ? AND deleted=? AND valid=?", "%"+arg.Title+"%", _del, arg.State).Find(&res).Error; err != nil {
log.Error("d.DB.Order Where error(%v)", err)
}
}
return
}
// AddReg add region .
func (d *Dao) AddReg(ctx context.Context, title, itype, itid, rank string) (err error) {
var (
pid int
res = &model.RegDB{}
)
tx := d.DB.Begin()
if err = d.DB.Order("page_id DESC", true).First(res).Error; err != nil || res == nil {
if err == ecode.NothingFound {
if err = d.DB.Exec(_addRegSQL, _firpid, title, itype, itid, rank).Error; err != nil {
log.Error(" d.DB.Exec error(%v)", err)
tx.Rollback()
return
}
tx.Commit()
return
}
log.Error(" d.DB.Order error(%v)", err)
tx.Rollback()
return
}
pid = res.PageID + 1
if err = d.DB.Exec(_addRegSQL, pid, title, itype, itid, rank).Error; err != nil {
log.Error(" d.DB.Exec error(%v)", err)
tx.Rollback()
return
}
tx.Commit()
return
}
// EditReg edit region .
func (d *Dao) EditReg(ctx context.Context, pid, title, itype, itid string) (err error) {
if err = d.DB.Exec(_editRegSQL, title, itype, itid, pid).Error; err != nil {
log.Error(" d.DB.Exec error(%v)", err)
}
return
}
// UpState publish or not .
func (d *Dao) UpState(ctx context.Context, pids []int, state string) (err error) {
m := map[string]string{"valid": state}
if err = d.DB.Table("tv_pages").Where("page_id IN (?)", pids).Updates(m).Error; err != nil {
log.Error(" d.DB.Table.Where.Updates error(%v)", err)
}
return
}

View File

@@ -0,0 +1,78 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/tv/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoRegList(t *testing.T) {
convey.Convey("RegList", t, func(ctx convey.C) {
var (
c = context.Background()
arg = &model.Param{PageID: "1"}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.RegList(c, arg)
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 TestDaoAddReg(t *testing.T) {
convey.Convey("AddReg", t, func(ctx convey.C) {
var (
c = context.Background()
title = "1"
itype = "1"
itid = "1"
rank = "1"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddReg(c, title, itype, itid, rank)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
println(err)
})
})
})
}
func TestDaoEditReg(t *testing.T) {
convey.Convey("EditReg", t, func(ctx convey.C) {
var (
c = context.Background()
pid = "1"
title = "1"
itype = "1"
itid = "1"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.EditReg(c, pid, title, itype, itid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUpState(t *testing.T) {
convey.Convey("UpState", t, func(ctx convey.C) {
var (
c = context.Background()
pids = []int{1}
state = "0"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpState(c, pids, state)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,93 @@
package dao
import (
"encoding/json"
"context"
"go-common/app/admin/main/tv/model"
"go-common/library/cache/memcache"
)
//SiMcOutKey is used for tv search intervene key with MC
const SiMcOutKey = "_tv_search"
//SiMcStateKey is used for tv search intervene publish status key with MC
const SiMcStateKey = "_tv_search_state"
// SetSearchInterv is used for setting search inter rank cache
func (d *Dao) SetSearchInterv(c context.Context, rank []*model.OutSearchInter) (err error) {
var (
conn memcache.Conn
item *memcache.Item
bs []byte
)
bs, err = json.Marshal(rank)
if err != nil {
return
}
conn = d.mc.Get(c)
defer conn.Close()
item = &memcache.Item{
Key: SiMcOutKey,
Value: bs,
Expiration: 0,
}
err = conn.Set(item)
return
}
// GetSearchInterv is used for getting search inter rank cache
func (d *Dao) GetSearchInterv(c context.Context) (rank []*model.OutSearchInter, err error) {
var (
conn memcache.Conn
item *memcache.Item
)
conn = d.mc.Get(c)
defer conn.Close()
if item, err = conn.Get(SiMcOutKey); err != nil {
return
}
if err = json.Unmarshal(item.Value, &rank); err != nil {
return
}
return
}
// SetPublishCache is used for setting publish status
func (d *Dao) SetPublishCache(c context.Context, state *model.PublishStatus) (err error) {
var (
conn memcache.Conn
item *memcache.Item
bs []byte
)
bs, err = json.Marshal(state)
if err != nil {
return
}
conn = d.mc.Get(c)
defer conn.Close()
item = &memcache.Item{
Key: SiMcStateKey,
Value: bs,
Expiration: 0,
}
err = conn.Set(item)
return
}
// GetPublishCache is used for getting search inter rank cache
func (d *Dao) GetPublishCache(c context.Context) (state *model.PublishStatus, err error) {
var (
conn memcache.Conn
item *memcache.Item
)
conn = d.mc.Get(c)
defer conn.Close()
if item, err = conn.Get(SiMcStateKey); err != nil {
return
}
if err = json.Unmarshal(item.Value, &state); err != nil {
return
}
return
}

View File

@@ -0,0 +1,70 @@
package dao
import (
"context"
"testing"
"time"
"go-common/app/admin/main/tv/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSetSearInterRankCache(t *testing.T) {
var (
c = context.Background()
rank = []*model.OutSearchInter{}
)
convey.Convey("SetSearchInterv", t, func(ctx convey.C) {
rank = append(rank, &model.OutSearchInter{
Keyword: "key",
Status: "1",
})
err := d.SetSearchInterv(c, rank)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoGetSearInterRankCache(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("GetSearchInterv", t, func(ctx convey.C) {
rank, err := d.GetSearchInterv(c)
ctx.Convey("Then err should be nil.rank should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rank, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetPublishCache(t *testing.T) {
var (
c = context.Background()
state = &model.PublishStatus{
Time: time.Now().Format("2006-01-02 15:04:05"),
State: 1,
}
)
convey.Convey("SetPublishCache", t, func(ctx convey.C) {
err := d.SetPublishCache(c, state)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoGetPublishCache(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("GetPublishCache", t, func(ctx convey.C) {
state, err := d.GetPublishCache(c)
ctx.Convey("Then err should be nil.state should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(state, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,83 @@
package dao
import (
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"hash"
"net/http"
"strconv"
"bytes"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_uploadURL = "/bfs/%s/%s"
_template = "%s\n%s\n%s\n%d\n"
_method = "PUT"
)
// Upload uploads cover to bfs
func (d *Dao) Upload(c context.Context, fileName string, fileType string, timing int64, data []byte) (location string, err error) {
bfs := d.c.Bfs
var (
req *http.Request
resp *http.Response
code int
url = fmt.Sprintf(bfs.Host+_uploadURL, bfs.Bucket, fileName)
)
// prepare the data of the file and init the request
buf := new(bytes.Buffer)
_, err = buf.Write(data)
if err != nil {
log.Error("Upload.buf.Write.error(%v)", err)
err = ecode.RequestErr
return
}
if req, err = http.NewRequest(_method, url, buf); err != nil {
log.Error("http.NewRequest() Upload(%v) error(%v)", url, err)
return
}
// request setting
authorization := authorize(bfs.Key, bfs.Secret, _method, bfs.Bucket, fileName, timing)
req.Header.Set("Date", fmt.Sprint(timing))
req.Header.Set("Authorization", authorization)
req.Header.Set("Content-Type", fileType)
resp, err = d.bfsClient.Do(req)
// response treatment
if err != nil {
log.Error("Bfs client.Do(%s) error(%v)", url, err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("Bfs status code error:%v", resp.StatusCode)
return
}
code, err = strconv.Atoi(resp.Header.Get("code"))
if err != nil || code != 200 {
err = fmt.Errorf("Bfs response code error:%v", code)
return
}
location = resp.Header.Get("Location")
return
}
// authorize returns authorization for upload file to bfs
func authorize(key, secret, method, bucket, file string, expire int64) (authorization string) {
var (
content string
mac hash.Hash
signature string
)
content = fmt.Sprintf(_template, method, bucket, file, expire)
mac = hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(content))
signature = base64.StdEncoding.EncodeToString(mac.Sum(nil))
authorization = fmt.Sprintf("%s:%s:%d", key, signature, expire)
return
}

View File

@@ -0,0 +1,57 @@
package dao
import (
"context"
"fmt"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoUpload(t *testing.T) {
var (
c = context.Background()
fileName = "test.txt"
fileType = "txt"
timing = time.Now().Unix()
bfs = d.c.Bfs
data = []byte("123")
url = fmt.Sprintf(bfs.Host+_uploadURL, bfs.Bucket, fileName)
)
convey.Convey("Upload", t, func(ctx convey.C) {
ctx.Convey("http code error", func(ctx convey.C) {
httpMock(_method, url).Reply(-400)
_, err := d.Upload(c, fileName, fileType, timing, data)
ctx.So(err, convey.ShouldNotBeNil)
})
ctx.Convey("business code error", func(ctx convey.C) {
httpMock(_method, url).Reply(200).JSON(`{"code":-400}`)
_, err := d.Upload(c, fileName, fileType, timing, data)
ctx.So(err, convey.ShouldNotBeNil)
})
ctx.Convey("everything is fine", func(ctx convey.C) {
httpMock(_method, url).Reply(200).SetHeader("Location", "test").SetHeader("code", "200").JSON(`{"code":200}`)
location, err := d.Upload(c, fileName, fileType, timing, data)
ctx.So(err, convey.ShouldBeNil)
ctx.So(location, convey.ShouldNotBeNil)
})
})
}
func TestDaoauthorize(t *testing.T) {
var (
key = "key"
secret = "secret"
method = "put"
bucket = "tv-cover"
file = "file"
expire = int64(0)
)
convey.Convey("authorize", t, func(ctx convey.C) {
authorization := authorize(key, secret, method, bucket, file, expire)
ctx.Convey("Then authorization should not be nil.", func(ctx convey.C) {
ctx.So(authorization, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,163 @@
package dao
import (
"context"
"fmt"
"strconv"
"go-common/app/admin/main/tv/model"
"go-common/library/cache/memcache"
"go-common/library/log"
"github.com/jinzhu/gorm"
)
const (
_setUploader = "REPLACE INTO ugc_uploader (mid, state) VALUES (?,?)"
_auditMids = "UPDATE ugc_uploader SET valid = ? WHERE mid IN (?) AND deleted = 0"
_intervUp = "UPDATE ugc_uploader SET cms_face = ?, cms_name = ? WHERE mid = ? AND deleted = 0"
_stateNormal = 1
_deleted = 1
// up list oder type
_ctimeNew = 1
_ctimeOld = 2
_mtimeNew = 3
_mtimeOld = 4
size = 20
)
// UpAdd def.
func (d *Dao) UpAdd(mid int64) (err error) {
if err = d.DB.Exec(_setUploader, mid, _stateNormal).Error; err != nil {
log.Error("UpAdd Error %v", err)
}
return
}
// UpList def.
func (d *Dao) UpList(order int, page int, ids []int64) (ups []*model.Upper, pager *model.Page, err error) {
var db = d.DB.Where("deleted != ?", _deleted)
if len(ids) != 0 {
db = db.Where("mid IN (?)", ids)
}
pager = &model.Page{
Num: page,
Size: size,
}
if err = db.Model(&model.Upper{}).Count(&pager.Total).Error; err != nil {
log.Error("Uplist Count Error %v", err)
return
}
db = treatOrder(order, db)
if err = db.Offset((page - 1) * size).Limit(size).Find(&ups).Error; err != nil {
log.Error("UpList Error %v, Order: %d", err, order)
}
return
}
func treatOrder(order int, db *gorm.DB) *gorm.DB {
switch order {
case _ctimeNew:
db = db.Order("ctime DESC")
case _ctimeOld:
db = db.Order("ctime ASC")
case _mtimeNew:
db = db.Order("mtime DESC")
case _mtimeOld:
db = db.Order("mtime ASC")
default:
db = db.Order("ctime DESC")
}
return db
}
// UpCmsList def.
func (d *Dao) UpCmsList(req *model.ReqUpCms) (ups []*model.CmsUpper, pager *model.Page, err error) {
var db = d.DB.Where("deleted = 0")
if req.MID != 0 {
db = db.Where("mid = ?", req.MID)
}
if req.Name != "" {
db = db.Where("ori_name LIKE ?", "%"+req.Name+"%")
}
if req.Valid != "" {
valid, _ := strconv.Atoi(req.Valid)
db = db.Where("valid = ?", valid)
}
pager = &model.Page{
Num: req.Pn,
Size: size,
}
if err = db.Model(&model.Upper{}).Count(&pager.Total).Error; err != nil {
log.Error("Uplist Count Error %v", err)
return
}
db = treatOrder(req.Order, db)
if err = db.Offset((req.Pn - 1) * size).Limit(size).Find(&ups).Error; err != nil {
log.Error("UpList Error %v, Order: %d", err, req.Order)
}
return
}
// VerifyIds verifies whether all the mids exist
func (d *Dao) VerifyIds(mids []int64) (okMids map[int64]*model.UpMC, err error) {
if len(mids) == 0 {
return
}
okMids = make(map[int64]*model.UpMC)
var ups []*model.UpMC
db := d.DB.Where("deleted != ?", _deleted).Where("mid IN (?)", mids)
if err = db.Find(&ups).Error; err != nil {
log.Error("VerifyIds Error %v, Mids %v", err, mids)
}
for _, v := range ups {
okMids[v.MID] = v
}
return
}
// AuditIds carries out the action to the given mids
func (d *Dao) AuditIds(mids []int64, validAct int) (err error) {
if err = d.DB.Exec(_auditMids, validAct, mids).Error; err != nil {
log.Error("AuditIds Error %v, Mids %v", err, mids)
}
return
}
// SetUpper updates the cms info of an upper in DB
func (d *Dao) SetUpper(req *model.ReqUpEdit) (err error) {
if err = d.DB.Exec(_intervUp, req.Face, req.Name, req.MID).Error; err != nil {
log.Error("SetUpper Error %v, Mid %v", err, req)
}
return
}
func upperMetaKey(MID int64) string {
return fmt.Sprintf("up_cms_%d", MID)
}
// SetUpMetaCache updates upinfo in MC
func (d *Dao) SetUpMetaCache(c context.Context, upper *model.UpMC) (err error) {
var (
key = upperMetaKey(upper.MID)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: upper, Flags: memcache.FlagJSON, Expiration: d.cmsExpire}); err != nil {
log.Error("conn.Set error(%v)", err)
}
return
}
// DelCache deletes the cache from CM
func (d *Dao) DelCache(c context.Context, mid int64) (err error) {
var (
key = upperMetaKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
log.Error("conn.Set error(%v)", err)
}
return
}

View File

@@ -0,0 +1,82 @@
package dao
import (
"context"
"encoding/json"
"fmt"
"testing"
"go-common/app/admin/main/tv/model"
. "github.com/smartystreets/goconvey/convey"
)
func getMids(limit int) (res []int64, err error) {
var (
db = d.DB.Where("deleted = 0")
ups []*model.Upper
)
if err = db.Limit(limit).Find(&ups).Error; err != nil {
fmt.Println("pickMid err ", err)
}
for _, v := range ups {
res = append(res, v.MID)
}
return
}
func TestDao_UpList(t *testing.T) {
Convey("TestDao_UpList", t, WithDao(func(d *Dao) {
mids, errGet := getMids(5)
if errGet != nil {
fmt.Println("empty mids")
return
}
res, pager, err := d.UpList(1, 1, mids)
So(err, ShouldBeNil)
So(pager, ShouldNotBeNil)
So(len(res), ShouldBeGreaterThan, 0)
}))
}
func TestDao_VerifyIds(t *testing.T) {
Convey("TestDao_VerifyIds", t, WithDao(func(d *Dao) {
mids, errGet := getMids(25)
if errGet != nil {
fmt.Println("empty mids")
return
}
okMids, err := d.VerifyIds(mids)
So(err, ShouldBeNil)
So(len(mids), ShouldBeGreaterThanOrEqualTo, len(okMids))
data, _ := json.Marshal(okMids)
fmt.Println(string(data))
}))
}
func TestDao_AuditIds(t *testing.T) {
Convey("TestDao_AuditIds", t, WithDao(func(d *Dao) {
mids, errGet := getMids(15)
if errGet != nil {
fmt.Println("empty mids")
return
}
err := d.AuditIds(mids, 1)
So(err, ShouldBeNil)
}))
}
func TestDao_DelCache(t *testing.T) {
Convey("TestDao_DelCache", t, WithDao(func(d *Dao) {
var (
mid = int64(88895270)
ctx = context.Background()
)
err := d.SetUpMetaCache(ctx, &model.UpMC{
MID: mid,
})
So(err, ShouldBeNil)
err = d.DelCache(ctx, mid)
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,23 @@
package dao
import (
"context"
"go-common/app/admin/main/tv/model"
"go-common/library/log"
)
const (
_userTableName = "tv_user_info"
)
// GetByMId select user info by mid
func (d *Dao) GetByMId(c context.Context, mid int64) (userInfo *model.TvUserInfoResp, err error) {
userInfo = &model.TvUserInfoResp{}
if err = d.DB.Table(_userTableName).Where("mid = ?", mid).First(userInfo).Error; err != nil {
log.Error("GetByMId (%v) error(%v)", mid, err)
}
return
}

View File

@@ -0,0 +1,48 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/tv/model"
"go-common/library/log"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGetByMId(t *testing.T) {
d.saveUser()
convey.Convey("GetByMId", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(100000000)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
userInfo, err := d.GetByMId(c, mid)
ctx.Convey("Then err should be nil.userInfo should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(userInfo, convey.ShouldNotBeNil)
})
})
})
d.delUser()
}
func (d *Dao) saveUser() {
userInfo := &model.TvUserInfo{
MID: 100000000,
RecentPayTime: 1544613229,
}
if err := d.DB.Save(userInfo).Error; err != nil {
log.Error("SaveUser error(%v)", err)
}
}
func (d *Dao) delUser() {
userInfo := &model.TvUserInfo{
MID: 100000000,
}
if err := d.DB.Where("mid = ?", userInfo.MID).Delete(userInfo).Error; err != nil {
log.Error("DelUser error(%v)", err)
}
}

View File

@@ -0,0 +1,66 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"arc_audit.go",
"archive.go",
"audit_result.go",
"channel.go",
"content_repo.go",
"ep_content.go",
"http.go",
"intervs.go",
"label.go",
"mango.go",
"modules.go",
"order.go",
"panel.go",
"region.go",
"sear_inter.go",
"season_repo.go",
"upbfs.go",
"upper.go",
"user.go",
"version.go",
"version_update.go",
"video.go",
"watermark.go",
],
importpath = "go-common/app/admin/main/tv/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/tv/conf:go_default_library",
"//app/admin/main/tv/model:go_default_library",
"//app/admin/main/tv/service:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/http/blademaster/render:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,16 @@
package http
import (
bm "go-common/library/net/http/blademaster"
)
//add archive
func arcAdd(c *bm.Context) {
v := new(struct {
Aids []int64 `form:"aids,split" validate:"required,min=1,dive,gt=0"`
})
if err := c.Bind(v); err != nil {
return
}
c.JSON(tvSrv.AddArcs(v.Aids))
}

View File

@@ -0,0 +1,98 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
//arcOnline archive online
func arcOnline(c *bm.Context) {
arcAction(c, 1)
}
func arcHidden(c *bm.Context) {
arcAction(c, 2)
}
func arcAction(c *bm.Context, action int) {
var (
err error
res = map[string]interface{}{}
)
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
})
if err = c.Bind(param); err != nil {
return
}
if err := tvSrv.ArcAction(param.IDs, action); err != nil {
res["message"] = "更新数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON("成功", nil)
}
// archive list repository
func arcList(c *bm.Context) {
var (
res = make(map[string]interface{})
param = new(model.ArcListParam)
)
if err := c.Bind(param); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if pager, err := tvSrv.ArchiveList(c, param); err != nil {
res["message"] = "获取数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
} else {
c.JSON(pager, nil)
}
}
//arcCategory archive category
func arcCategory(c *bm.Context) {
c.JSON(tvSrv.GetTps(c, true))
}
// auditCategory gets audit consult used categorys
func auditCategory(c *bm.Context) {
c.JSON(tvSrv.GetTps(c, false))
}
//arcTypeRPC get archive type from rpc
func arcTypeRPC(c *bm.Context) {
c.JSON(tvSrv.ArcTypes, nil)
}
func arcUpdate(c *bm.Context) {
param := new(struct {
ID int64 `form:"id" validate:"required"`
Cover string `form:"cover" validate:"required"`
Content string `form:"content" validate:"required"`
Title string `form:"title" validate:"required"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.ArcUpdate(param.ID, param.Cover, param.Content, param.Title))
}
func unShelve(c *bm.Context) {
var (
username string
param = new(model.ReqUnshelve)
)
if err := c.Bind(param); err != nil {
return
}
if un, ok := c.Get("username"); ok {
username = un.(string)
} else {
c.JSON(nil, ecode.Unauthorized)
return
}
c.JSON(tvSrv.Unshelve(c, param, username))
}

View File

@@ -0,0 +1,70 @@
package http
import (
"fmt"
"net/url"
"go-common/app/admin/main/tv/model"
bm "go-common/library/net/http/blademaster"
)
func epResult(c *bm.Context) {
var (
req = c.Request.Form
err error
page int
order int
)
if page, order, err = paramFilter(req); err != nil {
c.JSON(nil, err)
return
}
c.JSON(tvSrv.EpResult(req, page, order))
}
func seasonResult(c *bm.Context) {
var (
req = c.Request.Form
err error
page int
order int
)
if page, order, err = paramFilter(req); err != nil {
c.JSON(nil, err)
return
}
c.JSON(tvSrv.SeasonResult(req, page, order))
}
// filter the params: page & order
func paramFilter(req url.Values) (page int, order int, err error) {
page = atoi(req.Get("page"))
order = atoi(req.Get("order"))
if page == 0 {
page = 1
}
if order == 0 {
order = 1
}
if order != 1 && order != 2 {
err = fmt.Errorf("Param Order %d is incorrect", order)
return
}
return
}
func arcResult(c *bm.Context) {
v := new(model.ReqArcCons)
if err := c.Bind(v); err != nil {
return
}
c.JSON(tvSrv.ArcResult(c, v))
}
func videoResult(c *bm.Context) {
v := new(model.ReqVideoCons)
if err := c.Bind(v); err != nil {
return
}
c.JSON(tvSrv.VideoResult(c, v))
}

View File

@@ -0,0 +1,148 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
func chlInfo(c *bm.Context) {
var (
req = c.Request.Form
vid = parseInt(req.Get("id"))
err error
)
exist := model.ChannelFmt{}
if err = tvSrv.DB.Where("id=?", vid).Where("deleted!=?", _isDeleted).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
exist.MtimeFormat = tvSrv.TimeFormat(exist.Mtime)
exist.Mtime = 0
c.JSON(exist, nil)
}
func chlList(c *bm.Context) {
param := new(model.ReqChannel)
if err := c.Bind(param); err != nil {
return
}
c.JSON(tvSrv.ChlSplash(c, param))
}
func chlEdit(c *bm.Context) {
var (
req = c.Request.PostForm
vid = parseInt(req.Get("id"))
allowed bool
err error
)
exist := model.Channel{}
if err = tvSrv.DB.Where("id=?", vid).Where("deleted!=?", _isDeleted).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
alert, simple := validateChl(c)
if alert != "" {
renderErrMsg(c, ecode.RequestErr.Code(), alert)
return
}
if allowed, _ = nameExist(simple.Title, int(vid)); !allowed {
renderErrMsg(c, ecode.RequestErr.Code(), "Title exists")
return
}
if err = tvSrv.DB.Model(&model.Channel{}).Where("id=?", vid).Update(simple).Error; err != nil {
log.Error("tvSrv.saveChannel error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func chlAdd(c *bm.Context) {
var (
err error
allowed bool
)
alert, simple := validateChl(c)
if alert != "" {
renderErrMsg(c, ecode.RequestErr.Code(), alert)
return
}
if allowed, _ = nameExist(simple.Title, 0); !allowed {
renderErrMsg(c, ecode.RequestErr.Code(), _errTitleExist)
return
}
if err = tvSrv.DB.Create(simple).Error; err != nil {
log.Error("tvSrv.addChannel error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func chlDel(c *bm.Context) {
var (
req = c.Request.PostForm
vid = parseInt(req.Get("id"))
err error
)
exist := model.Channel{}
if err = tvSrv.DB.Where("id=?", vid).Where("deleted!=?", _isDeleted).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
if err = tvSrv.DB.Model(&model.Channel{}).Where("id=?", vid).Update(map[string]int{"deleted": _isDeleted}).Error; err != nil {
log.Error("tvSrv.chlDel error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
// avoid two same names in DB - conflict
func nameExist(name string, myID int) (allowed bool, err error) {
var (
exist = model.Channel{}
db = tvSrv.DB.Where("title = ?", name).Where("deleted!=?", _isDeleted)
)
if myID != 0 {
db = db.Where("id != ?", myID)
}
if err = db.First(&exist).Error; err != nil {
if err != gorm.ErrRecordNotFound {
log.Error("tvSrv.nameExist error(%v)", err)
return
}
return true, nil
}
return false, nil
}
// validate Channel params
func validateChl(c *bm.Context) (alert string, simple *model.Channel) {
var (
req = c.Request.PostForm
title = req.Get("title")
desc = req.Get("desc")
splash = req.Get("splash")
)
if title == "" {
alert = "Channel Title can't be empty"
return
}
if splash == "" {
alert = "Splash can't be empty"
return
}
return "", &model.Channel{
Title: title,
Desc: desc,
Splash: splash,
}
}

View File

@@ -0,0 +1,206 @@
package http
import (
"strings"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
func contList(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*model.ContentRepo
count int64
order = atoi(req.Get("order"))
page = atoi(req.Get("page"))
size = 20
)
if page == 0 {
page = 1
}
db := contWhere(c)
db.Model(&model.ContentRepo{}).Count(&count)
if order == 1 {
db = db.Order("tv_content.mtime ASC")
} else {
db = db.Order("tv_content.mtime DESC")
}
if err = db.Model(&model.ContentRepo{}).Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
for _, v := range items {
v.MtimeFormat = tvSrv.TimeFormat(v.Mtime)
v.Mtime = 0
}
pager := &model.ContentRepoPager{
TotalCount: count,
Pn: page,
Ps: size,
Items: items,
}
c.JSON(pager, nil)
}
func contInfo(c *bm.Context) {
var (
req = c.Request.Form
epid = parseInt(req.Get("id"))
err error
)
exist := model.Content{}
if err = tvSrv.DB.Where("epid=?", epid).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
c.JSON(exist, nil)
}
func saveCont(c *bm.Context) {
var (
req = c.Request.PostForm
epid = atoi(req.Get("id"))
err error
)
exist := model.Content{}
if err = tvSrv.DB.Where("epid=?", epid).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
title := req.Get("title")
cover := req.Get("cover")
if cover == "" {
renderErrMsg(c, ecode.RequestErr.Code(), "封面不能为空")
return
}
if err := tvSrv.DB.Model(&model.Content{}).Where("epid = ?", epid).Update(map[string]string{"title": title, "cover": cover}).Error; err != nil {
log.Error("tvSrv.saveCont error(%v)", err)
c.JSON(nil, err)
return
}
if err := tvSrv.DB.Model(&model.TVEpContent{}).Where("id = ?", epid).Update(map[string]string{"long_title": title, "cover": cover}).Error; err != nil {
log.Error("tvSrv.saveCont error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func preview(c *bm.Context) {
var (
req = c.Request.Form
err error
epid = atoi(req.Get("id"))
)
exist := model.Content{}
if err = tvSrv.DB.Where("epid=?", epid).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
url, err := tvSrv.Playurl(exist.CID)
if err != nil {
log.Error("tvSrv.Playurl error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(url, nil)
}
func contOptions(id string, valid int) (ret bool) {
var (
epid = atoi(id)
exist = model.Content{}
)
ret = false
if err := tvSrv.DB.Where("epid=?", epid).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
log.Error("tvSrv.contOptions error(%v)", err)
return
}
if err := tvSrv.DB.Model(&model.Content{}).Where("epid=?", epid).Update(map[string]int{"valid": valid}).Error; err != nil {
log.Error("tvSrv.contOptions error(%v)", err)
return
}
return true
}
func contOnline(c *bm.Context) {
var (
req = c.Request.PostForm
ids = req.Get("ids")
)
idList := strings.Split(ids, ",")
if len(idList) == 0 {
renderErrMsg(c, ecode.RequestErr.Code(), _errIDNotFound)
return
}
for _, val := range idList {
if !contOptions(val, 1) {
renderErrMsg(c, ecode.RequestErr.Code(), "Online("+val+") fail")
return
}
}
c.JSON(nil, nil)
}
func contHidden(c *bm.Context) {
var (
req = c.Request.PostForm
ids = req.Get("ids")
)
idList := strings.Split(ids, ",")
if len(idList) == 0 {
renderErrMsg(c, ecode.RequestErr.Code(), _errIDNotFound)
return
}
for _, val := range idList {
if !contOptions(val, 0) {
renderErrMsg(c, ecode.RequestErr.Code(), "Hide ("+val+") fail")
return
}
}
c.JSON(nil, nil)
}
func contWhere(c *bm.Context) *gorm.DB {
var (
req = c.Request.Form
sid = atoi(req.Get("sid"))
cat = atoi(req.Get("category"))
epid = atoi(req.Get("epid"))
validStr = req.Get("valid")
)
db := tvSrv.DB.
Joins("LEFT OUTER JOIN tv_ep_season ON tv_content.season_id=tv_ep_season.id").
Select("tv_content.*, tv_ep_season.category, tv_ep_season.title AS season_title").
Where("tv_content.state=?", 3).
Where("tv_content.is_deleted=?", 0).
Where("tv_ep_season.check=?", 1).
Where("tv_ep_season.is_deleted=?", 0)
if sid != 0 {
db = db.Where("tv_content.season_id=?", sid)
}
if epid != 0 {
db = db.Where("tv_content.epid=?", epid)
}
if cat != 0 {
db = db.Where("tv_ep_season.category=?", cat)
}
if validStr == "" {
return db
}
if valid := atoi(validStr); valid == 0 {
db = db.Where("tv_content.valid=?", 0)
} else if valid == 1 {
db = db.Where("tv_content.valid=?", 1)
}
return db
}

View File

@@ -0,0 +1,143 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func createEP(c *bm.Context) {
var (
err error
epc = &model.TVEpContent{}
)
if err = c.Bind(epc); err != nil {
return
}
exist := model.Content{}
tvSrv.DB.Where("epid=?", epc.ID).First(&exist)
if exist.ID <= 0 { // data not exist, brand new data
if err = tvSrv.DB.Create(epc.ToContent(true)).Error; err != nil {
log.Error("tvSrv.createEP error(%v)", err)
c.JSON(nil, err)
return
}
if err = tvSrv.DB.Create(epc).Error; err != nil {
log.Error("tvSrv.createEP error(%v)", err)
c.JSON(nil, err)
return
}
} else {
// data exists, but was deleted
if exist.IsDeleted == 1 {
if err = tvSrv.EpDel(epc.ID, 0); err != nil {
c.JSON(nil, err)
return
}
}
// data exist, so we update
if err := tvSrv.DB.Model(&model.TVEpContent{}).Where("id=?", epc.ID).Update(epc).Error; err != nil {
log.Error("tvSrv.modifyEP error(%v)", err)
c.JSON(nil, err)
return
}
if err := tvSrv.DB.Model(&model.TVEpContent{}).Where("id=?", epc.ID).Update(map[string]string{"long_title": epc.LongTitle, "title": epc.Title, "cover": epc.Cover}).Error; err != nil {
log.Error("tvSrv.modifyEP error(%v)", err)
c.JSON(nil, err)
return
}
lic := epc.ToContent(false)
if err := tvSrv.DB.Model(&model.Content{}).Where("epid=?", epc.ID).Update(lic).Error; err != nil {
log.Error("tvSrv.modifyEP error(%v)", err)
c.JSON(nil, err)
return
}
if err := tvSrv.DB.Model(&model.Content{}).Where("epid=?", epc.ID).Update(map[string]string{"title": lic.Title, "subtitle": lic.Subtitle, "desc": lic.Desc, "cover": lic.Cover}).Error; err != nil {
log.Error("tvSrv.modifyEP error(%v)", err)
c.JSON(nil, err)
return
}
if err := tvSrv.EpCheck(&exist); err != nil { // manage ep's check status
c.JSON(nil, err)
return
}
}
renderErrMsg(c, 0, "0")
log.Info("createEP success(%v)", epc)
}
func removeEP(c *bm.Context) {
var (
req = c.Request.PostForm
err error
id = parseInt(req.Get("id"))
)
exist := model.Content{}
if err = tvSrv.DB.Where("epid=?", id).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
if err = tvSrv.EpDel(id, 1); err != nil {
c.JSON(nil, err)
return
}
if err = tvSrv.EpCheck(&exist); err != nil { // manage ep's check status
c.JSON(nil, err)
return
}
log.Info("removeEP success(%v)", exist)
renderErrMsg(c, 0, "0")
}
func createSeason(c *bm.Context) {
var (
err error
eps = &model.TVEpSeason{}
)
if err = c.Bind(eps); err != nil {
return
}
if err = tvSrv.SnUpdate(c, eps); err != nil {
c.JSON(nil, err)
return
}
renderErrMsg(c, 0, "0")
}
func removeSeason(c *bm.Context) {
var (
req = c.Request.PostForm
err error
id = parseInt(req.Get("id"))
)
exist := model.TVEpSeason{}
if err = tvSrv.DB.Where("id=?", id).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
renderErrMsg(c, ecode.RequestErr.Code(), "Data not exist")
return
}
if err = tvSrv.SeasonRemove(&exist); err != nil {
c.JSON(nil, err)
return
}
log.Info("removeSeason success(%v)", exist)
renderErrMsg(c, 0, "0")
}
func act(c *bm.Context, action int) {
param := new(struct {
CID int64 `form:"cid" validate:"required"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.EpAct(c, param.CID, action))
}
func online(c *bm.Context) {
act(c, 1)
}
func hidden(c *bm.Context) {
act(c, 0)
}

View File

@@ -0,0 +1,298 @@
package http
import (
"net/http"
"strconv"
"go-common/app/admin/main/tv/conf"
"go-common/app/admin/main/tv/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
"go-common/library/net/http/blademaster/middleware/verify"
"go-common/library/net/http/blademaster/render"
)
var (
tvSrv *service.Service
vfySvc *verify.Verify
authSvc *permit.Permit
)
const (
_errIDNotFound = "ids not found"
_errTitleExist = "Title exists already"
)
// Init init http sever instance.
func Init(c *conf.Config, s *service.Service) {
initService(c, s)
engine := bm.DefaultServer(c.HTTPServer)
innerRouter(engine)
// init internal server
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
// initService init service
func initService(c *conf.Config, s *service.Service) {
tvSrv = s
vfySvc = verify.New(nil)
authSvc = permit.New(c.Auth)
}
func parseInt(value string) int64 {
intval, err := strconv.ParseInt(value, 10, 64)
if err != nil {
intval = 0
}
return intval
}
func atoi(value string) (intval int) {
intval, err := strconv.Atoi(value)
if err != nil {
intval = 0
}
return intval
}
// innerRouter
func innerRouter(e *bm.Engine) {
// ping monitor
e.GET("/monitor/ping", ping)
// internal api
bg := e.Group("/x/admin/tv")
{
// cms content edit
cont := bg.Group("/cont", vfySvc.Verify)
{
cont.POST("/online", online)
cont.POST("/hidden", hidden)
}
// pgc ep inject
epIn := bg.Group("/ep", vfySvc.Verify)
{
epIn.POST("/create", createEP)
epIn.POST("/remove", removeEP)
}
// pgc season inject
snIn := bg.Group("/season", vfySvc.Verify)
{
snIn.POST("/create", createSeason)
snIn.POST("/remove", removeSeason)
}
// intervsRank edit
interv := bg.Group("/intervs", vfySvc.Verify)
{
rank := interv.Group("/rank")
{
rank.GET("/list", intervsRank)
rank.POST("/publish", rankPub)
}
module := interv.Group("/module")
{
module.GET("/list", intervsMod)
module.POST("/publish", modPub)
}
index := interv.Group("/index")
{
index.GET("/list", intervsIndex)
index.POST("/publish", indexPub)
}
}
// audit result
audit := bg.Group("/audit_result")
{
aud := audit.Group("")
{
aud.GET("/ep", epResult)
aud.GET("/season", seasonResult)
aud.GET("/archive", arcResult)
aud.GET("/video", videoResult)
aud.GET("/ugctypes", auditCategory)
audit.GET("/abnor_export", abnorExport)
audit.GET("/abnor_debug", abnorDebug)
}
audit.POST("/unshelve", authSvc.Permit("TV_MEDIA_DEL"), unShelve)
}
// content repository
crepo := bg.Group("/contrepo", vfySvc.Verify)
{
crepo.GET("/list", contList)
crepo.GET("/info", contInfo)
crepo.POST("/save", saveCont)
crepo.GET("/preview", preview)
crepo.POST("/online", contOnline)
crepo.POST("/hidden", contHidden)
crepo.POST("/upload", upbfs)
}
// season repo
srepo := bg.Group("/searepo", vfySvc.Verify)
{
srepo.GET("/list", seasonList)
srepo.GET("/info", seasonInfo)
srepo.POST("/save", saveSeason)
srepo.POST("/online", seasonOnline)
srepo.POST("/hidden", seasonHidden)
// ugc
crugc := srepo.Group("/ugc")
{
//archive
crugc.GET("/archive/lists", arcList)
crugc.GET("/archive/category", arcCategory)
crugc.POST("/archive/online", arcOnline)
crugc.POST("/archive/hidden", arcHidden)
crugc.GET("/archive/arcTypeRPC", arcTypeRPC)
crugc.POST("/archive/update", arcUpdate)
//video
crugc.GET("/video/lists", VideoList)
crugc.POST("/video/online", VideoOnline)
crugc.POST("/video/hidden", VideoHidden)
crugc.GET("/video/preview", VideoPreview)
crugc.POST("/video/update", videoUpdate)
}
}
// version mgt
ver := bg.Group("/version", vfySvc.Verify)
{
ver.GET("/list", versionList)
ver.GET("/info", versionInfo)
ver.POST("/save", saveVersion)
ver.POST("/add", addVersion)
ver.POST("/delete", versionDel)
}
// version update mgt
verup := bg.Group("/verupdate", vfySvc.Verify)
{
verup.GET("/list", verUpdateList)
verup.POST("/add", addVerUpdate)
verup.POST("/save", saveVerUpdate)
verup.POST("/enable", verUpdateEnable)
verup.GET("/full", fullPackageImport)
}
// channel mgt
chl := bg.Group("/channel", vfySvc.Verify)
{
chl.GET("/list", chlList)
chl.GET("/info", chlInfo)
chl.POST("/edit", chlEdit)
chl.POST("/add", chlAdd)
chl.POST("/delete", chlDel)
}
upper := bg.Group("/upper", authSvc.Permit("TV_AUDIT_MGT"))
{
upper.POST("/add", upAdd)
upper.POST("/import", upImport)
upper.POST("/del", upDel)
upper.GET("", upList)
}
upCMS := bg.Group("upcms", vfySvc.Verify)
{
upCMS.GET("/list", upcmsList)
upCMS.POST("/audit", upcmsAudit)
upCMS.POST("/edit", upcmsEdit)
}
//search intervene
si := bg.Group("/searchInter", vfySvc.Verify)
{
si.GET("/list", searInterList)
si.POST("/add", searInterAdd)
si.POST("/edit", searInterEdit)
si.POST("/delete", searInterDel)
si.POST("/rank", searInterRank)
si.POST("/publish", searInterPublish)
si.POST("/publishList", searInterPubList)
}
bg.POST("/archive/add", authSvc.Permit("TV_AUDIT_MGT"), arcAdd)
//modules manager
mod := bg.Group("/modules", vfySvc.Verify)
{
mod.POST("/add", modulesAdd)
mod.GET("/list", modulesList)
mod.GET("/editGet", modulesEditGet)
mod.POST("/editPost", modulesEditPost)
mod.POST("/publish", modulesPublish)
mod.GET("/sup_cat", supCat)
}
//watermark
wr := bg.Group("/watermark", authSvc.Permit("TV_AUDIT_MGT"))
{
wr.GET("/list", waterMarklist)
wr.POST("/add", waterMarkAdd)
wr.POST("/delete", waterMarkDelete)
}
mango := bg.Group("/mango", authSvc.Permit("TV_AUDIT_MGT"))
{
mango.GET("/list", mangoList)
mango.POST("/add", mangoAdd)
mango.POST("/edit", mangoEdit)
mango.POST("/delete", mangoDel)
mango.POST("/publish", mangoPub)
}
trans := bg.Group("/trans", authSvc.Permit("TV_AUDIT_MGT"))
{
trans.GET("/list", transList)
}
label := bg.Group("/label", vfySvc.Verify)
{
label.POST("/act", actLabels)
label.POST("/edit", editLabel)
label.POST("/publish", pubLabel)
ugcLabel := label.Group("/ugc")
{
ugcLabel.POST("/add_time", addTime)
ugcLabel.POST("/edit_time", editTime)
ugcLabel.POST("/del_time", delTmLabels)
ugcLabel.GET("/list", ugcLabels)
}
pgcLabel := label.Group("/pgc")
{
pgcLabel.GET("/list", pgcLabels)
pgcLabel.GET("/types", pgcLblTps)
}
}
// app manager
app := bg.Group("/app", vfySvc.Verify)
{
// region manager
reg := app.Group("/region")
{
reg.GET("/list", reglist)
reg.POST("/sort", regSort)
reg.POST("/save", saveReg)
reg.POST("/publish", upState)
}
}
// vip tv-vip
vip := bg.Group("/vip", authSvc.Permit("TV_VIP"))
{
// user info
vip.GET("/user/info", userInfo)
//order info
vip.GET("/order/list", orderList)
//panel info
panel := vip.Group("/panel")
{
panel.GET("/info", panelInfo)
panel.POST("/status", panelStatus)
panel.POST("/save", savePanel)
panel.GET("/list", panelList)
}
}
}
}
// ping check server ok.
func ping(c *bm.Context) {
}
func renderErrMsg(c *bm.Context, code int, msg string) {
data := map[string]interface{}{
"code": code,
"message": msg,
}
c.Render(http.StatusOK, render.MapJSON(data))
}

View File

@@ -0,0 +1,137 @@
package http
import (
"fmt"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
const (
_jsonErr = "Incorrect Json Format"
)
func intervsRank(c *bm.Context) {
var (
form = new(model.RankListReq)
request = new(model.IntervListReq)
)
if err := c.Bind(form); err != nil {
return
}
request.FromRank(form)
c.JSON(tvSrv.Intervs(request))
}
func intervsMod(c *bm.Context) {
var (
form = new(model.ModListReq)
request = new(model.IntervListReq)
)
if err := c.Bind(form); err != nil {
return
}
request.FromMod(form)
c.JSON(tvSrv.Intervs(request))
}
func intervsIndex(c *bm.Context) {
var (
form = new(model.IdxListReq)
request = new(model.IntervListReq)
)
if err := c.Bind(form); err != nil {
return
}
request.FromIndex(form)
c.JSON(tvSrv.Intervs(request))
}
func rankPub(c *bm.Context) {
var (
form = new(model.RankPubReq)
req = new(model.IntervPubReq)
)
if err := c.Bind(form); err != nil {
return
}
if err := req.FromRank(form); err != nil {
renderErrMsg(c, ecode.RequestErr.Code(), _jsonErr)
return
}
intervPublish(c, req)
}
func indexPub(c *bm.Context) {
var (
form = new(model.IdxPubReq)
req = new(model.IntervPubReq)
)
if err := c.Bind(form); err != nil {
return
}
if err := req.FromIndex(form); err != nil {
renderErrMsg(c, ecode.RequestErr.Code(), _jsonErr)
return
}
intervPublish(c, req)
}
func modPub(c *bm.Context) {
var (
form = new(model.ModPubReq)
req = new(model.IntervPubReq)
)
if err := c.Bind(form); err != nil {
return
}
if err := req.FromMod(form); err != nil {
renderErrMsg(c, ecode.RequestErr.Code(), _jsonErr)
return
}
intervPublish(c, req)
}
// combine the alert msg for too many interventions and cut the slice
func alertMsg(items []*model.SimpleRank, nbLimit int) (msg string, restItems []*model.SimpleRank) {
var (
length = len(items)
)
if length <= nbLimit {
return "", items
}
msg = "以下内容因超量未发布干预:"
for i := nbLimit; i < length; i++ {
if i+1 == length {
msg = msg + fmt.Sprintf("id%d", items[i].ContID)
continue
}
msg = msg + fmt.Sprintf("id%d,", items[i].ContID)
}
return msg, items[:nbLimit]
}
func intervPublish(c *bm.Context, req *model.IntervPubReq) {
var (
err error
invalid *model.RankError
alertInfo string // used when too many interventions published
)
alertInfo, req.Items = alertMsg(req.Items, tvSrv.IntervLimit) // too many intervention treatment
invalid, err = tvSrv.RefreshIntervs(req)
if err != nil {
log.Error("RefreshIntervs Error %v", err)
c.JSON(nil, err)
return
}
if invalid != nil {
renderErrMsg(c, ecode.RequestErr.Code(), fmt.Sprintf("发布失败以下内容状态错误id%d", invalid.SeasonID))
return
}
if alertInfo != "" {
renderErrMsg(c, ecode.OK.Code(), alertInfo)
return
}
renderErrMsg(c, ecode.OK.Code(), "发布成功")
}

View File

@@ -0,0 +1,95 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func addTime(c *bm.Context) {
tm := new(model.UgcTime)
if err := c.Bind(tm); err != nil {
return
}
c.JSON(nil, tvSrv.AddUgcTm(tm))
}
func editTime(c *bm.Context) {
tm := new(model.EditUgcTime)
if err := c.Bind(tm); err != nil {
return
}
c.JSON(nil, tvSrv.EditUgcTm(tm))
}
func actLabels(c *bm.Context) {
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
Action string `form:"action" validate:"required"` // 0 = hide, 1 = recover
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.ActLabels(param.IDs, atoi(param.Action)))
}
func delTmLabels(c *bm.Context) {
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.DelLabels(param.IDs))
}
func ugcLabels(c *bm.Context) {
req := new(model.ReqLabel)
if err := c.Bind(req); err != nil {
return
}
if req.Param != model.ParamUgctime && req.Param != model.ParamTypeid {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(tvSrv.PickLabels(req, model.UgcLabel))
}
func pgcLabels(c *bm.Context) {
req := new(model.ReqLabel)
if err := c.Bind(req); err != nil {
return
}
c.JSON(tvSrv.PickLabels(req, model.PgcLabel))
}
func pgcLblTps(c *bm.Context) {
param := new(struct {
Category int `form:"category" validate:"required,min=1,gt=0"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(tvSrv.LabelTp(param.Category))
}
func editLabel(c *bm.Context) {
param := new(struct {
ID int64 `form:"id" validate:"required"`
Name string `form:"name" validate:"required"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.EditLabel(param.ID, param.Name))
}
func pubLabel(c *bm.Context) {
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.PubLabel(param.IDs))
}

View File

@@ -0,0 +1,49 @@
package http
import (
"go-common/app/admin/main/tv/model"
bm "go-common/library/net/http/blademaster"
)
func mangoList(c *bm.Context) {
c.JSON(tvSrv.MangoList(c))
}
func mangoAdd(c *bm.Context) {
param := new(struct {
IDs []int64 `form:"rids,split" validate:"required,min=1,dive,gt=0"`
RType int `form:"rtype" validate:"required,min=1,max=2"` // 1=pgc, 2=ugc
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(tvSrv.MangoAdd(c, param.RType, param.IDs))
}
func mangoEdit(c *bm.Context) {
param := new(model.ReqMangoEdit)
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.MangoEdit(c, param))
}
func mangoDel(c *bm.Context) {
param := new(struct {
ID int64 `form:"id" validate:"required,min=1,gt=0"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.MangoDel(c, param.ID))
}
func mangoPub(c *bm.Context) {
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.MangoPub(c, param.IDs))
}

View File

@@ -0,0 +1,193 @@
package http
import (
"strconv"
"time"
"go-common/app/admin/main/tv/model"
"go-common/library/cache/memcache"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func modulesAdd(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
)
param := new(model.Modules)
if err = c.Bind(param); err != nil {
return
}
if err = modValid(param.ModCore); err != nil {
c.JSON(nil, err)
return
}
if err = tvSrv.ModulesAdd(param); err != nil {
res["message"] = "添加模块列表失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
pageID := strconv.Itoa(int(param.ID))
if err := tvSrv.SetPublish(c, pageID, model.ModulesPublishNo); err != nil {
res["message"] = "设置模块发布状态失败!"
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func modValid(core model.ModCore) (err error) {
var t int
if t, err = strconv.Atoi(core.Type); err != nil {
log.Error("atoi %s, Err %v", core.Type, err)
return
}
if t < 2 || t > 7 {
err = ecode.RequestErr
return
}
if sup := tvSrv.TypeSupport(core.SrcType, atoi(core.Source)); !sup {
err = ecode.RequestErr
}
return
}
func modulesEditPost(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
)
param := new(model.ModulesAddParam)
if err = c.Bind(param); err != nil {
return
}
if err = modValid(param.ModCore); err != nil {
c.JSON(nil, err)
return
}
v := &model.Modules{
PageID: param.PageID,
Flexible: param.Flexible,
Icon: param.Icon,
Title: param.Title,
Capacity: param.Capacity,
More: param.More,
Order: param.Order,
Moretype: param.Moretype,
Morepage: param.Morepage,
ModCore: param.ModCore,
}
if err = tvSrv.ModulesEditPost(param.ID, v); err != nil {
res["message"] = "编辑数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func modulesList(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
v []*model.Modules
p model.ModPub
)
param := new(struct {
PageID string `form:"page_id" validate:"required"`
})
if err = c.Bind(param); err != nil {
return
}
if v, err = tvSrv.ModulesList(param.PageID); err != nil {
res["message"] = "获取模块列表失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
if p, err = tvSrv.GetModPub(c, param.PageID); err != nil {
if err == memcache.ErrNotFound {
nowTime := time.Now()
t := nowTime.Format("2006-01-02 15:04:05")
p = model.ModPub{
Time: t,
State: 0,
}
} else {
res["message"] = "获取模块发布状态失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
}
m := &model.ModulesList{
Items: v,
PubState: p.State,
PubTime: p.Time,
}
c.JSON(m, nil)
}
func modulesEditGet(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
v = &model.Modules{}
)
param := new(struct {
ID uint64 `form:"id" validate:"required"`
})
if err = c.Bind(param); err != nil {
return
}
if v, err = tvSrv.ModulesEditGet(param.ID); err != nil {
res["message"] = "获取数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(v, nil)
}
func modulesPublish(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
tmp = &model.Param{}
tmpRes []*model.RegList
)
param := new(struct {
IDs []int `form:"ids,split" validate:"required,min=1,dive,gt=0"`
DeletedIDs []int `form:"deleted_ids,split" validate:"required,dive,gt=0"`
PageID string `form:"page_id" validate:"required"`
})
if err = c.Bind(param); err != nil {
return
}
if param.PageID != "0" {
tmp.PageID = param.PageID
if tmpRes, err = tvSrv.RegList(c, tmp); err != nil || len(tmpRes) != 1 {
log.Error("search region is publish count(%d) error(%v)", len(tmpRes), err)
c.JSON(nil, ecode.RequestErr)
return
}
if tmpRes[0].Valid == 0 {
log.Error("该分区region(%d)未上线 valid(%d)", param.PageID, tmpRes[0].Valid)
c.JSON(nil, ecode.RequestErr)
return
}
}
if err := tvSrv.ModulesPublish(c, param.PageID, model.ModulesPublishYes, param.IDs, param.DeletedIDs); err != nil {
res["message"] = "模块发布失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func supCat(c *bm.Context) {
if len(tvSrv.SupCats) > 0 {
c.JSON(tvSrv.SupCats, nil)
return
}
log.Error("SupCats empty")
c.JSON(nil, ecode.ServiceUnavailable)
}

View File

@@ -0,0 +1,23 @@
package http
import (
bm "go-common/library/net/http/blademaster"
)
func orderList(c *bm.Context) {
args := new(struct {
Mid int64 `form:"mid"`
OrderNo string `form:"order_no"`
Status int8 `form:"status"`
PaymentStime int64 `form:"payment_stime"`
PaymentEtime int64 `form:"payment_etime"`
PageNum int64 `form:"pn" default:"1"`
PageSize int64 `form:"ps" default:"20"`
})
if err := c.Bind(args); err != nil {
return
}
c.JSON(tvSrv.OrderList(args.Mid, args.PageNum, args.PageSize, args.PaymentStime, args.PaymentEtime, args.Status, args.OrderNo))
}

View File

@@ -0,0 +1,77 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func panelInfo(c *bm.Context) {
arg := new(struct {
ID int64 `form:"id" validate:"required"`
})
if err := c.Bind(arg); err != nil {
return
}
c.JSON(tvSrv.PanelInfo(arg.ID))
}
func panelStatus(c *bm.Context) {
args := new(struct {
ID int64 `form:"id" validate:"required"`
Status int64 `form:"status" default:"-1"`
})
if err := c.Bind(args); err != nil {
return
}
if args.Status == -1 {
renderErrMsg(c, ecode.RequestErr.Code(), "状态不能为空")
return
}
c.JSON(nil, tvSrv.PanelStatus(args.ID, args.Status))
}
func savePanel(c *bm.Context) {
panel := new(model.TvPriceConfig)
if err := c.Bind(panel); err != nil {
return
}
if panel.PID == 0 && panel.Price == 0 {
renderErrMsg(c, ecode.RequestErr.Code(), "价格不能为空")
return
}
if panel.PID == 0 && panel.Month == 0 {
renderErrMsg(c, ecode.RequestErr.Code(), "月份不能为空")
return
}
if panel.PID != 0 && panel.Stime >= panel.Etime {
renderErrMsg(c, ecode.RequestErr.Code(), "活动开始时间不能晚于结束时间")
return
}
c.JSON(nil, tvSrv.SavePanel(c, panel))
}
func panelList(c *bm.Context) {
args := new(struct {
Platform int64 `form:"platform"`
Month int64 `form:"month"`
SubType int64 `form:"sub_type" default:"-1"`
SuitType int64 `form:"suit_type" default:"-1"`
})
if err := c.Bind(args); err != nil {
return
}
c.JSON(tvSrv.PanelList(args.Platform, args.Month, args.SubType, args.SuitType))
}

View File

@@ -0,0 +1,72 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
const (
_stateup = "1"
_statedown = "0"
)
func reglist(c *bm.Context) {
var (
err error
v = &model.Param{}
)
if err = c.Bind(v); err != nil {
return
}
c.JSON(tvSrv.RegList(c, v))
}
func saveReg(c *bm.Context) {
var (
err error
v = new(struct {
IndexType string `form:"index_type"`
IndexTid string `form:"index_tid"`
Rank string `form:"rank"`
Title string `form:"title" validate:"required"`
PageId string `form:"page_id"`
})
)
if err = c.Bind(v); err != nil {
return
}
if v.PageId == "" {
c.JSON(nil, tvSrv.AddReg(c, v.Title, v.IndexType, v.IndexTid, v.Rank))
} else {
c.JSON(nil, tvSrv.EditReg(c, v.PageId, v.Title, v.IndexType, v.IndexTid))
}
}
func upState(c *bm.Context) {
var (
err error
v = new(struct {
Pids []int `form:"page_id,split" validate:"required,min=1,dive,gt=0"`
Valid string `form:"valid" validate:"required"`
})
)
if err = c.Bind(v); err != nil {
return
}
if !(v.Valid == _statedown || v.Valid == _stateup) {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(nil, tvSrv.UpState(c, v.Pids, v.Valid))
}
func regSort(c *bm.Context) {
param := new(struct {
IDs []int `form:"ids,split" validate:"required,min=1,dive,gt=0"`
})
if err := c.Bind(param); err != nil {
return
}
c.JSON(nil, tvSrv.RegSort(c, param.IDs))
}

View File

@@ -0,0 +1,338 @@
package http
import (
"go-common/library/cache/memcache"
"strings"
"time"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func searInterList(c *bm.Context) {
var (
req = c.Request.Form
items []*model.SearInter
total int
pn = atoi(req.Get("pn"))
ps = atoi(req.Get("ps"))
pubs *model.PublishStatus
err error
)
if pn == 0 {
pn = 1
}
if ps == 0 {
ps = 20
}
if items, total, err = tvSrv.GetSearInterList(c, pn, ps); err != nil {
log.Error("tvSrv.searInterList error(%v)", err)
c.JSON(nil, err)
return
}
//rank
for i := 0; i < len(items); i++ {
items[i].Rank = int64(i) + 1
}
if pubs, err = tvSrv.GetPublishState(c); err != nil {
if err == memcache.ErrNotFound {
nowTime := time.Now()
t := nowTime.Format("2006-01-02 15:04:05")
pubs = &model.PublishStatus{
Time: t,
State: 0,
}
} else {
log.Error("tvSrv.searInterList GetHotPubState error(%v)", err)
c.JSON("MC获取发布状态报错", ecode.RequestErr)
return
}
}
pager := &model.SearInterPager{
TotalCount: total,
Pn: pn,
Ps: ps,
Items: items,
PubState: pubs.State,
PubTime: pubs.Time,
}
c.JSON(pager, nil)
}
func searInterAdd(c *bm.Context) {
var (
req = c.Request.PostForm
searchword = req.Get("searchword")
err error
count int64
item model.SearInter
pubs *model.PublishStatus
)
if err = tvSrv.DB.Model(&model.SearInter{}).Where("deleted!=?", _isDeleted).Count(&count).Error; err != nil {
log.Error("tvSrv.searInterAdd err(%v)", err)
c.JSON(nil, err)
return
}
if count >= 20 {
c.JSON("热词数最多只能添加20条数据", ecode.RequestErr)
return
}
if searchword == "" {
c.JSON("searchword can not null", ecode.RequestErr)
return
}
exist := &model.SearInter{}
if err = tvSrv.DB.Where("searchword=?", searchword).Where("deleted!=?", _isDeleted).First(exist).Error; err != nil && err != ecode.NothingFound {
log.Error("tvSrv.searInterAdd error(%v)", err)
c.JSON("查找搜索词Mysql报错", ecode.RequestErr)
return
}
if exist.ID != 0 {
log.Error("searchword is existed, error(%v)", err)
c.JSON("搜索词已经存在", ecode.RequestErr)
return
}
if item, err = tvSrv.GetMaxRank(c); err != nil && err != ecode.NothingFound {
log.Error("tvSrv.searInterAdd GetMaxRank error(%v)", err)
c.JSON("查找最大的排序报错", ecode.RequestErr)
return
}
//default rank is last
rank := item.Rank + 1
searchInter := &model.SearInter{
Searchword: searchword,
Rank: rank,
}
if err = tvSrv.AddSearInter(c, searchInter); err != nil {
log.Error("tvSrv.searInterAdd error(%v)", err)
c.JSON("添加搜索词报错", ecode.RequestErr)
return
}
//get publish state
if pubs, err = tvSrv.GetPublishState(c); err != nil {
if err == memcache.ErrNotFound {
nowTime := time.Now()
t := nowTime.Format("2006-01-02 15:04:05")
pubs = &model.PublishStatus{
Time: t,
State: 0,
}
} else {
log.Error("tvSrv.searInterList GetHotPubState error(%v)", err)
c.JSON("MC获取发布状态报错", ecode.RequestErr)
return
}
}
//set publish state
s := &model.PublishStatus{
Time: pubs.Time,
State: 0,
}
if err = tvSrv.SetPublishState(c, s); err != nil {
log.Error("tvSrv.SetPubStat error(%v)", err)
c.JSON("设置发布状态到MC中报错", ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func searInterEdit(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
searchword = req.Get("searchword")
err error
pubs *model.PublishStatus
)
if req.Get("id") == "" {
c.JSON("id can no null", ecode.RequestErr)
return
}
if req.Get("searchword") == "" {
c.JSON("searchword can no null", ecode.RequestErr)
return
}
exist := &model.SearInter{}
if err = tvSrv.DB.Where("id=?", id).Where("deleted!=?", _isDeleted).First(exist).Error; err != nil {
log.Error("tvSrv.searInterEdit error(%v)", err)
c.JSON("can not find value", err)
return
}
exist = &model.SearInter{}
if err = tvSrv.DB.Where("searchword=?", searchword).Where("deleted!=?", _isDeleted).First(exist).Error; err != nil && err != ecode.NothingFound {
log.Error("tvSrv.searInterEdit error(%v)", err)
c.JSON(err, ecode.RequestErr)
return
}
if exist.ID != 0 && exist.ID != id {
c.JSON("searchword existed", nil)
return
}
if err = tvSrv.UpdateSearInter(c, id, searchword); err != nil {
log.Error("tvSrv.searInterEdit err(%v)", err)
c.JSON(nil, err)
return
}
//get publish state
if pubs, err = tvSrv.GetPublishState(c); err != nil {
log.Error("tvSrv.searInterEdit GetHotPubState error(%v)", err)
c.JSON(nil, err)
return
}
//set publish state
s := &model.PublishStatus{
Time: pubs.Time,
State: 0,
}
if err = tvSrv.SetPublishState(c, s); err != nil {
log.Error("tvSrv.searInterEdit SetPubStat error(%v)", err)
c.JSON(err, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func searInterDel(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
pubs *model.PublishStatus
)
if req.Get("id") == "" {
c.JSON("id can not null", err)
return
}
exist := &model.SearInter{}
if err = tvSrv.DB.Where("id=?", id).Where("deleted!=?", _isDeleted).First(exist).Error; err != nil {
c.JSON("can not find value", err)
return
}
if err = tvSrv.DelSearInter(c, id); err != nil {
log.Error("tvSrv.searInterDel err(%v)", err)
c.JSON(nil, err)
return
}
//get publish state
if pubs, err = tvSrv.GetPublishState(c); err != nil {
log.Error("tvSrv.searInterDel GetHotPubState error(%v)", err)
c.JSON(nil, err)
return
}
//set publish state
s := &model.PublishStatus{
Time: pubs.Time,
State: 0,
}
if err = tvSrv.SetPublishState(c, s); err != nil {
log.Error("tvSrv.searInterDel error(%v)", err)
c.JSON(err, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func searInterRank(c *bm.Context) {
var (
req = c.Request.PostForm
ids = req.Get("ids")
err error
pubs *model.PublishStatus
total int
)
if ids == "" {
c.JSON("不能发布空数据", ecode.RequestErr)
return
}
idsArr := strings.Split(ids, ",")
if len(idsArr) <= 0 {
c.JSON("不能发布空数据", ecode.RequestErr)
return
}
if total, err = tvSrv.GetSearInterCount(c); err != nil {
log.Error("tvSrv.GetSearInterCount err ", err)
c.JSON("更新排序失败,GetSearInterCount error ", err)
return
}
if len((idsArr)) != total {
c.JSON("请提交全部数据", ecode.RequestErr)
return
}
if err = tvSrv.RankSearInter(c, idsArr); err != nil {
log.Error("tvSrv.searInterRank err(%v),idsArr(%v)", err, idsArr)
c.JSON("更新排序失败, RankSearIntererror error ", err)
return
}
//get publish state
if pubs, err = tvSrv.GetPublishState(c); err != nil {
log.Error("tvSrv.searInterDel GetHotPubState error(%v)", err)
c.JSON(nil, err)
return
}
//set publish state
s := &model.PublishStatus{
Time: pubs.Time,
State: 0,
}
if err = tvSrv.SetPublishState(c, s); err != nil {
log.Error("tvSrv.searInterDel error(%v)", err)
c.JSON(err, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func searInterPublish(c *bm.Context) {
var (
items []*model.SearInter
err error
)
if items, err = tvSrv.GetSearInterPublish(c); err != nil {
log.Error("tvSrv.searInterPublish GetSearInterPublish error(%v)", err)
c.JSON(nil, ecode.RequestErr)
return
}
if len(items) == 0 {
c.JSON("不能发布空数据", ecode.RequestErr)
return
}
var rank []*model.OutSearchInter
for _, v := range items {
out := &model.OutSearchInter{
Keyword: v.Searchword,
Status: v.Tag,
}
rank = append(rank, out)
}
if err = tvSrv.SetSearInterRank(c, rank); err != nil {
log.Error("tvSrv.searInterPublish SearInterRank error(%v)", err)
c.JSON(nil, err)
return
}
t := time.Now().Format("2006-01-02 15:04:05")
s := &model.PublishStatus{
Time: t,
State: 1,
}
if err = tvSrv.SetPublishState(c, s); err != nil {
log.Error("tvSrv.searInterPublish SetPubStat error(%v)", err)
c.JSON(err, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func searInterPubList(c *bm.Context) {
var (
items []*model.OutSearchInter
err error
)
if items, err = tvSrv.GetSearInterRank(c); err != nil {
log.Error("tvSrv.searInterListOut error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(items, nil)
}

View File

@@ -0,0 +1,191 @@
package http
import (
"strings"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
func seasonList(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*model.SeaRepoDB
count int64
order = atoi(req.Get("order"))
page = atoi(req.Get("page"))
size = 20
)
if page == 0 {
page = 1
}
db := seasonWhere(c)
db.Model(&model.SeaRepoDB{}).Count(&count)
if order == 1 {
db = db.Order("mtime ASC")
} else {
db = db.Order("mtime DESC")
}
if err = db.Model(&model.SeaRepoDB{}).Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
pager := &model.SeasonRepoPager{
TotalCount: count,
Pn: page,
Ps: size,
}
for _, v := range items {
pager.Items = append(pager.Items, v.ToList())
}
c.JSON(pager, nil)
}
func seasonInfo(c *bm.Context) {
var (
req = c.Request.Form
sid = parseInt(req.Get("id"))
err error
)
exist := model.TVEpSeason{}
if err = tvSrv.DB.Where("id=?", sid).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
c.JSON(exist, nil)
}
func saveSeason(c *bm.Context) {
var (
req = c.Request.PostForm
sid = parseInt(req.Get("id"))
err error
)
exist := model.TVEpSeason{}
if err = tvSrv.DB.Where("id=?", sid).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
title := req.Get("title")
desc := req.Get("desc")
staff := req.Get("staff")
cover := req.Get("cover")
if title == "" {
renderErrMsg(c, ecode.RequestErr.Code(), "标题不能为空")
return
}
if desc == "" {
renderErrMsg(c, ecode.RequestErr.Code(), "简介不能为空")
return
}
if staff == "" {
renderErrMsg(c, ecode.RequestErr.Code(), "staff不能为空")
return
}
if cover == "" {
renderErrMsg(c, ecode.RequestErr.Code(), "封面不能为空")
return
}
if err := tvSrv.DB.Model(&model.TVEpSeason{}).Where("id = ?", sid).Update(map[string]string{"title": title, "desc": desc, "staff": staff, "cover": cover}).Error; err != nil {
log.Error("tvSrv.saveSeason error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func seasonOptions(id string, valid int) (ret bool) {
var (
sid = parseInt(id)
exist = model.TVEpSeason{}
)
ret = false
if err := tvSrv.DB.Where("id=?", sid).Where("is_deleted=?", 0).First(&exist).Error; err != nil {
log.Error("tvSrv.seasonOptions error(%v)", err)
return
}
if err := tvSrv.DB.Model(&model.TVEpSeason{}).Where("id=?", sid).Update(map[string]int{"valid": valid}).Error; err != nil {
log.Error("tvSrv.seasonOptions error(%v)", err)
return
}
return true
}
func seasonOnline(c *bm.Context) {
var (
req = c.Request.PostForm
ids = req.Get("ids")
)
idList := strings.Split(ids, ",")
if len(idList) == 0 {
renderErrMsg(c, ecode.RequestErr.Code(), _errIDNotFound)
return
}
for _, val := range idList {
if !seasonOptions(val, 1) {
renderErrMsg(c, ecode.RequestErr.Code(), "Online("+val+") fail")
return
}
}
c.JSON(nil, nil)
}
func seasonHidden(c *bm.Context) {
var (
req = c.Request.PostForm
ids = req.Get("ids")
)
idList := strings.Split(ids, ",")
if len(idList) == 0 {
renderErrMsg(c, ecode.RequestErr.Code(), _errIDNotFound)
return
}
for _, val := range idList {
if !seasonOptions(val, 0) {
renderErrMsg(c, ecode.RequestErr.Code(), "Hidden("+val+") fail")
return
}
}
c.JSON(nil, nil)
}
func seasonWhere(c *bm.Context) *gorm.DB {
var (
req = c.Request.Form
sid = atoi(req.Get("sid"))
cat = atoi(req.Get("category"))
validStr = req.Get("valid")
title = req.Get("title")
)
db := tvSrv.DB.Select("*").
Where("`check`=?", 1).
Where("is_deleted=?", 0)
if title != "" {
db = db.Where("title LIKE ?", "%"+title+"%")
}
if sid != 0 {
db = db.Where("id=?", sid)
}
if cat != 0 {
db = db.Where("category=?", cat)
}
if validStr == "" {
return db
}
if valid := atoi(validStr); valid == 0 {
db = db.Where("valid=?", 0)
} else if valid == 1 {
db = db.Where("valid=?", 1)
}
return db
}

View File

@@ -0,0 +1,45 @@
package http
import (
"io/ioutil"
"net/http"
"time"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
const maxSize = 1024 * 1024 * 20
func upbfs(c *bm.Context) {
var req = c.Request
// read the file
req.ParseMultipartForm(maxSize)
log.Info("Request Info: %v, %v, %v", req.PostForm, req.Form, req.MultipartForm)
file, _, err := req.FormFile("file")
if err != nil {
renderErrMsg(c, ecode.RequestErr.Code(), "文件为空")
return
}
defer file.Close()
content, err := ioutil.ReadAll(file)
if err != nil {
log.Error("resource uploadFile.ReadAll error(%v)", err)
return
}
// parse file, get type, size
ftype := http.DetectContentType(content)
if ftype != "image/jpeg" && ftype != "image/png" && ftype != "image/webp" && ftype != "image/gif" {
log.Error("filetype not allow file type(%s)", ftype)
renderErrMsg(c, ecode.RequestErr.Code(), "检查文件类型,需为图片")
return
}
fsize := len(content)
if fsize > maxSize {
renderErrMsg(c, ecode.RequestErr.Code(), "文件过大不支持超过20M的文件")
return
}
// upload file to BFS
c.JSON(tvSrv.Upload(c, "", ftype, time.Now().Unix(), content))
}

View File

@@ -0,0 +1,88 @@
package http
import (
"go-common/app/admin/main/tv/model"
bm "go-common/library/net/http/blademaster"
)
func upAdd(c *bm.Context) {
var (
err error
)
v := new(struct {
MIDs []int64 `form:"mids,split" validate:"required,min=1,dive,gt=0"`
})
if err = c.Bind(v); err != nil {
return
}
c.JSON(tvSrv.AddMids(v.MIDs))
}
func upImport(c *bm.Context) {
var (
err error
)
v := new(struct {
MIDs []int64 `form:"mids,split" validate:"required,min=1,dive,gt=0"`
})
if err = c.Bind(v); err != nil {
return
}
c.JSON(tvSrv.ImportMids(v.MIDs))
}
func upDel(c *bm.Context) {
var (
err error
)
v := new(struct {
MID int64 `form:"mid" validate:"required,min=1"`
})
if err = c.Bind(v); err != nil {
return
}
c.JSON(nil, tvSrv.DelMid(v.MID))
}
func upList(c *bm.Context) {
v := new(struct {
Order int `form:"order" validate:"required,min=1,max=4"`
Pn int `form:"pn"`
Name string `form:"name"`
ID int `form:"id"`
})
if err := c.Bind(v); err != nil {
return
}
if v.Pn == 0 {
v.Pn = 1
}
c.JSON(tvSrv.UpList(v.Order, v.Pn, v.Name, v.ID))
}
func upcmsList(c *bm.Context) {
v := new(model.ReqUpCms)
if err := c.Bind(v); err != nil {
return
}
c.JSON(tvSrv.CmsList(c, v))
}
func upcmsAudit(c *bm.Context) {
v := new(struct {
Action string `form:"action"`
MIDs []int64 `form:"mids,split" validate:"required,min=1,dive,gt=0"`
})
if err := c.Bind(v); err != nil {
return
}
c.JSON(tvSrv.CmsAudit(c, v.MIDs, v.Action))
}
func upcmsEdit(c *bm.Context) {
v := new(model.ReqUpEdit)
if err := c.Bind(v); err != nil {
return
}
c.JSON(nil, tvSrv.CmsEdit(c, v))
}

View File

@@ -0,0 +1,16 @@
package http
import (
bm "go-common/library/net/http/blademaster"
)
func userInfo(c *bm.Context) {
arg := new(struct {
MID int64 `form:"mid" validate:"required"`
})
if err := c.Bind(arg); err != nil {
return
}
c.JSON(tvSrv.UserInfo(c, arg.MID))
}

View File

@@ -0,0 +1,161 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/time"
)
const (
_platform = 12
_isDeleted = 1
)
func versionList(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*model.Version
count int64
ver = req.Get("ver")
page = atoi(req.Get("page"))
size = 20
)
if page == 0 {
page = 1
}
db := tvSrv.DBShow.Where("plat=?", _platform).Where("state!=?", _isDeleted)
if ver != "" {
db = db.Where("version=?", ver)
}
db.Model(&model.Version{}).Count(&count)
if err = db.Model(&model.Version{}).Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
pager := &model.VersionPager{
TotalCount: count,
Pn: page,
Ps: size,
Items: items,
}
c.JSON(pager, nil)
}
func versionInfo(c *bm.Context) {
var (
req = c.Request.Form
vid = parseInt(req.Get("id"))
err error
)
exist := model.Version{}
if err = tvSrv.DBShow.Where("id=?", vid).Where("state!=?", _isDeleted).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
c.JSON(exist, nil)
}
func saveVersion(c *bm.Context) {
var (
req = c.Request.PostForm
vid = parseInt(req.Get("id"))
err error
)
exist := model.Version{}
if err = tvSrv.DBShow.Where("id=?", vid).Where("state!=?", _isDeleted).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
alert, simple := validateVerPostData(c)
if alert != "" {
renderErrMsg(c, ecode.RequestErr.Code(), alert)
return
}
if err := tvSrv.DBShow.Model(&model.Version{}).Where("id=?", vid).Update(simple).Error; err != nil {
log.Error("tvSrv.saveVersion error(%v)", err)
c.JSON(nil, err)
return
}
if err := tvSrv.DBShow.Model(&model.Version{}).Where("id=?", vid).Update(map[string]int8{"state": simple.State}).Error; err != nil {
log.Error("tvSrv.saveVersion error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func addVersion(c *bm.Context) {
var (
err error
)
alert, simple := validateVerPostData(c)
if alert != "" {
renderErrMsg(c, ecode.RequestErr.Code(), alert)
return
}
if err = tvSrv.DBShow.Create(simple).Error; err != nil {
log.Error("tvSrv.addVersion error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func versionDel(c *bm.Context) {
var (
req = c.Request.PostForm
vid = parseInt(req.Get("id"))
err error
)
exist := model.Version{}
if err = tvSrv.DBShow.Where("id=?", vid).Where("state!=?", _isDeleted).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
if err := tvSrv.DBShow.Model(&model.Version{}).Where("id=?", vid).Update(map[string]int{"state": _isDeleted}).Error; err != nil {
log.Error("tvSrv.versionDel error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func validateVerPostData(c *bm.Context) (alert string, simple *model.Version) {
var (
req = c.Request.PostForm
plat = atoi(req.Get("plat"))
version = req.Get("version")
build = atoi(req.Get("build"))
ptime = time.Time(parseInt(req.Get("ptime")))
state = atoi(req.Get("state"))
desc = req.Get("description")
)
if plat == 0 {
alert = "平台不能为空"
return
}
if version == "" {
alert = "版本号不能为空"
return
}
if build == 0 {
alert = "build号不能为空"
return
}
if int64(ptime) == 0 {
alert = "发布时间不能为空"
return
}
if desc == "" {
alert = "描述不能为空"
return
}
return "", &model.Version{Plat: int8(plat), Description: desc, Version: version, Build: build, State: int8(state), Ptime: ptime}
}

View File

@@ -0,0 +1,275 @@
package http
import (
"fmt"
"net/url"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
const (
_isVerDeleted = 2
)
func verUpdateList(c *bm.Context) {
var (
req = c.Request.Form
err error
items []*model.VersionUpdate
limit []*model.VersionUpdateLimit
rets []*model.VersionUpdateDetail
count int64
vid = atoi(req.Get("vid"))
page = atoi(req.Get("page"))
size = 20
)
if page == 0 {
page = 1
}
db := tvSrv.DBShow.Where("vid=?", vid).Where("state!=?", _isVerDeleted)
db.Model(&model.VersionUpdate{}).Count(&count)
if err = db.Model(&model.VersionUpdate{}).Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
for _, val := range items {
if err = tvSrv.DBShow.Model(&model.VersionUpdateLimit{}).Where("up_id=?", val.ID).Find(&limit).Error; err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
rets = append(rets, &model.VersionUpdateDetail{VersionUpdate: val, VerLimit: limit})
}
version := model.Version{}
if err = tvSrv.DBShow.Where("id=?", vid).Where("state!=?", _isDeleted).First(&version).Error; err != nil {
log.Error("version info not exists-(%v)\n", err)
c.JSON(nil, err)
return
}
lists := map[string]interface{}{
"verUpdate": rets,
"version": version,
}
pager := &model.VersionUpdatePager{
TotalCount: count,
Pn: page,
Ps: size,
Items: lists,
}
c.JSON(pager, nil)
}
func saveVerUpdate(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
err error
)
exist := model.VersionUpdate{}
if err = tvSrv.DBShow.Where("id=?", id).Where("state!=?", _isVerDeleted).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
alert, simple := validateVerUpdatePostData(c)
if alert != "" {
renderErrMsg(c, ecode.RequestErr.Code(), alert)
return
}
if err = tvSrv.DBShow.Model(&model.VersionUpdate{}).Where("id = ?", id).Update(simple).Error; err != nil {
log.Error("tvSrv.saveVerUpdate error(%v)", err)
c.JSON(nil, err)
return
}
if err = tvSrv.DBShow.Model(&model.VersionUpdate{}).Where("id = ?", id).Update(map[string]int8{"is_push": simple.IsPush, "is_force": simple.IsForce}).Error; err != nil {
log.Error("tvSrv.saveVerUpdate error(%v)", err)
c.JSON(nil, err)
return
}
if err = tvSrv.DBShow.Model(&model.VersionUpdateLimit{}).Where("up_id=?", id).Delete(&model.VersionUpdateLimit{}).Error; err != nil {
log.Error("tvSrv.DeleteVerUpdateLimit error(%v)\n", err)
return
}
log.Info("saveVerUpdate exist.ID = %d", exist.ID)
if exist.ID > 0 {
addVerUpdateLimit(req, exist.ID)
}
c.JSON(nil, nil)
}
func addVerUpdate(c *bm.Context) {
var (
req = c.Request.PostForm
err error
)
alert, simple := validateVerUpdatePostData(c)
if alert != "" {
renderErrMsg(c, ecode.RequestErr.Code(), alert)
return
}
db := tvSrv.DBShow.Create(simple)
if err = db.Error; err != nil {
log.Error("tvSrv.addVerUpdate error(%v)", err)
c.JSON(nil, err)
return
}
insertID := (db.Value.(*model.VersionUpdate)).ID
if insertID > 0 {
addVerUpdateLimit(req, insertID)
}
c.JSON(nil, nil)
}
func addVerUpdateLimit(req url.Values, upid int64) (err error) {
var (
condi = req["condi[]"]
value = req["value[]"]
)
if len(condi) > 0 {
for key, val := range condi {
li := &model.VersionUpdateLimit{UPID: int32(upid)}
if key < len(condi) {
li.Condi = val
}
if key < len(value) {
li.Value = atoi(value[key])
}
if err = tvSrv.DBShow.Create(li).Error; err != nil {
log.Error("tvSrv.addVerUpdateLimit error(%v)", err)
break
}
}
}
return
}
func verUpdateEnable(c *bm.Context) {
var (
req = c.Request.PostForm
id = parseInt(req.Get("id"))
state = atoi(req.Get("state"))
err error
)
exist := model.VersionUpdate{}
if err = tvSrv.DBShow.Where("id=?", id).Where("state!=?", _isVerDeleted).First(&exist).Error; err != nil {
c.JSON(nil, err)
return
}
if err := tvSrv.DBShow.Model(&model.VersionUpdate{}).Where("id = ?", id).Update(map[string]int{"state": state}).Error; err != nil {
log.Error("tvSrv.verUpdateEnable error(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
}
func fullPackageImport(c *bm.Context) {
var (
req = c.Request.Form
vid = atoi(req.Get("vid"))
build = atoi(req.Get("build"))
err error
)
result, err := tvSrv.FullImport(c, build)
if err != nil {
log.Error("%v\n", err)
c.JSON(nil, err)
return
}
for _, val := range result {
if !createApk2Version(val, vid) {
renderErrMsg(c, ecode.RequestErr.Code(), fmt.Sprintf("fullPackageImport fail(%v)", val))
return
}
}
c.JSON(nil, nil)
}
func createApk2Version(val *model.APKInfo, vid int) (b bool) {
var (
err error
simple *model.VersionUpdate
limit *model.VersionUpdateLimit
)
b = false
simple = new(model.VersionUpdate)
simple.VID = vid
simple.PolicyName = "指定版本导入更新"
simple.IsForce = 0
simple.IsPush = 0
simple.Channel = "bili"
simple.URL = val.CDNAddr
simple.Size = val.Size
simple.Md5 = val.SignMd5
simple.Sdkint = 0
simple.Model = ""
simple.Policy = 0
simple.Coverage = 100
db := tvSrv.DBShow.Create(simple)
if err = db.Error; err != nil {
log.Error("tvSrv.createApk2Version error(%v)", err)
return
}
insertID := (db.Value.(*model.VersionUpdate)).ID
limit = &model.VersionUpdateLimit{UPID: int32(insertID), Condi: "", Value: 0}
if err = tvSrv.DBShow.Create(limit).Error; err != nil {
log.Error("tvSrv.createAPK2Version error(%v)", err)
return
}
return true
}
func validateVerUpdatePostData(c *bm.Context) (alert string, simple *model.VersionUpdate) {
var (
req = c.Request.PostForm
vid = atoi(req.Get("vid"))
isForce = atoi(req.Get("is_force"))
isPush = atoi(req.Get("is_push"))
channel = req.Get("channel")
url = req.Get("url")
size = atoi(req.Get("size"))
md5 = req.Get("md5")
sdkint = atoi(req.Get("sdkint"))
mod = req.Get("model")
policy = atoi(req.Get("policy"))
coverage = atoi(req.Get("coverage"))
policyName = req.Get("policy_name")
)
alert = string("")
simple = new(model.VersionUpdate)
simple.VID = vid
simple.PolicyName = policyName
simple.IsForce = int8(isForce)
simple.IsPush = int8(isPush)
simple.Channel = channel
simple.URL = url
simple.Size = size
simple.Md5 = md5
simple.Sdkint = sdkint
simple.Model = mod
simple.Policy = int8(policy)
simple.Coverage = int32(coverage)
if simple.Channel == "" {
alert = "渠道不能为空"
return
}
if simple.URL == "" {
alert = "安装包地址不能为空"
return
}
if simple.Size == 0 {
alert = "文件大小不能为0"
return
}
if simple.Md5 == "" {
alert = "文件hash值不能为空"
return
}
return
}

View File

@@ -0,0 +1,120 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
// VideoList get ugc video list
func VideoList(c *bm.Context) {
var (
res = map[string]interface{}{}
err error
pager *model.VideoListPager
)
param := new(model.VideoListParam)
if err = c.Bind(param); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if pager, err = tvSrv.VideoList(c, param); err != nil {
res["message"] = "获取数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(pager, nil)
}
// VideoOnline online ugc video
func VideoOnline(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
)
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
})
if err = c.Bind(param); err != nil {
return
}
if err := tvSrv.VideoOnline(param.IDs); err != nil {
res["message"] = "更新数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON("成功", nil)
}
// VideoHidden hidden ugc video
func VideoHidden(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
)
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
})
if err = c.Bind(param); err != nil {
return
}
if err := tvSrv.VideoHidden(param.IDs); err != nil {
res["message"] = "更新数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON("成功", nil)
}
// VideoPreview ugc video preview
func VideoPreview(c *bm.Context) {
var (
playurl string
err error
res = map[string]interface{}{}
)
param := new(struct {
ID int `form:"id" validate:"required"`
})
if err = c.Bind(param); err != nil {
return
}
if playurl, err = tvSrv.UPlayurl(param.ID); err != nil {
res["message"] = "获取playurl失败" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(playurl, nil)
}
// videoUpdate ugc video update
func videoUpdate(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
)
param := new(struct {
ID int `form:"id" validate:"required"`
Title string `form:"title" validate:"required"`
})
if err = c.Bind(param); err != nil {
return
}
if err = tvSrv.VideoUpdate(param.ID, param.Title); err != nil {
res["message"] = "更新失败" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func abnorExport(c *bm.Context) {
buf, fileName := tvSrv.AbnormExport()
c.Writer.Header().Set("Content-Type", "application/csv")
c.Writer.Header().Set("Content-Disposition", fileName)
c.Writer.Write(buf.Bytes())
}
func abnorDebug(c *bm.Context) {
c.JSON(tvSrv.AbnDebug(), nil)
}

View File

@@ -0,0 +1,87 @@
package http
import (
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func waterMarklist(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
pagers *model.WaterMarkListPager
)
param := new(model.WaterMarkListParam)
if err = c.Bind(param); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if pagers, err = tvSrv.WaterMarkist(c, param); err != nil {
res["message"] = "获取数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(pagers, nil)
}
func waterMarkAdd(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
addRes *model.AddEpIDResp
)
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
Type string `form:"type" validate:"required"`
})
if err = c.Bind(param); err != nil {
return
}
if param.Type == "seasonid" {
if addRes, err = tvSrv.AddSeasonID(c, param.IDs); err != nil {
res["message"] = "添加数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
} else if param.Type == "epid" {
if addRes, err = tvSrv.AddEpID(c, param.IDs); err != nil {
res["message"] = "添加数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
}
c.JSON(addRes, nil)
}
func waterMarkDelete(c *bm.Context) {
var (
err error
res = map[string]interface{}{}
)
param := new(struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
})
if err = c.Bind(param); err != nil {
return
}
if err = tvSrv.DeleteWatermark(param.IDs); err != nil {
res["message"] = "删除数据失败!" + err.Error()
c.JSONMap(res, ecode.RequestErr)
return
}
c.JSON(nil, nil)
}
func transList(c *bm.Context) {
var param = new(model.TransReq)
if err := c.Bind(param); err != nil {
return
}
if data, err := tvSrv.TransList(c, param); err == nil || err == ecode.NothingFound {
c.JSON(data, nil)
} else {
c.JSON(data, err)
}
}

View File

@@ -0,0 +1,54 @@
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"archive.go",
"audit_result.go",
"channel.go",
"content_repo.go",
"full.go",
"intervs.go",
"label.go",
"modules.go",
"order.go",
"panel.go",
"region.go",
"sear_inter.go",
"season_repo.go",
"tv_content.go",
"uplayurl.go",
"upper.go",
"user.go",
"version_update.go",
"video.go",
"water_mark.go",
],
importpath = "go-common/app/admin/main/tv/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/archive/api:go_default_library",
"//library/database/elastic:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/siddontang/go-mysql/mysql:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,159 @@
package model
import (
"go-common/library/time"
"github.com/siddontang/go-mysql/mysql"
)
// SimpleArc is the simple struct of archive
type SimpleArc struct {
ID int `gorm:"column:id"`
AID int64 `gorm:"column:aid"`
MID int `gorm:"column:mid"`
TypeID int32 `gorm:"column:typeid"`
Title string
Content string
Cover string
Deleted int
Result int
Valid int
Mtime time.Time
Pubtime time.Time
}
// Archive archive def. corresponding to our table structure
type Archive struct {
ID int `gorm:"column:id" json:"id"`
AID int64 `gorm:"column:aid" json:"aid"`
MID int `gorm:"column:mid" json:"mid"`
TypeID int32 `gorm:"column:typeid" json:"typeid"`
Videos int `gorm:"column:videos" json:"videos"`
Title string `gorm:"column:title" json:"title"`
Cover string `gorm:"column:cover" json:"cover"`
Content string `gorm:"column:content" json:"content"`
Duration int `gorm:"column:duration" json:"duration"`
Copyright int `gorm:"column:copyright" json:"copyright"`
Pubtime time.Time `gorm:"column:pubtime" json:"pubtime"`
InjectTime time.Time `gorm:"column:inject_time" json:"inject_time"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"mtime"`
State int `gorm:"column:state" json:"state"`
Manual int `gorm:"column:manual" json:"manual"`
Valid uint8 `gorm:"column:valid" json:"valid"`
Submit uint8 `gorm:"column:submit" json:"submit"`
Retry int `gorm:"column:retry" json:"retry"`
Result uint8 `gorm:"column:result" json:"result"`
Deleted uint8 `gorm:"column:deleted" json:"deleted"`
Reason string `gorm:"column:reason" json:"reason"`
}
// ArcPager is the result and page of archive query.
type ArcPager struct {
Items []*ArcList `json:"items"`
Page *Page `json:"page"`
}
// ArcListParam is archive list request params
type ArcListParam struct {
ID string `form:"id" json:"id"`
Title string `form:"title" json:"title"`
CID string `form:"cid" json:"cid"`
Typeid int32 `form:"typeid" json:"typeid"`
Valid string `form:"valid" json:"valid"`
Pid int32 `form:"pid" json:"-"`
Order int `form:"order" json:"order" default:"2"`
Mid int64 `form:"mid" json:"mid"`
UpName string `form:"up_name"`
PageCfg
}
// AddResp is for the response for adding archives/uppers
type AddResp struct {
Succ []int64 `json:"succ"` // successfully added ids
Exist []int64 `json:"exist"` // the ids already exist in our DB
Invalids []int64 `json:"invalids"` // the invalid ids ( not exist in archives/uppers )
}
// ArcType arctype
type ArcType struct {
ID int16 `json:"id"`
Pid int16 `json:"pid"`
Name string `json:"name"`
}
// ArcDB is the archive query result
type ArcDB struct {
ArcCore
Pubdate time.Time `gorm:"column:pubtime"`
}
// ArcCore is the archive core struct
type ArcCore struct {
ID string `json:"id"`
CID string `json:"cid" gorm:"column:aid"`
TypeID int32 `json:"typeid" gorm:"column:typeid"`
Title string `json:"title"`
Valid string `json:"valid" gorm:"column:valid"`
Mtime time.Time `json:"mtime"`
Content string `json:"content"`
Cover string `json:"cover"`
MID int64 `json:"mid" gorm:"column:mid"`
}
// ArcList def.
type ArcList struct {
ArcCore
PTypeID int32 `json:"parent_typeid"`
Pubdate string `json:"pubdate"`
UpName string `json:"up_name"`
}
// ToList def.
func (v *ArcDB) ToList(pid int32) (res *ArcList) {
return &ArcList{
ArcCore: v.ArcCore,
PTypeID: pid,
Pubdate: v.Pubdate.Time().Format(mysql.TimeFormat),
}
}
// UgcType ugc archive category typelist
type UgcType struct {
ID int32 `json:"id"`
Name string `json:"name"`
Children []UgcCType `json:"children"`
}
// UgcCType ugc archive children category type
type UgcCType struct {
Pid int32 `json:"pid"`
ID int32 `json:"id"`
Name string `json:"name"`
}
// Category is for getting pid and name from archive category
type Category struct {
Pid, Name string
}
// AvailTps structure in memory
type AvailTps struct {
PassedTps []UgcType
AllTps []UgcType
}
// TableName ugc_archive
func (v ArcDB) TableName() string {
return "ugc_archive"
}
// TableName ugc_archive
func (a SimpleArc) TableName() string {
return "ugc_archive"
}
// TableName ugc_archive
func (a Archive) TableName() string {
return "ugc_archive"
}

View File

@@ -0,0 +1,294 @@
package model
import (
"fmt"
"strconv"
"go-common/library/database/elastic"
"go-common/library/time"
)
const (
_TimeFormat = ("2006-01-02 15:04:05")
_mtimeDesc = "2"
_pubtimeDesc = "1"
_pagesize = 20
)
// EPRes def.
type EPRes struct {
ID int64 `json:"id"`
Title string `json:"title"`
Subtitle string `json:"subtitle"`
STitle string `json:"season_title" gorm:"column:stitle"`
Category int `json:"category"`
SeasonID int `json:"season_id"`
EPID int `json:"epid" gorm:"column:epid"`
State int `json:"state"`
Valid int `json:"valid"`
Reason string `json:"reason"`
}
// EPResDB defines the result structure of ep audit
type EPResDB struct {
EPRes
InjectTime time.Time `json:"inject_time" gorm:"column:inject_time"`
CTime time.Time `json:"ctime" gorm:"column:ctime"`
}
// EPResItem def.
type EPResItem struct {
EPRes
InjectTime string `json:"inject_time"`
CTime string `json:"ctime"`
}
// ToItem def.
func (v *EPResDB) ToItem() *EPResItem {
res := &EPResItem{
EPRes: v.EPRes,
CTime: v.CTime.Time().Format(_TimeFormat),
}
switch v.State {
case 3: // passed
res.State = 1
case 4: // rejected
res.State = 2
default:
res.State = 0
}
if v.InjectTime > 0 {
res.InjectTime = v.InjectTime.Time().Format(_TimeFormat)
}
return res
}
// Page represents the standard page structure
type Page struct {
Num int `json:"num"`
Size int `json:"size"`
Total int `json:"total"`
}
// SnCount def.
type SnCount struct {
Count int
}
// TableName tv_content
func (*EPResDB) TableName() string {
return "tv_content"
}
// EPResultPager def.
type EPResultPager struct {
Items []*EPResItem `json:"items"`
Page *Page `json:"page"`
}
// SeasonRes def.
type SeasonRes struct {
ID int64 `json:"id"`
Title string `json:"title"`
Check int `json:"check"`
Category int `json:"category"`
Valid int `json:"valid"`
Reason string `json:"reason"`
}
// SeasonResDB defines the result structure of ep audit
type SeasonResDB struct {
SeasonRes
InjectTime time.Time `json:"inject_time" gorm:"column:inject_time"`
CTime time.Time `json:"ctime" gorm:"column:ctime"`
}
// SeasonResItem def.
type SeasonResItem struct {
SeasonRes
InjectTime string `json:"inject_time"`
CTime string `json:"ctime"`
}
// ToItem Transforms to item
func (v *SeasonResDB) ToItem() *SeasonResItem {
res := &SeasonResItem{
CTime: v.CTime.Time().Format(_TimeFormat),
SeasonRes: v.SeasonRes,
}
switch v.Check {
case 0: // reject
res.Check = 2
case 1: // passed
res.Check = 1
default:
res.Check = 0
}
if v.InjectTime > 0 {
res.InjectTime = v.InjectTime.Time().Format(_TimeFormat)
}
return res
}
// TableName tv_content
func (*SeasonResDB) TableName() string {
return "tv_ep_season"
}
// SeasonResultPager def.
type SeasonResultPager struct {
Items []*SeasonResItem `json:"items"`
Page *Page `json:"page"`
}
// ReqArcCons def.
type ReqArcCons struct {
Order int `form:"order" json:"order;Min(1)" default:"1"` // 1 default, desc; 2 asc
FirstCat int32 `form:"first_cat"`
SecondCat int32 `form:"second_cat"`
Status string `form:"status"`
Title string `form:"title"`
AVID int64 `form:"avid"`
Pn int `form:"pn" default:"1"`
}
// ReqVideoCons def.
type ReqVideoCons struct {
AVID int64 `form:"avid" validate:"required"`
Order int `form:"order" json:"order;Min(1)" default:"1"` // 1 default, desc; 2 asc
Title string `form:"title"`
CID int64 `form:"cid"`
Status string `form:"status"`
Pn int `form:"pn"`
}
// PageCfg def.
type PageCfg struct {
Pn int `form:"pn" default:"1" json:"pn"`
Ps int `form:"ps" default:"20" json:"ps"`
}
// ReqArcES def.
type ReqArcES struct {
AID string
Mids []int64
Title string
Typeids []int32
Valid string
Result string
MtimeOrder string
PubtimeOrder string
PageCfg
}
// MtimeSort def.
func (v *ReqArcES) MtimeSort() string {
if v.MtimeOrder == _mtimeDesc {
return elastic.OrderDesc
}
return elastic.OrderAsc
}
// PubtimeSort def.
func (v *ReqArcES) PubtimeSort() string {
if v.PubtimeOrder == _pubtimeDesc {
return elastic.OrderDesc
}
return elastic.OrderAsc
}
// FromArcListParam build
func (v *ReqArcES) FromArcListParam(param *ArcListParam, tids []int32) {
v.Title = param.Title
v.Valid = param.Valid
v.MtimeOrder = strconv.Itoa(param.Order)
v.PageCfg = param.PageCfg
v.AID = param.CID
v.Typeids = tids
v.Result = "1"
}
// FromAuditConsult def.
func (v *ReqArcES) FromAuditConsult(param *ReqArcCons, tids []int32) {
v.PubtimeOrder = strconv.Itoa(param.Order)
v.Typeids = tids
v.Result = param.Status
v.Title = param.Title
if param.AVID != 0 {
v.AID = fmt.Sprintf("%d", param.AVID)
}
v.Pn = param.Pn
v.Ps = _pagesize
}
// ArcRes def.
type ArcRes struct {
AVID int64 `json:"avid"`
Title string `json:"title"`
FirstCat string `json:"first_cat"`
SecondCat string `json:"second_cat"`
Status int `json:"status"`
InjectTime string `json:"inject_time"`
PubTime string `json:"pubtime"`
Reason string `json:"reason"`
}
// VideoRes def.
type VideoRes struct {
CID int64 `json:"cid"`
Title string `json:"title"`
Page int `json:"page"`
Status int `json:"status"`
Ctime string `json:"ctime"`
InjectTime string `json:"inject_time"`
Reason string `json:"reason"`
}
// ArcResPager def.
type ArcResPager struct {
Items []*ArcRes `json:"items"`
Page *Page `json:"page"`
}
// VideoResPager def.
type VideoResPager struct {
Items []*VideoRes `json:"items"`
Page *Page `json:"page"`
}
// EsUgcConsult def.
type EsUgcConsult struct {
Fields []string `json:"fields"`
From string `json:"from"`
Highlight bool `json:"highlight"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Where *Where `json:"where,omitempty"`
Order []map[string]string `json:"order"`
}
// Where def.
type Where struct {
Eq map[string]string `json:"eq,omitempty"`
Or map[string][]interface{} `json:"or,omitempty"`
In map[string][]int32 `json:"in,omitempty"`
Range map[string]string `json:"range,omitempty"`
}
// EsArc def.
type EsArc struct {
AID int64 `json:"aid"`
MID int64 `json:"mid"`
Deleted int `json:"deleted"`
Mtime string `json:"mtime"`
Pubtime string `json:"pubtime"`
Result int `json:"result"`
Typeid int32 `json:"typeid"`
Valid int `json:"valid"`
}
// EsUgcResult def.
type EsUgcResult struct {
Result []*EsArc
Page *Page
}

View File

@@ -0,0 +1,52 @@
package model
import "go-common/library/time"
// Channel represents the table TV_RANK
type Channel struct {
ID int64 `json:"id"`
Title string `json:"title"`
Desc string `json:"desc"`
Splash string `json:"splash"`
Deleted int8 `json:"deleted"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime_nb"`
}
// ChannelFmt , mtimeFormat transforms the mtime timestamp
type ChannelFmt struct {
ID int64 `json:"id"`
Title string `json:"title"`
Desc string `json:"desc"`
Splash string `json:"splash"`
Deleted int8 `json:"deleted"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime_nb,omitempty"`
MtimeFormat string `json:"mtime"`
}
//ChannelPager def.
type ChannelPager struct {
TotalCount int64 `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items []*ChannelFmt `json:"items"`
}
// ReqChannel def.
type ReqChannel struct {
Page int `form:"page" default:"1"`
Order int `form:"order" default:"1"` // 1=desc,2=asc
Title string `form:"title"` // english name, precise search
Desc string `form:"desc"` // chinese name, fuzzy search
}
// TableName tv_rank
func (c Channel) TableName() string {
return "tv_channel"
}
// TableName tv_rank
func (c ChannelFmt) TableName() string {
return "tv_channel"
}

View File

@@ -0,0 +1,44 @@
package model
import (
"go-common/library/time"
)
// ContentRepo def.
type ContentRepo struct {
ID int64 `json:"id"`
Title string `json:"title"`
Subtitle string `json:"subtitle"`
Desc string `json:"desc"`
Cover string `json:"cover"`
SeasonID int `json:"season_id"`
CID int `json:"cid" gorm:"column:cid"`
EPID int `json:"epid" gorm:"column:epid"`
MenuID int `json:"menu_id"`
State int `json:"state"`
Valid int `json:"valid"`
PayStatus int `json:"pay_status"`
IsDeleted int `json:"is_deleted"`
AuditTime int `json:"audit_time"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime_nb,omitempty"`
MtimeFormat string `json:"mtime"`
InjectTime time.Time `json:"inject_time"`
// InjectTimeFormat string `json:"inject_time"`
Reason string `json:"reason"`
SeasonTitle string `json:"season_title" gorm:"column:season_title"`
Category int8 `json:"category" gorm:"column:category"`
}
// TableName tv_content
func (*ContentRepo) TableName() string {
return "tv_content"
}
// ContentRepoPager def.
type ContentRepoPager struct {
TotalCount int64 `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items []*ContentRepo `json:"items"`
}

View File

@@ -0,0 +1,111 @@
package model
import (
"go-common/library/time"
)
// APKInfo .
type APKInfo struct {
ID int64 `json:"id"`
CDNAddr string `json:"cdn_addr"`
CreatedAt time.Time `json:"created_at"`
FileMd5 string `json:"file_md5"`
InetAddr string `json:"inet_addr"`
IsDeleted bool `json:"is_deleted"`
IsGray bool `json:"is_gray"`
LocalPath string `json:"local_path"`
MappingAddr string `json:"mapping_addr"`
SignMd5 string `json:"sign_md5"`
Size int `json:"size"`
UpdatedAt time.Time `json:"updated_at"`
VersionCode int `json:"version_code"`
VersionID string `json:"version_id"`
VersionName string `json:"version_name"`
}
// MangoRecom is mango recom table structure
type MangoRecom struct {
ID int64 `json:"id" gorm:"column:id"`
RID int64 `json:"rid" gorm:"column:rid"`
Rtype int `json:"rtype"`
Title string `json:"title"`
Cover string `json:"cover"`
Category int `json:"category"`
Playcount int64 `json:"playcount"`
JID int64 `json:"jid" gorm:"column:jid"`
Content string `json:"content"`
Staff string `json:"staff"`
Rorder int `json:"rorder"`
}
// MangoListResp is the mango list response structure
type MangoListResp struct {
List []*MangoRecom `json:"list"`
Pubtime string `json:"pubtime"`
Message string `json:"message"` // 文案提示: rid, p213,u367 ...
}
// MangoAdd is the response of mango add function
type MangoAdd struct {
Succ []int64 `json:"succ"`
Invalids []int64 `json:"invalids"`
}
// TableName def.
func (*MangoRecom) TableName() string {
return "mango_recom"
}
// ToMango def.
func (sn *TVEpSeason) ToMango() *MangoRecom {
return &MangoRecom{
RID: sn.ID,
Rtype: 1,
Title: sn.Title,
Cover: sn.Cover,
Category: int(sn.Category),
Content: sn.Desc,
Staff: sn.Staff,
}
}
// ToMango def.
func (arc *SimpleArc) ToMango(cat int) *MangoRecom {
return &MangoRecom{
RID: arc.AID,
Rtype: 2,
Title: arc.Title,
Cover: arc.Cover,
Category: cat,
Content: arc.Content,
}
}
// ReqMangoEdit is the request for mango edit
type ReqMangoEdit struct {
ID int64 `form:"id" validate:"required"`
Title string `form:"title" validate:"required"`
Cover string `form:"cover" validate:"required"`
Playcount int64 `form:"playcount"`
JID int64 `form:"jid"`
Content string `form:"content" validate:"required"`
Staff string `form:"staff"`
}
// MRecomMC is mango recom struct in MC
type MRecomMC struct {
RIDs []int64
Pubtime time.Time
}
// ReqUnshelve is request for unshelve
type ReqUnshelve struct {
IDs []int64 `form:"ids,split" validate:"required,min=1,dive,gt=0"`
Type int `form:"type" validate:"required,min=1,max=4"`
}
// RespUnshelve is response for unshelve
type RespUnshelve struct {
SuccIDs []int64 `json:"succ_ids"`
FailIDs []int64 `json:"fail_ids"`
}

View File

@@ -0,0 +1,227 @@
package model
import (
"encoding/json"
"go-common/library/time"
"github.com/jinzhu/gorm"
"github.com/siddontang/go-mysql/mysql"
)
// Tv_rank table related const params
const (
_RankCategory = 5 // _RankCategory 模块干预
RankIdxBase = 5 // index page intervention base, pgc=5+1, ugc=5+2
)
// SimpleRank represents the table TV_RANK, but with only necessary fields for the front-end
type SimpleRank struct {
Title string `json:"title"`
Source int `json:"source"`
SourceName string `json:"source_name"`
Mtime string `json:"mtime"`
Pubdate string `json:"pubdate"`
RankCore
}
// RankCore def
type RankCore struct {
Rank int64 `json:"rank"`
ID int64 `json:"id"`
ContID int64 `json:"cid" gorm:"column:cont_id"`
ContType int `json:"cont_type"`
Position int `json:"position"`
}
// RankError represents the invalid season info
type RankError struct {
ID int `json:"id"`
SeasonID int `json:"season_id"`
}
// RankList is the output format for intervention list
type RankList struct {
List []*SimpleRank `json:"list"`
}
// Rank represents the table TV_RANK
type Rank struct {
Title string
ModuleID int64 `gorm:"column:module_id"`
Category int8
IsDeleted int8
Mtime time.Time
RankCore
}
// TableName tv_rank
func (c SimpleRank) TableName() string {
return "tv_rank"
}
// TableName tv_rank
func (v Rank) TableName() string {
return "tv_rank"
}
// BeComplete transforms a simpleRank to Complete rank in order to create it in DB
func (c SimpleRank) BeComplete(req *IntervPubReq, title string, position int) (res *Rank) {
res = &Rank{
Title: title,
RankCore: c.RankCore,
}
res.Position = position
if req.ModuleID > 0 {
res.Category = _RankCategory
res.ModuleID = req.ModuleID
return
}
if req.Rank > 0 {
res.Rank = req.Rank
}
if req.Category > 0 {
res.Category = int8(req.Category)
}
return
}
type catName func(int) string // translate pgc category to CN name
type tpParName func(int32) (string, int32, error) // translate ugc type to its parent tid and parent's name
// BeSimpleSn def.
func (v *Rank) BeSimpleSn(sn *TVEpSeason, translate catName) *SimpleRank {
return &SimpleRank{
RankCore: v.RankCore,
Title: sn.Title,
Source: sn.Category,
SourceName: translate(sn.Category),
Pubdate: sn.PlayTime.Time().Format(mysql.TimeFormat),
Mtime: v.Mtime.Time().Format(mysql.TimeFormat),
}
}
// BeSimpleArc def.
func (v *Rank) BeSimpleArc(arc *SimpleArc, translate tpParName) (res *SimpleRank) {
res = &SimpleRank{
RankCore: v.RankCore,
Title: arc.Title,
Mtime: v.Mtime.Time().Format(mysql.TimeFormat),
Pubdate: arc.Pubtime.Time().Format(mysql.TimeFormat),
}
if pname, pid, err := translate(arc.TypeID); err == nil {
res.Source = int(pid)
res.SourceName = pname
}
return
}
//BeError transforms a rank to rankError
func (v Rank) BeError() *RankError {
return &RankError{
ID: int(v.ID),
SeasonID: int(v.ContID),
}
}
// RankListReq is rank list request
type RankListReq struct {
Rank int64 `form:"rank" validate:"min=0"`
Category int64 `form:"category" validate:"required,min=1"`
}
// RankPubReq is rank publish request
type RankPubReq struct {
RankListReq
Intervs string `form:"intervs" validate:"required"`
}
// ModListReq is mod list request
type ModListReq struct {
ModuleID int64 `form:"module_id" validate:"required,min=1"`
}
// ModPubReq is mod publish request
type ModPubReq struct {
ModListReq
Intervs string `form:"intervs" validate:"required"`
}
// IdxListReq is index list request
type IdxListReq struct {
TypeID int64 `form:"type_id" validate:"required,min=1"`
RankType int64 `form:"rank_type" validate:"required,min=1,max=2"` // 1=pgc, 2=ugc
}
// IdxPubReq is index publish request.
type IdxPubReq struct {
IdxListReq
Intervs string `form:"intervs" validate:"required"`
}
// IntervListReq is common request for interv list.
type IntervListReq struct {
Rank int64
Category int64
ModuleID int64
}
// IntervPubReq is common request for interv publish.
type IntervPubReq struct {
IntervListReq
Items []*SimpleRank
}
// FromRank builds the request with rank & category params
func (v *IntervListReq) FromRank(rank *RankListReq) {
v.Rank = rank.Rank
v.Category = rank.Category
v.ModuleID = 0
}
// FromRank def.
func (v *IntervPubReq) FromRank(rank *RankPubReq) (err error) {
v.IntervListReq.FromRank(&rank.RankListReq)
return json.Unmarshal([]byte(rank.Intervs), &v.Items)
}
// FromMod builds the request with module params
func (v *IntervListReq) FromMod(mod *ModListReq) {
v.Rank = 0
v.Category = _RankCategory
v.ModuleID = mod.ModuleID
}
// FromMod builds the request with module params
func (v *IntervPubReq) FromMod(mod *ModPubReq) (err error) {
v.IntervListReq.FromMod(&mod.ModListReq)
return json.Unmarshal([]byte(mod.Intervs), &v.Items)
}
// FromIndex builds the request with index params
func (v *IntervListReq) FromIndex(idx *IdxListReq) {
v.Rank = idx.TypeID // category id, pgc or ugc type id
v.Category = idx.RankType + RankIdxBase // 6 or 7
v.ModuleID = 0
}
// IsIdx tells whether this request is from index
func (v *IntervListReq) IsIdx() bool {
return v.Category > RankIdxBase
}
// FromIndex def.
func (v *IntervPubReq) FromIndex(idx *IdxPubReq) (err error) {
v.IntervListReq.FromIndex(&idx.IdxListReq)
return json.Unmarshal([]byte(idx.Intervs), &v.Items)
}
// BuildDB builds the db from the intervention request
func (v *IntervListReq) BuildDB(db *gorm.DB) (newDB *gorm.DB) {
newDB = db.Model(Rank{}).Where("is_deleted = 0")
if v.ModuleID == 0 { // index or rank
newDB = newDB.Where("rank = ?", v.Rank).Where("category = ?", v.Category)
} else {
newDB = newDB.Where("module_id = ?", v.ModuleID)
}
return
}

View File

@@ -0,0 +1,179 @@
package model
import (
"encoding/json"
"fmt"
xtime "time"
arccli "go-common/app/service/main/archive/api"
"go-common/library/time"
"github.com/siddontang/go-mysql/mysql"
)
// label related params
const (
ParamTypeid = "typeid"
ParamUgctime = "pubtime"
UgcLabel = 2
PgcLabel = 1
)
// TpLabel def.
type TpLabel struct {
Category int `json:"-"`
Param string `json:"param"`
ParamName string `json:"param_name"`
}
// ReqLabel def.
type ReqLabel struct {
Category int `form:"category" validate:"required"`
Param string `form:"param" validate:"required"` // pubtime for time labels, typeid for type labels
Title string `form:"title"`
ID int `form:"id"`
}
// LabelDB is the index label in DB
type LabelDB struct {
LabelCore
Mtime time.Time `json:"Mtime"`
}
// SameType tells whether the given label has the exact same type with the V
func (v *LabelDB) SameType(given *LabelDB) bool {
return v.Category == given.Category && v.Param == given.Param && v.CatType == given.CatType
}
// LabelCore is core of Label
type LabelCore struct {
ID int64 `json:"id"`
Name string `json:"name"`
Param string `json:"param"`
ParamName string `json:"param_name"`
Value string `json:"value"`
Category int32 `json:"category"`
CatType int `json:"cat_type"`
Valid int `json:"valid"`
Position int `json:"position"`
}
// LabelList is used to list in TV CMS
type LabelList struct {
LabelCore
Mtime string `json:"mtime"`
Stime string `json:"stime,omitempty"`
Etime string `json:"etime,omitempty"`
}
// PgcCondResp is pgc condition response structure
type PgcCondResp struct {
Code int `json:"code"`
Message string `json:"message"`
Result *PgcCond `json:"result"`
}
// PgcCond def.
type PgcCond struct {
Filter []*Cond `json:"filter"`
}
// Cond def.
type Cond struct {
ID string `json:"id"`
Name string `json:"name"`
Value []*CondV `json:"value"`
}
// CondV def.
type CondV struct {
ID string `json:"id"`
Name string `json:"name"`
}
// UgcTime is used to add time labels for ugc
type UgcTime struct {
UTime
Category int32 `form:"category" validate:"required"`
Name string `form:"name" validate:"required"`
}
// EditUgcTime def.
type EditUgcTime struct {
ID int64 `form:"id" validate:"required"`
Name string `form:"name" validate:"required"`
UTime
}
// UTime is used for storage in DB by json
type UTime struct {
Stime int64 `form:"stime" validate:"required" json:"stime"`
Etime int64 `form:"etime" validate:"required" json:"etime"`
}
// TimeV picks time value in Json
func (tm *UTime) TimeV() string {
timeV, _ := json.Marshal(tm)
return string(timeV)
}
// ToList transforms LabelDB to LabelList
func (v *LabelDB) ToList() *LabelList {
res := &LabelList{
LabelCore: v.LabelCore,
Mtime: v.Mtime.Time().Format(mysql.TimeFormat),
}
if v.CatType == UgcLabel && v.Param == ParamUgctime && v.Value != "" {
utime := UTime{}
if err := json.Unmarshal([]byte(v.Value), &utime); err != nil {
return res
}
res.Stime = xtime.Unix(utime.Stime, 0).Format(mysql.TimeFormat)
res.Etime = xtime.Unix(utime.Etime, 0).Format(mysql.TimeFormat)
}
return res
}
// TableName tv_rank
func (v LabelDB) TableName() string {
return "tv_label"
}
// FromArcTp def.
func (v *LabelDB) FromArcTp(tp *arccli.Tp, paramName string) {
v.LabelCore = LabelCore{
Name: tp.Name,
Value: fmt.Sprintf("%d", tp.ID),
Category: tp.Pid,
Param: ParamTypeid,
ParamName: paramName,
CatType: UgcLabel,
Valid: 1,
}
}
// FromPgcCond def.
func (v *LabelDB) FromPgcCond(value *CondV, cond *Cond, category int32) {
v.LabelCore = LabelCore{
Name: value.Name,
Value: value.ID,
Category: category,
Param: cond.ID,
ParamName: cond.Name,
CatType: PgcLabel,
Valid: 1,
}
}
// FromUgcTime def.
func (v *LabelDB) FromUgcTime(tm *UgcTime, paramName string) {
v.LabelCore = LabelCore{
Name: tm.Name,
Value: tm.TimeV(),
Category: tm.Category,
Param: ParamUgctime,
ParamName: paramName,
CatType: UgcLabel,
Valid: 1,
}
}

View File

@@ -0,0 +1,166 @@
package model
import (
"fmt"
"go-common/library/time"
)
const (
//ModulesNotDelete module not delete
ModulesNotDelete = 0
//ModulesDelete module delete
ModulesDelete = 1
//ModulesValid module is valid
ModulesValid = 1
//ModulesPublishYes module is publish status in MC
ModulesPublishYes = 1
//ModulesPublishNo module is not publish status in MC
ModulesPublishNo = 0
//PageMain 主页
PageMain = 0
//PageJP 追番
PageJP = 1
//PageMovie 电影
PageMovie = 2
//PageDocumentary 纪录片
PageDocumentary = 3
//PageCN 国创
PageCN = 4
//PageSoapopera 电视剧
PageSoapopera = 5
//TypeSevenFocus 首页七格焦点图
TypeSevenFocus = 1
//TypeFiveFocus 5格焦点
TypeFiveFocus = 2
//TypeSixFocus 6格焦点
TypeSixFocus = 3
//TypeVertListFirst 竖图1列表
TypeVertListFirst = 4
//TypeVertListSecond 竖图2列表
TypeVertListSecond = 5
//TypeHorizList 横图列表
TypeHorizList = 6
//TypeZhuiFan 追番模块
TypeZhuiFan = 7
)
// Modules is use for Modular
type Modules struct {
ID uint64 `json:"id"`
PageID string `json:"page_id" form:"page_id" validate:"required"`
Flexible string `json:"flexible" form:"flexible" validate:"required"`
Icon string `json:"icon" form:"icon"`
Title string `json:"title" form:"title" validate:"required"`
Capacity uint64 `json:"capacity" form:"capacity" validate:"required"`
More string `json:"more" form:"more" validate:"required"`
Order uint8 `json:"order"`
Moretype string `json:"moretype" form:"moretype"`
Morepage int64 `json:"morepage" form:"morepage"`
Deleted uint8 `json:"-"`
Valid uint8 `json:"valid"`
ModCore
}
// ModulesAddParam is use for Modular add param
type ModulesAddParam struct {
ID uint64 `form:"id" validate:"required"`
PageID string `form:"page_id" validate:"required"`
Flexible string `form:"flexible" validate:"required"`
Icon string `form:"icon"`
Title string `form:"title" validate:"required"`
Capacity uint64 `form:"capacity" validate:"required"`
More string `form:"more" validate:"required"`
Moretype string `json:"moretype" form:"moretype"`
Morepage int64 `json:"morepage" form:"morepage"`
Order uint8
ModCore
}
// ModCore def.
type ModCore struct {
Type string `json:"type" form:"type" validate:"required"`
Source string `json:"source" form:"source" validate:"required"`
SrcType int `json:"src_type" form:"src_type" validate:"required"`
}
//ModPub is used for store publish status
type ModPub struct {
Time string
State uint8
}
//ModulesList is used for function module list
type ModulesList struct {
Items []*Modules `json:"items"`
PubState uint8 `json:"pubstate"`
PubTime string `json:"pubtime"`
}
// TableName tv modules
func (a Modules) TableName() string {
return "tv_modules"
}
//CommonCat , PGC types or ugc second level types
type CommonCat struct {
ID int32 `json:"id"`
PID int32 `json:"pid"`
Name string `json:"name"`
Type int `json:"type"`
}
//ParentCat : ugc first level types
type ParentCat struct {
ID int32 `json:"id"`
Name string `json:"name"`
Type int `json:"type"`
Children []*CommonCat `json:"children,omitempty"`
}
//SupCats : support category map
type SupCats struct {
UgcMap map[int32]int
PgcMap map[int32]int
}
// AbnorCids is the export format for abnormal cids
type AbnorCids struct {
CID int64 `json:"cid"`
VideoTitle string `json:"video_title"`
CTime string `json:"ctime"`
AID int64 `json:"aid"`
ArcTitle string `json:"arc_title"`
PubTime string `json:"pub_time"`
}
// Export transforms the structure to export csv data
func (v *AbnorCids) Export() (res []string) {
res = append(res, fmt.Sprintf("%d", v.CID))
res = append(res, v.VideoTitle)
res = append(res, v.CTime)
res = append(res, fmt.Sprintf("%d", v.AID))
res = append(res, v.ArcTitle)
res = append(res, v.PubTime)
return
}
// AbnorVideo def.
type AbnorVideo struct {
CID int64
VideoTitle string
CTime time.Time
AID int64
}
// ToCids transforms the archive & video to abnormal cid export structure
func (v *AbnorVideo) ToCids(arc *Archive) *AbnorCids {
return &AbnorCids{
CID: v.CID,
VideoTitle: v.VideoTitle,
CTime: v.CTime.Time().Format("2006-01-02 15:04:05"),
AID: v.AID,
ArcTitle: arc.Title,
PubTime: arc.Pubtime.Time().Format("2006-01-02 15:04:05"),
}
}

View File

@@ -0,0 +1,58 @@
package model
import "go-common/library/time"
// TvPayOrder is table struct
type TvPayOrder struct {
ID int64 `json:"id"`
OrderNo string `json:"order_no"`
Platform int8 `json:"platform"`
OrderType int8 `json:"order_type"`
ActiveType int8 `json:"active_type"`
MID int64 `json:"mid" gorm:"column:mid"`
BuyMonths int8 `json:"buy_months"`
ProductID string `json:"product_id"`
Money int64 `json:"money"`
Quantity int64 `json:"quantity"`
RefundAmount int64 `json:"refund_amount"`
Status int8 `json:"status"`
ThirdTradeNO string `json:"third_trade_no"`
PaymentMoney int64 `json:"payment_money"`
PaymentType string `json:"payment_type"`
PaymentTime time.Time `json:"payment_time"`
Ver int64 `json:"ver"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// TvPayOrderResp is used to list in TV pay order list
type TvPayOrderResp struct {
ID int64 `json:"id"`
OrderNo string `json:"order_no"`
OrderType int8 `json:"order_type"`
ActiveType int8 `json:"active_type"`
MID int64 `json:"mid" form:"mid" gorm:"column:mid"`
BuyMonths int8 `json:"buy_months"`
ProductID string `json:"product_id"`
Money int64 `json:"money"`
Quantity int64 `json:"quantity"`
RefundAmount int64 `json:"refund_amount"`
Status int8 `json:"status"`
ThirdTradeNO string `json:"third_trade_no"`
PaymentMoney int64 `json:"payment_money"`
PaymentType string `json:"payment_type"`
PaymentTime time.Time `json:"payment_time"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// OrderPageHelper is used to list in TV pay order list count
type OrderPageHelper struct {
Items []*TvPayOrderResp `json:"items"`
Total *int64 `json:"total"`
}
// TableName tv_pay_order
func (*TvPayOrderResp) TableName() string {
return "tv_pay_order"
}

View File

@@ -0,0 +1,100 @@
package model
import "go-common/library/time"
// TvPriceConfig is tv vip pay order
type TvPriceConfig struct {
ID int64 `form:"id" json:"id"`
PID int64 `form:"pid" json:"pid" gorm:"column:pid"`
Platform int8 `form:"platform" json:"platform" validate:"required"`
ProductName string `form:"product_name" validate:"required" json:"product_name"`
ProductID string `form:"product_id" validate:"required" json:"product_id"`
SuitType int8 `form:"suit_type" json:"suit_type" `
Month int64 `form:"month" json:"month"`
SubType int8 `form:"sub_type" json:"sub_type" `
Price int64 `form:"price" json:"price"`
Selected int8 `form:"selected" json:"selected"`
Remark string `form:"remark" json:"remark"`
Status int8 `form:"status" json:"status"`
Superscript string `form:"superscript" json:"superscript"`
Operator string `form:"operator" json:"operator"`
OperId int64 `form:"oper_id" json:"oper_id"`
Stime time.Time `form:"stime" json:"stime"`
Etime time.Time `form:"etime" json:"etime"`
Mtime time.Time `json:"mtime"`
}
// TvPriceConfigResp is used show panel info
type TvPriceConfigResp struct {
ID int64 `form:"id" json:"id"`
PID int64 `form:"pid" json:"pid" gorm:"column:pid"`
ProductName string `form:"product_name" json:"product_name"`
ProductID string `form:"product_id" json:"product_id"`
SuitType int8 `form:"suit_type" json:"suit_type"`
Month int64 `form:"month" json:"month"`
SubType int8 `form:"sub_type" json:"sub_type"`
Price int64 `form:"price" json:"price"`
OriginPrice int64 `form:"original_price" json:"original_price"`
Selected int8 `form:"selected" json:"selected"`
Remark string `form:"remark" json:"remark"`
Status int8 `form:"status" json:"status"`
Superscript string `form:"superscript" json:"superscript"`
Operator string `form:"operator" json:"operator"`
OperId int64 `form:"oper_id" json:"oper_id"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
Items []TvPriceConfig `json:"item"`
}
// TvPriceConfigListResp is used to list in TV panel list
type TvPriceConfigListResp struct {
ID int64 `form:"id" json:"id"`
PID int64 `form:"pid" json:"pid" gorm:"column:pid"`
ProductName string `form:"product_name" json:"product_name"`
ProductID string `form:"product_id" json:"product_id"`
SuitType int8 `form:"suit_type" json:"suit_type"`
Month int64 `form:"month" json:"month"`
SubType int8 `form:"sub_type" json:"sub_type"`
Price int64 `form:"price" json:"price"`
OriginPrice int64 `form:"original_price" json:"original_price"`
Selected int8 `form:"selected" json:"selected"`
Status int8 `form:"status" json:"status"`
Operator string `form:"operator" json:"operator"`
OperId int64 `form:"oper_id" json:"oper_id"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// RemotePanel YST product res
type RemotePanel struct {
Product []Product `json:"data"`
Result struct {
ResultCode string `json:"result_code"`
ResultMsg string `json:"result_msg"`
} `json:"result"`
}
// Product YST product
type Product struct {
ID string `json:"id"`
Description string `json:"description"`
Title string `json:"title"`
Price int64 `json:"price"`
ComboPkgID string `json:"combo_pkg_id"`
ComboDes string `json:"combo_des"`
VideoType string `json:"video_type"`
VodType string `json:"vod_type"`
ProductDuration string `json:"product_duration"`
Contract string `json:"contract"`
SuitType int8 `json:"suit_type"`
}
// TableName tv_price_config
func (*TvPriceConfig) TableName() string {
return "tv_price_config"
}
// TableName tv_price_config
func (*TvPriceConfigListResp) TableName() string {
return "tv_price_config"
}

View File

@@ -0,0 +1,51 @@
package model
import (
"go-common/library/time"
"github.com/siddontang/go-mysql/mysql"
)
// RegCore .
type RegCore struct {
ID int `json:"id" form:"id"`
PageID int `json:"page_id" form:"page_id"`
Title string `json:"title" form:"title"`
Valid int `json:"valid" form:"valid"`
IndexType int `json:"index_type" form:"index_type"`
IndexTid int `json:"index_tid" form:"index_tid"`
Deleted int `json:"deleted" form:"deleted"`
Rank int `json:"rank"`
}
// RegDB .
type RegDB struct {
RegCore
Mtime time.Time `json:"mtime" form:"mtime"`
}
// RegList .
type RegList struct {
RegCore
Mtime string `json:"mtime"`
}
// ToList ctime format .
func (v *RegDB) ToList() *RegList {
return &RegList{
RegCore: v.RegCore,
Mtime: v.Mtime.Time().Format(mysql.TimeFormat),
}
}
// TableName return table name .
func (*RegDB) TableName() string {
return "tv_pages"
}
// Param .
type Param struct {
Title string `form:"title"`
PageID string `form:"page_id"`
State string `form:"state"`
}

View File

@@ -0,0 +1,43 @@
package model
import (
"go-common/library/time"
)
//SearInter reprensents the search intervene
type SearInter struct {
ID int64 `json:"id" params:"id"`
Searchword string `json:"searchword" params:"searchword"`
Rank int64 `json:"rank" params:"rank"`
Tag string `json:"tag" params:"tag"`
Deleted int8 `json:"deleted"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// TableName gives the table name of search intervene
func (*SearInter) TableName() string {
return "search_intervene"
}
// SearInterPager search intervene pager
type SearInterPager struct {
TotalCount int `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items []*SearInter `json:"items"`
PubState int8
PubTime string
}
//OutSearchInter output search intervene
type OutSearchInter struct {
Keyword string `json:"keyword"`
Status string `json:"status"`
}
//PublishStatus search intervene publish status state 0-unPublish 1-publish
type PublishStatus struct {
Time string
State int8
}

View File

@@ -0,0 +1,187 @@
package model
import (
"net/url"
"reflect"
"strconv"
"go-common/library/time"
"github.com/siddontang/go-mysql/mysql"
)
// TVEpContent reprensents the content table
type TVEpContent struct {
ID int64 `form:"id" params:"id" validate:"required"`
CID int `form:"cid" params:"cid" gorm:"column:cid" validate:"required"`
SeasonID int64 `form:"season_id" params:"season_id" validate:"required"`
Title string `form:"title" params:"title"`
LongTitle string `form:"long_title" params:"long_title"`
Cover string `form:"cover" params:"cover"`
Length int32 `form:"length" params:"length"`
Order int `form:"order" params:"order" validate:"required"`
PayStatus int `form:"pay_status" validate:"required" gorm:"-"`
Desc string `form:"desc" gorm:"-"`
IsDeleted int8
Ctime time.Time
Mtime time.Time
}
// TVEpSeason represents the season table
type TVEpSeason struct {
ID int64 `form:"id" json:"id" params:"id" validate:"required" gorm:"column:id"`
OriginName string `form:"origin_name" json:"origin_name" params:"origin_name" validate:"required"`
Title string `form:"title" json:"title" params:"title"`
Alias string `form:"alias" json:"alias" params:"alias"`
Category int `form:"category" json:"category" params:"category" validate:"required" gorm:"column:category"`
Desc string `form:"desc" json:"desc" params:"desc"`
Style string `form:"style" json:"style" params:"style"`
Area string `form:"area" json:"area" params:"area"`
PlayTime time.Time `form:"play_time" json:"play_time" params:"play_time" validate:"required"`
Info int `form:"info" json:"info" params:"info" validate:"required"`
State string `form:"state" json:"state" validate:"required" params:"state"`
TotalNum string `form:"total_num" json:"total_num" params:"total_num" validate:"required"`
Upinfo string `form:"upinfo" json:"upinfo" params:"upinfo"`
Staff string `form:"staff" json:"staff" params:"staff"`
Role string `form:"role" json:"role" params:"role"`
Copyright string `form:"copyright" json:"copyright" params:"copyright"`
Cover string `form:"cover" json:"cover" params:"cover" gorm:"column:cover"`
Check int `json:"check"`
IsDeleted int `json:"is_deleted"`
AuditTime int `json:"audit_time"`
Valid int `json:"valid"`
Reason string `json:"reason"`
Version string `json:"version" form:"version"` // v1.13 new fields, movie, OVA or normal
Producer string `json:"producer" form:"producer"` // v1.13 new fields, BBC, CCTV etc
AliasSearch string `json:"alias_search" form:"alias_search"`
Brief string `json:"brief" form:"brief"`
Status string `json:"status" form:"status"`
}
// SeaRepoCore def.
type SeaRepoCore struct {
ID int64 `json:"id" params:"id"`
OriginName string `json:"origin_name" params:"origin_name"`
Title string `json:"title" params:"title"`
Alias string `json:"alias" params:"alias"`
Category int8 `json:"category" params:"category"`
Desc string `json:"desc" params:"desc"`
Style string `json:"style" params:"style"`
Area string `json:"area" params:"area"`
Info int8 `json:"info" params:"info"`
State int8 `json:"state" params:"state"`
TotalNum int32 `json:"total_num" params:"total_num"`
Upinfo string `json:"upinfo" params:"upinfo"`
Staff string `json:"staff" params:"staff"`
Role string `json:"role" params:"role"`
Copyright string `json:"copyright" params:"copyright"`
Cover string `json:"cover" params:"cover" gorm:"column:cover"`
Check int8 `json:"check"`
IsDeleted int8 `json:"is_deleted"`
AuditTime int `json:"audit_time"`
Ctime time.Time `json:"ctime"`
Valid int8 `json:"valid"`
InjectTime time.Time `json:"inject_time"`
Reason string `json:"reason"`
}
// SeaRepoDB def.
type SeaRepoDB struct {
SeaRepoCore
PlayTime time.Time `gorm:"column:play_time"`
Mtime time.Time `json:"mtime"`
}
// SeaRepoList def.
type SeaRepoList struct {
SeaRepoCore
Mtime string `json:"mtime"`
Pubdate string `json:"pubdate"`
}
// ToList transforms a SeaRepoDB to list, time transformation
func (v *SeaRepoDB) ToList() (list *SeaRepoList) {
list = &SeaRepoList{
SeaRepoCore: v.SeaRepoCore,
}
list.Mtime = v.Mtime.Time().Format(mysql.TimeFormat)
list.Pubdate = v.PlayTime.Time().Format(mysql.TimeFormat)
return
}
// TableName gives the table name of content
func (*TVEpContent) TableName() string {
return "tv_ep_content"
}
// TableName gives the table name of season
func (*TVEpSeason) TableName() string {
return "tv_ep_season"
}
// TableName gives the table name of season
func (v *SeaRepoDB) TableName() string {
return "tv_ep_season"
}
// SeasonRepoPager def.
type SeasonRepoPager struct {
TotalCount int64 `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items []*SeaRepoList `json:"items"`
}
// Updated picks value from request and compare with the struct to analyse the difference
func (sn TVEpSeason) Updated(req url.Values) (fields map[string]interface{}) {
var (
vl = reflect.ValueOf(sn)
tp = reflect.TypeOf(sn)
)
fields = make(map[string]interface{})
for i := 0; i < vl.NumField(); i++ {
var (
t = tp.Field(i)
v = vl.Field(i)
name = t.Tag.Get("json")
)
if reqV := req.Get(name); reqV != "" {
if kind := t.Type.Kind(); kind == reflect.Int || kind == reflect.Int64 {
if v.Int() != atoi(reqV) {
fields[name] = atoi(reqV)
}
} else {
if v.String() != reqV {
fields[name] = reqV
}
}
}
}
return
}
// ToContent transforms an ep to content object
func (epc *TVEpContent) ToContent(isInit bool) (res *Content) {
res = &Content{
Title: epc.LongTitle,
Subtitle: epc.Title,
Desc: epc.Desc,
Cover: epc.Cover,
SeasonID: int(epc.SeasonID),
CID: epc.CID,
EPID: int(epc.ID),
PayStatus: epc.PayStatus,
}
if isInit {
res.State = 1
}
return
}
func atoi(value string) (intval int64) {
intval, err := strconv.ParseInt(value, 10, 64)
if err != nil {
intval = 0
}
return intval
}

View File

@@ -0,0 +1,60 @@
package model
import (
"go-common/library/time"
)
// Content content def.
type Content struct {
ID int64 `json:"id"`
Title string `json:"title"`
Subtitle string `json:"subtitle"`
Desc string `json:"desc"`
Cover string `json:"cover"`
SeasonID int `json:"season_id"`
CID int `json:"cid" gorm:"column:cid"`
EPID int `json:"epid" gorm:"column:epid"`
MenuID int `json:"menu_id"`
State int `json:"state"`
Valid int `json:"valid"`
PayStatus int `json:"pay_status"`
IsDeleted int `json:"is_deleted"`
AuditTime int `json:"audit_time"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
InjectTime time.Time `json:"inject_time"`
Reason string `json:"reason"`
}
// ContentDetail def.
type ContentDetail struct {
ID int64 `json:"id"`
Title string `json:"title"`
Subtitle string `json:"subtitle"`
Desc string `json:"desc"`
Cover string `json:"cover"`
SeasonID int `json:"season_id"`
CID int `json:"cid" gorm:"column:cid"`
EPID int `json:"epid" gorm:"column:epid"`
MenuID int `json:"menu_id"`
State int `json:"state"`
Valid int `json:"valid"`
PayStatus int `json:"pay_status"`
IsDeleted int `json:"is_deleted"`
AuditTime int `json:"audit_time"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
InjectTime time.Time `json:"inject_time"`
Reason string `json:"reason"`
Order int `json:"order"`
}
// TableName tv_content
func (c Content) TableName() string {
return "tv_content"
}
// TableName tv_content
func (*ContentDetail) TableName() string {
return "tv_content"
}

View File

@@ -0,0 +1,52 @@
package model
//UPlayURLR ugc play url response
type UPlayURLR struct {
Code uint64 `json:"code"`
Result string `json:"result"`
Message string `json:"message"`
From string `json:"from"`
Quality int `json:"quality"`
Format string `json:"format"`
Timelength int `json:"timelength"`
AcceptFormat string `json:"accept_format"`
AcceptDescription []string `json:"accept_description"`
AcceptQuality []int `json:"accept_quality"`
AcceptWatermark []bool `json:"accept_watermark"`
VideoCodecid int `json:"video_codecid"`
VideoProject bool `json:"video_project"`
SeekParam string `json:"seek_param"`
SeekType string `json:"seek_type"`
Durl []struct {
Order int `json:"order"`
Length int `json:"length"`
Size int `json:"size"`
Ahead string `json:"ahead"`
Vhead string `json:"vhead"`
URL string `json:"url"`
} `json:"durl"`
}
// PlayurlResp is the response struct from Playurl API
type PlayurlResp struct {
Code int `json:"code"`
Message string `json:"message"`
From string `json:"from"`
Result string `json:"result"`
Quality int `json:"quality"`
Format string `json:"format"`
Timelength int `json:"timelength"`
AcceptFormat string `json:"accept_format"`
AcceptQuality []int `json:"accept_quality"`
SeekParam string `json:"seek_param"`
SeekType string `json:"seek_type"`
Durl []*Durl `json:"durl"`
}
// Durl def.
type Durl struct {
Order int `json:"order"`
Length int `json:"length"`
Size int `json:"size"`
URL string `json:"url"`
}

View File

@@ -0,0 +1,104 @@
package model
import "go-common/library/time"
// Upper corresponds to the structure of upper in our DB
type Upper struct {
ID int `json:"id"`
MID int64 `json:"mid" gorm:"column:mid"`
State int `json:"state"`
Toinit int `json:"toinit"`
Retry int `json:"retry"`
Deleted int `json:"deleted"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// UpperR corresponds to the structure of upper to show in front-end
type UpperR struct {
MID int64 `json:"mid"`
State int `json:"state"`
Name string `json:"name"`
Ctime string `json:"ctime"`
Mtime string `json:"mtime"`
}
// UpperPager def.
type UpperPager struct {
Items []*UpperR `json:"items"`
Page *Page `json:"page"`
}
// TableName ugc_uploader
func (a Upper) TableName() string {
return "ugc_uploader"
}
// ImportResp is for the response for import uppers' videos
type ImportResp struct {
NotExist []int64 `json:"not_exist"` // not existing uppers
Succ []int64 `json:"succ"` // succesffuly updated ids
}
// ReqUpCms is the request structure of upcmsList
type ReqUpCms struct {
Order int `form:"order" validate:"required,min=3,max=4" default:"3"` // 3 = mtime Desc, 4 = mtime Asc
Pn int `form:"pn" default:"1"`
Name string `form:"name"`
MID int64 `form:"mid"`
Valid string `form:"valid"` // 0 = offline, 1 = online
}
// CmsUpper corresponds to the structure of upper for CMS in our DB
type CmsUpper struct {
MID int64 `json:"mid" gorm:"column:mid"`
Mtime time.Time `json:"-"`
MtimeStr string `json:"mtime" gorm:"-"`
CmsName string `json:"cms_name"`
OriName string `json:"ori_name"`
CmsFace string `json:"cms_face"`
Valid int `json:"valid"`
}
// ReqUpEdit is the request of up edit function
type ReqUpEdit struct {
MID int64 `form:"mid" validate:"required"`
Name string `form:"name" validate:"required"`
Face string `form:"face" validate:"required"`
}
// TableName ugc_uploader
func (a CmsUpper) TableName() string {
return "ugc_uploader"
}
// CmsUpperPager is cms upper pager
type CmsUpperPager struct {
Items []*CmsUpper `json:"items"`
Page *Page `json:"page"`
}
// RespUpAudit is the response of up audit function
type RespUpAudit struct {
Succ []int64 `json:"succ"`
Invalid []int64 `json:"invalid"`
}
// UpMC is upper info in MC
type UpMC struct {
ID int
MID int64 `gorm:"column:mid"`
Toinit int
Submit int // 1=need report
OriName string `gorm:"column:ori_name"` // original name
CMSName string `gorm:"column:cms_name"` // cms intervened name
OriFace string `gorm:"column:ori_face"` // original face
CMSFace string `gorm:"column:cms_face"` // cms intervened face
Valid int // auth info: 1=online,0=hidden
Deleted int
}
// TableName ugc_uploader
func (a UpMC) TableName() string {
return "ugc_uploader"
}

View File

@@ -0,0 +1,55 @@
package model
import "go-common/library/time"
// TvUserInfo is table struct
type TvUserInfo struct {
ID int64 `json:"id"`
MID int64 `json:"mid" gorm:"column:mid"`
Ver int64 `json:"ver"`
VipType int8 `json:"vip_type"`
PayType int8 `json:"pay_type"`
PayChannelID string `json:"pay_channel_id"`
Status int8 `json:"status"`
OverdueTime time.Time `json:"overdue_time"`
RecentPayTime time.Time `json:"recent_pay_time"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// TvUserInfoResp is used to user info
type TvUserInfoResp struct {
ID int64 `json:"id"`
MID int64 `json:"mid" gorm:"column:mid"`
VipType int8 `json:"vip_type"`
PayType int8 `json:"pay_type"`
PayChannelID string `json:"pay_channel_id"`
Status int8 `json:"status"`
OverdueTime time.Time `json:"overdue_time"`
RecentPayTime time.Time `json:"recent_pay_time"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// TvUserChangeHistory is table struct
type TvUserChangeHistory struct {
ID int64 `json:"id"`
MID int64 `json:"mid"`
ChangeType int8 `json:"change_type"`
ChangeTime time.Time `json:"change_time"`
Days int64 `json:"days"`
OperatorId string `json:"operator_id"`
Remark string `json:"remark"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// TableName tv_user_info
func (t *TvUserInfo) TableName() string {
return "tv_user_info"
}
// TableName tv_user_info
func (t *TvUserInfoResp) TableName() string {
return "tv_user_info"
}

View File

@@ -0,0 +1,83 @@
package model
import (
"go-common/library/time"
)
// VersionUpdate .
type VersionUpdate struct {
ID int64 `json:"id"`
VID int `json:"vid" gorm:"column:vid"`
Channel string `json:"channel"`
Coverage int32 `json:"coverage"`
Size int `json:"size"`
URL string `json:"url" gorm:"column:url"`
Md5 string `json:"md5"`
State int8 `json:"state"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
Sdkint int `json:"sdkint"`
Model string `json:"model"`
Policy int8 `json:"policy"`
IsForce int8 `json:"is_force"`
PolicyName string `json:"policy_name"`
IsPush int8 `json:"is_push"`
}
// VersionUpdateLimit .
type VersionUpdateLimit struct {
ID int64 `json:"id"`
UPID int32 `json:"up_id" gorm:"column:up_id"`
Condi string `json:"condi"`
Value int `json:"value"`
}
// VersionUpdateDetail .
type VersionUpdateDetail struct {
*VersionUpdate
VerLimit []*VersionUpdateLimit `json:"ver_limit"`
}
// TableName version_update
func (v VersionUpdate) TableName() string {
return "version_update"
}
// TableName version_update_limit
func (l VersionUpdateLimit) TableName() string {
return "version_update_limit"
}
// VersionUpdatePager def.
type VersionUpdatePager struct {
TotalCount int64 `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items map[string]interface{} `json:"items"`
}
// Version .
type Version struct {
ID int64 `json:"id"`
Plat int8 `json:"plat"`
Description string `json:"description"`
Version string `json:"version"`
Build int `json:"build"`
State int8 `json:"state"`
Ptime time.Time `json:"ptime"`
Ctime time.Time `json:"ctime"`
Mtime time.Time `json:"mtime"`
}
// TableName version
func (*Version) TableName() string {
return "version"
}
// VersionPager def.
type VersionPager struct {
TotalCount int64 `json:"total_count"`
Pn int `json:"pn"`
Ps int `json:"ps"`
Items []*Version `json:"items"`
}

View File

@@ -0,0 +1,110 @@
package model
import (
arccli "go-common/app/service/main/archive/api"
"go-common/library/time"
)
// Video is used from PGC video
type Video struct {
ID int `gorm:"column:id" json:"id"`
AID int `gorm:"column:aid" json:"aid"`
Eptitle string `gorm:"column:eptitle" json:"eptitle"`
Description string `gorm:"column:description" json:"description"`
CID int64 `gorm:"column:cid" json:"cid"`
Duration int `gorm:"column:duration" json:"duration"`
IndexOrder int `gorm:"column:duration" json:"index_order"`
Ctime time.Time `gorm:"column:ctime" json:"ctime"`
Mtime time.Time `gorm:"column:mtime" json:"mtime"`
InjectTime time.Time `gorm:"column:inject_time" json:"inject_time"`
Valid uint8 `gorm:"column:valid" json:"valid"`
Submit uint8 `gorm:"column:submit" json:"submit"`
Retry int `gorm:"column:retry" json:"retry"`
Result int `gorm:"column:result" json:"result"`
Deleted uint8 `gorm:"column:deleted" json:"deleted"`
State int `gorm:"column:state" json:"state"`
Reason string `gorm:"column:reason" json:"reason"`
Manual int `gorm:"column:manual" json:"manual"`
}
// VideoListParam is used for vlideolist funtion param valid
type VideoListParam struct {
CID string `form:"cid" json:"cid"`
VID string `form:"vid" json:"vid"`
Typeid int16 `form:"typeid" json:"typeid"`
Pid int32 `form:"pid" json:"-"`
Valid string `form:"valid" json:"valid"`
Order int `form:"order" json:"order" default:"2"`
Pn int `form:"pn" json:"pn" default:"1"`
Ps int `form:"ps" json:"ps" default:"20"`
}
// VideoListQuery is used for selecting the field of pgc video
type VideoListQuery struct {
ID string `json:"id"`
VID string `json:"vid" gorm:"column:cid"`
CID string `json:"cid" gorm:"column:aid"`
Eptitle string `json:"eptitle"`
Valid string `json:"valid" gorm:"column:valid"`
Mtime time.Time `json:"mtime"`
SeasonTitle string `json:"season_title" gorm:"column:title"`
TypeID int32 `json:"typeid" gorm:"column:typeid"`
PTypeID int32 `json:"parent_typeid"`
Page int `json:"page" gorm:"column:index_order"`
}
// VideoListPager is used by video list function to return result and page info
type VideoListPager struct {
Items []*VideoListQuery `json:"items"`
Page *Page `json:"page"`
}
// TableName ugc_video
func (a VideoListQuery) TableName() string {
return "ugc_video"
}
// TableName ugc_video
func (video Video) TableName() string {
return "ugc_video"
}
// ConsultRes transforms an archive to ArcRes
func (arc *Archive) ConsultRes(dict map[int32]*arccli.Tp) (res *ArcRes) {
var pid int32
res = &ArcRes{}
if cat, ok := dict[arc.TypeID]; ok {
pid = cat.Pid
res.SecondCat = cat.Name
}
if pid != 0 {
if pcat, ok := dict[pid]; ok {
res.FirstCat = pcat.Name
}
}
res.Status = int(arc.Result)
res.AVID = arc.AID
res.Title = arc.Title
res.PubTime = arc.Pubtime.Time().Format("2006-01-02 15:04:05")
if arc.InjectTime >= 0 {
res.InjectTime = arc.InjectTime.Time().Format("2006-01-02 15:04:05")
}
res.Reason = arc.Reason
return
}
// ConsultRes transforms an video to VideoRes
func (video *Video) ConsultRes() (res *VideoRes) {
res = &VideoRes{
CID: video.CID,
Title: video.Eptitle,
Page: video.IndexOrder,
Status: video.Result,
Ctime: video.Ctime.Time().Format("2006-01-02 15:04:05"),
Reason: video.Reason,
}
if video.InjectTime >= 0 {
res.InjectTime = video.InjectTime.Time().Format("2006-01-02 15:04:05")
}
return
}

View File

@@ -0,0 +1,93 @@
package model
import "go-common/library/time"
const (
//WatermarkWhite 水印白名单
WatermarkWhite = 1
//WatermarkDefault 水印默认值
WatermarkDefault = 0
//OrderDesc 降序
OrderDesc = 1
)
// WaterMarkList def.
type WaterMarkList struct {
ID string `form:"id" json:"id"`
Epid string `form:"epid" json:"epid"`
SeasonID string `form:"season_id" json:"season_id"`
Category string `form:"category" json:"category"`
SeasonTitle string `form:"season_title" json:"season_title"`
ContentTitle string `form:"content_title" json:"content_title"`
MarkTime time.Time `form:"mark_time" json:"mark_time"`
}
// WaterMarkOne is used for only selecting some field from gorm query
type WaterMarkOne struct {
ID string `form:"id" json:"id"`
Mark uint8 `form:"mark" json:"mark"`
MarkTime string `form:"mark_time" json:"mark_time"`
}
// WaterMarkListPager is used for return items and pager info
type WaterMarkListPager struct {
Items []*WaterMarkList `json:"items"`
Page *Page `json:"page"`
}
// WaterMarkListParam is use for watermarklist function query param valid
type WaterMarkListParam struct {
Order uint8 `form:"id" json:"order" default:"1"`
EpID string `form:"epid" json:"epid"`
SeasonID string `form:"season_id" json:"season_id"`
Category string `form:"category" json:"category"`
Pn int `form:"pn" json:"pn;Min(1)" default:"1"`
Ps int `form:"ps" json:"ps;Min(1)" default:"20"`
}
// TransReq is the request for transcode consulting
type TransReq struct {
Order int `form:"order" default:"1"` // 1=desc,2=asc
EpID int64 `form:"epid"`
SeasonID int64 `form:"season_id"`
Title string `form:"title"`
Category int `form:"category" validate:"min=0,max=5"`
Status string `form:"status"`
Pn int `form:"pn" default:"1"`
}
// TransReply is the response for transList
type TransReply struct {
EpID int64 `json:"epid"`
SeasonID int64 `json:"season_id"`
Category string `json:"category"`
Etitle string `json:"etitle"`
Stitle string `json:"stitle"`
Transcoded int `json:"transcoded"`
ApplyTime string `json:"apply_time"`
MarkTime string `json:"mark_time"`
}
// TransPager is used for return items and pager info
type TransPager struct {
Items []*TransReply `json:"items"`
Page *Page `json:"page"`
CountSn int `json:"count_sn"`
}
// AddEpIDResp is for function addEpID to return success and not exist and invalid values
type AddEpIDResp struct {
Succ []int64
NotExist []int64
Invalids []int64
}
// TableName select watermark list
func (a WaterMarkList) TableName() string {
return "tv_content"
}
//TableName only select watermark one
func (a WaterMarkOne) TableName() string {
return "tv_content"
}

View File

@@ -0,0 +1,91 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"archive_test.go",
"audit_result_test.go",
"intervs_test.go",
"playurl_test.go",
"region_test.go",
"service_test.go",
"sync_pgc_test.go",
"uplayurl_test.go",
"upper_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/admin/main/tv/conf:go_default_library",
"//app/admin/main/tv/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"arcType.go",
"arc_audit.go",
"archive.go",
"audit_result.go",
"full.go",
"intervs.go",
"label.go",
"mango.go",
"modules.go",
"order.go",
"others.go",
"panel.go",
"region.go",
"sear_inter.go",
"service.go",
"sync_pgc.go",
"uplayurl.go",
"upper.go",
"user.go",
"video.go",
"watermark.go",
],
importpath = "go-common/app/admin/main/tv/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/tv/conf:go_default_library",
"//app/admin/main/tv/dao:go_default_library",
"//app/admin/main/tv/model:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/time:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/siddontang/go-mysql/mysql:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,75 @@
package service
import (
"fmt"
arcmdl "go-common/app/service/main/archive/api"
"go-common/library/ecode"
"go-common/library/log"
"github.com/pkg/errors"
)
// loadTypes is used for gettting archive data from rpc
func (s *Service) loadTypes() (err error) {
var (
res map[int32]*arcmdl.Tp
resRel = make(map[int32][]int32)
typeReply *arcmdl.TypesReply
)
if typeReply, err = s.arcClient.Types(ctx, &arcmdl.NoArgRequest{}); err != nil {
log.Error("arcRPC loadType Error %v", err)
return
}
res = typeReply.Types
if len(res) == 0 {
log.Error("arcRPC loadType Empty")
return
}
for _, tInfo := range res {
if _, ok := resRel[tInfo.Pid]; !ok {
resRel[tInfo.Pid] = []int32{tInfo.ID}
continue
}
resRel[tInfo.Pid] = append(resRel[tInfo.Pid], tInfo.ID)
}
s.ArcTypes = res
s.arcPTids = resRel
return
}
// arcPName is used for get arc first partition with typeID(second partition)
func (s *Service) arcPName(cID int32) (name string, pid int32, err error) {
var (
c, p *arcmdl.Tp
ok bool
code = ecode.RequestErr.Code()
)
if c, ok = s.ArcTypes[cID]; !ok {
err = errors.Wrap(ecode.Int(code), fmt.Sprintf("can't find type for ID: %d ", cID))
return
}
if p, ok = s.ArcTypes[c.Pid]; !ok {
err = errors.Wrap(ecode.Int(code), fmt.Sprintf("can't find type for ID: %d, parent id: %d", cID, c.Pid))
return
}
return p.Name, c.Pid, nil
}
//Contains is used for check string in array
func (s *Service) Contains(tid int32) (contain bool) {
var (
name string
err error
)
if name, _, err = s.arcPName(tid); err != nil {
log.Warn("s.CheckArc.arcPName Tid %d, error(%v)", tid, err)
return
}
for _, v := range s.c.Cfg.PGCTypes {
if v == name {
return true
}
}
return
}

View File

@@ -0,0 +1,107 @@
package service
import (
"go-common/app/admin/main/tv/model"
arcmdl "go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
"go-common/library/ecode"
"go-common/library/log"
"github.com/jinzhu/gorm"
)
func arcNormal(state int32) bool {
if state >= 0 || state == -6 { // archive can play
return true
}
return false
}
//AddArcs is used for adding archive
func (s *Service) AddArcs(aids []int64) (res *model.AddResp, err error) {
var (
valid bool
arc *model.SimpleArc
errFmt = "AddArcs %d, Error %v"
)
res = &model.AddResp{
Succ: []int64{},
Invalids: []int64{},
Exist: []int64{},
}
for _, v := range aids {
if valid, err = s.CheckArc(v); err != nil {
log.Error(errFmt, v, err)
return
}
// not valid aids
if !valid {
res.Invalids = append(res.Invalids, v)
continue
}
if arc, err = s.ExistArc(v); err != nil {
log.Error(errFmt, v, err)
return
}
// in our DB, already exist aids
if arc != nil {
res.Exist = append(res.Exist, v)
continue
}
if err = s.dao.NeedImport(v); err != nil {
log.Error(errFmt, v, err)
return
}
// added succesfully aids
res.Succ = append(res.Succ, v)
}
return
}
// CheckArc checks whether the archive is able to play and existing in Archive DB
func (s *Service) CheckArc(aid int64) (ok bool, err error) {
var (
argAid2 = &arcmdl.ArcRequest{Aid: aid}
arcReply *arcmdl.ArcReply
)
if arcReply, err = s.arcClient.Arc(ctx, argAid2); err != nil {
if ecode.NothingFound.Equal(err) { // archive not found at all
err = nil
return
}
log.Error("s.arcRPC.Archive3(%v) error(%v)", argAid2, err)
return
}
arc := arcReply.Arc
if s.Contains(arc.TypeID) { // filter pgc types
ok = false
return
}
if arc.Copyright != 1 {
ok = false
return
}
if arc.Rights.UGCPay == archive.AttrYes {
ok = false
return
}
if arcNormal(arc.State) {
ok = true
}
return
}
// ExistArc checks whether the archive is already in our TV DB, which means no need to import again
func (s *Service) ExistArc(aid int64) (res *model.SimpleArc, err error) {
var arc = model.SimpleArc{}
if err = s.DB.Where("aid = ?", aid).Where("deleted = ?", 0).First(&arc).Error; err != nil {
if err == gorm.ErrRecordNotFound {
err = nil
res = nil
return
}
log.Error("ExistArc DB Error %v", err)
return
}
return &arc, nil
}

View File

@@ -0,0 +1,260 @@
package service
import (
"fmt"
"context"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/xstr"
)
const (
_arcOnline = 1
_arcOffline = 2
)
// typeBubbleSort sort type
func typeBubbleSort(pTypes []model.UgcType) (pSortTypes []model.UgcType) {
flag := true
for i := 0; i < len(pTypes)-1; i++ {
flag = true
for j := 0; j < len(pTypes)-i-1; j++ {
if pTypes[j].ID > pTypes[j+1].ID {
pTypes[j], pTypes[j+1] = pTypes[j+1], pTypes[j]
flag = false
}
}
if flag {
break
}
}
pSortTypes = pTypes
return
}
func (s *Service) existArcTps(passed bool) (existTypes map[int32]int, err error) {
var (
arcs []*model.Archive
db = s.DB.Where("deleted = ?", 0)
)
if passed {
db = db.Where("result = ?", 1)
}
existTypes = make(map[int32]int)
if err = db.Select("DISTINCT(typeid)").Find(&arcs).Error; err != nil {
log.Error("DistinctType Error %v", err)
return
}
for _, v := range arcs {
existTypes[v.TypeID] = 1
}
return
}
//arcTp return archive type list
func (s *Service) arcTp(passed bool) (pTypes []model.UgcType, err error) {
var (
cTypeList = make(map[int32][]model.UgcCType)
oriPTypes []model.UgcType
existTypes map[int32]int
)
typeList := s.ArcTypes
if existTypes, err = s.existArcTps(passed); err != nil {
return
}
//make parent and child node sperate
for _, v := range typeList {
if v.Pid == 0 {
oriPTypes = append(oriPTypes, model.UgcType{
ID: v.ID,
Name: v.Name,
})
} else {
cType := model.UgcCType{
Pid: v.Pid,
ID: v.ID,
Name: v.Name,
}
if _, ok := existTypes[v.ID]; ok {
cTypeList[v.Pid] = append(cTypeList[v.Pid], cType)
}
}
}
for _, v := range oriPTypes {
if cValue, ok := cTypeList[v.ID]; ok {
v.Children = cValue
pTypes = append(pTypes, v)
}
}
pTypes = typeBubbleSort(pTypes)
return
}
func (s *Service) loadTps() {
var (
data = &model.AvailTps{}
err error
)
if data.AllTps, err = s.arcTp(false); err != nil {
log.Error("loadTps Passed Err %v", err)
return
}
if data.PassedTps, err = s.arcTp(true); err != nil {
log.Error("loadTps All Err %v", err)
return
}
if len(data.AllTps) > 0 || len(data.PassedTps) > 0 {
s.avaiTps = data
}
}
// GetTps get cms used types data
func (s *Service) GetTps(c context.Context, passed bool) (data []model.UgcType, err error) {
if s.avaiTps == nil {
err = ecode.ServiceUnavailable
return
}
if passed {
data = s.avaiTps.PassedTps
} else {
data = s.avaiTps.AllTps
}
return
}
//GetArchivePid get archive pid with child id
func (s *Service) GetArchivePid(id int32) (pid int32) {
if value, ok := s.ArcTypes[id]; ok {
pid = value.Pid
return
}
return 0
}
func (s *Service) midTreat(param *model.ArcListParam) (mids []int64) {
if param.Mid != 0 {
return []int64{param.Mid}
}
if param.UpName != "" {
var data []*model.Upper
if err := s.DB.Where("ori_name LIKE ?", "%"+param.UpName+"%").Where("deleted = 0").Find(&data).Error; err != nil {
log.Error("ArchiveList MidTreat UpName %s, Err %v", param.UpName, err)
return
}
if len(data) > 0 {
for _, v := range data {
mids = append(mids, v.MID)
}
}
}
return
}
// ArchiveList is used for getting archive list
func (s *Service) ArchiveList(c *bm.Context, param *model.ArcListParam) (pager *model.ArcPager, err error) {
var (
archives []*model.ArcDB
reqES = new(model.ReqArcES)
data *model.EsUgcResult
aids []int64
mids []int64
upsInfo map[int64]string
)
reqES.FromArcListParam(param, s.typeidsTreat(param.Typeid, param.Pid))
reqES.Mids = s.midTreat(param)
pager = new(model.ArcPager)
if data, err = s.dao.ArcES(c, reqES); err != nil {
log.Error("ArchiveList Req %v, Err %v", param, err)
return
}
pager.Page = data.Page
if len(data.Result) == 0 {
return
}
for _, v := range data.Result {
aids = append(aids, v.AID)
mids = append(mids, v.MID)
}
if err = s.DB.Order("mtime " + reqES.MtimeSort()).Where(fmt.Sprintf("aid IN (%s)", xstr.JoinInts(aids))).Find(&archives).Error; err != nil {
log.Error("s.ArchiveList Find archives error(%v)", err)
return
}
if upsInfo, err = s.pickUps(mids); err != nil {
return
}
for _, v := range archives {
item := v.ToList(s.GetArchivePid(v.TypeID))
if name, ok := upsInfo[v.MID]; ok {
item.UpName = name
}
pager.Items = append(pager.Items, item)
}
return
}
func (s *Service) pickUps(mids []int64) (res map[int64]string, err error) {
if len(mids) == 0 {
return
}
var resSlice []*model.CmsUpper
res = make(map[int64]string, len(mids))
if err = s.DB.Where(fmt.Sprintf("mid IN (%s)", xstr.JoinInts(mids))).Where("deleted = 0").Find(&resSlice).Error; err != nil {
log.Error("pickUps Mids %v, Err %v", mids, err)
return
}
for _, v := range resSlice {
res[v.MID] = v.OriName
}
return
}
// ArcAction is used for online ugc archive
func (s *Service) ArcAction(ids []int64, action int) (err error) {
var (
w = map[string]interface{}{"deleted": 0, "result": 1}
tx = s.DB.Model(&model.Archive{}).Begin()
actValid int
)
if action == _arcOnline {
actValid = 1
} else if action == _arcOffline {
actValid = 0
} else {
return ecode.TvDangbeiWrongType
}
for _, v := range ids {
arch := model.Archive{}
if errDB := tx.Where(w).Where("id=?", v).First(&arch).Error; errDB != nil {
err = fmt.Errorf("找不到id为%v的数据", v)
log.Error("s.ArcAction First error(%v)", err)
tx.Rollback()
return
}
if errDB := tx.Where("id=?", v).
Update("valid", actValid).Error; errDB != nil {
err = errDB
log.Error("s.ArcAction Update error(%v)", err)
tx.Rollback()
return
}
}
tx.Commit()
return
}
// ArcUpdate is used for update ugc archive
func (s *Service) ArcUpdate(id int64, cover string, content string, title string) (err error) {
up := map[string]interface{}{
"cover": cover,
"content": content,
"title": title,
}
if err = s.DB.Model(&model.Archive{}).Where("id=?", id).Update(up).Error; err != nil {
log.Error("s.ArcUpdate Update error(%v)", err)
return
}
return
}

View File

@@ -0,0 +1,35 @@
package service
import (
"testing"
"fmt"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_CheckArc(t *testing.T) {
Convey("TestService_CheckArc Test", t, WithService(func(s *Service) {
res, err := s.CheckArc(10099763)
So(res, ShouldBeTrue)
So(err, ShouldBeNil)
}))
}
func TestService_ExistArc(t *testing.T) {
Convey("TestService_ExistArc Test", t, WithService(func(s *Service) {
res, err := s.ExistArc(12009430)
So(err, ShouldBeNil)
fmt.Println(res)
}))
}
func TestService_AddArcs(t *testing.T) {
Convey("TestService_ArchiveAdd Test", t, WithService(func(s *Service) {
res, err := s.AddArcs([]int64{
10099763, 10099764,
})
So(err, ShouldBeNil)
fmt.Println(res)
}))
}

View File

@@ -0,0 +1,247 @@
package service
import (
"net/url"
"context"
"fmt"
"go-common/app/admin/main/tv/model"
"go-common/library/log"
"go-common/library/time"
"go-common/library/xstr"
)
// order const
const (
newOrder = 1
)
// EpResult gives the result of ep audit
func (s *Service) EpResult(req url.Values, page int, order int) (pager *model.EPResultPager, err error) {
var (
count int64
size = s.c.Cfg.AuditRSize
items []*model.EPResDB
db = s.DB.Model(&model.Content{}).
Where("tv_content.is_deleted=?", 0).
Joins("LEFT JOIN tv_ep_season ON tv_content.season_id=tv_ep_season.id").
Select("tv_content.*,tv_ep_season.title as stitle,tv_ep_season.category")
)
// order treatment
if order == newOrder {
db = db.Order("tv_content.inject_time DESC")
} else {
db = db.Order("tv_content.inject_time ASC")
}
// category treatment
if category := req.Get("category"); category != "" {
db = db.Where("tv_ep_season.category=?", category)
}
// audit status treatment
if state := req.Get("state"); state != "" {
switch state {
case "1": // passed
db = db.Where("tv_content.`state` = ?", 3)
case "2": // reject
db = db.Where("tv_content.`state` = ?", 4)
default: // waiting result
db = db.Where("tv_content.`state` NOT IN (3,4)")
}
}
// season_id treatment
if sid := req.Get("season_id"); sid != "" {
db = db.Where("tv_content.season_id=?", sid)
}
// epid treatment
if epid := req.Get("epid"); epid != "" {
db = db.Where("tv_content.epid=?", epid)
}
if err = db.Count(&count).Error; err != nil {
log.Error("Count Err %v", err)
return
}
pager = &model.EPResultPager{
Page: &model.Page{
Num: page,
Size: size,
Total: int(count),
},
}
if err = db.Offset((page - 1) * size).Limit(size).Find(&items).Error; err != nil {
return
}
// use time in string format to replace the time in number format
for _, v := range items {
pager.Items = append(pager.Items, v.ToItem())
}
return
}
//TimeFormat is used for format time
func (s *Service) TimeFormat(time time.Time) (format string) {
if time < 0 {
return ""
}
return time.Time().Format("2006-01-02 15:04:05")
}
// SeasonResult gives the result of ep audit
func (s *Service) SeasonResult(req url.Values, page int, order int) (pager *model.SeasonResultPager, err error) {
var (
count int64
size = s.c.Cfg.AuditRSize
dbTerms []*model.SeasonResDB
db = s.DB.Model(&model.TVEpSeason{}).Where("is_deleted=?", 0)
)
// order treatment
if order == newOrder {
db = db.Order("inject_time DESC")
} else {
db = db.Order("inject_time ASC")
}
// category treatment
if category := req.Get("category"); category != "" {
db = db.Where("tv_ep_season.category=?", category)
}
// audit status treatment
if state := req.Get("check"); state != "" {
switch state {
case "1": // passed
db = db.Where("tv_ep_season.`check` = ?", 1)
case "2": // reject
db = db.Where("tv_ep_season.`check` = ?", 0)
default: // waiting result
db = db.Where("tv_ep_season.`check` NOT IN (0,1)")
}
}
// season_id treatment
if sid := req.Get("season_id"); sid != "" {
db = db.Where("id=?", sid)
}
// title treatment
if title := req.Get("title"); title != "" {
db = db.Where("title LIKE ?", "%"+title+"%")
}
if err = db.Count(&count).Error; err != nil {
log.Error("db Count Err %v", err)
return
}
pager = &model.SeasonResultPager{
Page: &model.Page{
Num: page,
Size: size,
Total: int(count),
},
}
if err = db.Offset((page - 1) * size).Limit(size).Find(&dbTerms).Error; err != nil {
return
}
for _, v := range dbTerms {
pager.Items = append(pager.Items, v.ToItem())
}
return
}
func (s *Service) typeidsTreat(secondCat int32, firstCat int32) (typeids []int32) {
if secondCat != 0 { // typeid logic
typeids = []int32{secondCat}
} else if firstCat != 0 {
if secondCats, ok := s.arcPTids[firstCat]; ok && len(secondCats) > 0 {
typeids = secondCats
}
}
return
}
// ArcResult picks archive result data
func (s *Service) ArcResult(c context.Context, req *model.ReqArcCons) (data *model.ArcResPager, err error) {
if data, err = s.arcByES(req, s.typeidsTreat(req.SecondCat, req.FirstCat)); err != nil {
log.Error("arcByEs Err %v", err)
return
}
return
}
func (s *Service) arcByES(req *model.ReqArcCons, typeids []int32) (data *model.ArcResPager, err error) {
var (
esRes *model.EsUgcResult
aids []int64
arcs []*model.Archive
arcsMap = make(map[int64]*model.ArcRes)
reqES = new(model.ReqArcES)
)
reqES.FromAuditConsult(req, typeids)
if esRes, err = s.dao.ArcES(ctx, reqES); err != nil {
log.Error("UgcConsult Err %v", err)
return
}
data = &model.ArcResPager{
Page: esRes.Page,
}
if len(esRes.Result) == 0 {
return
}
for _, v := range esRes.Result {
aids = append(aids, v.AID)
}
if err = s.DB.Where(fmt.Sprintf("aid IN (%s)", xstr.JoinInts(aids))).Find(&arcs).Error; err != nil {
log.Error("arcByES DB Aids %v Err %v", aids, err)
return
}
if len(arcs) == 0 {
return
}
for _, v := range arcs {
arcsMap[v.AID] = v.ConsultRes(s.ArcTypes)
}
for _, v := range aids {
if arc, ok := arcsMap[v]; ok {
data.Items = append(data.Items, arc)
}
}
return
}
// VideoResult picks video audit consult result
func (s *Service) VideoResult(c context.Context, req *model.ReqVideoCons) (data *model.VideoResPager, err error) {
var (
videos []*model.Video
)
data = &model.VideoResPager{
Page: &model.Page{
Num: req.Pn,
Size: _pagesize,
},
}
db := s.DB.Model(&model.Video{}).Where("aid = ?", req.AVID).Where("deleted = 0")
if req.Status != "" {
db = db.Where("result = ?", req.Status)
}
if req.Title != "" {
db = db.Where("eptitle LIKE ?", "%"+req.Title+"%")
}
if req.CID != 0 {
db = db.Where("cid = ?", req.CID)
}
if err = db.Count(&data.Page.Total).Error; err != nil {
log.Error("VideoResult Count Err %v", err)
return
}
if req.Order != 1 {
db = db.Order("index_order ASC")
} else {
db = db.Order("index_order DESC")
}
if err = db.Offset((req.Pn - 1) * _pagesize).Limit(_pagesize).Find(&videos).Error; err != nil {
log.Error("arcByDB Err %v", err)
}
if len(videos) == 0 {
return
}
for _, v := range videos {
data.Items = append(data.Items, v.ConsultRes())
}
return
}

View File

@@ -0,0 +1,26 @@
package service
import (
"net/url"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_EpResult(t *testing.T) {
Convey("EPResult Test", t, WithService(func(s *Service) {
var req = url.Values{}
pager, err := s.EpResult(req, 1, 1)
So(err, ShouldBeNil)
So(len(pager.Items), ShouldBeGreaterThan, 0)
}))
}
func TestService_SeasonResult(t *testing.T) {
Convey("SeasonResult Test", t, WithService(func(s *Service) {
var req = url.Values{}
pager, err := s.SeasonResult(req, 1, 1)
So(err, ShouldBeNil)
So(len(pager.Items), ShouldBeGreaterThan, 0)
}))
}

View File

@@ -0,0 +1,59 @@
package service
import (
"context"
"database/sql"
"time"
"go-common/app/admin/main/tv/model"
"go-common/library/log"
)
// FullImport .
func (s *Service) FullImport(c context.Context, build int) (result []*model.APKInfo, err error) {
result, err = s.dao.FullImport(c, build)
return
}
func (s *Service) loadSnsproc() {
for {
time.Sleep(time.Duration(s.c.Cfg.LoadSnFre))
s.loadSns(context.Background())
}
}
// loadSns loads all not deleted season Info
func (s *Service) loadSns(c context.Context) (err error) {
var (
rows *sql.Rows
sns = make(map[int64]*model.TVEpSeason)
sidCats = make(map[int][]int64)
)
if rows, err = s.DB.Model(&model.TVEpSeason{}).Where("is_deleted = 0").Select("id, title, category, state, valid, `check`").Rows(); err != nil {
log.Error("rows Err %v", err)
return
}
defer rows.Close()
for rows.Next() {
cont := &model.TVEpSeason{}
if err = rows.Scan(&cont.ID, &cont.Title, &cont.Category, &cont.State, &cont.Valid, &cont.Check); err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
sns[cont.ID] = cont
if dataSet, ok := sidCats[cont.Category]; !ok {
sidCats[cont.Category] = []int64{cont.ID}
} else {
sidCats[cont.Category] = append(dataSet, cont.ID)
}
}
if err = rows.Err(); err != nil {
log.Error("rows.Err %v", err)
return
}
if len(sns) > 0 {
s.snsInfo = sns
s.snsCats = sidCats
}
return
}

View File

@@ -0,0 +1,199 @@
package service
import (
"go-common/app/admin/main/tv/model"
"go-common/library/database/sql"
"go-common/library/log"
)
// 0=not found, 1=pgc, 2=cms, 3=license
const (
ErrNotFound = 0
_TypeDefault = 0
_TypePGC = 1
_TypeUGC = 2
)
func (s *Service) getSeason(sid int64) (res *model.TVEpSeason, err error) {
sn := model.TVEpSeason{}
if err = s.DB.Where("id = ?", sid).First(&sn).Error; err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
log.Error("GetSeason error(%v)\n", err)
return
}
return &sn, nil
}
// RemoveInvalids removes invalid interventions
func (s *Service) RemoveInvalids(invalids []*model.RankError) (err error) {
tx := s.DB.Begin()
for _, v := range invalids {
if err = tx.Model(&model.Rank{}).Where("id=?", v.ID).Update(map[string]int{"is_deleted": 1}).Error; err != nil {
log.Error("tvSrv.RemoveInvalids error(%v)", err)
tx.Rollback()
return
}
}
tx.Commit()
log.Info("Remove Invalid Interventions: %d", len(invalids))
return
}
// Intervs pick the intervention and combine the season data
func (s *Service) Intervs(req *model.IntervListReq) (res *model.RankList, err error) {
var (
intervs []*model.Rank
items []*model.SimpleRank
invalids []*model.RankError
db = req.BuildDB(s.DB).Order("position asc")
)
if err = db.Find(&intervs).Error; err != nil {
log.Error("[Intervs] DB query fail(%v)", err)
return
}
items, invalids = s.intervsValid(intervs)
err = s.RemoveInvalids(invalids)
res = &model.RankList{
List: items,
}
return
}
func (s *Service) intervsValid(intervs []*model.Rank) (items []*model.SimpleRank, invalids []*model.RankError) {
// check Its Season Status, pick invalid ones
for _, v := range intervs {
switch v.ContType {
case _TypePGC, _TypeDefault:
isValid, sn := s.snValid(v.ContID)
if !isValid {
invalids = append(invalids, v.BeError())
continue
}
items = append(items, v.BeSimpleSn(sn, s.pgcCatToName))
case _TypeUGC:
isValid, arc := s.arcValid(v.ContID)
if !isValid {
invalids = append(invalids, v.BeError())
continue
}
items = append(items, v.BeSimpleArc(arc, s.arcPName))
default:
log.Error("[Intervs] Rank Error Cont_Type %d, RankID:%d", v.ContType, v.ID)
continue
}
}
return
}
// snValid Distinguish whether the Season is existing and valid
func (s *Service) snValid(sid int64) (res bool, season *model.TVEpSeason) {
var err error
if season, err = s.getSeason(sid); err != nil || season == nil {
return
}
res = errTyping(int(season.Check), int(season.Valid), int(season.IsDeleted))
return
}
// arcValid Distinguish whether the archive is existing and valid
func (s *Service) arcValid(aid int64) (res bool, arc *model.SimpleArc) {
var err error
if arc, err = s.ExistArc(aid); err != nil || arc == nil {
return
}
res = errTyping(arc.Result, arc.Valid, arc.Deleted)
return
}
func errTyping(check, valid, isDeleted int) (res bool) {
if check == 1 && valid == 1 && isDeleted == 0 {
return true
}
return false
}
// RefreshIntervs is used to delete the previous interventions
func (s *Service) RefreshIntervs(req *model.IntervPubReq) (invalid *model.RankError, err error) {
var (
tx = s.DB.Begin()
txDel = req.BuildDB(tx)
position = 1
title string
)
if err = txDel.Delete(&model.Rank{}).Error; err != nil { // delete old intervs
log.Error("Del Previsou Intervs error(%v)\n", err)
tx.Rollback()
return
}
for _, v := range req.Items {
if invalid, title = s.checkInterv(req, v); invalid != nil {
tx.Rollback()
return
}
if err = tx.Create(v.BeComplete(req, title, position)).Error; err != nil { // create new ones
log.Error("Create New Intervs %v ,Error(%v)\n", v, err)
tx.Rollback()
return
}
position = position + 1
}
tx.Commit()
log.Info("RefreshIntervs Success")
return
}
// checkInterv checks whether the to-publish intervention is valid
func (s *Service) checkInterv(req *model.IntervPubReq, v *model.SimpleRank) (invalid *model.RankError, title string) {
var (
isValid bool
sn *model.TVEpSeason
arc *model.SimpleArc
rankErr = &model.RankError{
ID: int(v.ID),
SeasonID: int(v.ContID),
}
)
if req.IsIdx() {
if int(req.Category) != v.ContType+model.RankIdxBase { // if ugc, we can't accept pgc data
isValid = false
return rankErr, ""
}
}
switch v.ContType {
case _TypePGC, _TypeDefault:
isValid, sn = s.snValid(v.ContID)
if isValid && req.IsIdx() { // if index, check it's the pgc category's season
isValid = (sn.Category == int(req.Rank))
}
case _TypeUGC:
isValid, arc = s.arcValid(v.ContID)
if isValid && req.IsIdx() { // if index, check it's the first level type's archive
pid := s.GetArchivePid(arc.TypeID)
isValid = pid == int32(req.Rank)
}
default:
log.Error("[Intervs] Rank Error Cont_Type %d, RankID:%d", v.ContType, v.ID)
return rankErr, ""
}
if !isValid {
log.Error("snValid (%d) Not passed", v.ContID)
return rankErr, ""
}
if v.ContType == _TypeUGC && arc != nil {
title = arc.Title
}
if (v.ContType == _TypePGC || v.ContType == _TypeDefault) && sn != nil {
title = sn.Title
}
return
}
func (s *Service) pgcCatToName(cat int) (res string) {
if res, ok := s.pgcCatName[cat]; ok {
return res
}
return ""
}

View File

@@ -0,0 +1,59 @@
package service
import (
"fmt"
"testing"
"go-common/app/admin/main/tv/model"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_SeasonValidation(t *testing.T) {
Convey("Season Validation Test", t, WithService(func(s *Service) {
var season model.TVEpSeason
if err := s.DB.Model(&model.TVEpSeason{}).Where("`check`=?", 1).
Where("valid=?", 1).Where("is_deleted=?", 0).First(&season).Error; err != nil {
fmt.Printf("Error:(%v)", err)
return
}
fmt.Printf("Target ID is: %d", season.ID)
res, sModel := s.snValid(season.ID)
So(res, ShouldBeTrue)
So(sModel.ID == season.ID, ShouldBeTrue)
}))
}
func TestService_Intervs(t *testing.T) {
Convey("Get Intervention List", t, WithService(func(s *Service) {
res, err := s.Intervs(&model.IntervListReq{
Rank: 0,
Category: 1,
})
So(err, ShouldBeNil)
fmt.Println(res)
}))
}
func TestService_RemoveInvalids(t *testing.T) {
Convey("Remove Invalid Test", t, WithService(func(s *Service) {
var (
rank model.Rank
err error
invalids []*model.RankError
)
if err = s.DB.Where("is_deleted=?", 0).First(&rank).Error; err != nil {
fmt.Println(err)
return
}
invalids = append(invalids, &model.RankError{
ID: int(rank.ID),
SeasonID: int(rank.ContID),
})
err = s.RemoveInvalids(invalids)
So(err, ShouldBeNil)
// recover
err = s.DB.Model(rank).Where("id=?", rank.ID).Update(map[string]int{"is_deleted": 0}).Error
So(err, ShouldBeNil)
}))
}

View File

@@ -0,0 +1,447 @@
package service
import (
"context"
"database/sql"
"fmt"
"time"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/xstr"
"github.com/jinzhu/gorm"
)
// ugcLabels refreshes ugc labels
func (s *Service) ugcLabels() (err error) {
var firstTps = s.firstTps()
if err = s.ugcTpLabel(firstTps); err != nil {
log.Error("ugcTpLabel Err %v", err)
return
}
if err = s.ugcPubLabel(firstTps); err != nil {
log.Error("ugcPubLabel Tps %v, Err %v", firstTps, err)
}
return
}
func (s *Service) ugcPubLabel(firstTps []int32) (err error) {
var (
exist bool
cfg = s.c.Cfg.RefLabel
)
for _, v := range firstTps { // check and create pub_time label
pubtCore := &model.LabelCore{
CatType: model.UgcLabel,
Category: v,
Param: model.ParamUgctime,
Value: cfg.AllValue,
Valid: 1,
ParamName: cfg.UgcTime,
Name: cfg.AllName,
}
if exist, err = s.labelExist(pubtCore); err != nil {
return
}
if !exist {
if err = s.DB.Create(&model.LabelDB{LabelCore: *pubtCore}).Error; err != nil {
log.Error("ugcLabels Pubtime All, Create Err %v", err)
return
}
}
time.Sleep(20 * time.Millisecond)
}
return
}
func (s *Service) firstTps() (tps []int32) {
for _, v := range s.ArcTypes {
if v.Pid == 0 {
tps = append(tps, v.ID)
}
}
return
}
func (s *Service) ugcTpLabel(firstTps []int32) (err error) {
var (
exist bool
cfg = s.c.Cfg.RefLabel
)
for _, v := range firstTps {
extCore := &model.LabelCore{
CatType: model.UgcLabel,
Param: model.ParamTypeid,
Valid: 1,
Category: v,
Value: cfg.AllValue,
ParamName: cfg.UgcType,
Name: cfg.AllName,
}
if exist, err = s.labelExist(extCore); err != nil {
return
}
if !exist {
if err = s.DB.Create(&model.LabelDB{LabelCore: *extCore}).Error; err != nil {
log.Error("ugcLabels ArcTypeID %d, Create ALL Label Err %v", v, err)
return
}
}
}
for _, v := range s.ArcTypes {
if v.Pid == 0 { // if first level type, we check the "ALL" label
continue
}
extCore := &model.LabelCore{
CatType: model.UgcLabel,
Param: model.ParamTypeid,
Valid: 1,
Category: v.Pid,
Value: fmt.Sprintf("%d", v.ID),
}
if exist, err = s.labelExist(extCore); err != nil {
return
}
if !exist {
label := model.LabelDB{}
label.FromArcTp(v, s.c.Cfg.RefLabel.UgcType)
if err = s.DB.Create(&label).Error; err != nil {
log.Error("ugcLabels ArcTypeID %d, Create Err %v", v.ID, err)
return
}
time.Sleep(20 * time.Millisecond)
}
}
return
}
// labelsExist distinguishes whether the ids are existing
func (s *Service) labelsExist(ids []int64) (err error) {
var (
labels []*model.LabelDB
idmap = make(map[int64]int)
)
if err = s.DB.Where(fmt.Sprintf("id IN (%s)", xstr.JoinInts(ids))).Where("deleted = 0").Find(&labels).Error; err != nil {
log.Error("labelsExist Ids %v, Err %v", ids, err)
return
}
if len(labels) >= len(ids) {
return
}
for _, v := range labels {
idmap[v.ID] = 1
}
for _, v := range ids {
if _, ok := idmap[v]; !ok {
log.Warn("labelsExist ids %v, not exist %d", ids, v)
return ecode.RequestErr
}
}
return
}
func (s *Service) labelExist(req *model.LabelCore) (exist bool, err error) {
var (
label = model.LabelDB{}
db = s.DB.Model(label).Where("deleted = 0")
)
if req.ID != 0 {
db = db.Where("id = ?", req.ID)
}
if req.Category != 0 {
db = db.Where("category = ?", req.Category)
}
if req.CatType != 0 {
db = db.Where("cat_type = ?", req.CatType)
}
if req.Param != "" {
db = db.Where("param = ?", req.Param)
}
if req.Value != "" {
db = db.Where("value = ?", req.Value)
}
if req.Name != "" {
db = db.Where("name = ?", req.Name)
}
if err = db.First(&label).Error; err != nil {
if err == gorm.ErrRecordNotFound {
err = nil
return
}
log.Error("labelExist V %v, Err %v", req, err)
return
}
if label.ID > 0 {
exist = true
}
return
}
func (s *Service) pgcLabels() (err error) {
var (
result *model.PgcCond
exist bool
)
for _, cat := range s.c.Cfg.SupportCat.PGCTypes {
if result, err = s.dao.PgcCond(context.Background(), cat); err != nil {
log.Error("PgcCond Cat %d, Err %v", cat, err)
return
}
for _, cond := range result.Filter {
if len(cond.Value) == 0 {
continue
}
for _, v := range cond.Value {
if exist, err = s.labelExist(&model.LabelCore{
CatType: model.PgcLabel,
Category: cat,
Param: cond.ID,
Value: v.ID,
}); err != nil {
return
}
if exist {
continue
}
label := model.LabelDB{}
label.FromPgcCond(v, cond, cat)
if err = s.DB.Create(&label).Error; err != nil {
log.Error("pgcLabels Param %s, Cond %v Create Err %v", cond.ID, v, err)
return
}
time.Sleep(20 * time.Millisecond)
}
}
}
return
}
// AddUgcTm adds time label for ugc
func (s *Service) AddUgcTm(tm *model.UgcTime) (err error) {
var (
exist bool
timeV = tm.TimeV()
)
if exist, err = s.labelExist(&model.LabelCore{
Category: tm.Category,
Param: model.ParamUgctime,
Name: tm.Name,
}); err != nil {
return
}
if exist {
err = ecode.TvLabelExist
return
}
label := model.LabelDB{}
label.FromUgcTime(tm, s.c.Cfg.RefLabel.UgcTime)
if err = s.DB.Create(&label).Error; err != nil {
log.Error("ugcTimeLabel Time %s, Create Err %v", timeV, err)
}
return
}
// EditUgcTm edits a time label by name
func (s *Service) EditUgcTm(tm *model.EditUgcTime) (err error) {
var exist bool
if exist, err = s.labelExist(&model.LabelCore{
ID: tm.ID,
}); err != nil {
return
}
if !exist {
err = ecode.NothingFound
return
}
if err = s.DB.Model(&model.LabelDB{}).Where("id = ?", tm.ID).Update(map[string]string{
"name": tm.Name,
"value": tm.TimeV(),
}).Error; err != nil {
log.Error("ugcTimeLabel LabelID %d, Update Err %v", tm.ID, err)
}
return
}
// ActLabels act on labels
func (s *Service) ActLabels(ids []int64, act int) (err error) {
if err = s.labelsExist(ids); err != nil {
return
}
if err = s.DB.Model(&model.LabelDB{}).Where(fmt.Sprintf("id IN (%s)", xstr.JoinInts(ids))).Update(map[string]int{
"valid": act,
}).Error; err != nil {
log.Error("ActLabels LabelID %s, Update Err %v", ids, err)
}
return
}
// DelLabels deletes labels
func (s *Service) DelLabels(ids []int64) (err error) {
var exist bool
for _, v := range ids {
if exist, err = s.labelExist(&model.LabelCore{
ID: v,
CatType: model.UgcLabel,
Param: model.ParamUgctime,
}); err != nil {
return
}
if !exist {
log.Warn("DelLabels IDs %v, ID not exist %d", ids, v)
return ecode.RequestErr
}
}
if err = s.DB.Exec(fmt.Sprintf("UPDATE tv_label SET deleted = 1 WHERE id IN (%s)", xstr.JoinInts(ids))).Error; err != nil {
log.Error("DelLabels LabelID %s, Update Err %v", ids, err)
}
return
}
// DynamicLabels picks the defined pgc label types
func (s *Service) labelTypes() (tps []*model.TpLabel, err error) {
var rows *sql.Rows
// select category, param , param_name from tv_label where deleted = 0 and cat_type = 1 group by category,param
if rows, err = s.DB.Model(&model.LabelDB{}).Where("deleted = 0").
Where("cat_type = ?", model.PgcLabel).Select("category, param, param_name").Group("category,param").Rows(); err != nil {
log.Error("labelTypes rows Err %v", err)
return
}
defer rows.Close()
for rows.Next() {
var cont = &model.TpLabel{}
if err = rows.Scan(&cont.Category, &cont.Param, &cont.ParamName); err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
tps = append(tps, cont)
}
if err = rows.Err(); err != nil {
log.Error("labelTypes rows Err %v", err)
}
return
}
func (s *Service) loadLabel() (err error) {
var (
newTps = make(map[int][]*model.TpLabel)
labels []*model.TpLabel
)
if labels, err = s.labelTypes(); err != nil {
log.Error("labelTypes err %v", err)
time.Sleep(time.Duration(10 * time.Second))
return
}
for _, v := range labels {
if lbs, ok := newTps[v.Category]; ok {
newTps[v.Category] = append(lbs, v)
} else {
newTps[v.Category] = append([]*model.TpLabel{}, v)
}
}
if len(newTps) > 0 {
s.labelTps = newTps
}
return
}
// LabelTp returns the category's label types
func (s *Service) LabelTp(category int) (lbs []*model.TpLabel, err error) {
var ok bool
if lbs, ok = s.labelTps[category]; !ok {
err = ecode.RequestErr
}
return
}
// PickLabels picks ugc labels
func (s *Service) PickLabels(req *model.ReqLabel, catType int) (data []*model.LabelList, err error) {
var (
db = s.DB.Model(&model.LabelDB{}).
Where("param = ?", req.Param).
Where("category = ?", req.Category).
Where("deleted = 0").
Where("cat_type = ?", catType)
labels []*model.LabelDB
)
if req.Title != "" {
db = db.Where("name LIKE ?", "%"+req.Title+"%")
}
if req.ID != 0 {
db = db.Where("id = ?", req.ID)
}
if err = db.Order("position ASC").Find(&labels).Error; err != nil {
log.Error("PickLabels Req %v, Err %v", req, err)
}
for _, v := range labels {
data = append(data, v.ToList())
}
return
}
// EditLabel edits a pgc label
func (s *Service) EditLabel(id int64, name string) (err error) {
var exist bool
if exist, err = s.labelExist(&model.LabelCore{
ID: id,
}); err != nil {
return
}
if !exist {
err = ecode.NothingFound
return
}
if err = s.DB.Model(&model.LabelDB{}).Where("id = ?", id).Update(map[string]string{
"name": name,
}).Error; err != nil {
log.Error("EditLabel LabelID %d, Update Err %v", id, err)
}
return
}
// PubLabel publish label's order
func (s *Service) PubLabel(ids []int64) (err error) {
if len(ids) == 0 {
return
}
var (
labels []*model.LabelDB
position = 1
tx = s.DB.Begin()
labelMap = make(map[int64]*model.LabelDB, len(ids))
)
if err = s.DB.Where(fmt.Sprintf("id IN (%s)", xstr.JoinInts(ids))).Find(&labels).Error; err != nil {
log.Error("PubLabel Ids %v, Err %v", ids, err)
return
}
if len(labels) == 0 {
err = ecode.NothingFound
return
}
for _, v := range labels {
labelMap[v.ID] = v
}
for _, id := range ids {
lbl, ok := labelMap[id]
if !ok {
err = ecode.RequestErr
log.Warn("PubLabel Id %d Not found", id)
return
}
if !lbl.SameType(labels[0]) {
log.Error("PubLabel Id %d FirstLabel ID %d, Not same type", lbl.ID, labels[0].ID)
err = ecode.RequestErr
tx.Rollback()
return
}
if err = tx.Model(&model.LabelDB{}).Where("id = ?", lbl.ID).Update(map[string]int{"position": position}).Error; err != nil {
log.Error("PubLabel ID %d, Err %v", lbl.ID, err)
tx.Rollback()
return
}
position = position + 1
}
tx.Commit()
return
}

View File

@@ -0,0 +1,205 @@
package service
import (
"fmt"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/pkg/errors"
)
// recomExist checks whether the recom exist or not
func (s *Service) recomExist(id int64) (exist bool) {
var recom model.MangoRecom
if err := s.DB.Where("id = ?", id).Where("deleted = 0").Find(&recom).Error; err != nil {
log.Error("[recomExist] ID %d, Err %v", id, err)
return
}
if recom.ID != 0 {
return true
}
return
}
func (s *Service) resExist(rid int64, rtype int) (exist bool) {
var recom model.MangoRecom
if err := s.DB.Where("rid = ?", rid).Where("rtype = ?", rtype).Where("deleted = 0").Find(&recom).Error; err != nil {
log.Error("[resExist] rid %d, Err %v", rid, err)
return
}
if recom.ID != 0 {
return true
}
return
}
// MangoList picks the mango recom list data
func (s *Service) MangoList(c *bm.Context) (data *model.MangoListResp, err error) {
var (
recoms []*model.MangoRecom
msg = s.c.Cfg.MangoErr
invalids []string
mre *model.MRecomMC
)
data = &model.MangoListResp{List: make([]*model.MangoRecom, 0)}
if err = s.DB.Where("deleted = ?", 0).Order("`rorder` ASC").Find(&recoms).Error; err != nil {
log.Error("[MangoList] DB query fail(%v)", err)
return
}
for _, v := range recoms { // check whether the archive or the season is still valid, otherwise we delete it and remind the user
if v.Rtype == _TypePGC {
if ok, _ := s.snValid(v.RID); ok {
data.List = append(data.List, v)
} else {
invalids = append(invalids, fmt.Sprintf("p%d", v.RID))
s.MangoDel(c, v.ID)
}
} else if v.Rtype == _TypeUGC {
if ok, _ := s.arcValid(v.RID); ok {
data.List = append(data.List, v)
} else {
invalids = append(invalids, fmt.Sprintf("u%d", v.RID))
s.MangoDel(c, v.ID)
}
} else {
log.Error("MangoList ID %d, Rid %d, Type %d, TypeError", v.ID, v.RID, v.Rtype)
invalids = append(invalids, fmt.Sprintf("%d", v.RID))
}
}
if len(invalids) > 0 {
data.Message = msg + joinStr(invalids)
}
if mre, err = s.dao.GetMRecom(c); err != nil {
log.Error("MangoList GetMRecom Err %v", err)
err = nil
return
}
data.Pubtime = mre.Pubtime.Time().Format("2006-01-02 15:04:05")
return
}
// joinStr joins strings
func joinStr(src []string) (res string) {
for k, v := range src {
if k == len(src)-1 {
res = res + v
} else {
res = res + v + ","
}
}
return
}
// MangoAdd adds the mango recom data
func (s *Service) MangoAdd(c *bm.Context, rtype int, rids []int64) (data *model.MangoAdd, err error) {
data = &model.MangoAdd{
Succ: make([]int64, 0),
Invalids: make([]int64, 0),
}
var (
succRecoms []*model.MangoRecom
newRids []int64
)
for _, v := range rids { // 检查是否存在
if ok := s.resExist(v, rtype); ok {
data.Invalids = append(data.Invalids, v)
continue
}
newRids = append(newRids, v)
}
if rtype == _TypePGC { // 检查对应的pgc和ugc是否存在并有效
for _, v := range newRids {
if ok, sn := s.snValid(v); !ok {
data.Invalids = append(data.Invalids, v)
} else {
succRecoms = append(succRecoms, sn.ToMango())
}
}
} else if rtype == _TypeUGC {
for _, v := range newRids {
if ok, arc := s.arcValid(v); !ok {
data.Invalids = append(data.Invalids, v)
} else {
var pid int32
if _, pid, err = s.arcPName(arc.TypeID); err != nil || pid == 0 {
log.Warn("MangoAdd Aid %d, TypeID %d, Err %v", v, arc.TypeID, err)
data.Invalids = append(data.Invalids, v)
continue
}
succRecoms = append(succRecoms, arc.ToMango(int(pid)))
}
}
} else {
err = ecode.TvDangbeiWrongType
return
}
if len(succRecoms) > 0 { // 选取最大顺序,在之后递增
tx := s.DB.Begin()
maxOrder := s.dao.MaxOrder(c)
for _, v := range succRecoms {
maxOrder = maxOrder + 1
v.Rorder = maxOrder
if err = tx.Create(v).Error; err != nil {
log.Error("MangoAdd Create Rid %d, Recom %v, Err %v", v.RID, v, err)
tx.Rollback()
return
}
}
tx.Commit() // add succ
for _, v := range succRecoms {
data.Succ = append(data.Succ, v.RID)
}
}
return
}
// MangoDel deletes the mango resource
func (s *Service) MangoDel(c *bm.Context, id int64) (err error) {
if !s.recomExist(id) {
return ecode.NothingFound
}
return s.dao.DelMRecom(c, id)
}
// MangoEdit edits the mango resource
func (s *Service) MangoEdit(c *bm.Context, req *model.ReqMangoEdit) (err error) {
if !s.recomExist(req.ID) {
return ecode.NothingFound
}
if err = s.DB.Model(&model.MangoRecom{}).Where("id = ?", req.ID).Update(map[string]interface{}{
"title": req.Title,
"cover": req.Cover,
"content": req.Content,
"staff": req.Staff,
"jid": req.JID,
"playcount": req.Playcount,
}).Error; err != nil {
log.Error("MangoDel ID %d, Mango %v, Err %v", req.ID, req, err)
}
return
}
// MangoPub publish the latest order of ids
func (s *Service) MangoPub(c *bm.Context, ids []int64) (err error) {
var order = 0
for _, v := range ids {
if !s.recomExist(v) {
return errors.Wrap(ecode.Int(404), fmt.Sprintf("ID: %d", v))
}
}
tx := s.DB.Begin()
for _, v := range ids {
order = order + 1
if err = tx.Model(&model.MangoRecom{}).Where("id = ?", v).Update(map[string]int{"rorder": order}).Error; err != nil {
log.Error("MangoPub ID %d, Err %v", v, err)
tx.Rollback()
return
}
}
tx.Commit()
err = s.dao.MangoRecom(c, ids)
return
}

View File

@@ -0,0 +1,295 @@
package service
import (
"fmt"
"strconv"
"time"
"go-common/app/admin/main/tv/model"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"github.com/jinzhu/gorm"
)
//ModulesAdd is used for add modules
func (s *Service) ModulesAdd(v *model.Modules) (err error) {
var (
order uint8
mod *model.Modules
)
if mod, err = s.isModulesExists(v.PageID, v.Title); err != nil {
return
}
if mod != nil {
err = fmt.Errorf("当前模块下,标题已存在")
return
}
if order, err = s.getOrder(v.PageID); err != nil {
return
}
//在已存在顺序上加一
v.Order = order + 1
if err = s.DB.Model(&model.Modules{}).Create(v).Error; err != nil {
return
}
return
}
//isModulesExists is use for checking is module exists
func (s *Service) isModulesExists(pageID string, title string) (v *model.Modules, err error) {
v = &model.Modules{}
w := map[string]interface{}{
"deleted": model.ModulesNotDelete,
"page_id": pageID,
"title": title,
}
if err = s.DB.Where(w).First(v).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
}
return
}
return
}
//getOrder is used for getting existed model order
func (s *Service) getOrder(pageID string) (order uint8, err error) {
var v model.Modules
if err = s.DB.Where("deleted = 0").Where("page_id = ?", pageID).Order("`order` DESC").First(&v).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return 0, nil
}
log.Error("getOrder Err %v", err)
return
}
order = v.Order
return
}
//ModulesList is used for get module list
func (s *Service) ModulesList(pageID string) (v []*model.Modules, err error) {
selectStr := []string{
"id",
"title",
"page_id",
"source",
"type",
"flexible",
"icon",
"capacity",
"more",
"`order`",
"moretype",
"morepage",
"valid",
"src_type",
}
w := map[string]interface{}{
"deleted": model.ModulesNotDelete,
"page_id": pageID,
}
if err = s.DB.Where(w).Select(selectStr).Order("`order` ASC").Find(&v).Error; err != nil {
return
}
for i := range v {
attr := v[i]
pid, _ := strconv.Atoi(attr.PageID)
switch pid {
case model.PageMain:
attr.PageID = "主页"
case model.PageJP:
attr.PageID = "番剧"
case model.PageMovie:
attr.PageID = "电影"
case model.PageDocumentary:
attr.PageID = "纪录片"
case model.PageCN:
attr.PageID = "国创"
case model.PageSoapopera:
attr.PageID = "电视剧"
}
t, _ := strconv.Atoi(attr.Type)
switch t {
case model.TypeSevenFocus:
attr.Type = "首页七格焦点图"
case model.TypeFiveFocus:
attr.Type = "5格焦点"
case model.TypeSixFocus:
attr.Type = "6格焦点"
case model.TypeVertListFirst:
attr.Type = "竖图1列表"
case model.TypeVertListSecond:
attr.Type = "竖图2列表"
case model.TypeHorizList:
attr.Type = "横图列表"
case model.TypeZhuiFan:
attr.Type = "追番模块"
}
}
return
}
//ModulesEditGet is used for get module with module id
func (s *Service) ModulesEditGet(id uint64) (v *model.Modules, err error) {
selectStr := []string{
"id",
"title",
"page_id",
"type",
"source",
"flexible",
"icon",
"capacity",
"more",
"`order`",
"moretype",
"morepage",
"src_type",
}
w := map[string]interface{}{
"id": id,
"deleted": model.ModulesNotDelete,
}
v = &model.Modules{}
if err = s.DB.Where(w).Select(selectStr).First(v).Error; err != nil {
return
}
return
}
//ModulesEditPost is used for update module value
func (s *Service) ModulesEditPost(id uint64, v *model.Modules) (err error) {
var (
mod = &model.Modules{}
)
if mod, err = s.isModulesExists(v.PageID, v.Title); err != nil {
return
}
if mod != nil && mod.ID != id {
err = fmt.Errorf("当前模块下,标题已存在")
return
}
return s.DB.Model(&model.Modules{}).Where("id = ?", id).Update(v).Error
}
//GetModPub is used for get publish status from MC
func (s *Service) GetModPub(c *bm.Context, pageID string) (p model.ModPub, err error) {
return s.dao.GetModPub(c, pageID)
}
//ModulesPublish is used for publish module or deleted modules
func (s *Service) ModulesPublish(c *bm.Context, pageID string, state uint8, ids []int, deletedIds []int) (err error) {
if len(ids) > 30 {
err = fmt.Errorf("模块发布不能超过30个")
return
}
tx := s.DB.Begin()
for k, v := range ids {
up := map[string]interface{}{
"order": k + 1,
"valid": model.ModulesValid,
}
where := map[string]interface{}{
"id": v,
"page_id": pageID,
}
if err = tx.Model(&model.Modules{}).Where(where).Update(up).Error; err != nil {
tx.Rollback()
return
}
}
if len(deletedIds) > 0 {
deletedUp := map[string]interface{}{
"deleted": model.ModulesDelete,
}
if err = s.DB.Model(&model.Modules{}).Where("id in (?)", deletedIds).Where("page_id=?", pageID).
Update(deletedUp).Error; err != nil {
tx.Rollback()
return
}
}
if err = s.SetPublish(c, pageID, state); err != nil {
tx.Rollback()
return
}
tx.Commit()
return
}
//SetPublish is used for set publish status
func (s *Service) SetPublish(c *bm.Context, pageID string, state uint8) (err error) {
nowTime := time.Now()
t := nowTime.Format("2006-01-02 15:04:05")
p := model.ModPub{
Time: t,
State: state,
}
return s.dao.SetModPub(c, pageID, p)
}
// TypeSupport distinguish whether the source is supported or not
func (s *Service) TypeSupport(srcType int, source int) bool {
if srcType == _TypePGC {
_, ok := s.supCatMap.PgcMap[int32(source)]
return ok
}
if srcType == _TypeUGC {
_, ok := s.supCatMap.UgcMap[int32(source)]
return ok
}
return false
}
// loadCats, reload pgc & ugc support cats
func (s *Service) loadCats() {
var (
pgcTypes = s.c.Cfg.SupportCat.PGCTypes
ugcTypes = s.c.Cfg.SupportCat.UGCTypes
newCats = []*model.ParentCat{}
newCatsMap = &model.SupCats{
UgcMap: make(map[int32]int),
PgcMap: make(map[int32]int),
}
)
// load supporting pgc types
if len(pgcTypes) > 0 {
for _, v := range pgcTypes {
newCats = append(newCats, &model.ParentCat{
ID: v,
Name: s.pgcCatToName(int(v)),
Type: _TypePGC,
})
newCatsMap.PgcMap[v] = 1
}
}
// load support ugc first level types and their children
if len(ugcTypes) > 0 {
for _, v := range ugcTypes {
newCatsMap.UgcMap[v] = 1
var ugcCat = &model.ParentCat{
ID: v,
Type: _TypeUGC,
}
if tp, ok := s.ArcTypes[v]; ok {
ugcCat.Name = tp.Name
}
for _, types := range s.ArcTypes { // gather children
if types.Pid == v {
ugcCat.Children = append(ugcCat.Children, &model.CommonCat{
ID: types.ID,
Name: types.Name,
PID: types.Pid,
Type: _TypeUGC,
})
newCatsMap.UgcMap[types.ID] = 1
}
}
newCats = append(newCats, ugcCat)
}
}
if len(newCats) > 0 {
s.SupCats = newCats
s.supCatMap = newCatsMap
}
}

View File

@@ -0,0 +1,45 @@
package service
import (
"time"
"go-common/app/admin/main/tv/model"
"go-common/library/log"
)
const (
_orderTable = "tv_pay_order"
)
//OrderList user tv-vip order list
func (s *Service) OrderList(mid, pn, ps, paymentStime, paymentEtime int64, status int8, orderNo string) (data *model.OrderPageHelper, err error) {
var (
db = s.dao.DB.Table(_orderTable)
orders []*model.TvPayOrderResp
)
data = &model.OrderPageHelper{}
if mid != 0 {
db = db.Where("mid = ?", mid)
}
if orderNo != "" {
db = db.Where("order_no = ?", orderNo)
}
if status != 0 {
db = db.Where("status = ?", status)
}
if paymentStime != 0 {
db = db.Where("payment_time > ?", time.Unix(paymentStime, 0))
}
if paymentEtime != 0 {
db = db.Where("payment_time < ?", time.Unix(paymentEtime, 0))
}
db.Count(&data.Total)
if err := db.Offset((pn - 1) * ps).Limit(ps).Find(&orders).Error; err != nil {
log.Error("OrderList %v, Err %v", orders, err)
}
data.Items = orders
return
}

View File

@@ -0,0 +1,177 @@
package service
import (
"context"
"database/sql"
"fmt"
"net/url"
"strconv"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/xstr"
"github.com/jinzhu/gorm"
)
// Playurl new playurl function, get url from API
func (s *Service) Playurl(cid int) (playurl string, err error) {
if playurl, err = s.dao.Playurl(ctx, cid); err != nil {
log.Error("Playurl API Error(%d) (%v)", cid, err)
return
}
if playurl, err = s.hostChange(playurl); err != nil {
log.Error("hostChange Error(%s)-(%v)", playurl, err)
return
}
log.Info("NewPlayURL cid = %d, playurl = %s", cid, playurl)
return
}
// hostChange can change the url from playurl api to tvshenhe's host
func (s *Service) hostChange(playurl string) (replacedURL string, err error) {
u, err := url.Parse(playurl)
if err != nil {
log.Error("hostChange ParseURL error (%v)", err)
return
}
log.Info("[hostChange] for URL: %s, Original Host: %s, Now we change it to: %s", playurl, u.Host, s.c.Cfg.Playpath)
u.Host = s.c.Cfg.Playpath // replace the host
u.RawQuery = "" // remove useless query
replacedURL = u.String()
return
}
// Upload can upload a file object: store the info in Redis, and transfer the file to Bfs
func (s *Service) Upload(c context.Context, fileName string, fileType string, timing int64, body []byte) (location string, err error) {
if location, err = s.dao.Upload(c, fileName, fileType, timing, body); err != nil {
log.Error("s.upload.Upload() error(%v)", err)
}
return
}
// unshelveReqT treats the unshelve request to db ( for update ) and dbSel (for select )
func (s *Service) unshelveReqT(req *model.ReqUnshelve) (db, dbSel *gorm.DB, err error) {
if length := len(req.IDs); length == 0 || length > s.c.Cfg.AuditConsult.UnshelveNb {
err = ecode.RequestErr
return
}
switch req.Type {
case 1: // sid
db = s.DB.Model(&model.TVEpSeason{}).Where("is_deleted = 0").
Where(fmt.Sprintf("id IN (%s)", xstr.JoinInts(req.IDs)))
dbSel = db.Select("id")
case 2: // epid
db = s.DB.Model(&model.Content{}).Where("is_deleted = 0").
Where(fmt.Sprintf("epid IN (%s)", xstr.JoinInts(req.IDs)))
dbSel = db.Select("epid")
case 3: // aid
db = s.DB.Model(&model.Archive{}).Where("deleted = 0").
Where(fmt.Sprintf("aid IN (%s)", xstr.JoinInts(req.IDs)))
dbSel = db.Select("aid")
case 4: // cid
db = s.DB.Model(&model.Video{}).Where("deleted = 0").
Where(fmt.Sprintf("cid IN (%s)", xstr.JoinInts(req.IDs)))
dbSel = db.Select("cid")
default:
err = ecode.RequestErr
}
return
}
// Unshelve is to soft delete the media data
func (s *Service) Unshelve(c context.Context, req *model.ReqUnshelve, username string) (resp *model.RespUnshelve, err error) {
var (
rows *sql.Rows
existMap = make(map[int64]int, len(req.IDs))
db, dbSelect *gorm.DB
updField = make(map[string]int, 1)
)
log.Warn("Unshelve Req Type %d, IDs %v, Username %s", req.Type, req.IDs, username) // record user's action
resp = &model.RespUnshelve{
SuccIDs: make([]int64, 0),
FailIDs: make([]int64, 0),
}
if db, dbSelect, err = s.unshelveReqT(req); err != nil {
log.Error("unshelve ReqT Err %v", err)
return
}
if rows, err = dbSelect.Rows(); err != nil {
log.Error("db rows Ids %v, Err %v", req.IDs, err)
return
}
defer rows.Close()
for rows.Next() { // pick existing ids
var sid int64
if err = rows.Scan(&sid); err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
resp.SuccIDs = append(resp.SuccIDs, sid)
existMap[sid] = 1
}
if err = rows.Err(); err != nil {
log.Error("rows.Err %v", err)
return
}
for _, v := range req.IDs { // treat to have the non-existing ids
if _, ok := existMap[v]; !ok {
resp.FailIDs = append(resp.FailIDs, v)
}
}
if len(resp.SuccIDs) == 0 { // there isn't any to update ids
return
}
switch req.Type {
case 1, 2: // sid, epid
updField["is_deleted"] = 1
case 3, 4: // aid, cid
updField["deleted"] = 1
}
if err = db.Update(updField).Error; err != nil {
log.Error("update Ids %v, err %v", req.IDs, err)
}
return
}
// ChlSplash gets channel's splash data
func (s *Service) ChlSplash(c context.Context, req *model.ReqChannel) (res *model.ChannelPager, err error) {
var (
db = s.DB.Model(&model.Channel{}).Where("deleted!=?", _isDeleted)
items []*model.ChannelFmt
count int64
)
if req.Desc != "" {
db = db.Where("`desc` LIKE ?", "%"+req.Desc+"%")
}
if req.Title != "" {
db = db.Where("title = ?", req.Title)
}
db.Count(&count)
if req.Order == model.OrderDesc {
db = db.Order("mtime DESC")
} else {
db = db.Order("mtime ASC")
}
if err = db.Offset((req.Page - 1) * _pagesize).Limit(_pagesize).Find(&items).Error; err != nil {
log.Error("chlList Error (%v)", err)
return
}
for _, v := range items {
v.MtimeFormat = s.TimeFormat(v.Mtime)
v.Mtime = 0
}
res = &model.ChannelPager{
TotalCount: count,
Pn: req.Page,
Ps: _pagesize,
Items: items,
}
return
}
func atoi(str string) (res int) {
res, _ = strconv.Atoi(str)
return
}

View File

@@ -0,0 +1,412 @@
package service
import (
"bytes"
"context"
"encoding/json"
"net/http"
"strconv"
"time"
"go-common/app/admin/main/tv/model"
"go-common/library/ecode"
"go-common/library/log"
"github.com/jinzhu/gorm"
)
const (
_configTableName = "tv_price_config"
_valid = 0
_invalid = 1
_noPid = 0
_orderField = "ctime"
_vip = 10
_online = 0
_delete = 2
)
// PanelInfo select panel info by id
func (s *Service) PanelInfo(id int64) (panelInfo *model.TvPriceConfigResp, err error) {
if panelInfo, err = s.dao.GetById(id); err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
}
log.Error("PanelInfo (%v) error(%v)", panelInfo, err)
return
}
if panelInfo != nil {
panelInfo.OriginPrice = panelInfo.Price
hasDiscount, price, discountInfos := s.hasDiscount(nil, panelInfo.ID)
if hasDiscount {
panelInfo.Price = price
}
panelInfo.Items = discountInfos
}
return
}
// PanelStatus change panel status by id
func (s *Service) PanelStatus(id, status int64) (err error) {
var (
flag bool
panelInfo *model.TvPriceConfigResp
)
if panelInfo, err = s.dao.GetById(id); err != nil {
log.Error("PanelInfo (%v) error(%v)", panelInfo, err)
}
if status == _online && panelInfo.SuitType == _vip {
if flag, err = s.hasOnlineUpgradeVipProduct(); err != nil {
log.Error("GetValidUpgradeVipProduct Err %v", err)
return
}
if flag {
err = ecode.TVVipSuitTypeConflict
return err
}
}
if panelInfo.PID == 0 && status == _delete {
if err = s.dao.DB.Table(_configTableName).Where("pid = ?", id).Update("status", _delete).Error; err != nil {
log.Error("PanelStatus discount (%v) error(%v)", id, err)
}
}
if err = s.dao.PanelStatus(id, status); err != nil {
log.Error("PanelStatus (%v) error(%v)", id, err)
}
return
}
// SavePanel add or update panel info
func (s *Service) SavePanel(c context.Context, panel *model.TvPriceConfig) (err error) {
opType := s.c.YSTParam.Update
//start tx
tx := s.DB.Begin()
if panel.PID != 0 {
_, _, discounts := s.hasDiscount(nil, panel.PID)
if flag := checkDisCountTime(discounts, panel); !flag {
err = ecode.TvPriceTimeConflict
return err
}
s.copyParentExtraField(panel)
}
if panel.ID != 0 && panel.PID == 0 {
if err = tx.Table(_configTableName).Where("pid = ?", panel.ID).
Update(map[string]interface{}{
"suit_type": panel.SuitType,
"sub_type": panel.SubType,
"selected": panel.Selected,
"superscript": panel.Superscript,
"month": panel.Month,
}).Error; err != nil {
log.Error("Update discount failed while update panel, Err %v", err)
tx.Rollback()
return
}
_, _, discounts := s.hasDiscount(tx, panel.ID)
for _, discount := range discounts {
if err = s.syncPanels(c, opType, &discount); err != nil {
err = ecode.TvVipProdSyncErr
tx.Rollback()
return err
}
}
}
if panel.ID == 0 {
opType = s.c.YSTParam.Insert
if panel.PID == 0 {
panel.Status = _invalid
} else {
s.copyParentExtraField(panel)
}
if flag := s.dao.ExistProduct(panel.ProductID); flag {
err = ecode.TvVipProductExit
return err
}
}
if err = tx.Save(panel).Error; err != nil {
log.Error("SavePanel %s, Err %v", panel, err)
return err
}
if err = s.syncPanels(c, opType, panel); err != nil {
err = ecode.TvVipProdSyncErr
tx.Rollback()
return err
}
tx.Commit()
return
}
// PanelList get panle list
func (s *Service) PanelList(platform, month, subType, suitType int64) (panels []*model.TvPriceConfigListResp, err error) {
var (
db = s.dao.DB.Model(&model.TvPriceConfigListResp{}).Where("pid = ? and status in (?, ?)", _noPid, _valid, _invalid)
)
if platform != 0 {
db = db.Where("platform = ?", platform)
}
if month != 0 {
db = db.Where("month = ?", month)
}
if subType != -1 {
db = db.Where("sub_type = ?", subType)
}
if suitType != -1 {
db = db.Where("suit_type = ?", suitType)
}
if err = db.Order("suit_type, sub_type desc, month desc").Find(&panels).Error; err != nil {
log.Error("OrderList %v, Err %v", panels, err)
return panels, err
}
for _, panel := range panels {
hasDiscount, price, _ := s.hasDiscount(nil, panel.ID)
panel.OriginPrice = panel.Price
if hasDiscount {
panel.Price = price
}
}
return
}
// HasDiscount Judge whether there is a discount
func (s *Service) hasDiscount(tx *gorm.DB, id int64) (hasDiscount bool, price int64, panels []model.TvPriceConfig) {
if tx == nil {
tx = s.dao.DB
}
if err := tx.Table(_configTableName).Where("pid = ? and status = ?", id, _valid).Find(&panels).Error; err != nil {
log.Error("HasDiscount %v, Err %v", id, err)
return
}
nowTime := time.Now().Unix()
for _, panel := range panels {
if int64(panel.Stime) < nowTime && nowTime < int64(panel.Etime) {
hasDiscount = true
price = panel.Price
return
}
}
return
}
// checkDisCountTime check discount time conflict
func checkDisCountTime(discounts []model.TvPriceConfig, panel *model.TvPriceConfig) (flag bool) {
var (
startTime = panel.Stime
endTime = panel.Etime
)
for _, discount := range discounts {
// do not compare with self
if panel.ID != discount.ID {
if discount.Stime < startTime && startTime < discount.Etime {
return false
}
if discount.Stime < endTime && endTime < discount.Etime {
return false
}
if discount.Stime > startTime && endTime > discount.Etime {
return false
}
}
}
return true
}
// checkRemotePanel check YST panel
func (s *Service) checkRemotePanel(c context.Context) {
var (
panels []*model.TvPriceConfigListResp
)
if err := s.dao.DB.Table(_configTableName).Order(_orderField).Find(&panels).Error; err != nil {
log.Error("CheckRemotePanel Err %v", err)
return
}
res, _ := s.getRemotePanels(c)
remotePanels := res.Product
panelMap := make(map[string]*model.TvPriceConfigListResp, len(panels))
remotePaneMap := make(map[string]model.Product, len(remotePanels))
for i := 0; i < len(panels); i++ {
panelMap[panels[i].ProductID] = panels[i]
}
for i := 0; i < len(remotePanels); i++ {
remotePaneMap[remotePanels[i].ID] = remotePanels[i]
}
for i := 0; i < len(panels); i++ {
rp, exists := remotePaneMap[panels[i].ProductID]
if exists {
s.compareFiled(rp, panels[i])
} else {
log.Error("Our panel not exists in YST, panel id is (%v)", panels[i].ProductID)
}
}
for i := 0; i < len(remotePanels); i++ {
p, exists := panelMap[remotePanels[i].ID]
if exists {
s.compareFiled(remotePanels[i], p)
} else {
log.Error("YST panel not exists in our db, panel id is (%v)", remotePanels[i].ID)
}
}
}
// getRemotePanels get YST panel
func (s *Service) getRemotePanels(c context.Context) (res *model.RemotePanel, err error) {
var (
req *http.Request
)
res = &model.RemotePanel{}
params := map[string]string{
"vod_type": s.c.YSTParam.QueryPanelType,
"source": s.c.YSTParam.Source,
}
reqBody, _ := json.Marshal(params)
getRemotePanelUrl := s.c.URLConf.GetRemotePanelUrl
if req, err = http.NewRequest(http.MethodPost, getRemotePanelUrl, bytes.NewReader(reqBody)); err != nil {
log.Error("MerakNotify NewRequest Err %v, Url %v", err, getRemotePanelUrl)
return
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
if err = s.client.Do(c, req, &res); err != nil {
log.Error("MergeUpInfo http req failed ,err:%v", err)
return
}
return
}
// compareFiled compare our panel field with YST
func (s *Service) compareFiled(remotePanel model.Product, panel *model.TvPriceConfigListResp) {
rpid := remotePanel.ID
prodiuctId := panel.ProductID
if rpid != prodiuctId {
log.Error("PanelInfo id different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
}
if remotePanel.Price != panel.Price {
log.Error("PanelInfo price different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
}
if remotePanel.Contract != strconv.Itoa(int(panel.SubType)) {
log.Error("PanelInfo subType different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
}
if remotePanel.SuitType != panel.SuitType {
log.Error("PanelInfo suitType different, Remote panel id is (%v), Our panel id is (%v)", rpid, prodiuctId)
}
if remotePanel.ProductDuration != strconv.FormatInt(panel.Month*31, 10) {
log.Error("PanelInfo months different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
}
if remotePanel.Title != panel.ProductName {
log.Error("PanelInfo productName different, Remote panel prodiuctId is (%v), Our panel id prodiuctId (%v)", rpid, prodiuctId)
}
if panel.PID != 0 {
parentPanel, err := s.dao.GetById(panel.PID)
if err != nil {
log.Error("PanelInfo (%v) error(%v)", parentPanel, err)
}
if remotePanel.ComboPkgID != parentPanel.ProductID {
log.Error("PanelInfo pid different, Remote panel prodiuctId is (%v), Our panel prodiuctId is (%v)", rpid, prodiuctId)
}
}
}
// syncPanels send our panel to YST
func (s *Service) syncPanels(c context.Context, opType string, panel *model.TvPriceConfig) (err error) {
var (
req *http.Request
res struct {
Result string `json:"result"`
Message string `json:"message"`
}
params struct {
OpType string `json:"optype"`
Source string `json:"source"`
Product model.Product `json:"product"`
}
)
params.OpType = opType
params.Source = s.c.YSTParam.Source
params.Product.ID = panel.ProductID
params.Product.VodType = s.c.YSTParam.InsertPanelType
params.Product.Title = panel.ProductName
params.Product.ProductDuration = strconv.FormatInt(31*panel.Month, 10)
params.Product.Description = panel.Remark
params.Product.Contract = strconv.Itoa(int(panel.SubType))
if panel.PID != 0 {
parentPanel, _ := s.dao.GetById(panel.PID)
if parentPanel != nil {
params.Product.ComboPkgID = parentPanel.ProductID
params.Product.ComboDes = parentPanel.Remark
} else {
log.Error("Prarent PanelInfo not found, pid =(%v)", panel.PID)
err = ecode.NothingFound
return err
}
}
params.Product.Price = panel.Price
params.Product.SuitType = panel.SuitType
reqBody, _ := json.Marshal(params)
SyncPanelUrl := s.c.URLConf.SyncPanelUrl
if req, err = http.NewRequest(http.MethodPost, SyncPanelUrl, bytes.NewReader(reqBody)); err != nil {
log.Error("MerakNotify NewRequest Err %v, Url %v", err, SyncPanelUrl)
return err
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
if err = s.client.Do(c, req, &res); err != nil {
log.Error("MergeUpInfo http req failed ,err:%v", err)
return err
}
if res.Result != "SUCCESS" {
err = ecode.TvVipProdSyncErr
log.Info("Sync panel To YST Fail,err:%v", res.Message)
return err
}
return
}
func (s *Service) hasOnlineUpgradeVipProduct() (flag bool, err error) {
var (
panels []*model.TvPriceConfig
)
if err = s.dao.DB.Table(_configTableName).Where("suit_type = ? and status = ? and pid = ?", _vip, _valid, _noPid).Find(&panels).Error; err != nil {
log.Error("GetValidUpgradeVipProduct Err %v", err)
return
}
flag = !(len(panels) == 0)
return
}
func (s *Service) copyParentExtraField(panel *model.TvPriceConfig) {
parentPanel, _ := s.dao.GetById(panel.PID)
if parentPanel != nil {
panel.SuitType = parentPanel.SuitType
panel.SubType = parentPanel.SubType
panel.Selected = parentPanel.Selected
panel.Superscript = parentPanel.Superscript
panel.Month = parentPanel.Month
}
}

View File

@@ -0,0 +1,16 @@
package service
import (
"fmt"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_Playurl(t *testing.T) {
Convey("PlayURL test", t, WithService(func(s *Service) {
url, err := s.Playurl(2476470)
fmt.Println(url)
So(err, ShouldBeNil)
}))
}

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