// Copyright 2019  getensh.com. All rights reserved.
// Use of this source code is governed by  getensh.com.
package ctrl_v1

import (
	"encoding/json"
	"fmt"
	"gd_management_gateway/errors"
	"gd_management_gateway/params/param_base"
	"gd_management_gateway/params/param_v1_0"
	"gd_management_gateway/rpc_apis"
	"gd_management_gateway/rpc_apis/gd_admin"
	"gd_management_gateway/rpc_apis/gd_management"
	"net/url"
	"reflect"
	"strconv"
	"time"

	"gd_management_gateway/common.in/httper"
	"gd_management_gateway/common.in/jsonrpc2"
	"gd_management_gateway/common.in/task"
	"gd_management_gateway/common.in/utils"

	"go.uber.org/zap"

	"context"
	"os"
	"path"
	"sort"
	"strings"

	"bytes"
	"crypto/tls"
	"io"
	"net/http"
	"sync"

	"gd_management_gateway/common.in/cache"

	"github.com/astaxie/beego"
	"github.com/tealeg/xlsx"
)

// Operations about base api
type BaseApiController struct {
	metadata interface{} // 中继元数据
	beego.Controller
	LogID string
}

var DiscoveryType = "etcd"

var taskMux sync.Mutex
var taskMap = map[string]bool{}
var taskCountMux sync.Mutex
var taskCount int
var ExitRecieved bool

func taskIncrease() {
	taskCountMux.Lock()
	defer taskCountMux.Unlock()
	taskCount++
}

func taskDecrease() {
	taskCountMux.Lock()
	defer taskCountMux.Unlock()
	if taskCount > 0 {
		taskCount--
	}
}

func IsApiTaskRun() bool {
	taskCountMux.Lock()
	defer taskCountMux.Unlock()
	if taskCount > 0 {
		return true
	}
	return false
}

func setTaskStop(taskId string) {
	taskMux.Lock()
	defer taskMux.Unlock()
	if value, ok := taskMap[taskId]; ok && value == true {
		return
	}
	taskMap[taskId] = true
	go func() {
		t := time.NewTicker(1 * time.Second)
		count := 0
		for {

			select {
			case <-t.C:
				count++
				taskMux.Lock()
				if _, ok := taskMap[taskId]; ok == false {
					taskMux.Unlock()
					return
				}
				if count >= 120 {
					delete(taskMap, taskId)
					taskMux.Unlock()
					return
				}
				taskMux.Unlock()
			}

		}
	}()
}

func removeBatchFile(path string) {
	os.Remove(path)
	if true {
		array := strings.Split(path, "/")
		if len(array) > 1 {
			length := len(array)
			utils.OssDeleteFile(array[length-1])
		}
	}
}

const (
	BatchApiStopNotifyChannel    = "batch_api_stop_notify"
	BatchRemoveFileNotifyChannel = "batch_remove_file_notify"
)

func Watch() {
	go func() {
		cache.Redis.RegisterFunc(BatchApiStopNotifyChannel, setTaskStop)
		cache.Redis.RegisterFunc(BatchRemoveFileNotifyChannel, removeBatchFile)
		cache.Redis.SubscribeAndHandle(BatchApiStopNotifyChannel, BatchRemoveFileNotifyChannel)
	}()
}

