Create & Init Project...

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

View File

@@ -0,0 +1,61 @@
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_stat_test.go",
"csv_test.go",
"service_test.go",
"task_log_test.go",
"task_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/laser/conf:go_default_library",
"//app/admin/main/laser/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"archive_stat.go",
"csv.go",
"service.go",
"task.go",
"task_log.go",
],
importpath = "go-common/app/admin/main/laser/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/laser/conf:go_default_library",
"//app/admin/main/laser/dao:go_default_library",
"//app/admin/main/laser/model:go_default_library",
"//library/log:go_default_library",
"//library/time:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,615 @@
package service
import (
"context"
"sort"
"time"
"go-common/app/admin/main/laser/model"
)
const (
// ALLNAME is specific name video_audit overview
ALLNAME = "ALL全体总览"
// ALLUID is specific uid for video_audit overview
ALLUID = -1
)
// ArchiveRecheck is stat recheck flow data node.
func (s *Service) ArchiveRecheck(c context.Context, typeIDS []int64, unames string, startDate int64, endDate int64) (recheckViews []*model.StatView, err error) {
start := time.Unix(startDate, 0)
end := time.Unix(endDate, 0)
var uids []int64
var res map[string]int64
if len(unames) != 0 {
res, err = s.dao.GetUIDByNames(c, unames)
if err != nil {
return
}
for _, uid := range res {
uids = append(uids, uid)
}
}
statTypes := []int64{model.TotalArchive, model.TotalOper, model.ReCheck, model.Lock,
model.ThreeLimit, model.FirstCheck, model.SecondCheck, model.ThirdCheck, model.NoRankArchive, model.NoIndexArchive, model.NoRecommendArchive, model.NoPushArchive,
model.FirstCheckOper, model.FirstCheckTime, model.SecondCheckOper,
model.SecondCheckTime, model.ThirdCheckOper, model.ThirdCheckTime}
var statViews []*model.StatView
for !start.After(end) {
statViews, err = s.dailyStatArchiveRecheck(c, model.ArchiveRecheck, typeIDS, statTypes, uids, start)
if err != nil {
return
}
recheckViews = append(recheckViews, statViews...)
start = start.AddDate(0, 0, 1)
}
return
}
// UserRecheck is stat user recheck data node.
func (s *Service) UserRecheck(c context.Context, typeIDS []int64, unames string, startDate int64, endDate int64) (
recheckViews []*model.StatView, err error) {
start := time.Unix(startDate, 0)
end := time.Unix(endDate, 0)
var uids []int64
var res map[string]int64
if len(unames) != 0 {
res, err = s.dao.GetUIDByNames(c, unames)
if err != nil {
return
}
for _, uid := range res {
uids = append(uids, uid)
}
}
statTypes := []int64{model.TotalOperFrequency, model.FirstCheckOper, model.SecondCheckOper, model.ThirdCheckOper,
model.FirstCheckOper, model.FirstCheckTime, model.SecondCheckOper,
model.SecondCheckTime, model.ThirdCheckOper, model.ThirdCheckTime}
var statViews []*model.StatView
for !start.After(end) {
statViews, err = s.dailyStatArchiveRecheck(c, model.ArchiveRecheck, typeIDS, statTypes, uids, start)
if err != nil {
return
}
recheckViews = append(recheckViews, statViews...)
start = start.AddDate(0, 0, 1)
}
return
}
func (s *Service) dailyStatArchiveRecheck(c context.Context, business int, typeIDS []int64, statTypes []int64, uids []int64, statDate time.Time) (statViews []*model.StatView, err error) {
mediateView, err := s.dailyArchiveStat(c, business, typeIDS, statTypes, uids, statDate)
if err != nil || len(mediateView) == 0 {
return
}
statViews = makeUpArchiveRecheck(mediateView)
return
}
func makeUpArchiveRecheck(mediateView map[int64]map[int]int64) (statViews []*model.StatView) {
items := make(map[int64][]*model.StatItem)
for k1, v1 := range mediateView {
var recheckItems []*model.StatItem
denominatorValue, ok1 := v1[model.FirstCheckOper]
numeratorValue, ok2 := v1[model.FirstCheckTime]
if ok1 && ok2 {
if denominatorValue == 0 {
recheckItems = append(recheckItems, &model.StatItem{
DataCode: model.FirstAvgTime,
Value: 0,
})
} else {
recheckItems = append(recheckItems, &model.StatItem{
DataCode: model.FirstAvgTime,
Value: numeratorValue / denominatorValue,
})
}
}
denominatorValue, ok1 = v1[model.SecondCheckOper]
numeratorValue, ok2 = v1[model.SecondCheckTime]
if ok1 && ok2 {
if denominatorValue == 0 {
recheckItems = append(recheckItems, &model.StatItem{
DataCode: model.SecondAvgTime,
Value: 0,
})
} else {
recheckItems = append(recheckItems, &model.StatItem{
DataCode: model.SecondAvgTime,
Value: numeratorValue / denominatorValue,
})
}
}
denominatorValue, ok1 = v1[model.ThirdCheckOper]
numeratorValue, ok2 = v1[model.ThirdCheckTime]
if ok1 && ok2 {
if denominatorValue == 0 {
recheckItems = append(recheckItems, &model.StatItem{
DataCode: model.ThirdAvgTime,
Value: 0,
})
} else {
recheckItems = append(recheckItems, &model.StatItem{
DataCode: model.ThirdAvgTime,
Value: numeratorValue / denominatorValue,
})
}
}
for k2, v2 := range v1 {
recheckItems = append(recheckItems, &model.StatItem{DataCode: k2, Value: v2})
}
items[k1] = recheckItems
}
for k, v := range items {
statViews = append(statViews, &model.StatView{Date: k, Stats: v})
}
return
}
func (s *Service) dailyArchiveStat(c context.Context, business int, typeIDS []int64, statTypes []int64, uids []int64, statDate time.Time) (mediateView map[int64]map[int]int64, err error) {
statNodes, err := s.dao.StatArchiveStat(c, business, typeIDS, uids, statTypes, statDate)
if err != nil || len(statNodes) == 0 {
return
}
mediateView = make(map[int64]map[int]int64)
for _, node := range statNodes {
k1 := node.StatDate.Time().Unix()
k2 := node.StatType
newValue := node.StatValue
if v1, ok := mediateView[k1]; ok {
if v2, ok := v1[k2]; ok {
mediateView[k1][k2] = v2 + newValue
} else {
mediateView[k1][k2] = newValue
}
} else {
mediateView[k1] = map[int]int64{k2: newValue}
}
}
return
}
// TagRecheck is stat archive tag recheck.
func (s *Service) TagRecheck(c context.Context, startDate int64, endDate int64, unames string) (tagViews []*model.StatView, err error) {
start := time.Unix(startDate, 0)
end := time.Unix(endDate, 0)
var uids []int64
var uname2uid map[string]int64
if len(unames) != 0 {
uname2uid, err = s.dao.GetUIDByNames(c, unames)
if err != nil {
return
}
for _, uid := range uname2uid {
uids = append(uids, uid)
}
}
statTypes := []int64{model.TagRecheckTotalTime, model.TagRecheckTotalCount, model.TagChangeCount, model.TagRecheckTotalCount, model.TagRecheckTotalTime}
var statViews []*model.StatView
for !start.After(end) {
statViews, err = s.dailyStatTagRecheck(c, model.TagRecheck, statTypes, uids, start)
if err != nil {
return
}
tagViews = append(tagViews, statViews...)
start = start.AddDate(0, 0, 1)
}
return
}
func (s *Service) dailyStatTagRecheck(c context.Context, business int, statTypes []int64, uids []int64, statDate time.Time) (statViews []*model.StatView, err error) {
mediateView, err := s.dailyArchiveStat(c, business, []int64{}, statTypes, uids, statDate)
if err != nil || len(mediateView) == 0 {
return
}
statViews = makeUpTagRecheck(mediateView)
return
}
func makeUpTagRecheck(mediateView map[int64]map[int]int64) (statViews []*model.StatView) {
items := make(map[int64][]*model.StatItem)
for k1, v1 := range mediateView {
var recheckItems []*model.StatItem
denominatorValue, ok1 := v1[model.TagRecheckTotalCount]
numeratorValue, ok2 := v1[model.TagRecheckTotalTime]
if ok1 && ok2 {
if denominatorValue == 0 {
recheckItems = append(recheckItems, &model.StatItem{
DataCode: model.TagRecheckAvgTime,
Value: 0,
})
} else {
recheckItems = append(recheckItems, &model.StatItem{
DataCode: model.TagRecheckAvgTime,
Value: numeratorValue / denominatorValue,
})
}
}
for k2, v2 := range v1 {
recheckItems = append(recheckItems, &model.StatItem{DataCode: k2, Value: v2})
}
items[k1] = recheckItems
}
for k, v := range items {
statViews = append(statViews, &model.StatView{Date: k, Stats: v})
}
return
}
// Recheck123 is stat 123 recheck.
func (s *Service) Recheck123(c context.Context, startDate int64, endDate int64, typeIDS []int64) (recheckView []*model.StatView, err error) {
start := time.Unix(startDate, 0)
end := time.Unix(endDate, 0)
emptyUids := []int64{}
statTypes := []int64{model.FIRST_RECHECK_IN, model.FIRST_RECHECK_OUT, model.SECOND_RECHECK_IN, model.SECOND_RECHECK_OUT, model.THIRD_RECHECK_IN, model.THIRD_RECHECK_OUT}
var statViews []*model.StatView
for !start.After(end) {
statViews, err = s.dailyStatArchiveStreamStat(c, model.Recheck123, typeIDS, emptyUids, statTypes, start)
if err != nil {
return
}
recheckView = append(recheckView, statViews...)
start = start.AddDate(0, 0, 1)
}
return
}
func (s *Service) dailyStatArchiveStreamStat(c context.Context, business int, typeIDS []int64, uids []int64, statTypes []int64, statDate time.Time) (statViews []*model.StatView, err error) {
statNodes, err := s.dao.StatArchiveStatStream(c, model.Recheck123, typeIDS, uids, statTypes, statDate)
if err != nil || len(statNodes) == 0 {
return
}
mediateView := make(map[int64]map[int]int64)
for _, v := range statNodes {
k1 := v.StatDate.Time().Unix()
k2 := v.StatType
newValue := v.StatValue
if v1, ok := mediateView[k1]; ok {
if v2, ok := v1[k2]; ok {
mediateView[k1][k2] = newValue + v2
} else {
mediateView[k1][k2] = newValue
}
} else {
mediateView[k1] = map[int]int64{k2: newValue}
}
}
for k1, v1 := range mediateView {
var statItems []*model.StatItem
for k2, v2 := range v1 {
statItems = append(statItems, &model.StatItem{DataCode: k2, Value: v2})
}
statViews = append(statViews, &model.StatView{Date: k1, Stats: statItems})
}
return
}
func wrap(cargoMap map[int64]*model.CargoItem) (views []*model.CargoView) {
// 适配返回的JSON结构,减少前端工作量, cargoMap 2 views.
mediateView := make(map[string]map[int]*model.CargoItem)
for k, v := range cargoMap {
statDate := time.Unix(k, 0)
k1 := statDate.Format("2006-01-02")
k2 := statDate.Hour()
if value1, ok := mediateView[k1]; ok {
if value2, ok := value1[k2]; ok {
value2.AuditValue = value2.AuditValue + v.AuditValue
value2.ReceiveValue = value2.ReceiveValue + v.ReceiveValue
mediateView[k1][k2] = value2
} else {
mediateView[k1][k2] = &model.CargoItem{
ReceiveValue: v.ReceiveValue,
AuditValue: v.AuditValue,
}
}
} else {
mediateView[k1] = map[int]*model.CargoItem{
k2: {
ReceiveValue: v.ReceiveValue,
AuditValue: v.AuditValue,
},
}
}
}
for k, v := range mediateView {
views = append(views, &model.CargoView{
Date: k,
Data: v,
})
}
return
}
// CsvAuditCargo is download archive cargo audit data by csv file type.
func (s *Service) CsvAuditCargo(c context.Context, startDate int64, endDate int64, unames string) (res []byte, err error) {
wrappers, lineWidth, err := s.AuditorCargoList(c, startDate, endDate, unames)
if err != nil {
return
}
data := formatAuditCargo(wrappers, lineWidth)
return FormatCSV(data)
}
// AuditorCargoList is query archive audit cargo by uname respectively with stat_date condition.
func (s *Service) AuditorCargoList(c context.Context, startDate int64, endDate int64, unames string) (wrappers []*model.CargoViewWrapper, lineWidth int, err error) {
start := time.Unix(startDate, 0)
end := time.Unix(endDate, 0)
var uids []int64
var name2uid map[string]int64
uid2name := make(map[int64]string)
if len(unames) != 0 {
name2uid, err = s.dao.GetUIDByNames(c, unames)
if err != nil {
return
}
for name, uid := range name2uid {
uids = append(uids, uid)
uid2name[uid] = name
}
}
var items, itemsBlock []*model.CargoDetail
for !start.After(end) {
itemsBlock, err = s.dao.QueryArchiveCargo(c, start, uids)
if err != nil {
return
}
items = append(items, itemsBlock...)
start = start.Add(time.Hour * 1)
}
if len(items) == 0 {
return
}
mediateViews := make(map[int64]map[int64]*model.CargoItem)
uidMap := make(map[int64]bool)
for _, v := range items {
k1 := v.UID
k2 := v.StatDate.Time().Unix()
uidMap[k1] = true
if v1, ok := mediateViews[k1]; ok {
if v2, ok := v1[k2]; ok {
v2.ReceiveValue = v2.ReceiveValue + v.ReceiveValue
v2.AuditValue = v2.AuditValue + v.AuditValue
mediateViews[k1][k2] = v2
} else {
lineWidth = lineWidth + 1
mediateViews[k1][k2] = &model.CargoItem{
ReceiveValue: v.ReceiveValue,
AuditValue: v.AuditValue,
}
}
} else {
lineWidth = lineWidth + 1
mediateViews[k1] = map[int64]*model.CargoItem{
k2: {
ReceiveValue: v.ReceiveValue,
AuditValue: v.AuditValue,
},
}
}
}
if len(unames) == 0 {
for uid := range uidMap {
uids = append(uids, uid)
}
uid2name, err = s.dao.GetUNamesByUids(c, uids)
if err != nil {
return
}
}
for k, v := range mediateViews {
cargoViews := wrap(v)
for _, v := range cargoViews {
wrappers = append(wrappers, &model.CargoViewWrapper{
Username: uid2name[k],
CargoView: v,
})
}
}
return
}
// CsvRandomVideoAudit is download random video audit statistic data by csv file type.
func (s *Service) CsvRandomVideoAudit(c context.Context, startDate int64, endDate int64, unames string, typeIDS []int64) (res []byte, err error) {
statViewExts, lineWidth, err := s.RandomVideo(c, startDate, endDate, typeIDS, unames)
if err != nil {
return
}
sort.Slice(statViewExts, func(i, j int) bool {
return statViewExts[i].Date > statViewExts[j].Date
})
data := formatVideoAuditStat(statViewExts, lineWidth)
return FormatCSV(data)
}
// CsvFixedVideoAudit is download fixed video audit statistic data by csv file type.
func (s *Service) CsvFixedVideoAudit(c context.Context, startDate int64, endDate int64, unames string, typeIDS []int64) (res []byte, err error) {
statViewExts, lineWidth, err := s.FixedVideo(c, startDate, endDate, typeIDS, unames)
if err != nil {
return
}
sort.Slice(statViewExts, func(i, j int) bool {
return statViewExts[i].Date > statViewExts[j].Date
})
data := formatVideoAuditStat(statViewExts, lineWidth)
return FormatCSV(data)
}
// RandomVideo is stat random video type.
func (s *Service) RandomVideo(c context.Context, startDate int64, endDate int64, typeIDS []int64, uname string) (statViewExts []*model.StatViewExt, lineWidth int, err error) {
start := time.Unix(startDate, 0)
end := time.Unix(endDate, 0)
var viewExts []*model.StatViewExt
var width int
for !start.After(end) {
viewExts, width, err = s.videoAudit(c, model.RandomVideoAudit, start, typeIDS, uname)
if err != nil {
return
}
lineWidth = lineWidth + width
statViewExts = append(statViewExts, viewExts...)
start = start.AddDate(0, 0, 1)
}
return
}
// FixedVideo is stat fixed video type.
func (s *Service) FixedVideo(c context.Context, startDate int64, endDate int64, typeIDS []int64, uname string) (statViewExts []*model.StatViewExt, lineWidth int, err error) {
start := time.Unix(startDate, 0)
end := time.Unix(endDate, 0)
var viewExts []*model.StatViewExt
var width int
for !start.After(end) {
viewExts, width, err = s.videoAudit(c, model.FixedVideoAudit, start, typeIDS, uname)
if err != nil {
return
}
lineWidth = lineWidth + width
statViewExts = append(statViewExts, viewExts...)
start = start.AddDate(0, 0, 1)
}
return
}
func (s *Service) videoAudit(c context.Context, business int, statDate time.Time, typeIDS []int64, unames string) (viewExts []*model.StatViewExt, lineWidth int, err error) {
var uids []int64
var res map[string]int64
needAll := true
if len(unames) != 0 {
needAll = false
res, err = s.dao.GetUIDByNames(c, unames)
if err != nil {
return
}
for _, uid := range res {
uids = append(uids, uid)
}
}
statNodes, err := s.dao.StatArchiveStat(c, business, typeIDS, uids, []int64{}, statDate)
if err != nil || len(statNodes) == 0 {
return
}
return s.statNode2ViewExt(c, statNodes, needAll)
}
func (s *Service) statNode2ViewExt(c context.Context, statNodes []*model.StatNode, needAll bool) (statViewsExts []*model.StatViewExt, lineWidth int, err error) {
mediateViews := make(map[int64]map[int64]map[int]int64)
uidMap := make(map[int64]bool)
var uids []int64
for _, v := range statNodes {
k1 := v.StatDate.Time().Unix()
k2 := v.UID
k3 := v.StatType
newValue := v.StatValue
uidMap[k2] = true
if v1, ok := mediateViews[k1]; ok {
if needAll {
if allV2, ok := v1[ALLUID]; ok {
if allV3, ok := allV2[k3]; ok {
mediateViews[k1][ALLUID][k3] = allV3 + newValue
} else {
mediateViews[k1][ALLUID][k3] = newValue
}
} else {
lineWidth = lineWidth + 1
mediateViews[k1][ALLUID] = map[int]int64{k3: newValue}
}
}
if v2, ok := v1[k2]; ok {
if v3, ok := v2[k3]; ok {
mediateViews[k1][k2][k3] = v3 + newValue
} else {
mediateViews[k1][k2][k3] = newValue
}
} else {
lineWidth = lineWidth + 1
mediateViews[k1][k2] = map[int]int64{k3: newValue}
}
} else {
lineWidth = lineWidth + 1
mediateViews[k1] = map[int64]map[int]int64{k2: {k3: newValue}}
if needAll {
lineWidth = lineWidth + 1
mediateViews[k1] = map[int64]map[int]int64{ALLUID: {k3: newValue}}
}
}
}
//fetch uid map uname
for uid := range uidMap {
uids = append(uids, uid)
}
uid2name, err := s.dao.GetUNamesByUids(c, uids)
if err != nil {
return
}
if needAll {
uid2name[ALLUID] = ALLNAME
}
for k1, v1 := range mediateViews {
for k2, v2 := range v1 {
var numeratorValue int64
var denominatorValue int64
for k3, v3 := range v2 {
if k3 == model.WaitAuditDuration {
numeratorValue = v3
}
if k3 == model.WaitAuditOper {
denominatorValue = v3
}
}
if denominatorValue == 0 {
mediateViews[k1][k2][model.WaitAuditAvgTime] = 0
} else {
mediateViews[k1][k2][model.WaitAuditAvgTime] = numeratorValue / denominatorValue
}
}
}
for k1, v1 := range mediateViews {
var wraps []*model.StatItemExt
for k2, v2 := range v1 {
var statItems []*model.StatItem
for k3, v3 := range v2 {
statItems = append(statItems, &model.StatItem{
DataCode: k3,
Value: v3,
})
}
wraps = append(wraps, &model.StatItemExt{
Uname: uid2name[k2],
Stats: statItems,
})
}
// uname排序
sort.Slice(wraps, func(i, j int) bool {
if wraps[i].Uname == ALLNAME {
return true
}
if wraps[j].Uname == ALLNAME {
return false
}
return wraps[i].Uname < wraps[j].Uname
})
statViewsExts = append(statViewsExts, &model.StatViewExt{
Date: k1,
Wraps: wraps,
})
}
return
}

