123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615 |
- 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
- }
|