// @Title add base api
// @Description 添加基础api
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   base_api_info    body   rpc_apis.gd_management.ManagementBaseApiInfo true "api信息"
// @Success 200 	{object} params.param_v1_0.ManagementAddBaseApiResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api [post]
func (u *BaseApiController) ManagementAddBaseApi() {
	u.LogID = fmt.Sprintf("ManagementAddBaseApi[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementAddBaseApiReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	// 加入行为日志
	AddActionLogTask := func() error {
		go func() {
			// 构建json
			contentBytes, _ := json.Marshal(req.BaseApiInfo)

			areq := gd_admin.AddActionLogReq{
				Uid:        req.Uid,
				Name:       req.BaseApiInfo.Name,
				Modules:    "基础API",
				Func:       "添加基础API",
				Before:     "",
				Content:    string(contentBytes),
				ModifyTime: time.Now().Format("2006-01-02 15:04:05"),
			}

			AddActionLog(areq)
		}()
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementAddBaseApiReq{}
		mreq.BaseApiInfo = req.BaseApiInfo

		reply, err := rpc_apis.Management.ManagementAddBaseApi(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementAddBaseApi"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementAddBaseApiResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		resp.Data = reply

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, AddActionLogTask, handleDataTask,
	)
}

// @Title del base api
// @Description 删除基础api
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_id    query   int true "api id"
// @Success 200 	{object} params.param_v1_0.ManagementDelBaseApiResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api [delete]
func (u *BaseApiController) ManagementDelBaseApi() {
	u.LogID = fmt.Sprintf("ManagementDelBaseApi[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementDelBaseApiReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	// 记录用户行为日志
	AddActionLogTask := func() error {
		// 获取api信息
		mreq := gd_management.ManagementGetBaseApiInfoReq{
			ApiId: req.ApiId,
		}

		reply, err := rpc_apis.Management.ManagementGetBaseApiInfo(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetBaseApiInfo"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}

		// 构建json
		beforeBytes, _ := json.Marshal(reply.BaseApiInfo)

		areq := gd_admin.AddActionLogReq{
			Uid:        req.Uid,
			Name:       reply.BaseApiInfo.Name,
			Modules:    "基础api",
			Func:       "删除基础api",
			Before:     string(beforeBytes),
			Content:    "",
			ModifyTime: time.Now().Format("2006-01-02 15:04:05"),
		}

		err = AddActionLog(areq)
		if err != nil {
			return err
		}

		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementDelBaseApiReq{}
		mreq.ApiId = req.ApiId
		_, err := rpc_apis.Management.ManagementDelBaseApi(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementDelBaseApi"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementDelBaseApiResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, AddActionLogTask, handleDataTask,
	)
}

// @Title update base api
// @Description 修改基础api
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_id    path   int true "api id"
// @Param   base_api_info    body   rpc_apis.gd_management.ManagementBaseApiInfo true "api信息"
// @Success 200 	{object} params.param_v1_0.ManagementUpdateBaseApiResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api/:api_id [put]
func (u *BaseApiController) ManagementUpdateBaseApi() {
	u.LogID = fmt.Sprintf("ManagementUpdateBaseApi[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementUpdateBaseApiReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	// 记录行为日志
	AddActionLogTask := func() error {
		// 获取修改前数据api内容
		mreq := gd_management.ManagementGetBaseApiInfoReq{
			ApiId: req.ApiId,
		}

		reply, err := rpc_apis.Management.ManagementGetBaseApiInfo(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetBaseApiInfo"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}

		// 构建json
		contentBytes, _ := json.Marshal(reply)

		areq := gd_admin.AddActionLogReq{
			Uid:        req.Uid,
			Name:       req.BaseApiInfo.Name,
			Modules:    "基础API",
			Func:       "修改基础API",
			Before:     "",
			Content:    string(contentBytes),
			ModifyTime: time.Now().Format("2006-01-02 15:04:05"),
		}

		err = AddActionLog(areq)
		if err != nil {
			return err
		}

		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementUpdateBaseApiReq{}
		mreq.BaseApiInfo = req.BaseApiInfo
		mreq.ApiId = req.ApiId
		_, err := rpc_apis.Management.ManagementUpdateBaseApi(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementUpdateBaseApi"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementUpdateBaseApiResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, AddActionLogTask, handleDataTask,
	)
}

// @Title get base api list
// @Description 获取api列表
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_type    query   int false "api类型"
// @Param   page_number    query   int false "当前页"
// @Param   is_all    query   bool false "是否全部返回"
// @Param   search    query   string false "搜索字符串"
// @Param   merchant_id    query   int64 false ""
// @Success 200 	{object} params.param_v1_0.ManagementGetBaseApiListResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_list [get]
func (u *BaseApiController) ManagementGetBaseApiList() {
	u.LogID = fmt.Sprintf("ManagementGetBaseApiList[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementGetBaseApiListReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementGetBaseApiListReq{}
		mreq.ApiType = req.ApiType
		mreq.PageNumber = req.PageNumber
		mreq.IsAll = req.IsAll
		mreq.Search = req.Search
		mreq.MerchantId = req.MerchantId
		reply, err := rpc_apis.Management.ManagementGetBaseApiList(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetBaseApiList"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementGetBaseApiListResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		resp.Data = reply
		if resp.Data.BaseApiItemLManagementBaseApiListItemist == nil {
			resp.Data.BaseApiItemLManagementBaseApiListItemist = []gd_management.ManagementBaseApiListItem{}
		}
		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

// @Title get base api info
// @Description 获取api信息
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_id    query   int true "api id"
// @Success 200 	{object} params.param_v1_0.ManagementGetBaseApiInfoResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_info [get]
func (u *BaseApiController) ManagementGetBaseApiInfo() {
	u.LogID = fmt.Sprintf("ManagementGetBaseApiInfo[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementGetBaseApiInfoReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementGetBaseApiInfoReq{}
		mreq.ApiId = req.ApiId
		reply, err := rpc_apis.Management.ManagementGetBaseApiInfo(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetBaseApiInfo"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementGetBaseApiInfoResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		resp.Data = reply.BaseApiInfo

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

// @Title set base api state
// @Description 停启用api
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_id    path   int true "api id"
// @Param	body	body	params.param_v1_0.ManagementSetBaseApiStateBody	true	""
// @Success 200 	{object} params.param_v1_0.ManagementSetBaseApiStateResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_state/:api_id [put]
func (u *BaseApiController) ManagementSetBaseApiState() {
	u.LogID = fmt.Sprintf("ManagementSetBaseApiState[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementSetBaseApiStateReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	// 记录用户行为日志
	AddActionLogTask := func() error {
		// 获取api信息
		mreq := gd_management.ManagementGetBaseApiInfoReq{
			ApiId: req.ApiId,
		}

		reply, err := rpc_apis.Management.ManagementGetBaseApiInfo(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetBaseApiInfo"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}

		// 构建json
		b := map[string]interface{}{
			"enable": reply.BaseApiInfo.Enable,
		}
		beforeBytes, _ := json.Marshal(b)
		contentBytes, _ := json.Marshal(req.Body)

		areq := gd_admin.AddActionLogReq{
			Uid:        req.Uid,
			Name:       reply.BaseApiInfo.Name,
			Modules:    "基础API",
			Func:       "停启用api",
			Before:     string(beforeBytes),
			Content:    string(contentBytes),
			ModifyTime: time.Now().Format("2006-01-02 15:04:05"),
		}
		err = AddActionLog(areq)
		if err != nil {
			return err
		}

		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementSetBaseApiStateReq{
			ApiId:  req.ApiId,
			Enable: req.Body.Enable,
		}
		_, err := rpc_apis.Management.ManagementSetBaseApiState(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementSetBaseApiState"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementSetBaseApiStateResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, AddActionLogTask, handleDataTask,
	)
}

// @Title add base api provider
// @Description 添加基础api数据源接口
// @Param   token    header   string true "token"
// @Param   uid    header   string true "管理用户id"
// @Param   providers    body   rpc_apis.gd_management.ManagementAddBaseApiProviderReq true "数据源"
// @Success 200 	{object} params.param_v1_0.ManagementAddBaseApiProviderResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_provider [post]
func (u *BaseApiController) ManagementAddBaseApiProvider() {
	u.LogID = fmt.Sprintf("ManagementAddBaseApiProvider[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementAddBaseApiProviderReq{}
	getParamsTask := func() error {
		//httper.FillRequireParams(u.Ctx, req, u.LogID)
		uid, err := strconv.ParseInt(u.Ctx.Input.Header("uid"), 10, 64)
		if err != nil {
			return errors.ArgsError
		}
		req.Uid = uid
		req.Token = u.Ctx.Input.Header("token")
		body := u.Ctx.Input.RequestBody
		err = json.Unmarshal(body, &req.Providers)
		if err != nil {
			return errors.ArgsError
		}
		return nil
	}

	// 添加用户行为日志
	AddActionLogTask := func() error {
		// 获取api基本信息
		rreq := gd_management.ManagementGetBaseApiInfoReq{
			ApiId: req.Providers.ApiId,
		}

		reply, err := rpc_apis.Management.ManagementGetBaseApiInfo(utils.NewContextFromBeegoCtx(u.Ctx), &rreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetBaseApiInfo"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}

		// 构建json
		contentBytes, _ := json.Marshal(req.Providers)

		areq := gd_admin.AddActionLogReq{
			Uid:        req.Uid,
			Name:       reply.BaseApiInfo.Name,
			Modules:    "基础API",
			Func:       "添加基础api数据源接口",
			Before:     "",
			Content:    string(contentBytes),
			ModifyTime: time.Now().Format("2006-01-02 15:04:05"),
		}

		err = AddActionLog(areq)
		if err != nil {
			return err
		}

		return nil
	}

	handleDataTask := func() error {
		mreq := req.Providers
		_, err := rpc_apis.Management.ManagementAddBaseApiProvider(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementAddBaseApiProvider"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementAddBaseApiProviderResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		/*
			resp.Priority = reply.Priority
			resp.Name = reply.Name
			resp.Router = reply.Router
			resp.Platform = reply.Platform
		*/

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, AddActionLogTask, handleDataTask,
	)
}

/*
// @Title del base api provider
// @Description 删除基础api数据源接口
// @Param   token    header   string true "token"
// @Param   uid    header   string true "管理用户id"
// @Param   api_id    query   uint64 true ""
// @Param   group_number    query   int true ""
// @Param   provider_api_id    query   uint64 true ""
// @Success 200 	{object} params.param_v1_0.ManagementDelBaseApiProviderResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_provider [delete]
func (u *BaseApiController) ManagementDelBaseApiProvider() {
	u.LogID = fmt.Sprintf("ManagementDelBaseApiProvider[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementDelBaseApiProviderReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementDelBaseApiProviderReq{}
		mreq.ApiId = req.ApiId
		mreq.GroupNumber = req.GroupNumber
		mreq.ProviderApiId = req.ProviderApiId
		_, err := rpc_apis.Management.ManagementDelBaseApiProvider(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementDelBaseApiProvider"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementDelBaseApiProviderResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}
*/

// @Title get base api provider list
// @Description 获取基础api数据源接口列表
// @Param   token    header   string true "token"
// @Param   uid    header   string true "管理用户id"
// @Param   api_id    query   uint64 true ""
// @Success 200 	{object} params.param_v1_0.ManagementGetBaseApiProviderListResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_provider_list [get]
func (u *BaseApiController) ManagementGetBaseApiProviderList() {
	u.LogID = fmt.Sprintf("ManagementGetBaseApiProviderList[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementGetBaseApiProviderListReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementGetBaseApiProviderListReq{}
		mreq.ApiId = req.ApiId
		reply, err := rpc_apis.Management.ManagementGetBaseApiProviderList(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetBaseApiProviderList"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementGetBaseApiProviderListResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		resp.Data = reply.ProviderGroupList

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

/*
// @Title set base api provider priority
// @Description 设置基础api数据源接口优先级
// @Param   token    header   string true "token"
// @Param   uid    header   string true "管理用户id"
// @Param   api_id    query   uint64 true ""
// @Param   group_number    query   int true ""
// @Param   provider_api_ids    query   string true "数据源接口id按优先级排序后列表，以逗号分隔"
// @Success 200 	{object} params.param_v1_0.ManagementSetBaseApiProviderPriorityResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_provider_priority [put]
func (u *BaseApiController) ManagementSetBaseApiProviderPriority() {
	u.LogID = fmt.Sprintf("ManagementSetBaseApiProviderPriority[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementSetBaseApiProviderPriorityReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementSetBaseApiProviderPriorityReq{}
		mreq.ApiId = req.ApiId
		mreq.GroupNumber = req.GroupNumber
		mreq.ProviderApiIds = req.ProviderApiIds
		_, err := rpc_apis.Management.ManagementSetBaseApiProviderPriority(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementSetBaseApiProviderPriority"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementSetBaseApiProviderPriorityResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}
*/

// @Title try api
// @Description 测试api调用
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_info    body   rpc_apis.gd_management.ManagementTryBaseApiReq true "api信息"
// @Success 200 	{object} params.param_v1_0.ManagementTryBaseApiResp "响应信息"
// @Failure 500 	服务器错误
// @router /try [post]
func (u *BaseApiController) ManagementTryBaseApi() {
	u.LogID = fmt.Sprintf("ManagementTryBaseApi[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementTryBaseApiReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := req.ApiInfo
		reply, err := rpc_apis.Management.ManagementTryBaseApi(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementTryBaseApi"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementTryBaseApiResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		resp.Data = reply.Data
		resp.OrderNo = reply.OrderNo
		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

type batchTryApiResParam struct {
	Name  string
	Value string
}

type CommonRes struct {
	Code int
	Msg  string
	Data string
}

func batchTryApiParseResponse(data string, origin string) []batchTryApiResParam {
	ret := []batchTryApiResParam{}
	item := batchTryApiResParam{}
	item.Name = "origin"
	item.Value = origin
	if item.Value == "" {
		item.Value = data
	}
	ret = append(ret, item)

	if len(data) == 0 {
		return ret
	}
	r := CommonRes{}
	json.Unmarshal([]byte(data), &r)
	item = batchTryApiResParam{}
	item.Name = "code"
	item.Value = fmt.Sprintf("%v", r.Code)
	ret = append(ret, item)

	item = batchTryApiResParam{}
	item.Name = "msg"
	item.Value = r.Msg
	ret = append(ret, item)

	if r.Data == "" {
		return ret
	}

	m := map[string]interface{}{}
	json.Unmarshal([]byte(r.Data), &m)
	names := []string{}
	for k, _ := range m {
		names = append(names, k)
	}
	sort.Strings(names)

	for _, v := range names {
		item = batchTryApiResParam{}
		item.Name = v
		item.Value = fmt.Sprintf("%v", m[v])
		if reflect.ValueOf(m[v]).Kind() == reflect.Map ||
			reflect.ValueOf(m[v]).Kind() == reflect.Array ||
			reflect.ValueOf(m[v]).Kind() == reflect.Slice ||
			reflect.ValueOf(m[v]).Kind() == reflect.Struct {
			bytes, _ := json.Marshal(m[v])
			item.Value = fmt.Sprintf("%s", bytes)
		}
		ret = append(ret, item)
	}
	return ret

}

func setTaskFirstRow(rs []batchTryApiResParam, firstRow *xlsx.Row) {

	if firstRow != nil && len(rs) > 0 {
		for _, v := range rs {
			cell := firstRow.AddCell()
			cell.Value = v.Name
		}
	}
}

func setTaskResponse(rows []*xlsx.Row, res []gd_management.BatchTryApiParams) (ret []batchTryApiResParam) {

	for i, v := range rows {
		if len(res) <= i {
			break
		}
		rs := batchTryApiParseResponse(res[i].Response, res[i].OriginResponse)
		for _, col := range rs {
			cell := v.AddCell()
			cell.Value = col.Value
		}
		if len(rs) > len(ret) {
			ret = rs
		}
	}
	return ret
}

func setBatchApiFirstRows(row *xlsx.Row, paramCount int, rs []batchTryApiResParam, headMap map[string]string) {
	cells := len(row.Cells)
	for i, v := range rs {
		index := paramCount + i
		var cell *xlsx.Cell
		if cells > index {
			cell = row.Cells[index]
		} else {
			cell = row.AddCell()
		}
		cell.Value = getChineseHeader(v.Name, headMap)
	}
}

func setTaskResponseNew(file *xlsx.File, path string, paramCount int, reqs [][]string, res []gd_management.BatchTryApiParams, headMap map[string]string) error {
	sheet := file.Sheets[0]
	firstRow := sheet.Rows[0]
	for index, req := range reqs {
		newRow := sheet.AddRow()
		for i := 0; i < paramCount; i++ {
			cell := newRow.AddCell()
			if i >= len(req) {
				cell.Value = ""
				continue
			}
			cell.Value = req[i]
		}
		if len(res) <= index {
			continue
		}
		rs := batchTryApiParseResponse(res[index].Response, res[index].OriginResponse)
		for _, col := range rs {
			cell := newRow.AddCell()
			cell.Value = col.Value
		}
		if len(rs)+paramCount > len(firstRow.Cells) {
			setBatchApiFirstRows(firstRow, paramCount, rs, headMap)
		}
	}

	return nil
}

func getChineseHeader(engName string, headMap map[string]string) string {
	if headMap == nil {
		return engName
	}

	if v, ok := headMap[engName]; ok {
		return v
	} else {
		return engName
	}
	return engName
}

func setBatchApiParamName(file *xlsx.File, paramName map[int]string, headMap map[string]string) error {
	if len(file.Sheets) == 0 {
		return errors.FileOpenFailed
	}
	sheet := file.Sheets[0]
	row := sheet.AddRow()
	for _, v := range paramName {
		cell := row.AddCell()
		cell.Value = getChineseHeader(v, headMap)
	}
	return nil
}

func isTaskStop(staskId string) bool {
	taskMux.Lock()
	defer taskMux.Unlock()
	if stop, ok := taskMap[staskId]; ok && stop {
		delete(taskMap, staskId)
		return true
	}
	if ExitRecieved {
		return true
	}
	return false
}

func batchTryApi(info *batchApiInfo, multiNumber int, headMap map[string]string) (bool, error) {
	realfile := beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + info.filename
	file, err := xlsx.OpenFile(realfile)
	if err != nil {
		return false, err
	}
	newFile, err := xlsx.OpenFile(info.NewFilePath)
	if err != nil {
		return false, err
	}
	if len(file.Sheets) == 0 {
		return false, jsonrpc2.NewJsonError(20317, "参数文件没有sheet")
	}
	sheet := file.Sheets[0]
	if len(sheet.Rows) == 0 {
		return false, jsonrpc2.NewJsonError(20317, "参数文件为空")
	}
	var nameMap = map[int]string{}
	var paramMap = map[string]string{}
	mreq := gd_management.ManagementBatchTryApiReq{}
	mreq.Method = info.method
	mreq.Router = info.router
	mreq.AppSecret = info.appSecret
	mreq.AppKey = info.appKey
	mreq.IsCrypto = info.isCrypto
	mreq.MerchantAccount = info.MerchantAccount
	mreq.AppPassword = info.appPassword
	mreq.EncryptoType = info.EncryptoType
	if multiNumber > 1 {
		mreq.MultiMode = true
	}
	params := []string{}
	rows := []*xlsx.Row{}
	number := 5
	if multiNumber > 1 {
		number = multiNumber
	}
	parray := [][]string{}
	stopped := false
	for index, cell := range sheet.Rows[0].Cells {
		nameMap[index] = cell.Value
	}
	existRows := len(newFile.Sheets[0].Rows)
	writeCount := 0
	for index, row := range sheet.Rows {
		if writeCount >= 500 {
			newFile.Save(info.NewFilePath)
			newFile, _ = xlsx.OpenFile(info.NewFilePath)
			writeCount = 0
		}
		if index < existRows {
			continue
		}
		if stopped = isTaskStop(info.taskId); stopped {
			break
		}
		empty := true
		if index == 0 {
			setBatchApiParamName(newFile, nameMap, headMap)
			continue
		}
		array := make([]string, len(nameMap))
		for _, cell := range row.Cells {
			if cell.Value != "" {
				empty = false
			}
		}
		if empty == true {
			break
		}
		rows = append(rows, row)
		for index, cell := range row.Cells {
			array[index] = cell.Value
			paramMap[nameMap[index]] = cell.Value

		}
		parray = append(parray, array)
		bytes, _ := json.Marshal(paramMap)
		params = append(params, string(bytes))
		if (index)%number == 0 {
			mreq.Params = params
			params = []string{}
			reply, err := rpc_apis.Management.ManagementBatchTryApi(context.Background(), &mreq)
			if err != nil {
				return false, err
			}
			setTaskResponseNew(newFile, info.NewFilePath, len(nameMap), parray, reply.Params, headMap)
			writeCount += len(reply.Params)
			parray = [][]string{}
			rows = []*xlsx.Row{}
			if reply.Stop == true {
				break
			}
		}
	}

	if len(rows) > 0 && stopped == false {
		mreq.Params = params
		reply, err := rpc_apis.Management.ManagementBatchTryApi(context.Background(), &mreq)
		if err != nil {
			return false, err
		}
		setTaskResponseNew(newFile, info.NewFilePath, len(nameMap), parray, reply.Params, headMap)
		rows = []*xlsx.Row{}
	}
	newFile.Save(info.NewFilePath)
	if true {
		err := utils.OssUploadFile(info.NewFilePath, info.NewFileName)
		if err != nil {
			l.Error("oss",
				zap.String("call", "OssUploadFile"),
				zap.String("args", info.NewFilePath+","+info.NewFileName),
				zap.String("error", err.Error()))
			return stopped, jsonrpc2.NewJsonError(20317, fmt.Sprintf("oss 上传失败，%s, %s %v", info.NewFilePath, info.NewFileName, err))
		}
	}
	return stopped, err
}

func handleUploadFile(u *BaseApiController) (string, error) {
	f, h, err := u.GetFile("file") //获取上传的文件
	if err != nil {
		return "", errors.ArgsError
	}
	defer f.Close()
	if h.Size <= 0 {
		return "", errors.FileErr
	}
	if h.Size > 10*1024*1024 {
		return "", errors.FileSizeErr
	}
	ext := path.Ext(h.Filename)
	if ext != ".xlsx" {
		return "", errors.ExtErr
	}
	array := strings.Split(h.Filename, ".")
	array[0] = strings.Replace(array[0], " ", "-", -1)
	array[0] = strings.Replace(array[0], "/", "-", -1)
	newfile := array[0] + fmt.Sprintf("%d", time.Now().Unix()) + ".xlsx"
	filename := beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + newfile
	u.SaveToFile("file", filename)
	if true {
		utils.OssUploadFile(filename, newfile)
	}
	return newfile, nil
}

type batchApiInfo struct {
	filename        string
	router          string
	method          string
	appKey          string
	appSecret       string
	isCrypto        bool
	MerchantAccount bool
	NewFilePath     string
	NewFileName     string
	taskId          string
	appPassword     string
	EncryptoType    int `json:"encrypto_type"`
}

func initBatchApiFile(path string) error {

	f := xlsx.NewFile()
	f.AddSheet("-")
	err := f.Save(path)
	if err != nil {
		return errors.FileOpenFailed
	}
	return nil
}

func getOssFileUrl(filename string) string {
	return utils.OssGetUrl() + "/" + filename
}

// @Title create api task
// @Description 测试api调用
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_name    query  string true ""
// @Param   router query string true ""
// @Param   method query string true ""
// @Param   app_key query string true ""
// @Param   app_secret query string true ""
// @Param   is_crypto  query bool true ""
// @Param   merchant_account  query bool true ""
// @Param   multi_number query int false ""
// @Param   task_name query string false ""
// @Param   chinese_header query bool false ""
// @Param   encrypto_type query int false ""
// @Success 200 	{object} params.param_v1_0.ManagementTryBaseApiResp "响应信息"
// @Failure 500 	服务器错误
// @router /try_api_task [post]
func (u *BaseApiController) ManagementCreateTryBaseApiTask() {
	u.LogID = fmt.Sprintf("ManagementCreateTryBaseApiTask[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementCreateTryApiTaskReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		if req.MultiNumber > 100 {
			return jsonrpc2.NewJsonError(20001, "参数错误: 并发数不能大于100")
		}
		return nil
	}

	handleDataTask := func() error {
		var headMap map[string]string
		if !req.EnglishHeader {
			hReq := gd_management.ManagementGetBaseApiByRouterReq{}
			hReq.Router = req.Router
			hReq.Method = req.Method
			hReq.AppKey = req.AppKey
			hReply, err := rpc_apis.Management.ManagementGetBaseApiByRouter(utils.NewContextFromBeegoCtx(u.Ctx), &hReq)
			if err != nil {
				l.Error("rpc",
					zap.String("call", "ManagementGetBaseApiByRouter"),
					zap.String("args", utils.MarshalJsonString(req)),
					zap.String("error", err.Error()))
				//return errors.ErrorTransform(err)
			} else {
				headMap = hReply.Data
			}
			fmt.Println("ManagementGetBaseApiByRouter:", hReply, err)
		}
		//fmt.Println("headMap", headMap)
		filename, err := handleUploadFile(u)
		if err != nil {
			return err
		}

		newFileName := "batch_result_" + filename
		newFilePath := beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + newFileName
		if err := initBatchApiFile(newFilePath); err != nil {
			return err
		}

		mreq := gd_management.ManagementCreateTryApiTaskReq{}
		bytes, _ := json.Marshal(req)
		mreq.RequestInfo = string(bytes)
		mreq.Router = req.Router
		mreq.ApiName = req.ApiName
		mreq.Method = req.Method
		mreq.FileName = newFileName
		mreq.AppKey = req.AppKey
		mreq.TaskName = req.TaskName
		if req.MerchantAccount {
			mreq.IsMerchant = true
		}
		mreq.OriginFile = "http://" + ServerIp + ":" + ServerPort + "/try_api_task_dir/" + filename
		mreq.DownloadFile = "http://" + ServerIp + ":" + ServerPort + "/try_api_task_dir/" + newFileName
		if true {
			mreq.OriginFile = getOssFileUrl(filename)
			mreq.DownloadFile = getOssFileUrl(newFileName)
		}

		reply, err := rpc_apis.Management.ManagementCreateTryApiTask(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementTryBaseApi"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		go func() {
			info := batchApiInfo{
				filename:        filename,
				method:          mreq.Method,
				isCrypto:        req.IsCrypto,
				appKey:          req.AppKey,
				appSecret:       req.AppSecret,
				appPassword:     req.AppPassword,
				router:          mreq.Router,
				MerchantAccount: req.MerchantAccount,
				NewFileName:     newFileName,
				NewFilePath:     newFilePath,
				taskId:          fmt.Sprintf("%d", reply.Id),
				EncryptoType:req.EncryptoType,
			}
			taskIncrease()
			stopped, err := batchTryApi(&info, req.MultiNumber, headMap)
			ureq := gd_management.ManagementUpdateTryApiTaskReq{}
			ureq.TaskId = reply.Id
			ureq.DownloadFile = "http://" + ServerIp + ":" + ServerPort + "/try_api_task_dir/" + newFileName
			if true {
				ureq.DownloadFile = getOssFileUrl(newFileName)
			}
			if err != nil {
				ureq.Status = TaskStatusStateFailed
				ureq.ErrMsg = err.Error()
			} else if stopped {
				ureq.Status = TaskStatusStateStop
				ureq.ErrMsg = "已停止"
			} else {
				ureq.Status = TaskStatusStateFinish
				ureq.ErrMsg = "success"
			}
			rpc_apis.Management.ManagementUpdateTryApiTask(utils.NewContextFromBeegoCtx(u.Ctx), &ureq)
			taskDecrease()
		}()

		resp := param_v1_0.ManagementCreateTryApiTaskResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

// @Title create api task
// @Description 测试api调用
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   data    body  params.param_v1_0.ManagementChangeApiTaskBody true ""
// @Success 200 	{object} params.param_v1_0.params.param_v1_0.ManagementTryBaseApiResp "响应信息"
// @Failure 500 	服务器错误
// @router /try_api_task [put]
func (u *BaseApiController) ManagementChangeApiTaskState() {
	u.LogID = fmt.Sprintf("ManagementChangeApiTaskState[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementChangeApiTaskStateReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		// 停止任务
		var headMap map[string]string
		if !req.Data.EnglishHeader {
			hReq := gd_management.ManagementGetBaseApiByRouterReq{}
			//hReq.Router = req.Data.Router
			//hReq.Method = req.Data.Method
			hReply, err := rpc_apis.Management.ManagementGetBaseApiByRouter(utils.NewContextFromBeegoCtx(u.Ctx), &hReq)
			if err != nil {
				l.Error("rpc",
					zap.String("call", "ManagementGetBaseApiByRouter"),
					zap.String("args", utils.MarshalJsonString(req)),
					zap.String("error", err.Error()))
				//return errors.ErrorTransform(err)
			} else {
				headMap = hReply.Data
			}
		}

		taskReply, err := getTaskInfo(req.Data.TaskId)
		if err != nil {
			return err
		}
		if req.Data.StatusCode == TaskStatusFrontStateStop {
			if taskReply.Data.Status != TaskStatusStateRun {
				return jsonrpc2.NewJsonError(10003, "当前任务未运行")
			}
			ureq := gd_management.ManagementUpdateTryApiTaskReq{}
			ureq.TaskId = req.Data.TaskId
			ureq.Status = TaskStatusStateStopping
			rpc_apis.Management.ManagementUpdateTryApiTask(utils.NewContextFromBeegoCtx(u.Ctx), &ureq)
			_, err := cache.Redis.Publish(BatchApiStopNotifyChannel, fmt.Sprintf("%d", req.Data.TaskId))
			if err != nil {
				return errors.DataBaseError
			}
			resp := param_v1_0.ManagementChangeApiTaskStateResp{
				SimpleResp: param_base.SimpleResp{
					Code: 0,
					Msg:  "SUCCESS",
				},
			}
			httper.JSON(u.Ctx, resp, u.LogID)
			return nil
		}

		// 启动任务
		originInfo, err := getOriginTaskInfo(req.Data.TaskId, taskReply)
		if err != nil {
			return err
		}
		if originInfo.Status != TaskStatusStateStop {
			return jsonrpc2.NewJsonError(10003, "该任务无法启动")
		}
		newFileName := originInfo.NewFile
		ureq := gd_management.ManagementUpdateTryApiTaskReq{}
		ureq.TaskId = req.Data.TaskId
		ureq.Status = TaskStatusStateRun
		rpc_apis.Management.ManagementUpdateTryApiTask(utils.NewContextFromBeegoCtx(u.Ctx), &ureq)

		go func() {
			info := batchApiInfo{
				filename:        originInfo.OriginFile,
				method:          originInfo.Req.Method,
				isCrypto:        originInfo.Req.IsCrypto,
				appKey:          originInfo.Req.AppKey,
				appSecret:       originInfo.Req.AppSecret,
				router:          originInfo.Req.Router,
				appPassword:     originInfo.Req.AppPassword,
				MerchantAccount: originInfo.Req.MerchantAccount,
				NewFileName:     originInfo.NewFile,
				NewFilePath:     originInfo.NewFilePath,
				taskId:          fmt.Sprintf("%d", req.Data.TaskId),
				EncryptoType:originInfo.Req.EncryptoType,
			}
			taskIncrease()
			stopped, err := batchTryApi(&info, originInfo.Req.MultiNumber, headMap)
			ureq := gd_management.ManagementUpdateTryApiTaskReq{}
			ureq.TaskId = req.Data.TaskId
			ureq.DownloadFile = "http://" + ServerIp + ":" + ServerPort + "/try_api_task_dir/" + newFileName
			if true {
				ureq.DownloadFile = getOssFileUrl(newFileName)
			}
			if err != nil {
				ureq.Status = TaskStatusStateFailed
				ureq.ErrMsg = err.Error()
			} else if stopped {
				ureq.Status = TaskStatusStateStop
				ureq.ErrMsg = "已停止"
			} else {
				ureq.Status = TaskStatusStateFinish
				ureq.ErrMsg = "success"
			}
			rpc_apis.Management.ManagementUpdateTryApiTask(utils.NewContextFromBeegoCtx(u.Ctx), &ureq)
			taskDecrease()
		}()

		resp := param_v1_0.ManagementCreateTryApiTaskResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

type originTaskInfo struct {
	OriginFile    string
	OriginPath    string
	OriginFilePtr *xlsx.File
	NewFile       string
	NewFilePath   string
	NewFilePtr    *xlsx.File
	Rows          int
	Status        int
	Req           *param_v1_0.ManagementCreateTryApiTaskReq
}

func getFile(path string, filePath string) error {
	request, err := http.NewRequest("GET", path, bytes.NewReader(nil))
	if err != nil {
		return err
	}
	tr := &http.Transport{
		TLSClientConfig:   &tls.Config{InsecureSkipVerify: true},
		DisableKeepAlives: true,
	}
	client := http.Client{
		Transport: tr,
		Timeout:   60 * time.Second,
	}
	resp, err := client.Do(request)
	if err != nil {
		return err
	}
	if resp.Body == nil {
		return nil
	}
	defer resp.Body.Close()
	f, err := os.OpenFile(filePath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
	if err != nil {
		return err
	}
	defer f.Close()
	io.Copy(f, resp.Body)
	return nil
}

func getFileNameFromUrl(path string) string {
	array := strings.Split(path, "/")
	length := len(array)
	if length < 1 {
		return ""
	}
	return array[length-1]
}

func isFileExist(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	return false
}

func getTaskInfo(taskId int64) (*gd_management.ManagementGetApiTaskReply, error) {

	mreq := gd_management.ManagementGetApiTaskReq{TaskId: taskId}
	mreply, err := rpc_apis.Management.ManagementGetApiTask(context.Background(), &mreq)
	if err != nil {
		return nil, err
	}
	return &mreply, nil
}

func getOriginTaskInfo(taskId int64, mreply *gd_management.ManagementGetApiTaskReply) (*originTaskInfo, error) {

	if mreply.Data.RequestInfo == "" || mreply.Data.OriginFile == "" || mreply.Data.DownloadFile == "" {
		return nil, jsonrpc2.NewJsonError(10003, "任务文件信息")
	}

	originReq := param_v1_0.ManagementCreateTryApiTaskReq{}
	json.Unmarshal([]byte(mreply.Data.RequestInfo), &originReq)
	ret := originTaskInfo{}
	ret.Status = mreply.Data.Status
	ret.Req = &originReq
	ret.NewFile = getFileNameFromUrl(mreply.Data.DownloadFile)
	ret.OriginFile = getFileNameFromUrl(mreply.Data.OriginFile)
	ret.NewFilePath = beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + ret.NewFile
	ret.OriginPath = beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + ret.OriginPath

	if isFileExist(ret.NewFilePath) == false || isFileExist(ret.OriginPath) == false {
		if err := getFile(mreply.Data.DownloadFile, ret.NewFilePath); err != nil {
			return nil, jsonrpc2.NewJsonError(20317, fmt.Sprintf("获取文件失败:%s", err.Error()))
		}
		if err := getFile(mreply.Data.OriginFile, ret.OriginPath); err != nil {

			return nil, jsonrpc2.NewJsonError(20317, fmt.Sprintf("获取文件失败:%s", err.Error()))
		}
	}

	return &ret, nil
}

/*
// @Title upload file
// @Description 上传跑批数据
// @Failure 500 	服务器错误
// @router /try_api_task_file [post]
func (u *BaseApiController) ManagementUploadTryBaseApiTask() {
	uploadTask := func() error {
		resp := param_v1_0.ManagementUploadApiTaskResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		f, h, err := u.GetFile("file")
		if err != nil {
			return errors.ArgsError
		}
		defer f.Close()
		array := strings.Split(h.Filename, ".")
		newfile := array[0] + fmt.Sprintf("%d", time.Now().Unix()) + ".xlsx"
		filename := beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + newfile
		fmt.Printf("filename:%s\n", filename)
		file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR|os.O_TRUNC, 0666)
		if err != nil {
			return errors.FileOpenFailed
		}
		defer file.Close()
		var msg [1024]byte
		for {
			n, err := f.Read(msg[:])
			if err == io.EOF {
				break
			}
			if err != nil {
				return errors.ServiceError
			}
			file.Write(msg[:n])
		}
		resp.FileName = newfile
		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		uploadTask,
	)
}
*/

const (
	TaskStatusStateRun           = 0
	TaskStatusStateFinish        = 1
	TaskStatusStateStop          = 2
	TaskStatusStateStopping      = 3
	TaskStatusStateFailed        = -1
	TaskStatusFrontStateRun      = 1
	TaskStatusFrontStateFinish   = 2
	TaskStatusFrontStateStop     = 3
	TaskStatusFrontStateFailed   = 4
	TaskStatusFrontStateStopping = 5
)

// 后端到前端的映射
var taskStatusBtoF = map[int]int{
	// 进行中
	TaskStatusStateRun: TaskStatusFrontStateRun,
	// 完成
	TaskStatusStateFinish: TaskStatusFrontStateFinish,
	// 停止
	TaskStatusStateStop: TaskStatusFrontStateStop,
	// 正在暂停
	TaskStatusStateStopping: TaskStatusFrontStateStopping,
	// 失败
	TaskStatusStateFailed: TaskStatusFrontStateFailed,
}

var taskStatusMsg = map[int]string{
	// 进行中
	TaskStatusStateRun: "进行中",
	// 完成
	TaskStatusStateFinish: "已完成",
	// 停止
	TaskStatusStateStop: "已停止",
	// 失败
	TaskStatusStateFailed: "失败",

	// 正在暂停
	TaskStatusStateStopping: "正在暂停",
}

var taskStatusFtoB = map[int]int{
	// 进行中
	TaskStatusFrontStateRun: TaskStatusStateRun,
	// 完成
	TaskStatusFrontStateFinish: TaskStatusStateFinish,
	// 停止
	TaskStatusFrontStateStop: TaskStatusStateStop,
	// 正在暂停
	TaskStatusFrontStateStopping: TaskStatusStateStopping,
	// 失败
	TaskStatusFrontStateFailed: TaskStatusStateFailed,
}

// convertTaskFileName去掉文件后的时间戳后缀
func convertTaskFileName(src string) string {
	tail := ""
	if strings.Contains(src, ".xlsx") {
		src = strings.TrimRight(src, ".xlsx")
		tail = ".xlsx"
	}
	length := len([]byte(src))
	if length <= 10 {
		return src
	}
	timestampString := string([]byte(src)[length-10:])
	_, err := strconv.ParseInt(timestampString, 10, 64)
	if err != nil {
		return src
	}
	return string([]byte(src)[:length-10]) + tail
}

// @Title get api task list
// @Description api跑批任务列表
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   is_all    query   bool true ""
// @Param   page_number query int true ""
// @Param   page_size query int false ""
// @Param   api_name query string false ""
// @Param   type query int false "类型：1、平台接口，2、数据源"
// @Success 200 	{object} params.param_v1_0.ManagementGetTryApiTaskListResp "响应信息"
// @Failure 500 	服务器错误
// @router /try_api_task_list [get]
func (u *BaseApiController) ManagementGetTryApiTaskList() {
	u.LogID = fmt.Sprintf("ManagementGetTryApiTaskList[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementGetTryApiTaskListReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementGetTryApiTaskListReq{}
		mreq.PageNumber = req.PageNumber
		mreq.IsAll = req.IsAll
		mreq.ApiName = req.ApiName
		mreq.Type = req.Type
		mreq.PageSize = req.PageSize

		reply, err := rpc_apis.Management.ManagementGetTryApiTaskList(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetTryApiTaskList"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}

		resp := param_v1_0.ManagementGetTryApiTaskListResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		for i, v := range reply.Tasks {

			reply.Tasks[i].StatusCode, _ = taskStatusBtoF[v.StatusCode]
			reply.Tasks[i].Status, _ = taskStatusMsg[v.StatusCode]
			reply.Tasks[i].FileName = strings.TrimPrefix(v.FileName, "batch_result_")
			reply.Tasks[i].TaskName = strings.TrimPrefix(v.TaskName, "batch_result_")
			reply.Tasks[i].FileName = convertTaskFileName(reply.Tasks[i].FileName)
			reply.Tasks[i].TaskName = convertTaskFileName(reply.Tasks[i].TaskName)
		}
		resp.Data = reply
		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

func delLocalTryApiFile(downloadFile string, originFile string) {
	downFile := getFileNameFromUrl(downloadFile)
	originFile = getFileNameFromUrl(originFile)
	if downFile != "" {
		path := beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + downFile
		os.Remove(path)
		cache.Redis.Publish(BatchRemoveFileNotifyChannel, path)
	}
	if originFile != "" {
		path := beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + originFile
		os.Remove(path)
		cache.Redis.Publish(BatchRemoveFileNotifyChannel, path)
	}
}

func delLocalTryProviderFile(downloadFile string) {
	u, err := url.Parse(downloadFile)
	if err != nil {
		return
	}
	os.Remove(u.Path)
	cache.Redis.Publish(BatchRemoveFileNotifyChannel, u.Path)
}

func delLocalTryFile(downloadFile string, originFile string, taskType int) {
	if taskType == 1 {
		delLocalTryApiFile(downloadFile, originFile)
		return
	}
	delLocalTryProviderFile(downloadFile)
}

// @Title del api task
// @Description 删除api跑批任务
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   task_id    query   int true ""
// @Success 200 	{object} params.param_v1_0.ManagementDeleteTryApiTaskResp "响应信息"
// @Failure 500 	服务器错误
// @router /try_api_task [delete]
func (u *BaseApiController) ManagementDeleteTryApiTask() {
	u.LogID = fmt.Sprintf("ManagementDeleteTryApiTask[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementDeleteTryApiTaskReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementDeleteTryApiTaskReq{}
		mreq.TaskId = req.TaskId
		cache.Redis.Publish(BatchApiStopNotifyChannel, fmt.Sprintf("%d", req.TaskId))
		reply, err := rpc_apis.Management.ManagementDeleteTryApiTask(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementDeleteTryApiTask"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		if reply.DownloadFile != "" && reply.TaskType > 0 {
			delLocalTryFile(reply.DownloadFile, reply.OriginFile, reply.TaskType)
		}

		resp := param_v1_0.ManagementDeleteTryApiTaskResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

// @Title set base api waring threshold
// @Description 设置api告警阀值
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_id  path int64 true ""
// @Param   body  body param_v1_0.ManagementSetBaseApiThresholdBody true ""
// @Success 200 	{object} params.param_v1_0.ManagementSetBaseApiThresholdResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_threshold/:api_id [put]
func (u *BaseApiController) ManagementSetBaseApiThreshold() {
	u.LogID = fmt.Sprintf("ManagementSetBaseApiThreshold[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementSetBaseApiThresholdReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	// 加入用户行为日志
	AddActionLogTask := func() error {
		// 获取api信息
		mreq := gd_management.ManagementGetBaseApiInfoReq{
			ApiId: req.ApiId,
		}

		reply, err := rpc_apis.Management.ManagementGetBaseApiInfo(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementGetBaseApiInfo"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}

		// 构建json
		bmap := map[string]interface{}{
			"threshold_timeout":       reply.BaseApiInfo.ThresholdTimeout,
			"threshold_fail_rate":     reply.BaseApiInfo.ThresholdFailRate,
			"threshold_norecord_rate": reply.BaseApiInfo.ThresholdNorecordRate,
		}
		beforeBytes, _ := json.Marshal(bmap)
		contentBytes, _ := json.Marshal(req.Body)

		areq := gd_admin.AddActionLogReq{
			Uid:        req.Uid,
			Name:       reply.BaseApiInfo.Name,
			Modules:    "基础API",
			Func:       "设置api告警阀值",
			Before:     string(beforeBytes),
			Content:    string(contentBytes),
			ModifyTime: time.Now().Format("2006-01-02 15:04:05"),
		}

		err = AddActionLog(areq)
		if err != nil {
			return err
		}

		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementSetBaseApiThresholdReq{}
		mreq.ApiId = req.ApiId
		mreq.ThresholdFailRate = req.Body.ThresholdFailRate
		mreq.ThresholdNorecordRate = req.Body.ThresholdNorecordRate
		mreq.ThresholdTimeout = req.Body.ThresholdTimeout
		mreq.WarningEnable = req.Body.WarningEnable
		mreq.RateLimit = req.Body.RateLimit

		_, err := rpc_apis.Management.ManagementSetBaseApiThreshold(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementSetBaseApiThreshold"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementSetBaseApiThresholdResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, AddActionLogTask, handleDataTask,
	)
}

// @Title excel template
// @Description 跑批数据 excel 模板
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Success 200 	{object} params.param_v1_0.ManagementTryApiExcelResp "响应信息"
// @Failure 500 	服务器错误
// @router /try_api_excel_template [get]
func (u *BaseApiController) ManagementTryApiExcel() {
	u.LogID = fmt.Sprintf("ManagementTryApiExcel[%d]", time.Now().UnixNano())

	handleDataTask := func() error {
		file := xlsx.NewFile()
		sheet, _ := file.AddSheet("模板")
		for i := 0; i < 4; i++ {
			row := sheet.AddRow()
			if i == 0 {
				row.AddCell().Value = "plate_no"
				row.AddCell().Value = "plate_type"
				row.AddCell().Value = "vin"
				row.AddCell().Value = "engine_no"
				continue
			}
			row.AddCell().Value = "川A123XX"
			row.AddCell().Value = "02"
			row.AddCell().Value = "LXGXXXXXXXXXX"
			row.AddCell().Value = "123456"
		}
		filename := beego.BConfig.WebConfig.StaticDir["/try_api_task_dir"] + "template.xlsx"
		file.Save(filename)
		if true {
			utils.OssUploadFile(filename, "template.xlsx")
		}

		resp := param_v1_0.ManagementTryApiExcelResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		resp.FileName = "http://" + ServerIp + ":" + ServerPort + "/try_api_task_dir/template.xlsx"
		if true {
			resp.FileName = getOssFileUrl("template.xlsx")
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		handleDataTask,
	)
}

// @Title is show in report
// @Description 报表是否展示该api
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Param   api_id    path   int true "api id"
// @Param   show_info    body   params.param_v1_0.ManagementBaseApiShowInfo true "api信息"
// @Success 200 	{object} params.param_v1_0.ManagementSetBaseApiShowInfoResp "响应信息"
// @Failure 500 	服务器错误
// @router /base_api_show_info/:api_id [put]
func (u *BaseApiController) ManagementSetBaseApiShowInfo() {
	u.LogID = fmt.Sprintf("ManagementSetBaseApiShowInfo[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementSetBaseApiShowInfoReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		mreq := gd_management.ManagementSetBaseApiShowInfoReq{}
		mreq.ApiId = req.ApiId
		mreq.IsShow = req.BaseApiShowInfo.IsShow
		_, err := rpc_apis.Management.ManagementSetBaseApiShowInfo(utils.NewContextFromBeegoCtx(u.Ctx), &mreq)
		if err != nil {
			l.Error("rpc",
				zap.String("call", "ManagementSetBaseApiShowInfo"),
				zap.String("args", utils.MarshalJsonString(req)),
				zap.String("error", err.Error()))
			return errors.ErrorTransform(err)
		}
		resp := param_v1_0.ManagementSetBaseApiShowInfoResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}

// @Title get param type list
// @Description 获取参数类型列表
// @Param   token    header   string true "token"
// @Param   uid    header   string true "uid"
// @Success 200 	{object} params.param_v1_0.ManagementGetBaseApiParamTypeListResp "响应信息"
// @Failure 500 	服务器错误
// @router /param_type_list [get]
func (u *BaseApiController) ManagementGetBaseApiParamTypeList() {
	u.LogID = fmt.Sprintf("ManagementGetBaseApiParamTypeList[%d]", time.Now().UnixNano())

	req := &param_v1_0.ManagementGetBaseApiParamTypeListReq{}
	getParamsTask := func() error {
		httper.FillRequireParams(u.Ctx, req, u.LogID)
		return nil
	}

	handleDataTask := func() error {
		resp := param_v1_0.ManagementGetBaseApiParamTypeListResp{
			SimpleResp: param_base.SimpleResp{
				Code: 0,
				Msg:  "SUCCESS",
			},
		}
		resp.TypeList = []string{
			"bool",
			"int",
			"string",
			"float",
			"struct",
			"list-int",
			"list-string",
			"list-bool",
			"list-float",
			"list-struct",
		}

		httper.JSON(u.Ctx, resp, u.LogID)
		return nil
	}

	// 执行以上定义的任务
	task.Do(&task.PanicRecover{
		Ctx:   u.Ctx,
		LogID: u.LogID}, u.Ctx,
		getParamsTask, handleDataTask,
	)
}
