bilibili-backup/app/admin/main/aegis/server/http/task.go
2019-04-22 02:59:20 +00:00

516 lines
11 KiB
Go

package http
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"strconv"
"strings"
"time"
"go-common/app/admin/main/aegis/model/business"
"go-common/app/admin/main/aegis/model/common"
taskmod "go-common/app/admin/main/aegis/model/task"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
libtime "go-common/library/time"
)
func taskDelay(c *bm.Context) {
opt := &taskmod.DelayOptions{}
if err := c.Bind(opt); err != nil {
return
}
err := srv.Delay(c, opt)
if err == ecode.AccessDenied || err == ecode.NothingFound {
c.JSONMap(map[string]interface{}{"tips": "任务已被他人处理,毋需延迟"}, nil)
return
}
c.JSON(nil, err)
}
func taskRelease(c *bm.Context) {
opt := &common.BaseOptions{}
if err := c.Bind(opt); err != nil {
return
}
c.JSON(srv.Release(c, opt, false))
}
func taskUnDo(c *bm.Context) {
opt := &common.BaseOptions{}
if err := c.Bind(opt); err != nil {
return
}
c.JSON(srv.UnDoStat(c, opt))
}
func taskStat(c *bm.Context) {
opt := &common.BaseOptions{}
if err := c.Bind(opt); err != nil {
return
}
c.JSON(srv.TaskStat(c, opt))
}
func consumerOn(c *bm.Context) {
opt := &common.BaseOptions{}
if err := c.Bind(opt); err != nil {
return
}
c.JSON(nil, srv.On(c, opt))
}
func consumerOff(c *bm.Context) {
opt := new(struct {
common.BaseOptions
Delay bool `form:"delay" default:"true"`
})
if err := c.Bind(opt); err != nil {
return
}
if err := srv.Off(c, &opt.BaseOptions); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
srv.Release(c, &opt.BaseOptions, opt.Delay)
}
func kickOut(c *bm.Context) {
opt := new(struct {
common.BaseOptions
KickUID int64 `form:"kick_uid" validate:"required"`
})
if err := c.Bind(opt); err != nil {
return
}
if opt.BaseOptions.Role != taskmod.TaskRoleLeader {
httpCode(c, "组长才有权限踢人", ecode.RequestErr)
return
}
if err := srv.KickOut(c, &opt.BaseOptions, opt.KickUID); err != nil {
c.JSON(nil, err)
return
}
c.JSON(nil, nil)
srv.Release(c, &opt.BaseOptions, false)
}
func consumerWatcher(c *bm.Context) {
opt := new(struct {
BizID int64 `form:"business_id" validate:"required"`
FlowID int64 `form:"flow_id" validate:"required"`
Role int8 `form:"role"`
})
if err := c.Bind(opt); err != nil {
return
}
c.JSON(srv.Watcher(c, opt.BizID, opt.FlowID, opt.Role))
}
func configEdit(c *bm.Context) {
twc, _, err := readConfig(c)
if err != nil || twc == nil {
c.JSON(nil, ecode.RequestErr)
return
}
if twc.ID <= 0 {
httpCode(c, "id错误", ecode.RequestErr)
return
}
c.JSON(nil, srv.UpdateConfig(c, twc))
}
func configAdd(c *bm.Context) {
twc, confJSON, err := readConfig(c)
if err != nil || twc == nil {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(nil, srv.AddConfig(c, twc, confJSON))
}
func readConfig(c *bm.Context) (tc *taskmod.Config, confJSON interface{}, err error) {
opt := &taskmod.ConfigOption{}
if err = c.Bind(opt); err != nil {
return nil, nil, err
}
switch opt.ConfType {
case taskmod.TaskConfigAssign:
type Assign struct {
Mids string `json:"mids"`
Uids string `json:"uids"`
}
confJSON = new(Assign)
case taskmod.TaskConfigRangeWeight:
confJSON = new(taskmod.RangeWeightConfig)
case taskmod.TaskConfigEqualWeight:
confJSON = new(taskmod.EqualWeightConfig)
default:
return nil, nil, ecode.RequestErr
}
tc = &taskmod.Config{
ID: opt.ID,
ConfType: opt.ConfType,
BusinessID: opt.BusinessID,
FlowID: opt.FlowID,
Description: opt.Description,
UID: opt.UID,
Uname: opt.Uname,
}
bt, _ := time.ParseInLocation(common.TimeFormat, opt.Btime, time.Local)
et, _ := time.ParseInLocation(common.TimeFormat, opt.Etime, time.Local)
if !bt.IsZero() {
tc.Btime = libtime.Time(bt.Unix())
}
if !et.IsZero() {
tc.Etime = libtime.Time(et.Unix())
}
err = jsonhelp(confJSON, []byte(opt.ConfJSON), tc)
return
}
func jsonhelp(jsonObject interface{}, bs []byte, tc *taskmod.Config) (err error) {
if err = json.Unmarshal(bs, jsonObject); err != nil {
log.Error("jsonhelp error(%v)", string(bs), err)
return
}
if bs, err = json.Marshal(jsonObject); err != nil {
log.Error("jsonhelp json.Marshal(%s) error(%v)", err)
return
}
tc.ConfJSON = string(bs)
return
}
func configList(c *bm.Context) {
qp := &taskmod.QueryParams{}
if err := c.Bind(qp); err != nil {
return
}
configs, count, err := srv.QueryConfigs(c, qp)
if err != nil {
c.JSON(nil, err)
return
}
qp.Pager.Total = int(count)
c.JSONMap(map[string]interface{}{
"pager": qp.Pager,
"data": configs,
}, nil)
}
func configDelete(c *bm.Context) {
opt := new(struct {
ID int64 `form:"id" validate:"required"`
})
if err := c.Bind(opt); err != nil {
return
}
c.JSON(nil, srv.DeleteConfig(c, opt.ID))
}
func configSet(c *bm.Context) {
opt := new(struct {
ID int64 `form:"id" validate:"required"`
State int8 `form:"state"`
})
if err := c.Bind(opt); err != nil {
return
}
c.JSON(nil, srv.SetStateConfig(c, opt.ID, opt.State))
}
func maxWeight(c *bm.Context) {
opt := &common.BaseOptions{}
if err := c.Bind(opt); err != nil {
return
}
c.JSON(srv.MaxWeight(c, opt))
}
func weightlog(c *bm.Context) {
opt := new(struct {
TaskID int64 `form:"task_id" validate:"required"`
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" default:"20"`
})
if err := c.Bind(opt); err != nil {
return
}
ls, count, err := srv.WeightLog(c, opt.TaskID, opt.Pn, opt.Ps)
c.JSONMap(map[string]interface{}{
"data": ls,
"pager": common.Pager{
Pn: opt.Pn,
Ps: opt.Ps,
Total: count,
},
}, err)
}
func role(c *bm.Context) {
opt := &common.BaseOptions{}
if err := c.Bind(opt); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
opt.UID = uid(c)
opt.Uname = uname(c)
_, role, err := srv.GetRole(c, opt)
c.JSON(role, err)
}
func roleFlush(c *bm.Context) {
opt := new(struct {
Uids []int64 `form:"uids,split" validate:"required"`
BizID int64 `form:"business_id" validate:"required"`
FlowID int64 `form:"flow_id" validate:"required"`
})
if err := c.Bind(opt); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(nil, srv.FlushRole(c, opt.BizID, opt.FlowID, opt.Uids))
}
func checkTaskRole() bm.HandlerFunc {
return func(ctx *bm.Context) {
opt := &common.BaseOptions{}
if err := ctx.Bind(opt); err != nil {
ctx.Abort()
return
}
if opt.BusinessID <= 0 || opt.FlowID <= 0 {
httpCode(ctx, "缺少business_id或flow_id", ecode.RequestErr)
ctx.Abort()
return
}
if srv.Debug() == "local" {
ctx.Request.Form.Set("role", strconv.Itoa(int(taskmod.TaskRoleLeader)))
return
}
user := uid(ctx)
if srv.IsAdmin(user) {
ctx.Request.Form.Set("role", strconv.Itoa(int(taskmod.TaskRoleLeader)))
log.Info("checkTaskRole uid(%d) is admin", user)
return
}
_, role, err := srv.GetRole(ctx, opt)
if err != nil || role == 0 {
ctx.JSON(nil, ecode.AccessDenied)
ctx.Abort()
return
}
log.Info("checkTaskRole opt(%+v) role(%d)", role)
ctx.Request.Form.Set("role", fmt.Sprint(role))
}
}
//判断业务用户权限,无授权业务则报错
func checkBizRole(role string, noAdmin bool, bizID bool) bm.HandlerFunc {
return func(ctx *bm.Context) {
if srv.Debug() == "local" {
return
}
user := uid(ctx)
if srv.IsAdmin(user) {
log.Info("checkBizRole uid(%d) is admin", user)
return
}
businessID, err := srv.GetRoleBiz(ctx, user, role, noAdmin)
if err != nil || len(businessID) == 0 {
ctx.JSON(nil, ecode.AccessDenied)
ctx.Abort()
return
}
ctx.Set(business.AccessBiz, businessID)
//request business in accessed biz range
if bizID {
var biz int64
if strings.Contains(ctx.Request.Header.Get("Content-Type"), "application/json") {
var body []byte
if body, err = ioutil.ReadAll(ctx.Request.Body); err != nil {
log.Error("checkBizRole ioutil.ReadAll error(%+v)", err)
return
}
ctx.Request.Body.Close()
ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
pm := new(struct {
BusinessID int64 `json:"business_id" form:"business_id"`
})
if err = json.Unmarshal(body, pm); err != nil {
log.Error("checkBizRole json.Unmarshal error(%+v) body(%s)", err, string(body))
ctx.JSON(nil, ecode.RequestErr)
ctx.Abort()
return
}
biz = pm.BusinessID
} else {
if biz, err = strconv.ParseInt(ctx.Request.Form.Get("business_id"), 10, 64); err != nil {
log.Error("checkBizRole strconv.ParseInt(%s) error(%v)", ctx.Request.Form.Get("business_id"), err)
ctx.JSON(nil, ecode.RequestErr)
ctx.Abort()
return
}
}
exist := false
for _, item := range businessID {
if item == biz {
exist = true
break
}
}
if !exist || biz <= 0 {
ctx.JSON(nil, ecode.AccessDenied)
ctx.Abort()
return
}
}
}
}
//判断任务用户权限,无授权业务则报错
func checkAccessTask() bm.HandlerFunc {
return func(ctx *bm.Context) {
if srv.Debug() == "local" {
return
}
user := uid(ctx)
if srv.IsAdmin(user) {
log.Info("checkrole uid(%d) is admin", user)
return
}
businessID, flowID, err := srv.GetTaskBizFlows(ctx, user)
if err != nil || len(businessID) == 0 || len(flowID) == 0 {
//ctx.JSON(nil, ecode.AccessDenied)
ctx.JSON(nil, nil)
ctx.Abort()
return
}
log.Info("checkAccessTask uid(%d) can see business(%+v) flow(%+v)", user, businessID, flowID)
ctx.Set(business.AccessBiz, businessID)
ctx.Set(business.AccessFlow, flowID)
}
}
//是否为指定业务的管理员角色
func checkBizID() bm.HandlerFunc {
return checkBizRole(business.BizBIDAdmin, false, true)
}
//为哪些业务的管理员角色
func checkBizAdmin() bm.HandlerFunc {
return checkBizRole(business.BizBIDAdmin, false, false)
}
//为哪些业务的非管理员角色
func checkBizBID() bm.HandlerFunc {
return checkBizRole("", true, false)
}
func checkBizLeader() bm.HandlerFunc {
return checkBizRole("leader", true, true)
}
func checkBizOper() bm.HandlerFunc {
return checkBizRole("oper", true, true)
}
//为指定业务的非管理员角色
func checkBizBIDBiz() bm.HandlerFunc {
return checkBizRole("", true, true)
}
func getAccessBiz(c *bm.Context) (biz []int64) {
biz = []int64{}
ids, _ := c.Get(business.AccessBiz)
if ids != nil {
biz = ids.([]int64)
}
return
}
func getAccessFlow(c *bm.Context) (flowID []int64) {
flowID = []int64{}
ids, _ := c.Get(business.AccessFlow)
if ids != nil {
flowID = ids.([]int64)
}
return
}
func checkon() bm.HandlerFunc {
return func(ctx *bm.Context) {
if srv.Debug() == "local" {
return
}
opt := &common.BaseOptions{}
if err := ctx.Bind(opt); err != nil {
ctx.Abort()
return
}
if !srv.IsOn(ctx, opt) {
if err := srv.On(ctx, opt); err != nil {
ctx.JSON(nil, err)
ctx.Abort()
}
return
}
}
}
func preHandlerUser() bm.HandlerFunc {
return func(ctx *bm.Context) {
if srv.Debug() == "local" {
return
}
uidS, ok := ctx.Get("uid")
if !ok {
ctx.JSON(nil, ecode.NoLogin)
ctx.Abort()
return
}
unamei, ok := ctx.Get("username")
if !ok {
ctx.JSON(nil, ecode.NoLogin)
ctx.Abort()
return
}
ctx.Request.Form.Set("uid", fmt.Sprint(uidS))
ctx.Request.Form.Set("uname", unamei.(string))
}
}