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,78 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"search_test.go",
"service_test.go",
"video_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/videoup-task/conf:go_default_library",
"//app/admin/main/videoup-task/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"consumer.go",
"extra_func.go",
"log.go",
"oper.go",
"qa_video.go",
"review.go",
"search.go",
"service.go",
"task.go",
"task_dispatch.go",
"task_report.go",
"utils.go",
"video.go",
"weight.go",
],
importpath = "go-common/app/admin/main/videoup-task/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/videoup-task/conf:go_default_library",
"//app/admin/main/videoup-task/dao:go_default_library",
"//app/admin/main/videoup-task/model:go_default_library",
"//app/admin/main/videoup/model/archive:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/up/api/v1:go_default_library",
"//library/database/elastic:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/queue/databus/report:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/xstr: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,172 @@
package service
import (
"context"
"fmt"
"go-common/library/sync/errgroup"
"strings"
"time"
"go-common/app/admin/main/videoup-task/model"
"go-common/library/log"
)
// HandsUp 签入
func (s *Service) HandsUp(c context.Context, uid int64, uname string) (err error) {
if s.CheckOnline(c, uid) {
log.Info("已经登入(%d)", uid)
return
}
_, err = s.dao.TaskUserCheckIn(c, uid)
if err != nil {
log.Error("s.dao.TaskUserCheckIn(%d) error(%v)", uid, err)
return
}
s.sendConsumerLog(c, &model.ConsumerLog{
UID: uid,
Uname: uname,
Action: model.ActionHandsUP,
Ctime: time.Now().Format(model.TimeFormatSec),
Desc: "checkin",
})
mapParas := map[string]interface{}{
"action": model.ActionHandsUP,
"uid": uid,
}
if _, err = s.dao.AddTaskHis(c, 0, model.ActionHandsUP, 0, 0, uid, 0, 0, "checkin"); err != nil {
log.Error("s.dao.AddTaskLog(%v) error(%v)", mapParas, uid)
return
}
log.Info("用户签入(%d)", uid)
return
}
// HandsOff 签出
func (s *Service) HandsOff(c context.Context, uid int64, fuid int64) (err error) {
if fuid != 0 { //管理员强制踢出组员
if !s.isLeader(c, uid) {
return fmt.Errorf("只有组长能强制踢出")
}
log.Info("管理员%d踢出组员%d", uid, fuid)
uid = fuid
}
err = s.checkOut(c, uid)
if err != nil {
log.Error("s.checkOut(%d) error(%v)", uid, err)
return
}
s.Free(c, uid)
return
}
// Online 用户列表
func (s *Service) Online(c context.Context) (cms []*model.Consumers, err error) {
cms, err = s.dao.Consumers(c)
if err != nil {
log.Error("s.dao.Consumers error(%v)", err)
return
}
if len(cms) > 0 {
var wg errgroup.Group
wg.Go(func() error {
if err := s.mulIDtoName(c, cms, s.dao.GetNameByUID, "UID", "UserName"); err != nil {
log.Error("mulIDtoName s.dao.GetNameByUID error(%v)", err)
}
return nil
})
wg.Go(func() error {
if err := s.mulIDtoName(c, cms, s.dao.OutTime, "UID", "LastOut"); err != nil {
log.Error("mulIDtoName s.dao.OutTime error(%v)", err)
}
return nil
})
wg.Wait()
}
return
}
// InOutList 用户登入登出历史
func (s *Service) InOutList(c context.Context, unames string, bt, et string) (l []*model.InQuit, err error) {
uids := []int64{}
if len(unames) > 0 {
if res, err := s.dao.Uids(c, strings.Split(unames, ",")); err == nil {
for _, uid := range res {
uids = append(uids, uid)
}
}
}
// 前端参数是日期,搜索参数必须到秒
if len(bt) > 0 && len(et) > 0 {
bt = bt + " 00:00:00"
et = et + " 23:59:59"
}
return s.dao.InQuitList(c, uids, bt, et)
}
// CheckOnline 检查在线状态
func (s *Service) CheckOnline(c context.Context, uid int64) (on bool) {
if s.dao.IsConsumerOn(c, uid) == 1 {
on = true
}
return
}
// CheckGroup 检查用户组权限
func (s *Service) CheckGroup(c context.Context, uid int64) (role int8, err error) {
role, err = s.dao.GetUserRole(c, uid)
if err != nil || role == 0 {
log.Error("非法用户(%d) error(%v)", uid, err)
return
}
return
}
func (s *Service) checkOut(c context.Context, uid int64) (err error) {
if s.dao.IsConsumerOn(c, uid) == 0 {
log.Info("已经签出(%d)", uid)
return
}
_, err = s.dao.TaskUserCheckOff(c, uid)
if err != nil {
log.Error("s.dao.TaskUserCheckOff(%d) error(%v)", uid, err)
return
}
s.sendConsumerLog(c, &model.ConsumerLog{
UID: uid,
Uname: "",
Action: model.ActionHandsOFF,
Ctime: time.Now().Format(model.TimeFormatSec),
Desc: "checkout",
})
mapParas := map[string]interface{}{
"action": model.ActionHandsOFF,
"uid": uid,
}
if _, err = s.dao.AddTaskHis(c, 0, model.ActionHandsOFF, 0, 0, uid, 0, 0, "checkOut"); err != nil {
log.Error("s.dao.AddTaskLog(%v) error(%v)", mapParas, uid)
}
return
}
func (s *Service) isLeader(c context.Context, uid int64) bool {
role, e := s.dao.GetUserRole(c, uid)
if e != nil {
log.Error("s.dao.GetUserRole(%d) error(%v)", uid, e)
return false
}
if role == model.TaskLeader {
return true
}
return false
}

View File

@@ -0,0 +1,106 @@
package service
import (
"context"
"errors"
tmod "go-common/app/admin/main/videoup-task/model"
account "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"
)
//ERROR
var (
ErrRPCEmpty = errors.New("rpc reply empty")
)
func (s *Service) profile(c context.Context, mid int64) (profile *account.ProfileStatReply, err error) {
if profile, err = s.accRPC.ProfileWithStat3(c, &account.MidReq{Mid: mid}); err != nil {
log.Error("s.accRPC.ProfileWithStat3(%d) error(%v)", mid, err)
}
return
}
func (s *Service) upSpecial(c context.Context) (ups map[int8]map[int64]struct{}, err error) {
var (
g errgroup.Group
whitegroup, blackgroup, policesgroup, enterprisegroup, signedgroup 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(tmod.UpperTypeWhite)
return err
})
g.Go(func() error {
blackgroup, err = f(tmod.UpperTypeBlack)
return err
})
g.Go(func() error {
policesgroup, err = f(tmod.UpperTypePolitices)
return err
})
g.Go(func() error {
enterprisegroup, err = f(tmod.UpperTypeEnterprise)
return err
})
g.Go(func() error {
signedgroup, err = f(tmod.UpperTypeSigned)
return err
})
if err = g.Wait(); err != nil {
return
}
ups[tmod.UpperTypeWhite] = whitegroup
ups[tmod.UpperTypeBlack] = blackgroup
ups[tmod.UpperTypePolitices] = policesgroup
ups[tmod.UpperTypeEnterprise] = enterprisegroup
ups[tmod.UpperTypeSigned] = signedgroup
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
}

View File

@@ -0,0 +1,69 @@
package service
import (
"context"
"strconv"
"time"
"go-common/app/admin/main/videoup-task/model"
"go-common/library/log"
"go-common/library/queue/databus/report"
)
// send to log service
func (s *Service) sendVideoLog(c context.Context, vp *model.VideoParam, others string) (err error) {
var (
v *model.ArcVideo
a *model.Archive
)
if vp.Cid != 0 {
v, err = s.dao.ArcVideoByCID(c, vp.Cid)
} else if vp.ID != 0 {
v, err = s.dao.NewVideoByID(c, vp.ID)
}
if err != nil || v == nil {
v = &model.ArcVideo{} // ignore err
}
a, err = s.dao.Archive(c, vp.Aid)
if err != nil || a == nil {
a = &model.Archive{} // ignore err
}
// send
logData := &report.ManagerInfo{
Uname: vp.Oname,
UID: vp.UID,
Business: model.LogClientVideo,
Type: model.LogClientTypeVideo,
Oid: vp.Cid,
Action: strconv.Itoa(int(vp.Status)),
Ctime: time.Now(),
Index: []interface{}{int64(vp.Attribute), v.CTime.Unix(), vp.TagID, a.Title, vp.Note},
Content: map[string]interface{}{
"content": vp,
"others": others,
},
}
report.Manager(logData)
return
}
// sendConsumerLog send consumer log
func (s *Service) sendConsumerLog(c context.Context, cl *model.ConsumerLog) (err error) {
logData := &report.ManagerInfo{
Uname: cl.Uname,
UID: cl.UID,
Business: model.LogClientConsumer,
Type: model.LogClientTypeConsumer,
Oid: cl.UID,
Action: strconv.Itoa(int(cl.Action)),
Ctime: time.Now(),
Index: []interface{}{cl.UID, cl.Action, cl.Ctime},
Content: map[string]interface{}{
"content": cl,
},
}
report.Manager(logData)
log.Info("sendConsumerLog logData(%+v)", cl)
return
}