View File

@@ -0,0 +1,337 @@
package service
import (
"context"
"go-common/app/admin/main/laser/model"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestServiceArchiveRecheck(t *testing.T) {
convey.Convey("ArchiveRecheck", t, func(convCtx convey.C) {
var (
c = context.Background()
typeIDS = []int64{}
unames = ""
startDate = int64(0)
endDate = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.ArchiveRecheck(c, typeIDS, unames, startDate, endDate)
convCtx.Convey("Then err should be nil.recheckViews should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceUserRecheck(t *testing.T) {
convey.Convey("UserRecheck", t, func(convCtx convey.C) {
var (
c = context.Background()
typeIDS = []int64{}
unames = ""
startDate = int64(0)
endDate = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.UserRecheck(c, typeIDS, unames, startDate, endDate)
convCtx.Convey("Then err should be nil.recheckViews should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceDailyStatArchiveRecheck(t *testing.T) {
convey.Convey("dailyStatArchiveRecheck", t, func(convCtx convey.C) {
var (
c = context.Background()
business = int(0)
typeIDS = []int64{}
statTypes = []int64{}
uids = []int64{}
statDate = time.Now()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.dailyStatArchiveRecheck(c, business, typeIDS, statTypes, uids, statDate)
convCtx.Convey("Then err should be nil.statViews should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServicemakeUpArchiveRecheck(t *testing.T) {
convey.Convey("makeUpArchiveRecheck", t, func(convCtx convey.C) {
var (
mediateView map[int64]map[int]int64
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
makeUpArchiveRecheck(mediateView)
convCtx.Convey("Then statViews should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceDailyStatArchiveStat(t *testing.T) {
convey.Convey("dailyArchiveStat", t, func(convCtx convey.C) {
var (
c = context.Background()
business = int(0)
typeIDS = []int64{}
statTypes = []int64{}
uids = []int64{}
statDate = time.Now()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.dailyArchiveStat(c, business, typeIDS, statTypes, uids, statDate)
convCtx.Convey("Then err should be nil.mediateView should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceTagRecheck(t *testing.T) {
convey.Convey("TagRecheck", t, func(convCtx convey.C) {
var (
c = context.Background()
startDate = int64(0)
endDate = int64(0)
unames = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.TagRecheck(c, startDate, endDate, unames)
convCtx.Convey("Then err should be nil.tagViews should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceDailyStatTagRecheck(t *testing.T) {
convey.Convey("dailyStatTagRecheck", t, func(convCtx convey.C) {
var (
c = context.Background()
business = int(0)
statTypes = []int64{}
uids = []int64{}
statDate = time.Now()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.dailyStatTagRecheck(c, business, statTypes, uids, statDate)
convCtx.Convey("Then err should be nil.statViews should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServicemakeUpTagRecheck(t *testing.T) {
convey.Convey("makeUpTagRecheck", t, func(convCtx convey.C) {
var (
mediateView map[int64]map[int]int64
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
makeUpTagRecheck(mediateView)
convCtx.Convey("Then statViews should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceRecheck123(t *testing.T) {
convey.Convey("Recheck123", t, func(convCtx convey.C) {
var (
c = context.Background()
startDate = int64(0)
endDate = int64(0)
typeIDS = []int64{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.Recheck123(c, startDate, endDate, typeIDS)
convCtx.Convey("Then err should be nil.recheckView should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceDailyStatArchiveStreamStat(t *testing.T) {
convey.Convey("dailyStatArchiveStreamStat", t, func(convCtx convey.C) {
var (
c = context.Background()
business = int(0)
typeIDS = []int64{}
uids = []int64{}
statTypes = []int64{}
statDate = time.Now()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.dailyStatArchiveStreamStat(c, business, typeIDS, uids, statTypes, statDate)
convCtx.Convey("Then err should be nil.statViews should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServicewrap(t *testing.T) {
convey.Convey("wrap", t, func(convCtx convey.C) {
var (
cargoMap map[int64]*model.CargoItem
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
wrap(cargoMap)
convCtx.Convey("Then views should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceCsvAuditCargo(t *testing.T) {
convey.Convey("CsvAuditCargo", t, func(convCtx convey.C) {
var (
c = context.Background()
startDate = int64(0)
endDate = int64(0)
unames = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.CsvAuditCargo(c, startDate, endDate, unames)
convCtx.Convey("Then err should be nil.res should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceAuditorCargoList(t *testing.T) {
convey.Convey("AuditorCargoList", t, func(convCtx convey.C) {
var (
c = context.Background()
startDate = int64(0)
endDate = int64(0)
unames = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.AuditorCargoList(c, startDate, endDate, unames)
convCtx.Convey("Then err should be nil.wrappers,lineWidth should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceCsvRandomVideoAudit(t *testing.T) {
convey.Convey("CsvRandomVideoAudit", t, func(convCtx convey.C) {
var (
c = context.Background()
startDate = int64(0)
endDate = int64(0)
unames = ""
typeIDS = []int64{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.CsvRandomVideoAudit(c, startDate, endDate, unames, typeIDS)
convCtx.Convey("Then err should be nil.res should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceCsvFixedVideoAudit(t *testing.T) {
convey.Convey("CsvFixedVideoAudit", t, func(convCtx convey.C) {
var (
c = context.Background()
startDate = int64(0)
endDate = int64(0)
unames = ""
typeIDS = []int64{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.CsvFixedVideoAudit(c, startDate, endDate, unames, typeIDS)
convCtx.Convey("Then err should be nil.res should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceRandomVideo(t *testing.T) {
convey.Convey("RandomVideo", t, func(convCtx convey.C) {
var (
c = context.Background()
startDate = int64(0)
endDate = int64(0)
typeIDS = []int64{}
uname = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.RandomVideo(c, startDate, endDate, typeIDS, uname)
convCtx.Convey("Then err should be nil.statViewExts,lineWidth should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceFixedVideo(t *testing.T) {
convey.Convey("FixedVideo", t, func(convCtx convey.C) {
var (
c = context.Background()
startDate = int64(0)
endDate = int64(0)
typeIDS = []int64{}
uname = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.FixedVideo(c, startDate, endDate, typeIDS, uname)
convCtx.Convey("Then err should be nil.statViewExts,lineWidth should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceVideoAudit(t *testing.T) {
convey.Convey("videoAudit", t, func(convCtx convey.C) {
var (
c = context.Background()
business = int(0)
statDate = time.Now()
typeIDS = []int64{}
unames = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.videoAudit(c, business, statDate, typeIDS, unames)
convCtx.Convey("Then err should be nil.viewExts,lineWidth should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServicestatNode2ViewExt(t *testing.T) {
convey.Convey("statNode2ViewExt", t, func(convCtx convey.C) {
var (
c = context.Background()
statNodes = []*model.StatNode{}
needALL = false
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
s.statNode2ViewExt(c, statNodes, needALL)
convCtx.Convey("Then err should be nil.statViewsExts,lineWidth should not be nil.", func(convCtx convey.C) {
})
})
})
}

View File

@@ -0,0 +1,110 @@
package service
import (
"bytes"
"encoding/csv"
"fmt"
"go-common/app/admin/main/laser/model"
"strconv"
"time"
)
var (
csvMetaNodes = []model.CsvMetaNode{
{Index: 0, Name: "日期", DataCode: 25},
{Index: 1, Name: "操作人", DataCode: 26},
{Index: 2, Name: "总操视频量", DataCode: model.TotalVideo},
{Index: 3, Name: "总操作次数", DataCode: model.TotalVideoOper},
{Index: 4, Name: "开放浏视频量", DataCode: model.OpenVideo},
{Index: 5, Name: "开放浏览操作次数", DataCode: model.OpenVideoOper},
{Index: 6, Name: "会员可视频量", DataCode: model.VipAccessVideo},
{Index: 7, Name: "会员可见操作次数", DataCode: model.VipAccessVideoOper},
{Index: 8, Name: "打视频量", DataCode: model.RejectVideo},
{Index: 9, Name: "打回操作次数", DataCode: model.RejectVideoOper},
{Index: 10, Name: "锁视频量", DataCode: model.LockVideo},
{Index: 11, Name: "锁定操作次数", DataCode: model.LockVideoOper},
{Index: 12, Name: "通过视频总时长", DataCode: model.PassVideoTotalDuration},
{Index: 13, Name: "未通过视频总时长", DataCode: model.FailVideoTotalDuration},
{Index: 14, Name: "视频提交到进入待审平均响应时间", DataCode: model.WaitAuditAvgTime},
{Index: 15, Name: "视频提交到进入待审时间", DataCode: model.WaitAuditDuration},
{Index: 16, Name: "视频提交到进入待审次数", DataCode: model.WaitAuditOper},
}
)
// FormatCSV format to csv data
func FormatCSV(records [][]string) (data []byte, err error) {
buf := new(bytes.Buffer)
// add utf bom
if len(records) > 0 {
buf.WriteString("\xEF\xBB\xBF")
}
w := csv.NewWriter(buf)
err = w.WriteAll(records)
if err != nil {
return
}
data = buf.Bytes()
return
}
func formatAuditCargo(wrappers []*model.CargoViewWrapper, lineWidth int) (data [][]string) {
size := len(wrappers)
if size <= 0 {
return
}
data = make([][]string, lineWidth+1)
index := 0
data[index] = []string{"username", "审核时间段", "接收量", "完成量"}
for _, v1 := range wrappers {
for k2, v2 := range v1.Data {
data[index+1] = []string{
v1.Username,
fmt.Sprintf("%s %d:00:00", v1.Date, k2),
strconv.FormatInt(v2.ReceiveValue, 10),
strconv.FormatInt(v2.AuditValue, 10),
}
index = index + 1
}
}
return
}
func formatVideoAuditStat(statViewExts []*model.StatViewExt, lineWidth int) (data [][]string) {
if lineWidth <= 0 {
return
}
data = make([][]string, lineWidth+1)
index := 0
rowHeight := len(csvMetaNodes)
titles := make([]string, rowHeight)
cursorMap := make(map[int]int)
for _, v := range csvMetaNodes {
titles[v.Index] = v.Name
cursorMap[v.DataCode] = v.Index
}
data[index] = titles
for _, v1 := range statViewExts {
date := time.Unix(v1.Date, 0).Format("2006-01-02")
for _, v2 := range v1.Wraps {
name := v2.Uname
tempRows := make([]string, rowHeight)
tempRows = append([]string{date, name}, tempRows[0:]...)
for _, v3 := range v2.Stats {
if cursor, ok := cursorMap[v3.DataCode]; ok {
if v3.DataCode == model.WaitAuditAvgTime || v3.DataCode == model.WaitAuditDuration || v3.DataCode == model.PassVideoTotalDuration || v3.DataCode == model.FailVideoTotalDuration {
tempRows[cursor] = fmt.Sprintf("%d:%d:%d", v3.Value/3600, v3.Value%3600/60, v3.Value%3600%60/1)
} else {
tempRows[cursor] = strconv.FormatInt(v3.Value, 10)
}
}
}
data[index+1] = tempRows
index = index + 1
}
}
return
}

View File

@@ -0,0 +1,52 @@
package service
import (
"go-common/app/admin/main/laser/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestServiceFormatCSV(t *testing.T) {
convey.Convey("FormatCSV", t, func(convCtx convey.C) {
var (
records = [][]string{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
FormatCSV(records)
convCtx.Convey("Then err should be nil.data should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceformatAuditCargo(t *testing.T) {
convey.Convey("formatAuditCargo", t, func(convCtx convey.C) {
var (
wrappers = []*model.CargoViewWrapper{}
lineWidth = int(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
formatAuditCargo(wrappers, lineWidth)
convCtx.Convey("Then data should not be nil.", func(convCtx convey.C) {
})
})
})
}
func TestServiceformatVideoAuditStat(t *testing.T) {
convey.Convey("formatVideoAuditStat", t, func(convCtx convey.C) {
var (
statViewExts = []*model.StatViewExt{}
lineWidth = int(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
formatVideoAuditStat(statViewExts, lineWidth)
convCtx.Convey("Then data should not be nil.", func(convCtx convey.C) {
})
})
})
}

View File

@@ -0,0 +1,33 @@
package service
import (
"context"
"go-common/app/admin/main/laser/conf"
"go-common/app/admin/main/laser/dao"
)
// Service struct
type Service struct {
conf *conf.Config
dao *dao.Dao
}
// New is new instance
func New(c *conf.Config) (s *Service) {
s = &Service{
conf: c,
dao: dao.New(c),
}
return
}
// Ping is check dao connected
func (s *Service) Ping(c context.Context) (err error) {
return s.dao.Ping(c)
}
// Close is close dao connection
func (s *Service) Close() (err error) {
return s.dao.Close(context.TODO())
}

View File

@@ -0,0 +1,32 @@
package service
import (
"flag"
"go-common/app/admin/main/laser/conf"
"os"
)
var (
s *Service
)
func init() {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "mobile.studio.laser-admin")
flag.Set("conf_token", "25911b439f4636ce9083f91c4882dffa")
flag.Set("tree_id", "19167")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/laser-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
s = New(conf.Conf)
}

View File

@@ -0,0 +1,124 @@
package service
import (
"fmt"
"strings"
"time"
"context"
"go-common/app/admin/main/laser/model"
"go-common/library/log"
xtime "go-common/library/time"
)
// AddTask is add a log task
func (s *Service) AddTask(ctx context.Context, mid int64, username string, adminID int64, logDate int64, contactEmail string, platform int, sourceType int) (err error) {
t, err := s.dao.FindTask(ctx, mid, 0)
if err != nil {
return
}
if t != nil {
err = fmt.Errorf("存在该 mid:%d 未完成的任务,请先删除后再添加", mid)
log.Error("s.AddTask() error(%v)", err)
return
}
_, err = s.dao.AddTask(ctx, mid, username, adminID, time.Unix(logDate, 0).Format("2006-01-02 15:03:04"), contactEmail, platform, sourceType)
go s.dao.AddTaskInfoCache(ctx, mid, &model.TaskInfo{
MID: mid,
LogDate: xtime.Time(logDate),
SourceType: sourceType,
Platform: platform,
Empty: false,
})
return
}
// DeleteTask is delete a log task
func (s *Service) DeleteTask(ctx context.Context, taskID int64, username string, adminID int64) (err error) {
t, err := s.dao.QueryTaskInfoByIDSQL(ctx, taskID)
if err != nil {
return
}
go s.dao.RemoveTaskInfoCache(ctx, t.MID)
return s.dao.DeleteTask(ctx, taskID, username, adminID)
}
// QueryTask is query Task by query params
func (s *Service) QueryTask(ctx context.Context, mid int64, logDateStart int64, logDateEnd int64, sourceType int, platform int, state int, sortBy string, pageNo int, pageSize int) (tasks []*model.Task, count int64, err error) {
var wherePairs []string
wherePairs = append(wherePairs, "is_deleted = 0")
wherePairs = append(wherePairs, fmt.Sprintf("state = %d", state))
if sourceType > 0 {
wherePairs = append(wherePairs, fmt.Sprintf("source_type = %d", sourceType))
}
if platform > 0 {
wherePairs = append(wherePairs, fmt.Sprintf("platform = %d", platform))
}
if mid > 0 {
wherePairs = append(wherePairs, fmt.Sprintf("mid = %d", mid))
}
layout := "2006-01-02 15:03:04"
if logDateStart > 0 && logDateEnd > 0 {
start := time.Unix(logDateStart, 0).Format(layout)
end := time.Unix(logDateEnd, 0).Format(layout)
wherePairs = append(wherePairs, fmt.Sprintf(" log_date between '%s' and '%s' ", start, end))
} else if logDateStart > 0 {
start := time.Unix(logDateStart, 0).Format(layout)
wherePairs = append(wherePairs, fmt.Sprintf("log_date >= '%s' ", start))
}
var queryStmt string
if len(wherePairs) > 0 {
queryStmt = strings.Join(wherePairs, " AND ")
}
sort := buildSortStmt(sortBy)
var limit, offset int
if pageNo > 0 && pageSize > 0 {
offset = (pageNo - 1) * pageSize
limit = pageSize
} else {
offset = 0
limit = 20
}
return s.dao.QueryTask(ctx, queryStmt, sort, offset, limit)
}
func buildSortStmt(sortBy string) (sort string) {
if sortBy == "" {
sort = "mtime Desc"
return
}
if strings.HasPrefix(sortBy, "-") {
sort = strings.TrimPrefix(sortBy, "-") + " " + "Desc"
}
return sort
}
// UpdateTask is update undone task where state = 0.
func (s *Service) UpdateTask(ctx context.Context, username string, adminID int64, taskID int64, mid int64, logDate int64, contactEmail string, sourceType int, platform int) (err error) {
var updatePairs []string
updatePairs = append(updatePairs, fmt.Sprintf("source_type = %d", sourceType))
updatePairs = append(updatePairs, fmt.Sprintf("platform = %d", platform))
updatePairs = append(updatePairs, fmt.Sprintf("mid = %d", mid))
updatePairs = append(updatePairs, fmt.Sprintf("log_date = '%s' ", time.Unix(logDate, 0).Format("2006-01-02 15:03:04")))
updatePairs = append(updatePairs, fmt.Sprintf("contact_email = '%s'", contactEmail))
if adminID > 0 {
updatePairs = append(updatePairs, fmt.Sprintf("admin_id = %d", adminID))
}
if len(username) != 0 {
updatePairs = append(updatePairs, fmt.Sprintf("username = '%s' ", username))
}
updateStmt := strings.Join(updatePairs, ", ")
// 0 undone
state := 0
// 下列参数前端必传.
go s.dao.AddTaskInfoCache(ctx, mid, &model.TaskInfo{
MID: mid,
LogDate: xtime.Time(logDate),
SourceType: sourceType,
Platform: platform,
Empty: false,
})
return s.dao.UpdateTask(ctx, taskID, state, updateStmt)
}

View File

@@ -0,0 +1,42 @@
package service
import (
"fmt"
"strings"
"context"
"go-common/app/admin/main/laser/model"
)
// QueryTaskLog is query the finished task
func (s *Service) QueryTaskLog(ctx context.Context, mid int64, taskID int64, platform int, taskState int, sortBy string, pageNo int, pageSize int) (logs []*model.TaskLog, count int64, err error) {
var wherePairs []string
if mid > 0 {
wherePairs = append(wherePairs, fmt.Sprintf("mid = %d", mid))
}
if taskID > 0 {
wherePairs = append(wherePairs, fmt.Sprintf("task_id = %d", taskID))
}
if platform > 0 {
wherePairs = append(wherePairs, fmt.Sprintf("platform = %d", platform))
}
if taskState > 0 {
wherePairs = append(wherePairs, fmt.Sprintf("task_state = %d", taskState))
}
var queryStmt string
if len(wherePairs) > 0 {
queryStmt = "WHERE " + strings.Join(wherePairs, " AND ")
}
sort := buildSortStmt(sortBy)
var limit, offset int
if pageNo >= 0 && pageSize > 0 {
offset = (pageNo - 1) * pageSize
limit = pageSize
} else {
offset = 0
limit = 20
}
logs, count, err = s.dao.QueryTaskLog(ctx, queryStmt, sort, offset, limit)
return
}

View File

@@ -0,0 +1,29 @@
package service
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestServiceQueryTaskLog(t *testing.T) {
convey.Convey("QueryTaskLog", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
taskID = int64(0)
platform = int(0)
taskState = int(0)
sortBy = ""
pageNo = int(0)
pageSize = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
s.QueryTaskLog(c, mid, taskID, platform, taskState, sortBy, pageNo, pageSize)
ctx.Convey("Then err should be nil.logs,count should not be nil.", func(ctx convey.C) {
})
})
})
}

View File

@@ -0,0 +1,103 @@
package service
import (
"context"
"github.com/smartystreets/goconvey/convey"
"testing"
)
func TestServiceAddTask(t *testing.T) {
convey.Convey("AddTask", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
username = ""
adminID = int64(0)
logDate = int64(0)
contactEmail = ""
platform = int(0)
sourceType = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
s.AddTask(c, mid, username, adminID, logDate, contactEmail, platform, sourceType)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
})
})
})
}
func TestServiceDeleteTask(t *testing.T) {
convey.Convey("DeleteTask", t, func(ctx convey.C) {
var (
c = context.Background()
taskID = int64(0)
username = ""
adminID = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
s.DeleteTask(c, taskID, username, adminID)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
})
})
})
}
func TestServiceQueryTask(t *testing.T) {
convey.Convey("QueryTask", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
logDateStart = int64(0)
logDateEnd = int64(0)
sourceType = int(0)
platform = int(0)
state = int(0)
sortBy = ""
pageNo = int(0)
pageSize = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
s.QueryTask(c, mid, logDateStart, logDateEnd, sourceType, platform, state, sortBy, pageNo, pageSize)
ctx.Convey("Then err should be nil.tasks,count should not be nil.", func(ctx convey.C) {
})
})
})
}
func TestServicebuildSortStmt(t *testing.T) {
convey.Convey("buildSortStmt", t, func(ctx convey.C) {
var (
sortBy = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
sort := buildSortStmt(sortBy)
ctx.Convey("Then sort should not be nil.", func(ctx convey.C) {
ctx.Convey(sort, convey.ShouldNotBeNil)
})
})
})
}
func TestServiceUpdateTask(t *testing.T) {
convey.Convey("UpdateTask", t, func(ctx convey.C) {
var (
c = context.Background()
username = ""
adminID = int64(0)
taskID = int64(0)
mid = int64(0)
logDate = int64(0)
contactEmail = ""
sourceType = int(0)
platform = int(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
s.UpdateTask(c, username, adminID, taskID, mid, logDate, contactEmail, sourceType, platform)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
})
})
})
}