123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533 |
- package service
- import (
- "context"
- "errors"
- "hash/crc32"
- "strconv"
- "strings"
- "time"
- "go-common/app/admin/main/videoup/model/archive"
- mngmdl "go-common/app/admin/main/videoup/model/manager"
- accApi "go-common/app/service/main/account/api"
- upsrpc "go-common/app/service/main/up/api/v1"
- "go-common/library/log"
- "go-common/library/sync/errgroup"
- xtime "go-common/library/time"
- "go-common/library/xstr"
- )
- //ERROR
- var (
- ErrRPCEmpty = errors.New("rpc reply empty")
- )
- func (s *Service) archiveRound(c context.Context, a *archive.Archive, aid, mid int64, typeID int16, nowRound, newState int8, cancelMission bool) (round int8) {
- //非特殊分区私单定时发布时,稿件进入四审
- //一个私单且定时发布的稿件 应该是先通过待审 传递到 私单四审 ,私单四审开放浏览后到达设置的定时时间最后再自动发布
- if s.isPorder(a) && newState == archive.StateForbidUserDelay && !s.isAuditType(typeID) {
- round = archive.RoundReviewFlow
- return
- }
- //定时发布的付费稿件 投上来就是round24 admin提交不需要再走付费审核
- //定时发布
- if newState == archive.StateForbidAdminDelay || newState == archive.StateForbidUserDelay {
- round = nowRound
- return
- }
- var addit *archive.Addit
- //活动稿件(非私单且非付费) | pgc 稿件 up_from(1,5,6) 直接round 99 简单流程业务
- if addit, _ = s.arc.Addit(c, aid); addit != nil && (addit.UpFrom == archive.UpFromPGC || addit.UpFrom == archive.UpFromSecretPGC || addit.UpFrom == archive.UpFromCoopera || (addit.MissionID > 0 && !s.isPorder(a) && !s.isUGCPay(a))) {
- if addit.UpFrom == archive.UpFromSecretPGC && newState == archive.StateForbidWait {
- //pgc 机密待审state=-1 不变更round
- round = nowRound
- return
- }
- if archive.NormalState(newState) {
- //pgc 生产组机密稿件(番剧、付费版权,严格要求时效和保密性) up_from=5 开放回查流程 90
- if addit.UpFrom == archive.UpFromSecretPGC && nowRound < archive.RoundTriggerClick {
- //三查
- round = archive.RoundTriggerClick
- return
- }
- }
- //pgc 生产组常规稿件(片包等其他内容) up_from=1 进三审
- if addit.UpFrom == archive.UpFromPGC && nowRound < archive.RoundAuditThird {
- round = archive.RoundAuditThird
- return
- }
- //pgc 合作方嵌套,终结
- if addit.UpFrom == archive.UpFromCoopera && nowRound < archive.RoundAuditThird {
- round = archive.RoundEnd
- return
- }
- round = archive.RoundEnd
- return
- }
- //其他稿件 (非定时,活动,pgc)
- if nowRound == archive.RoundAuditSecond {
- //二审阶段
- if newState == archive.StateForbidWait {
- //1、非特殊分区私单进入私单四审;2、私单活动稿件进入私单四审
- if (s.isPorder(a) && !s.isAuditType(typeID)) || (s.isPorder(a) && !cancelMission && addit.MissionID > 0) {
- //私单四审
- round = archive.RoundReviewFlow
- } else if s.isUGCPay(a) && (!s.isAuditType(typeID) || !s.isPorder(a) || (!cancelMission && addit.MissionID > 0)) {
- //付费稿件 非特殊分区 非私单
- round = archive.RoundAuditUGCPayFlow
- } else if s.isAuditType(typeID) || (addit != nil && addit.OrderID > 0) {
- //特殊分区 ,商单到三审 二审到三审
- round = archive.RoundAuditThird
- } else {
- //不变
- round = archive.RoundAuditSecond
- }
- } else if archive.NormalState(newState) {
- //回查控制
- round = s.normalRound(c, aid, mid, typeID, nowRound, newState)
- } else if newState == archive.StateForbidFixed {
- //1、非特殊分区私单进入私单四审修复待审;2、私单+活动稿件进入私单四审修复待审
- if (s.isPorder(a) && !s.isAuditType(typeID)) || (s.isPorder(a) && !cancelMission && addit.MissionID > 0) {
- round = archive.RoundReviewFlow
- } else if s.isAuditType(typeID) && !(!cancelMission && addit.MissionID > 0) {
- //特殊分区 二审到三审
- round = archive.RoundAuditThird
- } else if s.isUGCPay(a) && (!s.isAuditType(typeID) || !s.isPorder(a) || (!cancelMission && addit.MissionID > 0)) {
- //付费稿件 非特殊分区 非私单
- round = archive.RoundAuditUGCPayFlow
- } else {
- //不变
- round = archive.RoundAuditSecond
- }
- } else {
- round = archive.RoundEnd
- }
- } else if nowRound == archive.RoundReviewFlow {
- //私单四审21
- if archive.NormalState(newState) {
- if s.isAuditType(typeID) || addit.MissionID > 0 {
- round = archive.RoundEnd
- } else {
- round = s.normalRound(c, aid, mid, typeID, nowRound, newState)
- }
- } else {
- round = archive.RoundEnd
- }
- } else if nowRound == archive.RoundAuditUGCPayFlow {
- //付费待审 24
- if archive.NormalState(newState) {
- if s.isAuditType(typeID) || addit.MissionID > 0 {
- round = archive.RoundEnd
- } else {
- round = s.normalRound(c, aid, mid, typeID, nowRound, newState)
- }
- } else {
- round = archive.RoundEnd
- }
- } else if nowRound == archive.RoundReviewFirst {
- //一查
- if archive.NormalState(newState) {
- round = archive.RoundReviewFirstWaitTrigger
- } else {
- round = archive.RoundEnd
- }
- } else if nowRound == archive.RoundAuditThird {
- //三审
- if s.isPorder(a) {
- //私单四审
- round = archive.RoundReviewFlow
- } else if s.isUGCPay(a) {
- round = archive.RoundAuditUGCPayFlow
- } else {
- round = archive.RoundEnd
- }
- } else if nowRound == archive.RoundReviewSecond || nowRound == archive.RoundTriggerClick {
- //二查 三查
- round = archive.RoundEnd
- } else {
- round = nowRound
- }
- return
- }
- //normalRound 回查逻辑
- func (s *Service) normalRound(c context.Context, aid, mid int64, typeID int16, nowRound, newState int8) (round int8) {
- if s.isWhite(mid) || s.isBlack(mid) {
- round = archive.RoundReviewSecond
- } else if plf, _ := s.profile(c, mid); plf != nil && plf.Follower >= s.fansCache {
- //社区回查 粉丝阈值
- round = archive.RoundReviewSecond
- } else if plf != nil && plf.Follower < s.fansCache && s.isRoundType(typeID) {
- //回查分区
- round = archive.RoundReviewFirst // NOTE: if audit type, state must not open!!! so cannot execute here...
- } else {
- //点击量回查
- round = archive.RoundReviewFirstWaitTrigger
- if plf == nil {
- log.Info("archive(%d) card(%d) is nil", aid, mid)
- } else {
- log.Info("archive(%d) card(%d) fans(%d) little than config(%d)", aid, mid, plf.Follower, s.fansCache)
- }
- }
- return
- }
- func (s *Service) hadPassed(c context.Context, aid int64) (had bool) {
- id, err := s.arc.GetFirstPassByAID(c, aid)
- if err != nil {
- log.Error("hadPassed s.arc.GetFirstPassByAID error(%v) aid(%d)", err, aid)
- return
- }
- had = id > 0
- return
- }
- func (s *Service) isPorder(a *archive.Archive) bool {
- if a == nil {
- return false
- }
- return a.AttrVal(archive.AttrBitIsPorder) == archive.AttrYes
- }
- //ugc pay only
- func (s *Service) isUGCPay(a *archive.Archive) bool {
- if a == nil {
- return false
- }
- return a.AttrVal(archive.AttrBitUGCPay) == archive.AttrYes
- }
- func (s *Service) profile(c context.Context, mid int64) (card *accApi.ProfileStatReply, err error) {
- if card, err = s.accRPC.ProfileWithStat3(c, &accApi.MidReq{Mid: mid}); err != nil {
- log.Error("s.accRPC.ProfileWithStat3(%d) error(%v)", mid, err)
- }
- return
- }
- func (s *Service) upCards(c context.Context, mids []int64) (p map[int64]*accApi.Card, err error) {
- p = make(map[int64]*accApi.Card)
- if len(mids) == 0 {
- return
- }
- var res *accApi.CardsReply
- if res, err = s.accRPC.Cards3(c, &accApi.MidsReq{Mids: mids}); err != nil {
- p = nil
- log.Error("s.accRPC.Cards3(%v) error(%v)", mids, err)
- return
- }
- p = res.Cards
- return
- }
- func (s *Service) archivePtime(c context.Context, aid int64, newState int8, newPtime xtime.Time) (ptime xtime.Time) {
- if newState >= archive.StateOpen {
- if !s.hadPassed(c, aid) {
- ptime = xtime.Time(time.Now().Unix())
- return
- }
- }
- ptime = newPtime
- return
- }
- func (s *Service) archiveAttr(c context.Context, ap *archive.ArcParam, isExt bool) (attrs map[uint]int32, forbidAttrs map[string]map[uint]int32) {
- //批量和单个提交都需要补全对应属性值
- attrs = make(map[uint]int32)
- attrs[archive.AttrBitNoRank] = ap.Attrs.NoRank
- attrs[archive.AttrBitNoDynamic] = ap.Attrs.NoDynamic
- attrs[archive.AttrBitNoWeb] = ap.Attrs.NoWeb
- attrs[archive.AttrBitNoMobile] = ap.Attrs.NoMobile
- attrs[archive.AttrBitNoSearch] = ap.Attrs.NoSearch
- attrs[archive.AttrBitOverseaLock] = ap.Attrs.OverseaLock
- attrs[archive.AttrBitNoRecommend] = ap.Attrs.NoRecommend
- attrs[archive.AttrBitNoReprint] = ap.Attrs.NoReprint
- attrs[archive.AttrBitHasHD5] = ap.Attrs.HasHD5
- attrs[archive.AttrBitAllowBp] = ap.Attrs.AllowBp
- attrs[archive.AttrBitIsPorder] = ap.Attrs.IsPorder
- attrs[archive.AttrBitLimitArea] = ap.Attrs.LimitArea
- attrs[archive.AttrBitPushBlog] = ap.Attrs.PushBlog
- attrs[archive.AttrBitUGCPay] = ap.Attrs.UGCPay
- attrs[archive.AttrBitParentMode] = ap.Attrs.ParentMode
- // pgc
- attrs[archive.AttrBitIsMovie] = ap.Attrs.IsMovie
- attrs[archive.AttrBitBadgepay] = ap.Attrs.BadgePay
- attrs[archive.AttrBitIsBangumi] = ap.Attrs.IsBangumi
- attrs[archive.AttrBitIsPGC] = ap.Attrs.IsPGC
- if isExt {
- attrs[archive.AttrBitAllowTag] = ap.Attrs.AllowTag
- attrs[archive.AttrBitJumpURL] = ap.Attrs.JumpURL
- }
- forbidAttrs = make(map[string]map[uint]int32, 4)
- forbidAttrs[archive.ForbidRank] = map[uint]int32{
- archive.ForbidRankMain: ap.Forbid.Rank.Main,
- archive.ForbidRankRecentArc: ap.Forbid.Rank.RecentArc,
- archive.ForbidRankAllArc: ap.Forbid.Rank.AllArc,
- }
- forbidAttrs[archive.ForbidDynamic] = map[uint]int32{
- archive.ForbidDynamicMain: ap.Forbid.Dynamic.Main,
- }
- forbidAttrs[archive.ForbidRecommend] = map[uint]int32{
- archive.ForbidRecommendMain: ap.Forbid.Recommend.Main,
- }
- forbidAttrs[archive.ForbidShow] = map[uint]int32{
- archive.ForbidShowMain: ap.Forbid.Show.Main,
- archive.ForbidShowMobile: ap.Forbid.Show.Mobile,
- archive.ForbidShowWeb: ap.Forbid.Show.Web,
- archive.ForbidShowOversea: ap.Forbid.Show.Oversea,
- archive.ForbidShowOnline: ap.Forbid.Show.Online,
- }
- return
- }
- func (s *Service) isAccess(c context.Context, aid int64) (wm bool) {
- var vs []*archive.Video
- if vs, _ = s.arc.NewVideosByAid(c, aid); len(vs) <= 0 {
- return
- }
- for _, v := range vs {
- if v.Status == 10000 {
- wm = true
- return
- }
- }
- return
- }
- // CheckArchive check typeid
- func (s *Service) CheckArchive(aps []*archive.ArcParam) bool {
- for _, ap := range aps {
- if ap.Aid == 0 || ap.UID == 0 {
- return false
- }
- }
- return true
- }
- // CheckVideo check video
- func (s *Service) CheckVideo(vps []*archive.VideoParam) bool {
- for _, vp := range vps {
- if vp.ID == 0 || vp.Aid == 0 || vp.Filename == "" || vp.Cid == 0 || vp.UID == 0 {
- return false
- }
- }
- return true
- }
- // CheckStaff check
- func (s *Service) CheckStaff(vps []*archive.StaffParam) bool {
- //允许为空 不允许为Nil
- if len(vps) == 0 {
- return true
- }
- for _, vp := range vps {
- if vp.MID == 0 || vp.Title == "" {
- return false
- }
- }
- return true
- }
- // TypeTopParent get archive type's first level type
- func (s *Service) TypeTopParent(tid int16) (tp *archive.Type, err error) {
- if _, ok := s.typeCache[tid]; !ok {
- err = errors.New("archive type id not exist. id:" + strconv.Itoa(int(tid)))
- return
- }
- if s.typeCache[tid].PID == 0 {
- tp = s.typeCache[tid]
- } else {
- tp, err = s.TypeTopParent(s.typeCache[tid].PID)
- if err != nil {
- return
- }
- }
- return
- }
- //StringHandler handle two strings 以s1顺序为准
- func StringHandler(s1 string, s2 string, delimiter string, subtraction bool) string {
- if strings.TrimSpace(s2) == "" {
- return s1
- }
- var (
- res []string
- duplicate []int
- )
- s1Arr := strings.Split(s1, delimiter)
- s2Arr := strings.Split(s2, delimiter)
- for _, s1Item := range s1Arr {
- dupIndex := -1
- for k, s2Item := range s2Arr {
- if s1Item == s2Item {
- dupIndex = k
- break
- }
- }
- if dupIndex >= 0 && subtraction {
- continue
- }
- if dupIndex >= 0 {
- duplicate = append(duplicate, dupIndex)
- }
- res = append(res, s1Item)
- }
- if !subtraction {
- for k, s2Item := range s2Arr {
- s2Item = strings.TrimSpace(s2Item)
- if s2Item == "" {
- continue
- }
- add := true
- for _, dup := range duplicate {
- if k == dup {
- add = false
- break
- }
- }
- if add {
- res = append(res, s2Item)
- }
- }
- }
- return strings.Join(res, delimiter)
- }
- // SplitInts 去掉id字符串中的空白字符
- func (s *Service) SplitInts(str string) ([]int64, error) {
- empties := []string{" ", "\n", "\t", "\r"}
- for _, v := range empties {
- str = strings.Replace(str, v, "", -1)
- }
- str = strings.Trim(str, ",")
- return xstr.SplitInts(str)
- }
- // coverURL convert cover url to full url.
- func coverURL(uri string) (cover string) {
- if uri == "" {
- cover = "http://static.hdslb.com/images/transparent.gif"
- return
- }
- cover = uri
- if strings.Index(uri, "http://") == 0 {
- return
- }
- if len(uri) >= 10 && uri[:10] == "/templets/" {
- return
- }
- if strings.HasPrefix(uri, "group1") {
- cover = "http://i0.hdslb.com/" + uri
- return
- }
- if pos := strings.Index(uri, "/uploads/"); pos != -1 && (pos == 0 || pos == 3) {
- cover = uri[pos+8:]
- }
- cover = strings.Replace(cover, "{IMG}", "", -1)
- cover = "http://i" + strconv.FormatInt(int64(crc32.ChecksumIEEE([]byte(cover)))%3, 10) + ".hdslb.com" + cover
- return
- }
- func (s *Service) upGroupMids(c context.Context, gid int64) (mids []int64, err error) {
- var (
- total int
- maxps = 10000
- req = &upsrpc.UpGroupMidsReq{
- Pn: 1,
- GroupID: gid,
- Ps: maxps,
- }
- reply *upsrpc.UpGroupMidsReply
- )
- for {
- reply, err = s.upsRPC.UpGroupMids(c, req)
- if err == nil && (reply == nil || reply.Mids == nil) {
- err = ErrRPCEmpty
- }
- if err != nil {
- log.Error("UpGroupMids req(%+v) error(%v)", req, err)
- return
- }
- total = reply.Total
- mids = append(mids, reply.Mids...)
- if reply.Size() != maxps {
- break
- }
- req.Pn++
- }
- log.Info("upGroupMids(%d) reply total(%d) len(%d)", gid, total, len(mids))
- return
- }
- func (s *Service) upSpecial(c context.Context) (ups map[int8]map[int64]struct{}, err error) {
- var (
- g errgroup.Group
- whitegroup, blackgroup, pgcgroup, ugcxgroup, policygroup, dangergroup, twoforbidgroup, pgcwhitegroup map[int64]struct{}
- )
- ups = make(map[int8]map[int64]struct{})
- f := func(gid int8) (map[int64]struct{}, error) {
- group := make(map[int64]struct{})
- mids, e := s.upGroupMids(c, int64(gid))
- if e != nil {
- return group, e
- }
- for _, mid := range mids {
- group[mid] = struct{}{}
- }
- return group, nil
- }
- g.Go(func() error {
- whitegroup, err = f(mngmdl.UpperTypeWhite)
- return err
- })
- g.Go(func() error {
- blackgroup, err = f(mngmdl.UpperTypeBlack)
- return err
- })
- g.Go(func() error {
- pgcgroup, err = f(mngmdl.UpperTypePGC)
- return err
- })
- g.Go(func() error {
- ugcxgroup, err = f(mngmdl.UpperTypeUGCX)
- return err
- })
- g.Go(func() error {
- policygroup, err = f(mngmdl.UpperTypePolity)
- return err
- })
- g.Go(func() error {
- dangergroup, err = f(mngmdl.UpperTypeDanger)
- return err
- })
- g.Go(func() error {
- twoforbidgroup, err = f(mngmdl.UpperTypeTwoForbid)
- return err
- })
- g.Go(func() error {
- pgcwhitegroup, err = f(mngmdl.UpperTypePGCWhite)
- return err
- })
- if err = g.Wait(); err != nil {
- return
- }
- ups[mngmdl.UpperTypeWhite] = whitegroup
- ups[mngmdl.UpperTypeBlack] = blackgroup
- ups[mngmdl.UpperTypePGC] = pgcgroup
- ups[mngmdl.UpperTypeUGCX] = ugcxgroup
- ups[mngmdl.UpperTypePolity] = policygroup
- ups[mngmdl.UpperTypeDanger] = dangergroup
- ups[mngmdl.UpperTypeTwoForbid] = twoforbidgroup
- ups[mngmdl.UpperTypePGCWhite] = pgcwhitegroup
- return
- }
|