View File

@@ -0,0 +1,41 @@
package service
import (
"context"
"go-common/app/admin/main/videoup-task/model"
)
func (s *Service) diffVideoOper(vp *model.VideoParam) (conts []string) {
if vp.TagID > 0 {
var operType int8
if vp.Status >= model.VideoStatusOpen {
operType = model.OperTypeOpenTag
} else {
operType = model.OperTypeRecicleTag
}
conts = append(conts, model.Operformat(operType, "tagid", vp.TagID, model.OperStyleTwo))
}
if vp.Reason != "" {
conts = append(conts, model.Operformat(model.OperTypeAduitReason, "reason", vp.Reason, model.OperStyleTwo))
}
if vp.TaskID > 0 {
conts = append(conts, model.Operformat(model.OperTypeTaskID, "task", vp.TaskID, model.OperStyleTwo))
}
return
}
func (s *Service) addVideoOper(c context.Context, oper *model.VideoOper) (err error) {
/*
if oldOper, _ := s.dao.VideoOper(c, oper.Vid); oldOper != nil && oldOper.LastID == 1 {
oper.LastID = oldOper.ID
s.dao.AddVideoOper(c, oper.Aid, oper.UID, oper.Vid, oper.Attribute, oper.Status, oper.LastID, oper.Content, oper.Remark)
return
}
*/
if lastID, _ := s.dao.AddVideoOper(c, oper.Aid, oper.UID, oper.Vid, oper.Attribute, oper.Status, oper.LastID, oper.Content, oper.Remark); lastID > 0 {
s.dao.UpVideoOper(c, lastID, lastID)
return
}
return
}

View File

@@ -0,0 +1,320 @@
package service
import (
"context"
"fmt"
"strconv"
"time"
"go-common/app/admin/main/videoup-task/dao"
"go-common/app/admin/main/videoup-task/model"
accmdl "go-common/app/service/main/account/model"
"go-common/library/database/sql"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/queue/databus/report"
)
//GetVideoList list qa video tasks
func (s *Service) GetVideoList(ctx context.Context, pm *model.ListParams) (list *model.QAVideoList, err error) {
var (
listLen int
detailMap map[int64]map[string]int64
midList []int64
users map[int64]*model.UserRole
infos map[int64]*accmdl.Info
upGroupList map[int64][]*model.UPGroup
)
if list, err = s.searchQAVideo(ctx, pm); err != nil || list == nil || len(list.Result) <= 0 {
return
}
ids := make([]int64, listLen)
uids := make([]int64, listLen)
for _, item := range list.Result {
ids = append(ids, item.ID)
uids = append(uids, item.UID)
}
if detailMap, midList, err = s.dao.QAVideoDetail(ctx, ids); err != nil {
return
}
if users, err = s.dao.GetUsernameAndRole(ctx, uids); err != nil {
return
}
if infos, err = s.dao.AccountInfos(ctx, midList); err != nil {
return
}
//获取列表页获取
if upGroupList, err = s.dao.UPGroups(ctx, midList); err != nil {
return
}
for _, item := range list.Result {
item.User = users[item.UID]
item.StateName = model.QAStates[item.State]
item.UPName = ""
dt, exist := detailMap[item.ID]
if exist {
item.DetailID = dt["detail_id"]
item.TaskUTime = dt["task_utime"]
item.MID = dt["mid"]
item.UPGroupList = upGroupList[item.MID]
if infos[item.MID] != nil {
item.UPName = infos[item.MID].Name
}
}
}
return
}
//AddQATaskVideo add a qa video task
func (s *Service) AddQATaskVideo(ctx context.Context, detail *model.AddVideoParams) (taskID int64, err error) {
var vid int64
if vid, err = s.dao.GetVID(ctx, detail.AID, detail.CID); err != nil {
log.Error("AddQATaskVideo s.dao.GetVID(aid(%d), cid(%d)) error(%v)", detail.AID, detail.CID, err)
return
}
if vid <= 0 {
log.Error("AddQATaskVideo non-deleted video(aid(%d), cid(%d)) not exist", detail.AID, detail.CID)
return
}
taskID, err = s.insertVideoTask(ctx, detail)
return
}
func (s *Service) insertVideoTask(ctx context.Context, detail *model.AddVideoParams) (taskID int64, err error) {
var (
tx *sql.Tx
detailID int64
)
defer func() {
if msg := recover(); msg != nil {
if tx != nil {
tx.Rollback()
}
log.Error("insertVideoTask panic recover, msg(%s)", msg)
}
}()
if tx, err = s.dao.BeginTran(ctx); err != nil {
return
}
if detailID, err = s.dao.InsertQAVideo(tx, &detail.VideoDetail); err != nil {
tx.Rollback()
return
}
if taskID, err = s.dao.InTaskQA(tx, detail.OUID, detailID, model.QATypeVideo); err != nil {
tx.Rollback()
return
}
if err = tx.Commit(); err != nil {
dao.PromeErr("arcdb: commit", "insertVideoTask commit error(%v) aid(%d) cid(%d)", err, detail.AID, detail.CID)
}
return
}
func (s *Service) getQATaskVideo(ctx context.Context, id int64, simple bool) (task *model.QATaskVideo, err error) {
if simple {
task, err = s.dao.QATaskVideoSimpleByID(ctx, id)
} else {
task, err = s.dao.QATaskVideoByID(ctx, id)
}
if err != nil {
return
}
if task == nil {
err = ecode.NothingFound
return
}
task.GetAttributeList()
return
}
//GetDetail get qa video task detail
func (s *Service) GetDetail(ctx context.Context, id int64) (dt *model.TaskVideoDetail, err error) {
var (
taskVideo *model.QATaskVideo
video *model.Video
history []*model.VideoOperInfo
)
if taskVideo, err = s.getQATaskVideo(ctx, id, false); err != nil {
return
}
info := &model.VideoTaskInfo{
QATaskVideo: *taskVideo,
}
groups, _ := s.dao.UPGroups(ctx, []int64{taskVideo.MID})
info.UPGroupList = groups[taskVideo.MID]
info.GetWarnings()
if video, err = s.getVideo(ctx, taskVideo.AID, taskVideo.CID); err != nil {
return
}
if history, err = s.getVideoOperInfo(ctx, video.ID); err != nil {
return
}
dt = &model.TaskVideoDetail{
Task: info,
Video: video,
VideoHistory: history,
}
return
}
//QAVideoSubmit submit qa video task
func (s *Service) QAVideoSubmit(ctx context.Context, username string, uid int64, vp *model.QASubmitParams) (err error) {
var (
task *model.QATaskVideo
video *model.Video
)
if task, err = s.getQATaskVideo(ctx, vp.ID, true); err != nil {
log.Error("QAVideoSubmit s.arc.QATaskVideoByID error(%v), id(%d) task(%+v)", err, vp.ID, task)
return
}
if video, err = s.getVideo(ctx, task.AID, task.CID); err != nil {
log.Error("sendLog s.getVideo error(%v) qa.id(%d) aid(%d) cid(%d)", err, vp.ID, task.AID, task.CID)
return
}
//不重复质检
if task.State == model.QAStateFinish {
return
}
//更新task
task.State = model.QAStateFinish
task.FTime = time.Now()
if _, err = s.dao.UpTask(ctx, vp.ID, task.State, task.FTime); err != nil {
return
}
s.dao.AddVideoOper(ctx, task.AID, uid, video.ID, video.Attribute, video.Status, 0, fmt.Sprintf("一审任务质检TAG: [%s]", vp.QATag), vp.QaNote)
s.sendLog(ctx, username, uid, video, task, vp)
return
}
func (s *Service) sendLog(ctx context.Context, username string, uid int64, video *model.Video, task *model.QATaskVideo, vp *model.QASubmitParams) (err error) {
var (
note string
taskUIDName string
)
if task == nil || len(task.AttributeList) == 0 {
log.Error("sendLog task/task.attributelist not exist, task(%+v) params(%+v)", task, vp)
return
}
if note, err = task.GetNote(); err != nil {
log.Error("sendLog task.GetNote() error(%v), params(%+v)", err, vp)
return
}
if vp.Norank == 1 {
video.AttributeList["norank"] = 1
}
if vp.Nodynamic == 1 {
video.AttributeList["nodynamic"] = 1
}
if vp.Norecommend == 1 {
video.AttributeList["norecommend"] = 1
}
if vp.Nosearch == 1 {
video.AttributeList["nosearch"] = 1
}
if vp.PushBlog == 1 {
video.AttributeList["push_blog"] = 1
}
if vp.OverseaBlock == 1 {
video.AttributeList["oversea_block"] = 1
}
video.TagID = vp.TagID
video.Status = vp.AuditStatus
video.Note = vp.Note
video.Reason = vp.Reason
video.Encoding = vp.Encoding
if taskUIDNames, err := s.dao.GetUsername(ctx, []int64{task.UID}); err != nil {
taskUIDName = ""
err = nil
} else {
taskUIDName = taskUIDNames[task.UID]
}
content := map[string]interface{}{
"audit_status": task.AuditStatus,
"audit_attr": task.AttributeList,
"audit_tag_id": task.TagID,
"audit_note": note,
"qa_status": video.Status,
"qa_attr": video.AttributeList,
"qa_tag_id": video.TagID,
"qa_note": video.Note,
}
data := &report.ManagerInfo{
Uname: username,
UID: uid,
Business: model.LogQATask,
Type: model.LogQATaskVideo,
Oid: vp.ID,
Action: strconv.Itoa(int(video.Status)),
Ctime: task.FTime,
Index: []interface{}{task.TaskID, task.MID, task.CTime.Unix(), strconv.FormatInt(vp.QaTagID, 10), strconv.FormatInt(task.UID, 10), taskUIDName},
Content: content,
}
report.Manager(data)
log.Info(" sendLog data(%+v)", data)
return
}
//UpVideoUTime update qa video task utime
func (s *Service) UpVideoUTime(ctx context.Context, aid, cid, taskID, utime int64) (err error) {
var id int64
if id, err = s.dao.GetQAVideoID(ctx, aid, cid, taskID); err != nil {
log.Error("UpVideoUTime s.dao.GetQAVideoID error(%v) aid(%d) cid(%d) taskid(%d) utime(%d)", err, aid, cid, taskID, utime)
return
}
if id <= 0 {
log.Error("UpVideoUTime s.dao.GetQAVideoID not found aid(%d) cid(%d) taskid(%d) utime(%d)", aid, cid, taskID, utime)
err = ecode.RequestErr
return
}
return s.dao.UpdateQAVideoUTime(ctx, aid, cid, taskID, utime)
}
func (s *Service) delProc() {
var (
err error
qaVideoRows, qaTaskRows int64 = 1, 1
limit = 1000
)
for {
deadLine := time.Now().AddDate(0, -1, 0)
for {
if qaVideoRows > 0 {
if qaVideoRows, err = s.dao.DelQAVideo(context.TODO(), deadLine, limit); err != nil {
log.Error("delProc s.dao.DelQAVideo(%v,%d) error(%v)", deadLine, limit, err)
}
}
if qaTaskRows > 0 {
if qaTaskRows, err = s.dao.DelQATask(context.TODO(), deadLine, limit); err != nil {
log.Error("delProc s.dao.DelQATask(%v,%d) error(%v)", deadLine, limit, err)
}
}
if qaVideoRows+qaTaskRows == 0 {
break
}
time.Sleep(time.Minute)
}
time.Sleep(time.Hour * 24)
}
}

