534 lines
15 KiB
Go
534 lines
15 KiB
Go
|
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
|
|||
|
}
|