View File

@@ -0,0 +1,264 @@
package service
import (
"context"
"fmt"
"strings"
"time"
"go-common/app/admin/main/videoup-task/model"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
// ErrTaskMISS .
var ErrTaskMISS = fmt.Errorf("任务缓存查找失败")
// ReviewForm 复审表单
func (s *Service) ReviewForm(c context.Context, tid int64) (form *model.SubmitForm, err error) {
return s.dao.ReviewForm(c, tid)
}
// CheckReview 检查任务复审
func (s *Service) CheckReview(c context.Context, form *model.SubmitForm) (isReview bool, err error) {
var (
v *model.Video
attr int32
tx *sql.Tx
rows int64
tp *model.TaskPriority
)
attr, err = s.dao.VideoAttribute(c, form.CID)
if err != nil {
log.Error("CheckReview VideoAttribute(aid%d,cid%d) miss(%v)", form.AID, form.CID, err)
return false, ErrTaskMISS
}
v = &model.Video{Attribute: attr}
tp, err = s.getReviewParams(c, form)
if err != nil || tp == nil {
log.Info("CheckReview(%d) 不需要复审(%+v)", form.TaskID, tp)
return false, err
}
s.SyncRC(c)
ck := s.reviewCache.Check(c, tp, form.UID)
if !ck {
log.Info("CheckReview(%d) 不需要复审(%+v)", form.TaskID, tp)
return false, nil
}
if _, err = s.dao.InReviewForm(c, form, form.UID, form.Uname); err != nil {
return false, err
}
if tx, err = s.dao.BeginTran(c); err != nil {
return false, err
}
if rows, err = s.dao.TxUpTaskByID(tx, form.TaskID, map[string]interface{}{"state": model.TypeReview}); err != nil {
tx.Rollback()
return false, err
}
if rows > 0 {
if _, err = s.dao.TxAddTaskHis(tx, 0, model.ActionSubmit, form.TaskID, form.CID, form.UID, 0, form.Status, "TaskReview"); err != nil {
tx.Rollback()
return false, err
}
}
if err = tx.Commit(); err != nil {
log.Error("tx.Commit error(%v)", err)
return false, err
}
// log
attrs := map[uint]int32{
model.AttrBitNoRank: form.Norank,
model.AttrBitNoDynamic: form.Noindex,
model.AttrBitNoRecommend: form.NoRecommend,
model.AttrBitNoSearch: form.Nosearch,
model.AttrBitOverseaLock: form.OverseaBlock,
model.AttrBitPushBlog: form.PushBlog,
}
var conts []string
const template = "[%s]从[%s]设为[%s]"
var yesOrNo = map[int32]string{model.AttrYes: "是", model.AttrNo: "否"}
for bit, attr := range attrs {
v.AttrSet(attr, bit)
if attr == 1 {
conts = append(conts, fmt.Sprintf(template, model.BitDesc(bit), yesOrNo[^attr&1], yesOrNo[attr]))
log.Info("vid(%d) update video bit(%d) bitdesc(%s) attrs(%d)", form.ID, bit, model.BitDesc(bit), attr)
}
}
vp := &model.VideoParam{
ID: form.ID,
Aid: form.AID,
Mid: form.MID,
RegionID: tp.TypeID,
Status: form.Status,
Cid: form.CID,
Title: form.Eptitle,
Desc: form.Description,
UID: form.UID,
TaskID: form.TaskID,
Oname: form.Uname,
TagID: form.TID,
Reason: form.Reason,
ReasonID: form.ReasonID,
Note: form.Note,
Attribute: v.Attribute,
}
oper := &model.VideoOper{Aid: form.AID, UID: form.UID, Vid: form.ID, Attribute: vp.Attribute, Status: form.Status, Remark: form.Note}
operConts := append([]string{fmt.Sprintf("初审提交")}, conts...)
operConts = append(operConts, s.diffVideoOper(vp)...)
oper.Content = strings.Join(operConts, "")
s.addVideoOper(c, oper)
s.sendVideoLog(c, vp, oper.Content)
return true, nil
}
// ListReviewConfs 配置列表
func (s *Service) ListReviewConfs(c context.Context, unames, bt, et, sort string, pn, ps int64) (rcs []*model.ReviewConf, count int64, err error) {
var uids []int64
if len(unames) > 0 {
res, _ := s.dao.Uids(c, strings.Split(unames, ","))
for _, uid := range res {
uids = append(uids, uid)
}
}
rcs, count, err = s.dao.ListConfs(c, uids, bt, et, sort, pn, ps)
for _, v := range rcs {
if v.Bt.TimeValue().IsZero() {
v.Bt = ""
}
if v.Et.TimeValue().IsZero() {
v.Et = ""
}
if len(v.Uids) > 0 {
if unames, _ := s.dao.Unames(c, v.Uids); len(unames) > 0 {
for _, uname := range unames {
v.Unames = append(v.Unames, uname)
}
}
}
}
return
}
// AddReviewConf 添加配置
func (s *Service) AddReviewConf(c context.Context, rc *model.ReviewConf) (err error) {
if len(rc.Types) > 0 {
stypes, _ := xstr.SplitInts(s.tarnsType(c, xstr.JoinInts(rc.Types)))
rc.Types = stypes
}
if _, err = s.dao.InReviewConf(c, rc); err != nil {
log.Error("s.AddReviewConf(%+v) error(%v)", rc, err)
return err
}
s.SyncRC(c)
return
}
// EditReviewConf 修改配置
func (s *Service) EditReviewConf(c context.Context, rc *model.ReviewConf) (err error) {
if len(rc.Types) > 0 {
stypes, _ := xstr.SplitInts(s.tarnsType(c, xstr.JoinInts(rc.Types)))
rc.Types = stypes
}
if _, err = s.dao.UpReviewConf(c, rc); err != nil {
log.Error("s.EditReviewConf(%+v) error(%v)", rc, err)
return err
}
s.SyncRC(c)
return
}
// DelReviewConf 删除配置
func (s *Service) DelReviewConf(c context.Context, id int) (err error) {
if _, err = s.dao.DelReviewConf(c, id); err != nil {
log.Error("s.DelReviewConf(%d) error(%v)", id, err)
return err
}
s.SyncRC(c)
return
}
// SyncRC sync from db
func (s *Service) SyncRC(c context.Context) {
rcs, err := s.dao.ReviewConfs(context.TODO())
if err != nil {
log.Error("loadRC error(%v)", err)
return
}
if len(rcs) > 0 {
s.reviewCache.Mux.Lock()
defer s.reviewCache.Mux.Unlock()
s.reviewCache.MRC = make(map[int64]*model.ReviewConf)
for _, item := range rcs {
s.reviewCache.MRC[item.ID] = item
}
}
}
func (s *Service) loadRC() {
s.SyncRC(context.TODO())
}
func (s *Service) loadRCproc() {
for {
time.Sleep(3 * time.Minute)
s.SyncRC(context.TODO())
}
}
func (s *Service) getReviewParams(c context.Context, form *model.SubmitForm) (tp *model.TaskPriority, err error) {
t, err := s.dao.TaskByID(c, form.TaskID)
if err != nil || t == nil {
return nil, ErrTaskMISS
}
if t.State != model.TypeDispatched {
log.Info("CheckReview(%d) 不需要复审 state(%d)", form.TaskID, t.State)
return nil, nil
}
mp, err := s.dao.GetWeightRedis(c, []int64{form.TaskID})
if err != nil || len(mp) == 0 {
if mp, err = s.dao.GetWeightDB(c, []int64{form.TaskID}); err != nil || len(mp) == 0 {
log.Error("GetWeightDB(%d) miss", form.TaskID)
return nil, ErrTaskMISS
}
}
if _, ok := mp[form.TaskID]; !ok {
log.Error("mp(%d) miss", form.TaskID)
return nil, ErrTaskMISS
}
tp = mp[form.TaskID]
// 补充复审判断的参数
if tp.TypeID == 0 {
s.setReviewParams(c, form.MID, form.AID, tp)
}
return
}
func (s *Service) setReviewParams(c context.Context, mid, aid int64, tp *model.TaskPriority) {
typeid, upfrom, err := s.dao.ArchiveParam(c, aid)
if err == nil {
tp.TypeID = typeid
tp.UpFrom = upfrom
}
tp.UpGroups = s.getSpecial(mid)
}

View File

@@ -0,0 +1,118 @@
package service
import (
"context"
"go-common/library/ecode"
"go-common/library/xstr"
"net/url"
"strconv"
"go-common/app/admin/main/videoup-task/model"
"go-common/library/database/elastic"
"go-common/library/log"
)
const (
_searchBusinessQAVideo = "task_qa"
_searchBusinessQAVideoRandom = "task_qa_random"
_searchIndexQAVideo = "task_qa"
_searchLogURL = "/x/admin/search/log"
)
func (s *Service) searchQAVideo(c context.Context, pm *model.ListParams) (list *model.QAVideoList, err error) {
needRandom := pm.Limit > 0 && pm.Seed != ""
business := _searchBusinessQAVideo
if needRandom {
business = _searchBusinessQAVideoRandom
}
req := s.es.NewRequest(business).Index(_searchIndexQAVideo).Ps(pm.Ps).Pn(pm.Pn)
if pm.CTimeFrom != "" || pm.CTimeTo != "" {
req.WhereRange("ctime", pm.CTimeFrom, pm.CTimeTo, elastic.RangeScopeLcRc)
}
if pm.FTimeFrom != "" || pm.FTimeTo != "" {
req.WhereRange("ftime", pm.FTimeFrom, pm.FTimeTo, elastic.RangeScopeLcRc)
}
if pm.FansFrom > 0 || pm.FansTo > 0 {
req.WhereRange("fans", pm.FansFrom, pm.FansTo, elastic.RangeScopeLcRc)
}
if len(pm.UID) > 0 {
req.WhereIn("uid", pm.UID)
}
if len(pm.TaskID) > 0 {
req.WhereIn("task_id", pm.TaskID)
}
if len(pm.TagID) > 0 {
req.WhereIn("audit_tagid", pm.TagID)
}
if len(pm.UPGroup) > 0 {
req.WhereIn("up_groups", pm.UPGroup)
}
if len(pm.ArcTypeID) > 0 {
req.WhereIn("arc_typeid", pm.ArcTypeID)
}
if len(pm.AuditStatus) > 0 {
req.WhereIn("audit_status", pm.AuditStatus)
}
if len(pm.Keyword) > 0 {
req.WhereLike([]string{"arc_title"}, pm.Keyword, true, elastic.LikeLevelLow)
}
if needRandom {
req.WhereEq("seed", pm.Seed)
} else {
req.Order(pm.Order, pm.Sort)
}
if pm.State == model.QAStateWait || pm.State == model.QAStateFinish {
req.WhereEq("state", pm.State)
}
if err = req.Scan(c, &list); err != nil {
log.Error("searchQAVideo elastic scan error(%v) params(%+v)", err, pm)
return
}
if needRandom && list != nil && list.Page.Total > pm.Limit {
list.Page.Total = pm.Limit
//移除多余部分
addition := list.Page.Num*list.Page.Size - pm.Limit
if addition > 0 {
list.Result = list.Result[:(list.Page.Size - addition)]
}
}
return
}
func (s *Service) lastInTime(c context.Context, ids []int64) (mcases map[int64][]interface{}, err error) {
return s.lastTime(c, model.ActionHandsUP, ids)
}
func (s *Service) lastOutTime(c context.Context, ids []int64) (mcases map[int64][]interface{}, err error) {
return s.lastTime(c, model.ActionHandsOFF, ids)
}
// lastInOutTime
func (s *Service) lastTime(c context.Context, action int8, ids []int64) (mcases map[int64][]interface{}, err error) {
mcases = make(map[int64][]interface{})
params := url.Values{}
uri := s.c.Host.Search + _searchLogURL
params.Set("appid", "log_audit_group")
params.Set("group", "uid")
params.Set("uid", xstr.JoinInts(ids))
params.Set("business", strconv.Itoa(model.LogClientConsumer))
params.Set("action", strconv.Itoa(int(action)))
params.Set("ps", strconv.Itoa(len(ids)))
res := &model.SearchLogResult{}
if err = s.httpClient.Get(c, uri, "", params, &res); err != nil {
log.Error("log_audit_group d.httpClient.Get error(%v)", err)
return
}
if res.Code != ecode.OK.Code() {
log.Error("log_audit_group ecode:%v", res.Code)
return
}
for _, item := range res.Data.Result {
mcases[item.UID] = []interface{}{item.Ctime}
}
log.Info("log_audit_group get: %s params:%s ret:%v", uri, params.Encode(), res)
return
}

View File

@@ -0,0 +1,40 @@
package service
import (
"context"
"github.com/smartystreets/goconvey/convey"
"testing"
"go-common/app/admin/main/videoup-task/model"
)
func Test_searchQAVideo(t *testing.T) {
Init()
convey.Convey("search qavideo", t, func() {
pm := &model.ListParams{
State: 1,
Ps: 50,
Pn: 1,
Sort: "desc",
Order: "id",
CTimeFrom: "2018-05-08 00:00:00",
CTimeTo: "2018-07-20 00:00:00",
//FTimeFrom: "2018-07-10 00:00:00",
//FTimeTo: "2018-07-20 00:00:00",
FansFrom: 1,
FansTo: 100,
UID: []int64{421, 481},
UPGroup: []int64{1, 2},
AuditStatus: []int{-4, -2, 10000},
ArcTypeID: []int64{76},
TagID: []int64{14, 6, 23, 15},
Keyword: []string{"普通"},
TaskID: []int64{8326, 8327},
//Limit: 2,
}
resp, err := s.searchQAVideo(context.TODO(), pm)
convey.So(err, convey.ShouldBeNil)
t.Logf("resp(%+v)", resp)
})
}

View File

@@ -0,0 +1,136 @@
package service
import (
"context"
"sync"
"time"
"go-common/app/admin/main/videoup-task/conf"
"go-common/app/admin/main/videoup-task/dao"
"go-common/app/admin/main/videoup-task/model"
account "go-common/app/service/main/account/api"
upsrpc "go-common/app/service/main/up/api/v1"
"go-common/library/database/elastic"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
// MemberCache .
type MemberCache struct {
sync.RWMutex
uptime time.Time
ms map[int64]*model.MemberStat
}
//Service service
type Service struct {
c *conf.Config
dao *dao.Dao
es *elastic.Elastic
httpClient *bm.Client
memberCache *MemberCache
// cache
typeCache map[int16]*model.Type
reviewCache *model.ReviewCache
twConCache map[int8]map[int64]*model.WCItem
upperCache map[int8]map[int64]struct{}
typeCache2 map[int16][]int64 // 记录每个一级分区下的二级分区
//grpc
accRPC account.AccountClient
upsRPC upsrpc.UpClient
}
//New new service
func New(conf *conf.Config) (svr *Service) {
svr = &Service{
c: conf,
dao: dao.New(conf),
es: elastic.NewElastic(nil),
httpClient: bm.NewClient(conf.HTTPClient),
memberCache: &MemberCache{},
// cache
reviewCache: model.NewRC(),
}
var err error
if svr.accRPC, err = account.NewClient(conf.GRPC.AccRPC); err != nil {
panic(err)
}
if svr.upsRPC, err = upsrpc.NewClient(conf.GRPC.UpsRPC); err != nil {
panic(err)
}
go svr.memberproc()
svr.loadConf()
go svr.cacheproc()
go svr.delProc()
svr.loadRC()
go svr.loadRCproc()
return
}
//Close close
func (s *Service) Close() {
s.dao.Close()
}
//Ping ping
func (s *Service) Ping(ctx context.Context) (err error) {
err = s.dao.Ping(ctx)
return
}
func (s *Service) loadConf() {
var (
err error
tpm map[int16]*model.Type
tpm2 map[int16][]int64
twConCache map[int8]map[int64]*model.WCItem
upm map[int8]map[int64]struct{}
)
if tpm, err = s.dao.TypeMapping(context.TODO()); err != nil {
log.Error("s.dao.TypeMapping error(%v)", err)
return
}
s.typeCache = tpm
tpm2 = make(map[int16][]int64)
for id, tmod := range tpm {
if tmod.PID == 0 {
if _, ok := tpm2[id]; !ok {
tpm2[id] = []int64{}
}
continue
}
arrid, ok := tpm2[tmod.PID]
if !ok {
tpm2[tmod.PID] = []int64{int64(id)}
} else {
tpm2[tmod.PID] = append(arrid, int64(id))
}
}
s.typeCache2 = tpm2
if twConCache, err = s.weightConf(context.TODO()); err != nil {
log.Error("s.weightConf error(%v)", err)
return
}
s.twConCache = twConCache
upm, err = s.upSpecial(context.TODO())
if err != nil {
log.Error("s.upSpecial error(%v)", err)
return
}
s.upperCache = upm
}
func (s *Service) cacheproc() {
for {
time.Sleep(3 * time.Minute)
s.loadConf()
}
}

View File

@@ -0,0 +1,22 @@
package service
import (
"flag"
"go-common/app/admin/main/videoup-task/conf"
)
var s *Service
func Init() {
if s != nil {
return
}
flag.Set("conf", "../cmd/videoup-task-admin.toml")
if err := conf.Init(); err != nil {
panic(err)
}
s = New(conf.Conf)
}

View File

@@ -0,0 +1,198 @@
package service
import (
"context"
"fmt"
"sync"
"time"
"go-common/app/admin/main/videoup-task/model"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
// GetStats .
func (s *Service) GetStats(c context.Context) (stats []*model.MemberStat, err error) {
s.memberCache.RLock()
defer s.memberCache.RUnlock()
st := s.memberCache.uptime
if st.IsZero() {
st = time.Now().Add(-30 * time.Minute)
}
rst, err := s.memberStats(c, st, time.Now())
if err != nil {
log.Error("s.MemberStats error(%v)", err)
err = nil
}
for uid, omst := range s.memberCache.ms {
if nmst, ok := rst[uid]; ok {
mst := &model.MemberStat{UID: uid}
mst.DispatchCount = omst.DispatchCount + nmst.DispatchCount
mst.ReleaseCount = omst.ReleaseCount + nmst.ReleaseCount
mst.SubmitCount = omst.SubmitCount + nmst.SubmitCount
mst.OSubmitCount = omst.OSubmitCount + nmst.OSubmitCount
mst.NSubmitCount = omst.NSubmitCount + nmst.NSubmitCount
mst.BelongCount = omst.BelongCount + nmst.BelongCount
mst.PassCount = omst.PassCount + nmst.PassCount
mst.NormalCount = omst.NormalCount + nmst.NormalCount
mst.SubjectCount = omst.SubjectCount + nmst.SubjectCount
mst.SumDu = omst.SumDu + nmst.SumDu
mst.SumDuration = fmt.Sprintf("%.2d:%.2d:%.2d", mst.SumDu/3600, (mst.SumDu%3600)/60, (mst.SumDu%3600)%60)
var CompleteRate, PassRate = 100.0, 100.0
if mst.SubmitCount < mst.BelongCount {
CompleteRate = float64(mst.SubmitCount) / float64(mst.BelongCount) * 100.0
}
if mst.PassCount < mst.SubmitCount {
PassRate = float64(mst.PassCount) / float64(mst.SubmitCount) * 100.0
}
mst.CompleteRate = fmt.Sprintf("%.2f%%", CompleteRate)
mst.PassRate = fmt.Sprintf("%.2f%%", PassRate)
if mst.NSubmitCount == 0 {
mst.AvgUtime = "00:00:00"
} else {
mst.AvgUt = (omst.AvgUt*float64(omst.NSubmitCount) + nmst.AvgUt*float64(nmst.NSubmitCount)) / float64(mst.NSubmitCount)
mst.AvgUtime = fmt.Sprintf("%.2d:%.2d:%.2d", int64(mst.AvgUt)/3600, (int64(mst.AvgUt)%3600)/60, (int64(mst.AvgUt)%3600)%60)
}
delete(rst, uid)
stats = append(stats, mst)
} else {
stats = append(stats, omst)
}
}
if len(rst) > 0 {
for _, nmst := range rst {
stats = append(stats, nmst)
}
}
if len(stats) > 0 {
wg, ctx := errgroup.WithContext(c)
wg.Go(func() error {
if err := s.mulIDtoName(ctx, stats, s.lastInTime, "UID", "InTime"); err != nil {
log.Error("mulIDtoName s.lastInTime error(%v)", err)
}
return nil
})
wg.Go(func() error {
if err := s.mulIDtoName(ctx, stats, s.lastOutTime, "UID", "QuitTime"); err != nil {
log.Error("mulIDtoName s.lastOutTime error(%v)", err)
}
return nil
})
wg.Wait()
}
for _, st := range stats {
if st.QuitTime <= st.InTime {
st.QuitTime = ""
}
}
return
}
// MemberStats 审核人员统计数据[通过旧一审提交。会导致同一个任务被多次完成]
func (s *Service) memberStats(c context.Context, st, et time.Time) (stats map[int64]*model.MemberStat, err error) {
var (
mx sync.Mutex
uids []int64
)
stats = make(map[int64]*model.MemberStat)
if uids, err = s.dao.ActiveUids(c, st, et); err != nil || len(uids) == 0 {
return
}
log.Info("MemberStats,st(%s),et(%s) count(%d) uids(%v) ", st.String(), et.String(), len(uids), uids)
wg := errgroup.Group{}
for _, uid := range uids {
id := uid
wg.Go(func() error {
st, e := s.singleStat(context.TODO(), id, st, et)
if e != nil || st == nil {
log.Error("s.singleStat(%d) error(%v)", id, e)
return nil
}
mx.Lock()
stats[st.UID] = st
mx.Unlock()
return nil
})
}
err = wg.Wait()
return
}
func (s *Service) singleStat(c context.Context, uid int64, stime, etime time.Time) (stat *model.MemberStat, err error) {
var (
SumDuration int64
AvgUtime float64
)
stat = &model.MemberStat{UID: uid}
mapAction, err := s.dao.ActionCountByUID(c, uid, stime, etime)
if err != nil {
return
}
stat.OSubmitCount = mapAction[model.ActionOldSubmit]
stat.NSubmitCount = mapAction[model.ActionSubmit]
stat.SubmitCount = stat.OSubmitCount + stat.NSubmitCount
stat.DispatchCount = mapAction[model.ActionDispatch]
stat.ReleaseCount = mapAction[model.ActionRelease]
if stat.PassCount, err = s.dao.PassCountByUID(c, uid, stime, etime); err != nil {
return
}
if stat.SubjectCount, err = s.dao.SubjectCountByUID(c, uid, stime, etime); err != nil {
return
}
if SumDuration, err = s.dao.SumDurationByUID(c, uid, stime, etime); err != nil {
return
}
if AvgUtime, err = s.dao.AvgUtimeByUID(c, uid, stime, etime); err != nil {
return
}
stat.BelongCount = stat.DispatchCount - stat.ReleaseCount
var CompleteRate, PassRate = 100.0, 100.0
if stat.SubmitCount < stat.BelongCount {
CompleteRate = float64(stat.SubmitCount) / float64(stat.BelongCount) * 100.0
}
if stat.PassCount < stat.SubmitCount {
PassRate = float64(stat.PassCount) / float64(stat.SubmitCount) * 100.0
}
stat.CompleteRate = fmt.Sprintf("%.2f%%", CompleteRate)
stat.PassRate = fmt.Sprintf("%.2f%%", PassRate)
stat.NormalCount = stat.SubmitCount - stat.SubjectCount
stat.SumDu = SumDuration
stat.AvgUt = AvgUtime
stat.SumDuration = fmt.Sprintf("%.2d:%.2d:%.2d", SumDuration/3600, (SumDuration%3600)/60, (SumDuration%3600)%60)
stat.AvgUtime = fmt.Sprintf("%.2d:%.2d:%.2d", int64(AvgUtime)/3600, (int64(AvgUtime)%3600)/60, (int64(AvgUtime)%3600)%60)
return
}
func (s *Service) memberproc() {
for {
st := time.Now()
stats, err := s.memberStats(context.TODO(), st.Add(-24*time.Hour), st)
if err != nil {
log.Error("s.MemberStats error(%v)", err)
} else {
s.memberCache.Lock()
s.memberCache.uptime = st
s.memberCache.ms = stats
s.memberCache.Unlock()
}
log.Info("s.MemberStats ut(%.2f)", time.Since(st).Seconds())
time.Sleep(30 * time.Minute)
}
}

View File

@@ -0,0 +1,325 @@
package service
import (
"context"
"fmt"
"time"
"go-common/app/admin/main/videoup-task/model"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
// List 查看任务列表
func (s *Service) List(c context.Context, uid int64, pn, ps int, ltype, leader int8) (tasks []*model.Task, err error) {
return s.dao.ListByCondition(c, uid, pn, ps, ltype, leader)
}
// Delay 申请延迟
func (s *Service) Delay(c context.Context, id, uid int64, reason string) (err error) {
tx, err := s.dao.BeginTran(c)
if err != nil {
log.Error("s.dao.BeginTran() error(%v)", err)
return
}
rows, err := s.dao.TxUpTaskByID(tx, id, map[string]interface{}{"state": model.TypeDelay, "dtime": time.Now()})
if err != nil {
log.Error("s.dao.TxUpTaskByID(%d) error(%v)", id, err)
tx.Rollback()
return
}
if rows > 0 {
if _, err = s.dao.TxAddTaskHis(tx, 0, model.ActionDelay /*action*/, id /*task_id*/, 0, uid /*uid*/, 0, 0, reason /*reason*/); err != nil {
log.Error("s.dao.AddTaskLog(%d) error(%v)", id, err)
tx.Rollback()
return
}
}
return tx.Commit()
}
// TaskSubmit 提交审核结果
func (s *Service) TaskSubmit(c context.Context, t *model.Task, uid int64, status int16) (err error) {
var utime int64
switch {
case t.State == model.TypeDelay || t.State == model.TypeReview: //延迟任务复审任务不记录utime
utime = 0
case t.GTime.TimeValue().IsZero():
utime = int64(time.Since(t.MTime.TimeValue()))
default:
utime = int64(time.Since(t.GTime.TimeValue()))
}
tx, err := s.dao.BeginTran(c)
if err != nil {
log.Error("s.dao.BeginTran error(%v)", err)
return
}
rows, err := s.dao.TxUpTaskByID(tx, t.ID, map[string]interface{}{"state": model.TypeFinished, "utime": utime})
if err != nil {
log.Error("s.dao.TxUpTaskByID(%d) error(%v)", t.ID, err)
tx.Rollback()
return
}
if rows > 0 {
if _, err = s.dao.TxAddTaskHis(tx, 0, model.ActionSubmit /*action*/, t.ID /*task_id*/, t.Cid /*cid*/, uid /*uid*/, utime /*utime*/, status /*result*/, "TaskSubmit" /*reason*/); err != nil {
log.Error("s.dao.AddTaskLog(%d) error(%v)", t.ID, err)
tx.Rollback()
return
}
}
return tx.Commit()
}
// Next 领取任务
func (s *Service) Next(c context.Context, uid int64) (task *model.Task, err error) {
var rows int64
task, err = s.dao.GetNextTask(c, uid)
if err != nil {
log.Error("d.getTask(%d) error(%v)", uid, err)
return
}
if task != nil {
return
}
// 释放超时任务
s.Free(c, 0)
// 从实时任务池抢占
if rows, err = s.dispatchTask(c, uid); err != nil {
return
} else if rows > 0 {
return s.dao.GetNextTask(c, uid)
}
return
}
// Info 查询任务信息
func (s *Service) Info(c context.Context, tid int64) (task *model.Task, err error) {
return s.dao.TaskByID(c, tid)
}
// 抢占任务(先抢占再查,避免重复下发)
func (s *Service) dispatchTask(c context.Context, uid int64) (rows int64, err error) {
var (
tls []*model.TaskForLog
arrid []int64
)
if tls, err = s.dao.GetDispatchTask(c, uid); err != nil {
log.Error("s.dao.GetDispatchTask(%d) error(%v)", uid, err)
return
}
for _, item := range tls {
arrid = append(arrid, item.ID)
}
if len(arrid) > 0 {
if rows, err = s.dao.UpDispatchTask(c, uid, arrid); err != nil {
log.Error("s.dao.UpDispatchTask(%d,%v,%v) error(%v)", uid, arrid, err)
return
}
// 日志允许错误
if int(rows) == len(arrid) {
log.Info("UpDispatchTask 更新数量(%d)", rows)
} else {
log.Warn("UpDispatchTask 更新数量(%d) 日志数量(%d)", rows, len(arrid))
}
s.dao.MulAddTaskHis(c, tls, model.ActionDispatch, uid)
}
return
}
// Free 任务释放(有uid为主动释放没有uid为被动释放)(先查再释放,有可能记录冗余释放信息)
func (s *Service) Free(c context.Context, uid int64) (rows int64) {
var (
rts []*model.TaskForLog
ids, rtids []int64
lastid int64
err error
mtime = time.Now()
)
if uid == 0 {
if rts, err = s.dao.GetTimeOutTask(c); err != nil {
log.Error("s.Free s.dao.GetTimeOutTask error(%v)", err)
return
}
} else {
if rts, lastid, err = s.dao.GetRelTask(c, uid); err != nil {
log.Error("s.Free s.dao.GetRelTask(%d) error(%v)", uid, err)
return
}
}
mcases := make(map[int64]*model.WCItem)
for _, rt := range rts {
ids = append(ids, rt.ID)
if rt.Subject == 1 { //指派任务回流
rtids = append(rtids, rt.ID)
mcases[rt.ID] = &model.WCItem{Radio: 4, Weight: model.WLVConf.SubRelease,
Mtime: model.NewFormatTime(time.Now()), Desc: "指派回流权重"}
}
}
if len(ids) > 0 {
if rows, err = s.dao.MulReleaseMtime(c, ids, mtime); err != nil {
log.Error("s.dao.MulReleaseMtime(%v, %v) error(%v)", ids, mtime, err)
return
}
if rows > 0 {
s.dao.MulAddTaskHis(c, rts, model.ActionRelease, uid)
}
}
if lastid > 0 {
s.dao.UpGtimeByID(c, lastid, "0000-00-00 00:00:00")
timelogout := time.Now()
log.Info("添加延时释放任务(%d %v)", lastid, timelogout)
time.AfterFunc(5*time.Minute, func() {
s.releaseSpecial(timelogout, lastid, uid)
})
}
if len(rtids) > 0 {
s.setWeightConf(c, xstr.JoinInts(rtids), mcases)
}
return
}
func (s *Service) releaseSpecial(tout time.Time, taskid, uid int64) {
tx, err := s.dao.BeginTran(context.TODO())
if err != nil {
log.Error(" s.dao.BeginTran error(%v)", err)
return
}
rows, err := s.dao.TxReleaseSpecial(tx, tout, 1, taskid, uid)
if err != nil {
log.Error("s.dao.TxReleaseSpecial error(%v)", err)
tx.Rollback()
return
}
if rows > 0 {
log.Info("s.dao.TxReleaseSpecial 释放任务(%d)", taskid)
if _, err = s.dao.TxAddTaskHis(tx, 0, model.ActionRelease, taskid, 0, uid, 0, 0, "登出延时释放"); err != nil {
log.Error("s.dao.TxAddTaskHis error(%v)", err)
tx.Rollback()
return
}
}
tx.Commit()
}
func (s *Service) judge(c context.Context, tid, aid, cid, uid int64) (err error) {
var (
rows int64
tx *sql.Tx
v *model.ArcVideo
a *model.Archive
)
// 1.校验视频
if v, err = s.dao.ArcVideoByCID(c, cid); err != nil {
log.Error("s.dao.ArcVideoByCID(%d) error(%v)", cid, err)
return
}
if v == nil || v.Status == model.VideoStatusDelete {
err = fmt.Errorf("视频(cid=%d)被删除", cid)
goto DELETE
}
// 2.校验稿件
if a, err = s.dao.Archive(c, aid); err != nil {
log.Error("s.dao.Archive(%d) error(%v)", aid, err)
return
}
if a == nil || a.State == model.StateForbidUpDelete {
err = fmt.Errorf("稿件(aid=%d)被删除", aid)
}
DELETE:
if err != nil {
if tx, err = s.dao.BeginTran(c); err != nil {
log.Error("s.dao.BeginTran() error(%v)", err)
return
}
if rows, err = s.dao.TxUpTaskByID(tx, tid, map[string]interface{}{"state": model.TypeFinished, "utime": 0}); err != nil {
log.Error("s.dao.TxUpTaskByID(%d) error(%v)", tid, err)
tx.Rollback()
return
}
if rows > 0 {
if _, err = s.dao.TxAddTaskHis(tx, 0 /*pool*/, model.ActionTaskDelete /*action*/, tid /*task_id*/, cid /*cid*/, uid /*uid*/, 0 /*utime*/, model.VideoStatusDelete /*result*/, "judge delete" /*reason*/); err != nil {
log.Error("s.dao.AddTaskLog(%d) error(%v)", tid, err)
tx.Rollback()
return
}
}
return tx.Commit()
}
return
}
// CheckOwner 检查任务状态修改权限
func (s *Service) CheckOwner(c context.Context, tid, uid int64) (err error) {
var role int8
var rows int64
task, err := s.dao.TaskByID(c, tid)
if task == nil || err != nil {
log.Error("s.dao.TaskByID(%d) error(%v)", tid, err)
return
}
if err = s.judge(c, task.ID, task.Aid, task.Cid, uid); err != nil {
log.Error("s.judge(%+v) error(%v)", task, err)
return
}
if role, err = s.dao.GetUserRole(c, uid); err != nil || role == 0 {
err = fmt.Errorf("非法用户(%d)", uid)
return
}
if task.State == model.TypeDelay || task.State == model.TypeReview {
return
}
if !s.CheckOnline(c, uid) {
err = fmt.Errorf("请先签到(%d)", uid)
return
}
if role == model.TaskLeader {
return
}
if task.UID != uid {
err = fmt.Errorf("没有权限处理该任务")
return
}
// 普通用户处理超时了,将任务释放掉
if task.State == model.TypeDispatched && time.Since(task.GTime.TimeValue()).Minutes() > 10.0 {
var tx *sql.Tx
if tx, err = s.dao.BeginTran(c); err != nil {
log.Error("s.dao.BeginTran() error(%v)", err)
return
}
if rows, err = s.dao.TxUpTaskByID(tx, tid, map[string]interface{}{"state": model.TypeRealTime, "uid": 0, "gtime": "0000-00-00 00:00:00"}); err != nil {
log.Error("s.dao.TxUpTaskByID(%d) error(%v)", tid, err)
tx.Rollback()
return
}
if rows > 0 {
if _, err = s.dao.TxAddTaskHis(tx, 0 /*pool*/, model.ActionRelease /*action*/, tid /*task_id*/, 0 /*cid*/, uid /*uid*/, 0 /*utime*/, 0 /*result*/, "timeout release" /*reason*/); err != nil {
log.Error("s.dao.AddTaskLog(%d) error(%v)", tid, err)
tx.Rollback()
return
}
}
return tx.Commit()
}
return
}

View File

@@ -0,0 +1,18 @@
package service
import (
"context"
"time"
"go-common/app/admin/main/videoup/model/archive"
"go-common/library/log"
)
// TaskTooksByHalfHour get task books by ctime
func (s *Service) TaskTooksByHalfHour(c context.Context, stime, etime time.Time) (tooks []*archive.TaskTook, err error) {
if tooks, err = s.dao.TaskTooksByHalfHour(c, stime, etime); err != nil {
log.Error("s.dao.TaskTooksByHalfHour(%v,%v)", stime, etime)
return
}
return
}

View File

@@ -0,0 +1,123 @@
package service
import (
"context"
"fmt"
"reflect"
"go-common/library/log"
)
// 每个ID单独查询 strict严格模式下一次错误直接返回
func (s *Service) singleIDtoName(c context.Context, list interface{}, singletrans func(context.Context, int64) ([]interface{}, error), strict bool, ID string, Names ...string) (err error) {
var (
lV, itemI, itemIE, idFiled, nameFiled, valueField reflect.Value
id int64
values []interface{}
)
if lV = reflect.ValueOf(list); !lV.IsValid() || lV.IsNil() || lV.Kind() != reflect.Slice {
return fmt.Errorf("invalid list")
}
count := lV.Len()
for i := 0; i < count; i++ {
if itemI = lV.Index(i); !itemI.IsValid() || itemI.IsNil() || itemI.Kind() != reflect.Ptr {
return fmt.Errorf("invalid itemI")
}
if itemIE = itemI.Elem(); !itemIE.IsValid() || itemIE.Kind() != reflect.Struct {
return fmt.Errorf("invalid itemIE")
}
if idFiled = itemIE.FieldByName(ID); !idFiled.IsValid() || idFiled.Kind() != reflect.Int64 {
return fmt.Errorf("invalid idFiled")
}
for _, Name := range Names {
if nameFiled = itemIE.FieldByName(Name); !nameFiled.IsValid() || !nameFiled.CanSet() {
return fmt.Errorf("invalid nameFiled")
}
}
if id = idFiled.Int(); id != 0 {
if values, err = singletrans(c, id); err != nil || len(values) != len(Names) {
log.Error("s.sigleIDtoName error(%v) len(values)=%d len(Names)=%d", err, len(values), len(Names))
if strict {
return
}
err = nil
continue
}
for i, value := range values {
nameFiled = itemIE.FieldByName(Names[i])
valueField = reflect.ValueOf(value)
if nameFiled.Kind() != valueField.Kind() {
log.Error("singletrans return %s while need %s", valueField.Kind().String(), nameFiled.Kind().String())
continue
}
nameFiled.Set(valueField)
}
}
}
return
}
/* 批量查询,批量转换
* list []*struct{}
* multrans 转化器根据ID查出其他值
* ID id字段名称id字段类型必须是int64
* Names 查出来的各个字段名称
*/
func (s *Service) mulIDtoName(c context.Context, list interface{}, multrans func(context.Context, []int64) (map[int64][]interface{}, error), ID string, Names ...string) (err error) {
var (
lV, itemI, itemIE, idFiled, nameFiled, valueField reflect.Value
id int64
ids []int64
hashIDName = make(map[int64][]interface{})
)
if lV = reflect.ValueOf(list); !lV.IsValid() || lV.IsNil() || lV.Kind() != reflect.Slice {
return fmt.Errorf("invalid list")
}
count := lV.Len()
for i := 0; i < count; i++ {
if itemI = lV.Index(i); !itemI.IsValid() || itemI.IsNil() || itemI.Kind() != reflect.Ptr {
return fmt.Errorf("invalid itemI")
}
if itemIE = itemI.Elem(); !itemIE.IsValid() || itemIE.Kind() != reflect.Struct {
return fmt.Errorf("invalid itemIE")
}
if idFiled = itemIE.FieldByName(ID); !idFiled.IsValid() || idFiled.Kind() != reflect.Int64 {
return fmt.Errorf("invalid idFiled")
}
for _, name := range Names {
if nameFiled = itemIE.FieldByName(name); !nameFiled.IsValid() || !nameFiled.CanSet() {
return fmt.Errorf("invalid nameFiled")
}
}
if id = idFiled.Int(); id != 0 {
if _, ok := hashIDName[id]; !ok {
hashIDName[id] = []interface{}{}
ids = append(ids, id)
}
}
}
if hashIDName, err = multrans(c, ids); err != nil {
return
}
for i := 0; i < count; i++ {
itemIE = lV.Index(i).Elem()
id = itemIE.FieldByName(ID).Int()
if names, ok := hashIDName[id]; ok && len(names) == len(Names) {
for i, name := range names {
nameFiled = itemIE.FieldByName(Names[i])
valueField = reflect.ValueOf(name)
if nameFiled.Kind() != valueField.Kind() {
log.Error("multrans return %v while need %v", ids)
continue
}
itemIE.FieldByName(Names[i]).Set(reflect.ValueOf(name))
}
}
}
return
}

View File

@@ -0,0 +1,57 @@
package service
import (
"context"
"go-common/app/admin/main/videoup-task/model"
"go-common/library/ecode"
"go-common/library/log"
)
func (s *Service) getVideo(ctx context.Context, aid int64, cid int64) (video *model.Video, err error) {
if video, err = s.dao.Video(ctx, aid, cid); err != nil {
log.Error("getVideo s.arc.Video error(%v) aid(%d) cid(%d)", err, aid, cid)
return
}
if video == nil {
err = ecode.NothingFound
log.Error("getVideo s.arc.Video error(%v) aid(%d) cid(%d)", err, aid, cid)
return
}
video.AttributeList = model.AttributeList(video.Attribute)
if video.XcodeState >= model.VideoXcodeHDFinish {
video.Encoding = 1
}
return
}
func (s *Service) getVideoOperInfo(ctx context.Context, vid int64) (list []*model.VideoOperInfo, err error) {
var (
vopers []*model.VOper
uids []int64
users map[int64]*model.UserDepart
)
list = []*model.VideoOperInfo{}
if vopers, uids, err = s.dao.VideoOpers(ctx, vid); err != nil {
log.Error("getVideoOperInfo s.dao.VideoOpers(%d) error(%v)", vid, err)
return
}
if users, err = s.dao.GetUsernameAndDepartment(ctx, uids); err != nil {
log.Error("getVideoOperInfo s.dao.GetUsernameAndRol(%d) error(%v) uids(%v)", vid, err, uids)
return
}
for _, op := range vopers {
u := users[op.UID]
if u == nil {
u = &model.UserDepart{UID: op.UID}
}
info := &model.VideoOperInfo{
VOper: *op,
UserDepart: *u,
}
list = append(list, info)
}
return
}

View File

@@ -0,0 +1,21 @@
package service
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func Test_getVideoOperInfo(t *testing.T) {
Init()
convey.Convey("getVideoOperInfo", t, func() {
list, err := s.getVideoOperInfo(context.TODO(), 8942606)
for _, info := range list {
t.Logf("info(%+v)", info)
}
convey.So(err, convey.ShouldBeNil)
convey.So(len(list), convey.ShouldEqual, 66)
})
}

View File

@@ -0,0 +1,321 @@
package service
import (
"context"
"encoding/json"
"fmt"
"time"
"go-common/app/admin/main/videoup-task/model"
account "go-common/app/service/main/account/api"
"go-common/library/log"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
)
// weightConf 所有激活的配置项
func (s *Service) weightConf(c context.Context) (wconfs map[int8]map[int64]*model.WCItem, err error) {
items, err := s.dao.WeightConf(c)
if err != nil {
log.Error("WeightConf error(%v)", err)
return
}
wconfs = map[int8]map[int64]*model.WCItem{}
for _, item := range items {
conf, ok := wconfs[item.Radio]
if !ok {
conf = make(map[int64]*model.WCItem)
}
conf[item.CID] = item
wconfs[item.Radio] = conf
}
return
}
// 同一类型的同id配置只能有一个
func (s *Service) checkConflict(c context.Context, mcases map[int64]*model.WCItem) (err error) {
wcf, err := s.weightConf(c)
if err != nil {
log.Error("s.weightConf error(%v)", err)
return
}
s.twConCache = wcf
for _, item := range mcases {
if cfgs, ok := s.twConCache[item.Radio]; ok {
if cfg, ok := cfgs[item.CID]; ok {
return fmt.Errorf("config(%d) conflict with (id=%d,desc=%s)", item.CID, cfg.ID, cfg.Desc)
}
}
}
return
}
// AddWeightConf 配置权重
func (s *Service) AddWeightConf(c context.Context, cfg *model.WeightConf, uid int64, uname string) (err error) {
//0. 一级分区转化为二级分区
if cfg.Radio == model.WConfType {
cfg.Ids = s.tarnsType(c, cfg.Ids)
}
//1. 解析表单提交的配置
mcases, istaskid, err := model.ParseWeightConf(cfg, uid, uname)
if err != nil {
log.Error("model.ParseWeightConf(%v, %v, %v) error(%v)", cfg, uname, err)
return
}
//2. 检查是否互相冲突
if err = s.checkConflict(c, mcases); err != nil {
log.Error("s.checkConflict error(%v)", err)
return
}
//3. 更新任务的权重配置
if istaskid {
if err = s.setWeightConf(c, cfg.Ids, mcases); err != nil {
log.Error("s.setWeightConf error(%v)", err)
return
}
}
//4. 将配置存储到数据库表
if err = s.dao.InWeightConf(c, mcases); err != nil {
log.Error("s.dao.InWeightConf(%v) error(%v)", mcases, err)
return
}
return
}
// DelWeightConf 删除配置项
func (s *Service) DelWeightConf(c context.Context, id int64) (err error) {
if _, err = s.dao.DelWeightConf(c, id); err != nil {
log.Error("s.DelWeightConf(%d) error(%v)", id, err)
}
return
}
// ListWeightConf 列出配置
func (s *Service) ListWeightConf(c context.Context, v *model.Confs) (cfg []*model.WCItem, err error) {
if cfg, err = s.dao.ListWeightConf(c, v); err != nil {
log.Error("s.ListWeightConf(%+v) error(%v)", v, err)
return
}
// 根据taskid补充filename和title
switch v.Radio {
case model.WConfMid: // 补充昵称和粉丝数
s.singleIDtoName(c, cfg, func(c context.Context, cid int64) (res []interface{}, err error) {
stat, err := s.profile(c, cid)
if err != nil {
log.Error("s.profile(%d) error(%v)", cid, err)
return
}
res = []interface{}{stat.Profile.Name, stat.Follower}
return
}, false, "CID", "Creator", "Fans")
case model.WConfTaskID: //补充title和filename
s.mulIDtoName(c, cfg, s.dao.LWConfigHelp, "CID", "FileName", "Title", "Vid")
case model.WConfType: //补充分区名称
s.singleIDtoName(c, cfg, func(c context.Context, cid int64) (res []interface{}, err error) {
if item, ok := s.typeCache[int16(cid)]; ok {
res = []interface{}{item.Name}
}
return
}, false, "CID", "TypeName")
case model.WConfUpFrom: //补充投稿来源
s.singleIDtoName(c, cfg, func(c context.Context, cid int64) (res []interface{}, err error) {
res = []interface{}{model.UpFrom(int8(cid))}
return
}, false, "CID", "UpFrom")
default:
}
return
}
// ListWeightLogs 权重变更日志
func (s *Service) ListWeightLogs(c context.Context, taskid int64, page int) (cfg []*model.TaskWeightLog, items int64, err error) {
cfg, err = s.dao.WeightLog(c, taskid)
if err != nil {
log.Info("s.ListWeightLogs(%d) error(%v)", taskid, err)
return
}
cfg, items, err = s.weightLogHelp(c, taskid, cfg, page)
return
}
// MaxWeight 当前的权重最大值, 供用户配置做参考
func (s *Service) MaxWeight(c context.Context) (max int64, err error) {
return s.dao.GetMaxWeight(c)
}
// 补充查询日志需要的信息
func (s *Service) weightLogHelp(c context.Context, taskid int64, twl []*model.TaskWeightLog, page int) (retwl []*model.TaskWeightLog, items int64, err error) {
var (
mid int64
ps *account.ProfileStatReply
name string
fans int
upspecial []int8
)
task, err := s.dao.TaskByID(c, taskid)
if task == nil {
log.Error("s.dao.TaskByID(%d) err(%v)", taskid, err)
return
}
// 1.获取用户信息
items = int64(len(twl))
if items == 0 {
return
}
mid = twl[items-1].Mid
if mid == 0 {
log.Error("weightLogHelp taskid=%d miss mid", taskid)
goto EMPTYMID
}
ps, err = s.profile(c, mid)
if err != nil || ps == nil {
log.Error("can't get Account.Card(%d) err(%v)", mid, err)
err = nil
} else {
name = ps.Profile.Name
fans = int(ps.Follower)
}
upspecial = s.getSpecial(mid)
EMPTYMID:
retwl = []*model.TaskWeightLog{}
// 反转日志顺序
var count int
for i := len(twl) - 1 - (page-1)*20; i >= 0 && count <= 20; func() { i--; count++ }() {
twl[i].Creator = name
twl[i].UpSpecial = upspecial
twl[i].Fans = int64(fans)
twl[i].Wait = twl[i].Uptime.TimeValue().Sub(task.CTime.TimeValue()).Seconds() * 1000.0
if !task.PTime.TimeValue().IsZero() {
twl[i].Ptime = string(task.PTime)
}
if len(twl[i].CfItems) > 0 {
for _, item := range twl[i].CfItems {
var desc = item.Desc
var v = new(model.WCItem)
if err = json.Unmarshal([]byte(item.Desc), v); err == nil { //兼容新旧日志格式
desc = v.Desc
}
err = nil
twl[i].Desc += fmt.Sprintf("%s:%s; ", model.CfWeightDesc(item.Radio), desc)
}
}
retwl = append(retwl, twl[i])
}
return
}
func (s *Service) getSpecial(mid int64) []int8 {
upspecial := []int8{}
for k, v := range s.upperCache {
if _, ok := v[mid]; ok {
upspecial = append(upspecial, k)
}
}
return upspecial
}
func (s *Service) setWeightConf(c context.Context, ids string, mcases map[int64]*model.WCItem) (err error) {
var mitems map[int64]*model.TaskPriority
arrid, _ := xstr.SplitInts(ids)
// 1. 获取旧的配置
if mitems, err = s.getTWCache(c, arrid); err != nil {
log.Error("s.getTWCache(%v) error(%v)", arrid, err)
return
}
if len(mitems) == 0 {
return fmt.Errorf("没有找到任务(%v)", arrid)
}
// 2. 将新加配置加入
for _, item := range mitems {
if one, ok := mcases[item.TaskID]; ok && one != nil {
one.Mtime = model.NewFormatTime(time.Now())
item.CfItems = append(item.CfItems, one)
}
}
// 3. 更新配置到redis和数据库
var wg errgroup.Group
wg.Go(func() (err error) {
return s.dao.SetWeightRedis(c, mitems)
})
for _, item := range mitems {
var descb []byte
v := item
wg.Go(func() (err error) {
if descb, err = json.Marshal(v.CfItems); err != nil {
return
}
_, err = s.dao.UpCwAfterAdd(c, v.TaskID, string(descb))
return
})
}
err = wg.Wait()
return
}
// ShowWeightVC 展示权重配置值
func (s *Service) ShowWeightVC(c context.Context) (wvc *model.WeightVC, err error) {
if wvc, err = s.dao.WeightVC(c); err != nil {
log.Error("s.dao.WeightVC error(%v)", err)
return
}
if wvc == nil {
wvc = model.WLVConf
s.dao.InWeightVC(c, wvc, "默认权重配置")
}
return
}
// SetWeightVC 设置权重配置
func (s *Service) SetWeightVC(c context.Context, wvc *model.WeightVC) (err error) {
_, err = s.dao.SetWeightVC(c, wvc, "设置权重配置")
return
}
// 处理一级分区转二级分区
func (s *Service) tarnsType(c context.Context, ids string) (res string) {
var (
mapNoNeed = make(map[int16]struct{}) // 不需要的一级分区
mapNeed = make(map[int16]struct{}) // 需要的一级分区
idres = []int64{}
)
arrid, _ := xstr.SplitInts(ids)
for _, id := range arrid {
if mod, ok := s.typeCache[int16(id)]; ok {
if mod.PID == 0 {
mapNeed[int16(id)] = struct{}{}
} else {
mapNoNeed[mod.PID] = struct{}{}
idres = append(idres, id)
}
}
}
for k := range mapNoNeed {
delete(mapNeed, k)
}
for k := range mapNeed {
idres = append(idres, s.typeCache2[k]...)
}
return xstr.JoinInts(idres)
}
func (s *Service) getTWCache(c context.Context, ids []int64) (mcases map[int64]*model.TaskPriority, err error) {
if mcases, err = s.dao.GetWeightRedis(c, ids); len(mcases) != len(ids) {
mcases, err = s.dao.GetWeightDB(c, ids)
}
return
}