package sandbox

import (
	"encoding/json"
	"eta/eta_api/controllers"
	"eta/eta_api/models"
	"eta/eta_api/models/data_manage"
	"eta/eta_api/models/sandbox"
	"eta/eta_api/models/sandbox/request"
	"eta/eta_api/models/sandbox/response"
	sandboxService "eta/eta_api/services/sandbox"
	"eta/eta_api/utils"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"time"
)

// versionSize 版本列表第一页数据约定是：3条
var versionSize = 3

// SandboxController 逻辑导图
type SandboxController struct {
	controllers.BaseAuthController
}

// List
// @Title 逻辑导图列表
// @Description 逻辑导图列表接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码，从1开始"
// @Param   ChartPermissionId   query   int  true       "权限编号id"
// @Param   Keyword   query   string  false       "搜索关键词:沙盘名称/编辑人名称"
// @Success 200 {object} response.SandboxListResp
// @router /list [get]
//func (this *SandboxController) List() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//
//	chartPermissionId, _ := this.GetInt("ChartPermissionId")
//	keyword := this.GetString("Keyword")
//
//	pageSize, _ := this.GetInt("PageSize")
//	currentIndex, _ := this.GetInt("CurrentIndex")
//
//	var startSize int
//	if pageSize <= 0 {
//		pageSize = utils.PageSize20
//	}
//	if currentIndex <= 0 {
//		currentIndex = 1
//	}
//	startSize = paging.StartIndex(currentIndex, pageSize)
//
//	var condition string
//	var pars []interface{}
//
//	if chartPermissionId > 0 {
//		condition += " AND a.chart_permission_id=? "
//		pars = append(pars, chartPermissionId)
//	}
//
//	if keyword != "" {
//		condition += ` AND  ( a.name LIKE '%` + keyword + `%'  OR  b.name LIKE '%` + keyword + `%' )`
//	}
//
//	//获取指标信息
//	total, list, err := sandbox.GetList(condition, pars, startSize, pageSize)
//	if err != nil && err.Error() != utils.ErrNoRow() {
//		br.Success = true
//		br.Msg = "获取沙盘列表失败"
//		br.ErrMsg = "获取沙盘列表失败,Err:" + err.Error()
//		return
//	}
//
//	if list == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
//		list = make([]*sandbox.SandboxListItem, 0)
//	}
//
//	if len(list) > 0 {
//		sandboxIdList := make([]int, 0)
//		for _, v := range list {
//			sandboxIdList = append(sandboxIdList, v.SandboxId)
//		}
//
//		sandboxVersionTotalList, err := sandbox.GetTotalSandboxVersionBySandboxIdList(sandboxIdList)
//		if err != nil {
//			br.Success = true
//			br.Msg = "获取沙盘版本数量失败"
//			br.ErrMsg = "获取沙盘版本数量失败,Err:" + err.Error()
//			return
//		}
//		sandboxVersionTotalMap := make(map[int]int)
//
//		for _, v := range sandboxVersionTotalList {
//			sandboxVersionTotalMap[v.SandboxId] = v.Total
//		}
//
//		for _, item := range list {
//			/*key := fmt.Sprint(`crm:sandbox:edit:`, item.SandboxId)
//			opUserId, _ := utils.Rc.RedisInt(key)
//			//如果当前没有人操作，获取当前操作人是本人，那么编辑按钮可用
//			if opUserId <= 0 || (opUserId == this.SysUser.AdminId) {
//				item.CanEdit = true
//			} else {
//				adminInfo, errAdmin := system.GetSysUserById(opUserId)
//				if errAdmin != nil {
//					br.Msg = "获取失败"
//					br.ErrMsg = "获取失败，Err:" + errAdmin.Error()
//					return
//				}
//				item.Editor = adminInfo.RealName
//			}*/
//			markStatus, err := sandboxService.UpdateSandboxEditMark(item.SandboxId, this.SysUser.AdminId, 2, this.SysUser.RealName)
//			if err != nil {
//				br.Msg = "查询标记状态失败"
//				br.ErrMsg = "查询标记状态失败，Err:" + err.Error()
//				return
//			}
//			if markStatus.Status == 0 {
//				item.CanEdit = true
//			} else {
//				item.Editor = markStatus.Editor
//			}
//
//			// 沙盘版本数量
//			versionTotal := sandboxVersionTotalMap[item.SandboxId]
//			item.VersionTotal = versionTotal
//		}
//	}
//
//	page := paging.GetPaging(currentIndex, pageSize, total)
//	resp := response.SandboxListResp{
//		Paging: page,
//		List:   list,
//	}
//	br.Ret = 200
//	br.Success = true
//	br.Msg = "获取成功"
//	br.Data = resp
//}

// FirstVersionList
// @Title 逻辑导图版本列表（列表页第一页）
// @Description 逻辑导图版本列表接口（列表页第一页）
// @Param   SandboxId   query   int  true       "沙盘id"
// @Success 200 {object} response.SandboxVersionListResp
// @router /version/first_list [get]
func (this *SandboxController) FirstVersionList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sandboxId, _ := this.GetInt("SandboxId")
	keyword := this.GetString("Keyword")

	currentIndex := 1
	pageSize := versionSize
	startSize := 0

	var condition string
	var pars []interface{}

	if sandboxId <= 0 {
		br.Msg = "参数错误，沙盘编号id必传！"
		br.ErrMsg = "参数错误，沙盘编号id必传"
		return
	}
	condition += " AND a.sandbox_id=? "
	pars = append(pars, sandboxId)

	//不能筛选出当前版本
	condition += " AND b.curr_version < a.curr_version "

	if keyword != "" {
		condition += ` AND  ( a.name LIKE ?  OR  b.name LIKE ? )`
		pars = utils.GetLikeKeywordPars(pars, keyword, 2)
	}

	//获取指标信息
	total, list, err := sandbox.GetVersionList(condition, pars, startSize, pageSize)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Success = true
		br.Msg = "获取沙盘列表失败"
		br.ErrMsg = "获取沙盘列表失败,Err:" + err.Error()
		return
	}

	if list == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		list = make([]*sandbox.SandboxVersionListItem, 0)
	}
	for _, v := range list {
		v.ModifyTime = v.CreateTime
	}

	page := paging.GetPaging(currentIndex, pageSize, total)
	resp := response.SandboxVersionListResp{
		Paging: page,
		List:   list,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// VersionList
// @Title 逻辑导图版本列表
// @Description 逻辑导图版本列表接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码，从1开始"
// @Param   SandboxId   query   int  true       "沙盘id"
// @Success 200 {object} response.SandboxVersionListResp
// @router /version/list [get]
func (this *SandboxController) VersionList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sandboxId, _ := this.GetInt("SandboxId")
	keyWord := this.GetString("Keyword")

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	//第一页需要返回的几条数据（目前是3条）
	startSize = paging.StartIndex(currentIndex, pageSize) + versionSize

	var condition string
	var pars []interface{}

	if sandboxId <= 0 {
		br.Msg = "参数错误，沙盘编号id必传！"
		br.ErrMsg = "参数错误，沙盘编号id必传"
		return
	}
	condition += " AND a.sandbox_id=? "
	pars = append(pars, sandboxId)

	//不能筛选出当前版本
	condition += " AND b.curr_version < a.curr_version "

	if keyWord != "" {
		condition += ` AND  ( a.op_user_name LIKE ? OR  a.name LIKE ? or a.op_user_name LIKE ? OR  a.name LIKE ? )`
		pars = utils.GetLikeKeywordPars(pars, keyWord, 4)
	}

	//获取指标信息
	total, list, err := sandbox.GetVersionList(condition, pars, startSize, pageSize)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Success = true
		br.Msg = "获取沙盘列表失败"
		br.ErrMsg = "获取沙盘列表失败,Err:" + err.Error()
		return
	}

	if list == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		list = make([]*sandbox.SandboxVersionListItem, 0)
	}
	for _, v := range list {
		v.ModifyTime = v.CreateTime
		/*key := fmt.Sprint(`crm:sandbox:edit:`, v.SandboxId)
		opUserId, _ := utils.Rc.RedisInt(key)
		//如果当前没有人操作，获取当前操作人是本人，那么编辑按钮可用
		if opUserId <= 0 || (opUserId == this.SysUser.AdminId) {
			v.CanEdit = true
		}*/
		markStatus, err := sandboxService.UpdateSandboxEditMark(v.SandboxId, this.SysUser.AdminId, 2, this.SysUser.RealName)
		if err != nil {
			br.Msg = "查询标记状态失败"
			br.ErrMsg = "查询标记状态失败，Err:" + err.Error()
			return
		}
		if markStatus.Status == 0 {
			v.CanEdit = true
		}
	}

	//过滤第一页的几条数据（目前是3条）
	total = total - versionSize
	if total <= 0 {
		total = 0
	}
	page := paging.GetPaging(currentIndex, pageSize, total)
	resp := response.SandboxVersionListResp{
		Paging: page,
		List:   list,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

//// Save
//// @Title 新增/编辑保存沙盘
//// @Description 新增/编辑保存沙盘接口
//// @Param	request	body request.AddAndEditSandbox true "type json string"
//// @Success 200 {object} sandbox.Sandbox
//// @router /save [post]
//func (this *SandboxController) Save() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//	sysUser := this.SysUser
//	if sysUser == nil {
//		br.Msg = "请登录"
//		br.ErrMsg = "请登录，SysUser Is Empty"
//		br.Ret = 408
//		return
//	}
//	var req request.AddAndEditSandbox
//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
//	if err != nil {
//		br.Msg = "参数解析异常！"
//		br.ErrMsg = "参数解析失败，Err:" + err.Error()
//		return
//	}
//
//	var sandboxResp *sandbox.SandboxSaveResp
//	// 获取系统菜单, 如果没有对应的字段的特殊处理项, 则忽略必填
//	menus, e := system.GetSysMenuItemsByCondition(` AND hidden = 0`, make([]interface{}, 0), []string{}, ``)
//	if e != nil {
//		br.Msg = "保存失败"
//		br.ErrMsg = "获取菜单列表失败, Err: " + e.Error()
//		return
//	}
//	menuMap := make(map[string]bool)
//	for _, m := range menus {
//		if m.ButtonCode != "" {
//			menuMap[m.ButtonCode] = true
//		}
//	}
//	ignoreVariety := false
//	if !menuMap[system.MenuSpecialHandleSandboxVariety] {
//		ignoreVariety = true
//	}
//
//	var errMsg string
//	if req.SandboxVersionCode == `` {
//		//新增沙盘
//		sandboxResp, err = sandboxService.AddSandbox(req, sysUser.AdminId, sysUser.RealName, ignoreVariety)
//	} else {
//		////更新当前编辑中的状态缓存
//		//err = sandboxService.UpdateSandboxEditMark(req.SandboxId, sysUser.AdminId, 1)
//		//if err != nil {
//		//	br.Msg = err.Error()
//		//	return
//		//}
//
//		//编辑沙盘
//		sandboxResp, err, errMsg = sandboxService.UpdateSandbox(req, sysUser.AdminId, sysUser.RealName, ignoreVariety)
//	}
//	if err != nil {
//		br.Msg = "保存失败！"
//		if errMsg != `` {
//			br.Msg = errMsg
//		}
//		br.ErrMsg = "保存失败，Err:" + err.Error()
//		return
//	}
//
//	msg := "保存成功"
//	br.Ret = 200
//	br.Success = true
//	br.Msg = msg
//	br.Data = sandboxResp
//}

// AddSandboxDraft
// @Title 添加沙盘草稿
// @Description 添加沙盘草稿接口
// @Param	request	body request.AddAndEditSandbox true "type json string"
// @Success 200 {object} sandbox.SandboxDraft
// @Fail 202 另外的人在操作，不要重复添加草稿；204 错误了，当时不是必要性的错误，不用将错误信息暴露给用户
// @router /draft/add [post]
func (this *SandboxController) AddSandboxDraft() {
	br := new(models.BaseResponse).Init()
	br.IsSendEmail = false
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req request.AddAndEditSandbox
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.SandboxVersionCode == `` {
		br.Msg = "请传入沙盘版本！"
		return
	}

	// 获取沙盘版本信息
	sandboxVersion, err := sandbox.GetSandboxVersionBySandboxVersionCode(req.SandboxVersionCode)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "找不到该版本！"
			br.ErrMsg = "找不到该版本"
			return
		}
		br.Msg = "找不到该版本！"
		br.ErrMsg = "找不到该版本，Err:" + err.Error()
		br.IsSendEmail = false
		return
	}
	//更新标记key
	markStatus, err := sandboxService.UpdateSandboxEditMark(sandboxVersion.SandboxId, sysUser.AdminId, 1, sysUser.RealName)
	if err != nil {
		br.Msg = err.Error()
		return
	}
	if markStatus.Status == 1 {
		br.Msg = markStatus.Msg
		return
	}

	//新增沙盘草稿
	sandboxDraftInfo, err := sandboxService.AddSandboxDraft(sandboxVersion.SandboxId, req, sysUser.AdminId, sysUser.RealName)
	if err != nil {
		br.Msg = "保存失败！"
		br.ErrMsg = "保存失败，Err:" + err.Error()
		br.Ret = 204 //204 （无内容） ：服务器成功处理了请求，但没有返回任何内容。
		return
	}
	msg := "保存成功"
	br.Ret = 200
	br.Success = true
	br.Msg = msg
	br.Data = sandboxDraftInfo
}

// MarkEditStatus
// @Title 标记沙盘编辑状态
// @Description 标记沙盘编辑状态接口
// @Param	request	body request.MarkEditSandbox true "type json string"
// @Success 200 标记成功 ；202 标记成功
// @router /mark [post]
func (this *SandboxController) MarkEditStatus() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req request.MarkEditSandbox
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.SandboxId <= 0 {
		br.Msg = "缺少沙盘编号"
		return
	}
	if req.Status <= 0 {
		br.Msg = "标记状态异常"
		return
	}
	//更新标记key
	data, err := sandboxService.UpdateSandboxEditMark(req.SandboxId, sysUser.AdminId, req.Status, sysUser.RealName)
	if err != nil {
		br.Msg = err.Error()
		return
	}

	msg := "标记成功"
	br.Ret = 200
	br.Success = true
	br.Msg = msg
	br.Data = data
}

// GetSandboxVersionDetail
// @Title 获取沙盘版本数据详情（已保存的）
// @Description 获取沙盘版本数据详情接口（已保存的）
// @Param   SandboxVersionCode   query   string  true       "沙盘版本code"
// @Success 200 {object} sandbox.SandboxVersion
// @router /version/detail [get]
func (this *SandboxController) GetSandboxVersionDetail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	sandboxVersionCode := this.GetString("SandboxVersionCode")
	if sandboxVersionCode == "" {
		br.Msg = "缺少沙盘版本编号"
		return
	}

	//获取沙盘数据详情（已保存的）
	sandboxVersionInfo, err := sandboxService.GetSandboxVersionDetailByCode(sandboxVersionCode)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err：" + err.Error()
		return
	}
	msg := "获取成功"
	br.Ret = 200
	br.Success = true
	br.Msg = msg
	br.Data = sandboxVersionInfo
}

// GetLastSandboxInfo
// @Title 获取最后一次编辑的沙盘数据详情
// @Description 获取最后一次编辑的沙盘数据详情接口
// @Param   SandboxId   query   int  true       "沙盘编号id"
// @Success 200 {object} sandbox.Sandbox
// @router /last_info [get]
func (this *SandboxController) GetLastSandboxInfo() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	sandboxId, _ := this.GetInt("SandboxId", 0)
	if sandboxId <= 0 {
		br.Msg = "缺少沙盘编号"
		return
	}

	//获取最后一次操作的沙盘数据
	sandboxInfo, err := sandboxService.GetLastSandboxInfo(sandboxId)
	if err != nil {
		br.Msg = err.Error()
		return
	}
	msg := "获取成功"
	br.Ret = 200
	br.Success = true
	br.Msg = msg
	br.Data = sandboxInfo
}

// Delete
// @Title 删除沙盘
// @Description 删除沙盘接口
// @Param	request	body request.DeleteSandbox true "type json string"
// @Success 200 标记成功
// @router /delete [post]
func (this *SandboxController) Delete() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req request.DeleteSandbox
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.SandboxId <= 0 {
		br.Msg = "缺少沙盘编号"
		return
	}

	/*key := fmt.Sprint(`crm:sandbox:edit:`, req.SandboxId)
	opUserId, _ := utils.Rc.RedisInt(key)
	//如果当前有人操作，且获取当前操作人不是本人，那么不允许删除
	if opUserId > 0 && opUserId != this.SysUser.AdminId {
		br.Msg = "当前有其他人正在编辑，不允许删除该沙盘"
		return
	}*/
	markStatus, err := sandboxService.UpdateSandboxEditMark(req.SandboxId, this.SysUser.AdminId, 2, this.SysUser.RealName)
	if err != nil {
		br.Msg = "查询标记状态失败"
		br.ErrMsg = "查询标记状态失败，Err:" + err.Error()
		return
	}
	if markStatus.Status == 1 {
		br.Msg = fmt.Sprintf("当前%s正在编辑，不允许删除该沙盘", markStatus.Editor)
		return
	}

	//删除沙盘
	err = sandboxService.DeleteSandbox(req.SandboxId)
	if err != nil {
		br.Msg = err.Error()
		return
	}

	msg := "删除成功"
	br.Ret = 200
	br.Success = true
	br.Msg = msg
}

//// DeleteVersion
//// @Title 删除沙盘版本
//// @Description 删除沙盘版本接口
//// @Param	request	body request.DeleteSandbox true "type json string"
//// @Success 200 标记成功
//// @router /version/delete [post]
//func (this *SandboxController) DeleteVersion() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//	sysUser := this.SysUser
//	if sysUser == nil {
//		br.Msg = "请登录"
//		br.ErrMsg = "请登录，SysUser Is Empty"
//		br.Ret = 408
//		return
//	}
//	var req request.DeleteSandboxVersion
//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
//	if err != nil {
//		br.Msg = "参数解析异常！"
//		br.ErrMsg = "参数解析失败，Err:" + err.Error()
//		return
//	}
//
//	if req.SandboxVersionCode == `` {
//		br.Msg = "缺少沙盘版本号"
//		return
//	}
//	//删除沙盘
//	err, errMsg := sandboxService.DeleteSandboxVersion(req.SandboxVersionCode, this.SysUser.AdminId)
//	if err != nil {
//		br.Msg = "删除版本失败"
//		if errMsg != `` {
//			br.Msg = errMsg
//		}
//		br.ErrMsg = err.Error()
//		return
//	}
//
//	msg := "删除成功"
//	br.Ret = 200
//	br.Success = true
//	br.Msg = msg
//}

//// ResetDraftToLastVersion
//// @Title 重置沙盘草稿至最新版本
//// @Description 重置沙盘草稿至最新版本接口
//// @Param	request	body request.DeleteSandbox true "type json string"
//// @Success 200 {object} sandbox.SandboxDraft
//// @Fail 202 另外的人在操作，不要重复添加草稿；204 错误了，当时不是必要性的错误，不用将错误信息暴露给用户
//// @router /draft/reset [post]
//func (this *SandboxController) ResetDraftToLastVersion() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//	sysUser := this.SysUser
//	if sysUser == nil {
//		br.Msg = "请登录"
//		br.ErrMsg = "请登录，SysUser Is Empty"
//		br.Ret = 408
//		return
//	}
//	var req request.DeleteSandbox
//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
//	if err != nil {
//		br.Msg = "参数解析异常！"
//		br.ErrMsg = "参数解析失败，Err:" + err.Error()
//		return
//	}
//
//	if req.SandboxId <= 0 {
//		br.Msg = "缺少沙盘编号"
//		return
//	}
//
//	//更新标记key
//	markStatus, err := sandboxService.UpdateSandboxEditMark(req.SandboxId, sysUser.AdminId, 0, sysUser.RealName)
//	if err != nil {
//		br.Msg = err.Error()
//		return
//	}
//	if markStatus.Status == 1 {
//		br.Msg = markStatus.Msg
//		return
//	}
//
//	//重置沙盘草稿至最新版本
//	sandboxDraftInfo, err := sandboxService.ResetDraftToLastVersion(req.SandboxId, sysUser.AdminId, sysUser.RealName)
//	if err != nil {
//		br.Msg = "保存失败！"
//		br.ErrMsg = "保存失败，Err:" + err.Error()
//		return
//	}
//	msg := "保存成功"
//	br.Ret = 200
//	br.Success = true
//	br.Msg = msg
//	br.Data = sandboxDraftInfo
//}

// ListByQuote
// @Title 逻辑导图列表（其他地方引用到的，莫名其妙要根据输入的关键字匹配品种）
// @Description 逻辑导图列表接口（其他地方引用到的，莫名其妙要根据输入的关键字匹配品种）
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码，从1开始"
// @Param   ChartPermissionId   query   int  true       "权限编号id"
// @Param   Keyword   query   string  false       "搜索关键词:沙盘名称/编辑人名称"
// @Success 200 {object} response.SandboxListResp
// @router /list_by_quote [get]
func (this *SandboxController) ListByQuote() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	chartPermissionId, _ := this.GetInt("ChartPermissionId")
	keyword := this.GetString("Keyword")

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = paging.StartIndex(currentIndex, pageSize)

	var condition string
	var pars []interface{}

	if chartPermissionId > 0 {
		condition += " AND a.chart_permission_id=? "
		pars = append(pars, chartPermissionId)
	}

	if keyword != "" {
		condition += ` AND  ( a.name LIKE ? OR  a.chart_permission_name LIKE ? )`
		pars = utils.GetLikeKeywordPars(pars, keyword, 2)
	}

	//获取指标信息
	total, list, err := sandbox.GetList(condition, pars, startSize, pageSize)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Success = true
		br.Msg = "获取沙盘列表失败"
		br.ErrMsg = "获取沙盘列表失败,Err:" + err.Error()
		return
	}

	if list == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
		list = make([]*sandbox.Sandbox, 0)
	}

	page := paging.GetPaging(currentIndex, pageSize, total)
	resp := response.SandboxListResp{
		Paging: page,
		List:   list,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// SandboxClassifyItems
// @Title 获取所有沙盘分类接口-包含沙盘
// @Description 获取所有沙盘分类接口-包含沙盘
// @Param   IsShowMe   query   bool  true       "是否只看我的，true、false"
// @Success 200 {object} data_manage.ChartClassifyListResp
// @router /classify/list [get]
func (this *SandboxController) SandboxClassifyItems() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	resp := new(sandbox.SandboxClassifyListResp)
	sandboxClassifyId, _ := this.GetInt("SandboxClassifyId")

	isShowMe, _ := this.GetBool("IsShowMe")
	if isShowMe {
		errMsg, err := sandboxService.GetSandboxClassifyListForMe(*this.SysUser, resp, sandboxClassifyId)
		if err != nil {
			br.Msg = errMsg
			br.ErrMsg = err.Error()
			return
		}
		// 移除没有权限的图表
		//allNodes := sandboxService.HandleNoPermissionSandbox(resp.AllNodes, nil)
		//resp.AllNodes = allNodes

		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		br.Data = resp
		fmt.Println("source my classify")
		return
	}

	rootList, err := sandbox.GetSandboxClassifyAndInfoByParentId(sandboxClassifyId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败，Err:" + err.Error()
		return
	}

	classifyAll, err := sandbox.GetSandboxClassifyAndInfoByParentId(sandboxClassifyId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败，Err:" + err.Error()
		return
	}

	//sandboxAll, err := sandbox.GetSandboxItemsByClassifyId(sandboxClassifyId)
	//if err != nil && err.Error() != utils.ErrNoRow() {
	//	br.Msg = "获取失败"
	//	br.ErrMsg = "获取数据失败，Err:" + err.Error()
	//	return
	//}

	//sandListMap := make(map[int][]*sandbox.SandboxClassifyItems)
	//for _, v := range sandboxAll {
	//	if _, ok := sandListMap[v.SandboxClassifyId]; !ok {
	//		list := make([]*sandbox.SandboxClassifyItems, 0)
	//		list = append(list, v)
	//		sandListMap[v.SandboxClassifyId] = list
	//	} else {
	//		sandListMap[v.SandboxClassifyId] = append(sandListMap[v.SandboxClassifyId], v)
	//	}
	//}

	nodeAll := make([]*sandbox.SandboxClassifyItems, 0)
	for k := range rootList {
		rootNode := rootList[k]
		sandboxService.SandboxClassifyItemsMakeTreeV2(this.SysUser, classifyAll, rootNode)
		nodeAll = append(nodeAll, rootNode)
	}

	//newAll := sandboxService.SandboxItemsMakeTree(nodeAll, sandListMap, sandboxClassifyId)

	resp.AllNodes = nodeAll
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// @Title 新增沙盘分类
// @Description 新增沙盘分类接口
// @Param	request	body data_manage.AddChartClassifyReq true "type json string"
// @Success 200 Ret=200 保存成功
// @router /classify/add [post]
func (this *SandboxController) AddSandboxClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req sandbox.AddSandboxClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.SandboxClassifyName == "" {
		br.Msg = "请输入分类名称"
		br.IsSendEmail = false
		return
	}
	if req.ParentId < 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}

	count, err := sandbox.GetSandboxClassifyCount(req.SandboxClassifyName, req.ParentId)
	if err != nil {
		br.Msg = "判断名称是否已存在失败"
		br.ErrMsg = "判断名称是否已存在失败，Err:" + err.Error()
		return
	}
	if count > 0 {
		br.Msg = "分类名称已存在，请重新输入"
		br.IsSendEmail = false
		return
	}
	//获取该层级下最大的排序数
	maxSort, err := sandbox.GetSandboxClassifyMaxSort(req.ParentId)

	classify := new(sandbox.SandboxClassify)
	classify.ParentId = req.ParentId
	classify.SandboxClassifyName = req.SandboxClassifyName
	classify.HasData = 0
	classify.CreateTime = time.Now()
	classify.ModifyTime = time.Now()
	classify.SysUserId = this.SysUser.AdminId
	classify.SysUserRealName = this.SysUser.RealName
	classify.ChartPermissionId = req.ChartPermissionId
	classify.ChartPermissionName = req.ChartPermissionName
	classify.Level = req.Level + 1
	classify.Sort = maxSort + 1

	_, err = sandbox.AddSandboxClassify(classify)
	if err != nil {
		br.Msg = "保存分类失败"
		br.ErrMsg = "保存分类失败,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Msg = "保存成功"
	br.Success = true
}

// @Title 修改沙盘分类
// @Description 修改沙盘分类接口
// @Param	request	body data_manage.EditChartClassifyReq true "type json string"
// @Success 200 Ret=200 修改成功
// @router /classify/edit [post]
func (this *SandboxController) EditSandboxClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req sandbox.EditSandboxClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	if req.SandboxClassifyName == "" {
		br.Msg = "请输入分类名称"
		br.IsSendEmail = false
		return
	}

	if req.SandboxClassifyId <= 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}

	//item, err := sandbox.GetSandboxClassifyById(req.SandboxClassifyId)
	//if err != nil {
	//	br.Msg = "保存失败"
	//	br.Msg = "获取分类信息失败,Err:" + err.Error()
	//	return
	//}

	//count, err := sandbox.GetSandboxClassifyCount(req.SandboxClassifyName, item.ParentId)
	//if err != nil {
	//	br.Msg = "判断名称是否已存在失败"
	//	br.ErrMsg = "判断名称是否已存在失败，Err:" + err.Error()
	//	return
	//}
	//if count > 0 {
	//	br.Msg = "分类名称已存在，请重新输入"
	//	br.IsSendEmail = false
	//	return
	//}

	err = sandbox.EditSandboxClassify(req.SandboxClassifyId, req.ChartPermissionId, req.SandboxClassifyName, req.ChartPermissionName)
	if err != nil {
		br.Msg = "保存失败"
		br.ErrMsg = "保存失败,Err:" + err.Error()
		return
	}
	ids, err := sandbox.GetSandboxClassifySubcategories(req.SandboxClassifyId)
	if err != nil {
		br.Msg = "查询子级分类id失败"
		br.ErrMsg = "查询子级分类id失败,Err:" + err.Error()
		return
	}
	err = sandbox.UpdateSandboxClassifyChartPermissionById(req.ChartPermissionId, req.ChartPermissionName, ids)
	if err != nil {
		br.Msg = "修改子级分类错误"
		br.ErrMsg = "修改子级分类错误,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Msg = "保存成功"
	br.Success = true
	br.IsAddLog = true
}

// @Title 删除沙盘检测接口
// @Description 删除沙盘检测接口
// @Param	request	body data_manage.ChartClassifyDeleteCheckResp true "type json string"
// @Success 200 Ret=200 检测成功
// @router /classify/delete/check [post]
func (this *SandboxController) DeleteSandboxClassifyCheck() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req sandbox.SandboxClassifyDeleteCheckReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.SandboxClassifyId < 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}
	var deleteStatus int
	var tipsMsg string
	//删除分类
	if req.SandboxClassifyId > 0 {
		//判断沙盘分类下，是否含有沙盘
		count, err := sandbox.GetSandboxInfoCountByClassifyId(req.SandboxClassifyId)
		if err != nil {
			br.Msg = "删除失败"
			br.ErrMsg = "分类下是否含有指标失败，Err:" + err.Error()
			return
		}

		if count > 0 {
			deleteStatus = 1
			tipsMsg = "该分类下关联沙盘不可删除"
		}
	}

	if deleteStatus != 1 {
		classifyCount, err := sandbox.GetSandboxInfoCountByClassifyId(req.SandboxClassifyId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "删除失败"
			br.ErrMsg = "分类下是否含有沙盘失败，Err:" + err.Error()
			return
		}
		if classifyCount > 0 {
			deleteStatus = 2
			tipsMsg = "确认删除当前目录及包含的子目录吗"
		}
	}
	if deleteStatus == 0 {
		tipsMsg = "可删除，进行删除操作"
	}

	resp := new(sandbox.SandboxClassifyDeleteCheckResp)
	resp.DeleteStatus = deleteStatus
	resp.TipsMsg = tipsMsg
	br.Ret = 200
	br.Msg = "检测成功"
	br.Success = true
	br.Data = resp
}

// @Title 删除沙盘分类/沙盘
// @Description 删除沙盘分类/沙盘接口
// @Param	request	body data_manage.DeleteChartClassifyReq true "type json string"
// @Success 200 Ret=200 删除成功
// @router /classify/delete [post]
func (this *SandboxController) DeleteSandboxClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req sandbox.DeleteSandboxClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.SandboxClassifyId < 0 && req.SandboxId <= 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}

	//删除分类
	if req.SandboxClassifyId > 0 && req.SandboxId == 0 {
		//判断是否含有指标
		count, err := sandbox.GetSandboxInfoCountByClassifyId(req.SandboxId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "删除失败"
			br.ErrMsg = "判断名称是否已存在失败，Err:" + err.Error()
			return
		}

		if count > 0 {
			br.Msg = "该目录下存在关联指标，不可删除"
			br.IsSendEmail = false
			return
		}

		err = sandbox.DeleteSandboxClassify(req.SandboxClassifyId)
		if err != nil {
			br.Msg = "删除失败"
			br.ErrMsg = "删除失败,Err:" + err.Error()
			return
		}
	}

	//删除沙盘
	if req.SandboxId > 0 {
		sandboxInfo, err := sandbox.GetSandboxById(req.SandboxId)
		if err != nil {
			if err.Error() == utils.ErrNoRow() {
				br.Msg = "沙盘已删除，请刷新页面"
				br.ErrMsg = "指标不存在,Err:" + err.Error()
				return
			} else {
				br.Msg = "删除失败"
				br.ErrMsg = "删除失败，获取指标信息失败，Err:" + err.Error()
				return
			}
		}
		if sandboxInfo == nil {
			br.Msg = "沙盘已删除，请刷新页面"
			return
		}
		err = sandboxService.DeleteSandbox(req.SandboxId)
		if err != nil {
			br.Msg = err.Error()
			return
		}
	}
	br.Ret = 200
	br.Msg = "删除成功"
	br.Success = true
	br.IsAddLog = true
}

// ChartClassifyMove
// @Title 沙盘分类移动接口
// @Description 沙盘分类移动接口
// @Success 200 {object} data_manage.MoveChartClassifyReq
// @router /classify/move [post]
func (this *SandboxController) ChartClassifyMove() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req sandbox.MoveSandboxClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.ClassifyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "分类id小于等于0"
		return
	}
	//判断分类是否存在
	sandboxClassifyInfo, err := sandbox.GetSandboxClassifyById(req.ClassifyId)
	if err != nil {
		br.Msg = "移动失败"
		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
		return
	}

	updateCol := make([]string, 0)

	// 判断移动的是分类还是沙盘
	if req.SandboxId > 0 {
		//判断分类是否存在
		count, _ := sandbox.GetSandboxClassifyCountById(req.ClassifyId)
		if count <= 0 {
			br.Msg = "分类已被删除，不可移动，请刷新页面"
			return
		}

		sandboxInfo, err := sandbox.GetSandboxById(req.SandboxId)
		if err != nil {
			br.Msg = "移动失败"
			br.ErrMsg = "获取沙盘信息失败,Err:" + err.Error()
			return
		}

		//如果改变了分类，那么移动该图表数据
		// 11/22 ETA逻辑优化去除名称重复限制
		if sandboxInfo.SandboxClassifyId != req.ParentClassifyId {
			////查询需要修改的分类下是否存在同一个图表名称
			//tmpSandboxInfo, tmpErr := sandbox.GetSandboxByClassifyIdAndName(req.ParentClassifyId, sandboxInfo.Name)
			//if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
			//	br.Msg = "移动失败"
			//	br.ErrMsg = "移动失败,Err:" + tmpErr.Error()
			//	return
			//}
			//if tmpSandboxInfo != nil {
			//	br.Msg = "移动失败，同一个分类下沙盘名称不允许重复"
			//	br.ErrMsg = "移动失败，同一个分类下沙盘名称不允许重复"
			//	return
			//}
			err = sandbox.MoveSandbox(req.SandboxId, req.ParentClassifyId)
			if err != nil {
				br.Msg = "移动失败"
				br.ErrMsg = "移动失败,Err:" + err.Error()
				return
			}
		}

		//移动排序
		updateCol := make([]string, 0)
		//如果有传入 上一个兄弟节点分类id
		if req.PrevId > 0 {
			if req.PrevType == 1 {
				//上一个兄弟节点
				prevClassify, err := sandbox.GetSandboxClassifyById(req.PrevId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
					return
				}

				//如果是移动在两个兄弟节点之间
				if req.NextId > 0 {
					if req.NextType == 1 {
						//上一个节点是分类 下一个节点是分类的情况
						//下一个兄弟节点
						nextClassify, err := sandbox.GetSandboxClassifyById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟与下一个兄弟的排序权重是一致的，那么需要将下一个兄弟（以及下个兄弟的同样排序权重）的排序权重+2，自己变成上一个兄弟的排序权重+1
						if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == sandboxClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, prevClassify.SandboxClassifyId, prevClassify.Sort, updateSortStr)
							_ = sandbox.UpdateSandboxSortByClassifyId(prevClassify.SandboxClassifyId, prevClassify.Sort, 0, updateSortStr)
						} else {
							//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层，那么需要再加一层了
							if nextClassify.Sort-prevClassify.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
								_ = sandbox.UpdateSandboxSortByClassifyId(prevClassify.SandboxClassifyId, prevClassify.Sort, 0, updateSortStr)
							}
						}
					} else {
						//上一个节点是分类 下一个节点是沙盘的情况
						//下一个兄弟节点
						nextChartInfo, err := sandbox.GetSandboxById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(分类)与下一个兄弟(沙盘)的排序权重是一致的，那么需要将下一个兄弟(沙盘)（以及下个兄弟(沙盘)的同样排序权重）的排序权重+2，自己变成上一个兄弟(分类)的排序权重+1
						if prevClassify.Sort == nextChartInfo.Sort || prevClassify.Sort == sandboxInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, prevClassify.SandboxClassifyId, prevClassify.Sort, updateSortStr)
							_ = sandbox.UpdateSandboxSortByClassifyId(prevClassify.SandboxClassifyId, prevClassify.Sort, 0, updateSortStr)
						} else {
							//如果下一个兄弟(沙盘)的排序权重正好是上个兄弟节点(分类)的下一层，那么需要再加一层了
							if nextChartInfo.Sort-prevClassify.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.SandboxClassifyId, updateSortStr)
								_ = sandbox.UpdateSandboxSortByClassifyId(prevClassify.SandboxClassifyId, prevClassify.Sort, 0, updateSortStr)
							}
						}
					}

				}

				sandboxInfo.Sort = prevClassify.Sort + 1
				sandboxInfo.ModifyTime = time.Now()
				updateCol = append(updateCol, "Sort", "ModifyTime")

			} else {
				prevSandbox, err := sandbox.GetSandboxById(req.PrevId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
					return
				}

				//如果是移动在两个兄弟节点之间
				if req.NextId > 0 {
					if req.NextType == 1 {
						//上一个节点是沙盘 下一个节点是分类的情况
						//下一个兄弟节点
						nextClassify, err := sandbox.GetSandboxClassifyById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(沙盘)与下一个兄弟(分类)的排序权重是一致的，那么需要将下一个兄弟(分类)（以及下个兄弟(分类)的同样排序权重）的排序权重+2，自己变成上一个兄弟(沙盘)的排序权重+1
						if prevSandbox.Sort == nextClassify.Sort || prevSandbox.Sort == sandboxClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = sandbox.UpdateSandboxClassifySortByParentId(prevSandbox.SandboxClassifyId, 0, prevSandbox.Sort, updateSortStr)
							_ = sandbox.UpdateSandboxSortByClassifyId(prevSandbox.SandboxClassifyId, prevSandbox.Sort, prevSandbox.SandboxId, updateSortStr)
						} else {
							//如果下一个兄弟(分类)的排序权重正好是上个兄弟(沙盘)节点的下一层，那么需要再加一层了
							if nextClassify.Sort-prevSandbox.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = sandbox.UpdateSandboxClassifySortByParentId(prevSandbox.SandboxClassifyId, 0, prevSandbox.Sort, updateSortStr)
								_ = sandbox.UpdateSandboxSortByClassifyId(prevSandbox.SandboxClassifyId, prevSandbox.Sort, prevSandbox.SandboxId, updateSortStr)
							}
						}
					} else {
						//上一个节点是沙盘 下一个节点是沙盘的情况
						//下一个兄弟节点
						nextChartInfo, err := sandbox.GetSandboxById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(沙盘)与下一个兄弟(分类)的排序权重是一致的，那么需要将下一个兄弟(分类)（以及下个兄弟(分类)的同样排序权重）的排序权重+2，自己变成上一个兄弟(沙盘)的排序权重+1
						if prevSandbox.Sort == nextChartInfo.Sort || prevSandbox.Sort == sandboxInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = sandbox.UpdateSandboxClassifySortByParentId(prevSandbox.SandboxClassifyId, 0, prevSandbox.Sort, updateSortStr)
							_ = sandbox.UpdateSandboxSortByClassifyId(prevSandbox.SandboxClassifyId, prevSandbox.Sort, prevSandbox.SandboxId, updateSortStr)
						} else {
							//如果下一个兄弟(分类)的排序权重正好是上个兄弟(沙盘)节点的下一层，那么需要再加一层了
							if nextChartInfo.Sort-prevSandbox.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = sandbox.UpdateSandboxClassifySortByParentId(prevSandbox.SandboxClassifyId, 0, prevSandbox.Sort, updateSortStr)
								_ = sandbox.UpdateSandboxSortByClassifyId(prevSandbox.SandboxClassifyId, prevSandbox.Sort, prevSandbox.SandboxId, updateSortStr)
							}
						}
					}

				}

				sandboxInfo.Sort = prevSandbox.Sort + 1
				sandboxInfo.ModifyTime = time.Now()
				updateCol = append(updateCol, "Sort", "ModifyTime")
			}

		} else {
			// prevId为0，也就是沙盘移到最前端
			firstClassify, err := sandbox.GetFirstSandboxByClassifyId(req.ClassifyId)
			if err != nil && err.Error() != utils.ErrNoRow() {
				br.Msg = "移动失败"
				br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
				return
			}

			//如果该分类下存在其他分类，且第一个其他分类的排序等于0，那么需要调整排序
			if firstClassify != nil && firstClassify.Sort == 0 {
				updateSortStr := ` sort + 1 `
				_ = sandbox.UpdateSandboxSortByClassifyId(firstClassify.SandboxClassifyId, 0, firstClassify.SandboxId-1, updateSortStr)
			}

			sandboxInfo.Sort = 0 //那就是排在第一位
			sandboxInfo.ModifyTime = time.Now()
			updateCol = append(updateCol, "Sort", "ModifyTime")

		}

		//更新
		if len(updateCol) > 0 {
			err = sandboxInfo.Update(updateCol)
			if err != nil {
				br.Msg = "移动失败"
				br.ErrMsg = "修改失败,Err:" + err.Error()
				return
			}
		}
	} else {
		//移动的是分类
		//判断上级id是否一致，如果不一致的话，那么需要移动该分类层级
		if sandboxClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId != 0 {
			parentChartClassifyInfo, err := sandbox.GetSandboxClassifyById(req.ParentClassifyId)
			if err != nil {
				br.Msg = "移动失败"
				br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
				return
			}
			sandboxClassifyInfo.ParentId = parentChartClassifyInfo.SandboxClassifyId
			sandboxClassifyInfo.Level = parentChartClassifyInfo.Level + 1
			sandboxClassifyInfo.ModifyTime = time.Now()
			updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
		} else if sandboxClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId == 0 {
			//改为一级分类
			sandboxClassifyInfo.ParentId = req.ParentClassifyId
			sandboxClassifyInfo.Level = 1
			sandboxClassifyInfo.ModifyTime = time.Now()
			updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
		}

		//如果有传入 上一个兄弟节点分类id
		if req.PrevId > 0 {
			if req.PrevType == 1 {
				//上一个节点是分类
				//上一个兄弟节点
				prevClassify, err := sandbox.GetSandboxClassifyById(req.PrevId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
					return
				}

				//如果是移动在两个兄弟节点之间
				if req.NextId > 0 {
					if req.NextType == 1 {
						//上一个节点是分类 下一个节点是分类的情况
						//下一个兄弟节点
						nextClassify, err := sandbox.GetSandboxClassifyById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟与下一个兄弟的排序权重是一致的，那么需要将下一个兄弟（以及下个兄弟的同样排序权重）的排序权重+2，自己变成上一个兄弟的排序权重+1
						if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == sandboxClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, prevClassify.SandboxClassifyId, prevClassify.Sort, updateSortStr)
							_ = sandbox.UpdateSandboxSortByClassifyId(prevClassify.SandboxClassifyId, prevClassify.Sort, 0, updateSortStr)
						} else {
							//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层，那么需要再加一层了
							if nextClassify.Sort-prevClassify.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
								_ = sandbox.UpdateSandboxSortByClassifyId(prevClassify.SandboxClassifyId, prevClassify.Sort, 0, updateSortStr)
							}
						}
					} else {
						//上一个节点是分类 下一个节点是沙盘的情况
						//下一个兄弟节点
						nextChartInfo, err := sandbox.GetSandboxById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(分类)与下一个兄弟(沙盘)的排序权重是一致的，那么需要将下一个兄弟(沙盘)（以及下个兄弟(沙盘)的同样排序权重）的排序权重+2，自己变成上一个兄弟(分类)的排序权重+1
						if prevClassify.Sort == nextChartInfo.Sort || prevClassify.Sort == sandboxClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, prevClassify.SandboxClassifyId, prevClassify.Sort, updateSortStr)
							_ = sandbox.UpdateSandboxSortByClassifyId(prevClassify.SandboxClassifyId, prevClassify.Sort, 0, updateSortStr)
						} else {
							//如果下一个兄弟(沙盘)的排序权重正好是上个兄弟节点(分类)的下一层，那么需要再加一层了
							if nextChartInfo.Sort-prevClassify.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.SandboxClassifyId, updateSortStr)
								_ = sandbox.UpdateSandboxSortByClassifyId(prevClassify.SandboxClassifyId, prevClassify.Sort, 0, updateSortStr)
							}
						}
					}

				}

				sandboxClassifyInfo.Sort = prevClassify.Sort + 1
				sandboxClassifyInfo.ModifyTime = time.Now()
				updateCol = append(updateCol, "Sort", "ModifyTime")

			} else {
				//上一个节点是沙盘
				prevSandbox, err := sandbox.GetSandboxById(req.PrevId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
					return
				}

				//如果是移动在两个兄弟节点之间
				if req.NextId > 0 {
					if req.NextType == 1 {
						//上一个节点是沙盘 下一个节点是分类的情况
						//下一个兄弟节点
						nextClassify, err := sandbox.GetSandboxClassifyById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(沙盘)与下一个兄弟(分类)的排序权重是一致的，那么需要将下一个兄弟(分类)（以及下个兄弟(分类)的同样排序权重）的排序权重+2，自己变成上一个兄弟(沙盘)的排序权重+1
						if prevSandbox.Sort == nextClassify.Sort || prevSandbox.Sort == sandboxClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = sandbox.UpdateSandboxClassifySortByParentId(prevSandbox.SandboxClassifyId, 0, prevSandbox.Sort, updateSortStr)
							_ = sandbox.UpdateSandboxSortByClassifyId(prevSandbox.SandboxClassifyId, prevSandbox.Sort, prevSandbox.SandboxId, updateSortStr)
						} else {
							//如果下一个兄弟(分类)的排序权重正好是上个兄弟(沙盘)节点的下一层，那么需要再加一层了
							if nextClassify.Sort-prevSandbox.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = sandbox.UpdateSandboxClassifySortByParentId(prevSandbox.SandboxClassifyId, 0, prevSandbox.Sort, updateSortStr)
								_ = sandbox.UpdateSandboxSortByClassifyId(prevSandbox.SandboxClassifyId, prevSandbox.Sort, prevSandbox.SandboxId, updateSortStr)
							}
						}
					} else {
						//上一个节点是沙盘 下一个节点是沙盘的情况
						//下一个兄弟节点
						nextChartInfo, err := sandbox.GetSandboxById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(沙盘)与下一个兄弟(分类)的排序权重是一致的，那么需要将下一个兄弟(分类)（以及下个兄弟(分类)的同样排序权重）的排序权重+2，自己变成上一个兄弟(沙盘)的排序权重+1
						if prevSandbox.Sort == nextChartInfo.Sort || prevSandbox.Sort == sandboxClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = sandbox.UpdateSandboxClassifySortByParentId(prevSandbox.SandboxClassifyId, 0, prevSandbox.Sort, updateSortStr)
							_ = sandbox.UpdateSandboxSortByClassifyId(prevSandbox.SandboxClassifyId, prevSandbox.Sort, prevSandbox.SandboxId, updateSortStr)
						} else {
							//如果下一个兄弟(分类)的排序权重正好是上个兄弟(沙盘)节点的下一层，那么需要再加一层了
							if nextChartInfo.Sort-prevSandbox.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = sandbox.UpdateSandboxClassifySortByParentId(prevSandbox.SandboxClassifyId, 0, prevSandbox.Sort, updateSortStr)
								_ = sandbox.UpdateSandboxSortByClassifyId(prevSandbox.SandboxClassifyId, prevSandbox.Sort, prevSandbox.SandboxId, updateSortStr)
							}
						}
					}

				}
				sandboxClassifyInfo.Sort = prevSandbox.Sort + 1
				sandboxClassifyInfo.ModifyTime = time.Now()
				updateCol = append(updateCol, "Sort", "ModifyTime")

			}

		} else {
			firstClassify, err := sandbox.GetFirstSandboxClassifyByParentId(sandboxClassifyInfo.ParentId)
			if err != nil && err.Error() != utils.ErrNoRow() {
				br.Msg = "移动失败"
				br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
				return
			}

			//如果该分类下存在其他分类，且第一个其他分类的排序等于0，那么需要调整排序
			if firstClassify != nil && firstClassify.Sort == 0 {
				updateSortStr := ` sort + 1 `
				_ = sandbox.UpdateSandboxClassifySortByParentId(firstClassify.ParentId, firstClassify.SandboxClassifyId-1, 0, updateSortStr)
			}

			sandboxClassifyInfo.Sort = 0 //那就是排在第一位
			sandboxClassifyInfo.ModifyTime = time.Now()
			updateCol = append(updateCol, "Sort", "ModifyTime")
		}

		//更新
		if len(updateCol) > 0 {
			err = sandboxClassifyInfo.Update(updateCol)
			if err != nil {
				br.Msg = "移动失败"
				br.ErrMsg = "修改失败,Err:" + err.Error()
				return
			}
			if req.ParentClassifyId > 0 {
				ids, err := sandbox.GetSandboxClassifySubcategories(req.ClassifyId)
				if err != nil {
					br.Msg = "查询子级分类id失败"
					br.ErrMsg = "查询子级分类id失败,Err:" + err.Error()
					return
				}
				parentChartClassifyInfo, err := sandbox.GetSandboxClassifyById(req.ParentClassifyId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
					return
				}
				err = sandbox.UpdateSandboxClassifyChartPermissionById(parentChartClassifyInfo.ChartPermissionId, parentChartClassifyInfo.ChartPermissionName, ids)
				if err != nil {
					br.Msg = "修改子级分类错误"
					br.ErrMsg = "修改子级分类错误,Err:" + err.Error()
					return
				}
			}
		}
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "移动成功"
}

// @Title ETA图表列表接口
// @Description ETA图表列表接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码，从1开始"
// @Param   ChartClassifyId   query   int  true       "分类id"
// @Param   KeyWord   query   string  true       "搜索关键词"
// @Param   IsShowMe   query   bool  true       "是否只看我的，true、false"
// @Success 200 {object} data_manage.ChartListResp
// @router /listV2 [get]
func (this *SandboxController) ListV2() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	sandboxClassifyId, _ := this.GetInt("SandboxClassifyId")

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	keyWord := this.GetString("KeyWord")

	var total int
	page := paging.GetPaging(currentIndex, pageSize, total)

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = paging.StartIndex(currentIndex, pageSize)

	var condition string
	var pars []interface{}

	if sandboxClassifyId > 0 {
		sandboxClassifyId, err := sandbox.GetSandboxClassify(sandboxClassifyId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "获取图表信息失败"
			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
			return
		}
		condition += " AND sandbox_classify_id IN(" + sandboxClassifyId + ") "
		//pars = append(pars, chartClassifyId)
	}
	if keyWord != "" {
		condition += ` AND  ( name LIKE '%` + keyWord + `%' )`
	}

	//只看我的
	isShowMe, _ := this.GetBool("IsShowMe")
	if isShowMe {
		condition += ` AND sys_user_id = ? `
		pars = append(pars, sysUser.AdminId)
	}

	//获取图表信息
	condition += ` AND is_delete = 0 `
	list, err := sandbox.GetSandboxListByCondition(condition, pars, startSize, pageSize)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Success = true
		br.Msg = "获取沙盘信息失败"
		br.ErrMsg = "获取沙盘信息失败,Err:" + err.Error()
		return
	}

	for i, v := range list {
		ids, err := sandbox.GetSandboxAllParentByClassifyId(v.SandboxClassifyId)
		if err != nil {
			br.Msg = "获取父级信息错误！"
			br.ErrMsg = "获取父级信息错误，Err:" + err.Error()
			return
		}
		list[i].ParentIds = ids
	}
	resp := new(sandbox.SandboxListResp)
	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
		items := make([]*sandbox.SandboxListItems, 0)
		resp.Paging = page
		resp.List = items
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		return
	}

	dataCount, err := sandbox.GetSandboxListCountByCondition(condition, pars)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取指标信息失败"
		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
		return
	}
	page = paging.GetPaging(currentIndex, pageSize, dataCount)
	resp.Paging = page
	resp.List = list
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// Save
// @Title 新增/编辑保存沙盘
// @Description 新增/编辑保存沙盘接口
// @Param	request	body request.AddAndEditSandbox true "type json string"
// @Success 200 {object} sandbox.Sandbox
// @router /saveV2 [post]
func (this *SandboxController) SaveV2() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req request.AddAndEditSandboxV2
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	var sandboxResp *sandbox.SandboxSaveResp

	var errMsg string

	if req.SandboxId <= 0 {
		//新增沙盘
		sandboxResp, err = sandboxService.AddSandboxV2(req, sysUser.AdminId, sysUser.RealName)
		if err != nil {
			br.Msg = "保存失败！"
			if errMsg != `` {
				br.Msg = errMsg
			}
			br.ErrMsg = "保存失败，Err:" + err.Error()
			return
		}
	} else {
		//编辑沙盘
		sandboxInfo := &sandbox.Sandbox{
			SandboxId:         req.SandboxId,
			Name:              utils.TrimStr(req.Name),
			Content:           req.Content,
			MindmapData:       req.MindmapData,
			PicUrl:            utils.TrimStr(req.PicUrl),
			ModifyTime:        time.Now(),
			SandboxClassifyId: req.SandboxClassifyId,
			Style:             req.Style,
		}
		//缩略图为空时不更新
		var updateSandboxColumn = []string{}
		if req.PicUrl == "" {
			updateSandboxColumn = []string{"Content", "MindmapData", "ModifyTime", "SandboxClassifyId", "Style"}
		} else {
			updateSandboxColumn = []string{"Content", "MindmapData", "PicUrl", "ModifyTime", "SandboxClassifyId", "Style"}
		}
		err = sandboxInfo.Update(updateSandboxColumn)
		if err != nil {
			br.Msg = "保存失败！"
			if errMsg != `` {
				br.Msg = errMsg
			}
			br.ErrMsg = "保存失败，Err:" + err.Error()
			return
		}
	}

	msg := "保存成功"
	br.Ret = 200
	br.Success = true
	br.Msg = msg
	br.Data = sandboxResp
}

// Delete
// @Title 删除沙盘
// @Description 删除沙盘接口
// @Param	request	body request.DeleteSandbox true "type json string"
// @Success 200 标记成功
// @router /deleteV2 [post]
func (this *SandboxController) DeleteV2() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req request.DeleteSandbox
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.SandboxId <= 0 {
		br.Msg = "缺少沙盘编号"
		return
	}

	//删除沙盘
	err = sandboxService.DeleteSandbox(req.SandboxId)
	if err != nil {
		br.Msg = err.Error()
		return
	}

	msg := "删除成功"
	br.Ret = 200
	br.Success = true
	br.Msg = msg
}

// GetSandboxVersionDetail
// @Title 获取沙盘版本数据详情（已保存的）
// @Description 获取沙盘版本数据详情接口（已保存的）
// @Param   SandboxVersionCode   query   string  true       "沙盘版本code"
// @Success 200 {object} sandbox.SandboxVersion
// @router /detail [get]
func (this *SandboxController) GetSandboxDetail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	sandboxId, _ := this.GetInt("SandboxId")
	if sandboxId == 0 {
		br.Msg = "缺少沙盘Id"
		return
	}

	//获取沙盘数据详情（已保存的）
	sandboxInfo, err := sandbox.GetSandboxById(sandboxId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err：" + err.Error()
		return
	}
	msg := "获取成功"
	br.Ret = 200
	br.Success = true
	br.Msg = msg
	br.Data = sandboxInfo
}

//// SandboxClassifyItems
//// @Title 获取所有沙盘分类接口-包含沙盘-先分类后沙盘区分，暂时弃用
//// @Description 获取所有沙盘分类接口-包含沙盘
//// @Param   IsShowMe   query   bool  true       "是否只看我的，true、false"
//// @Success 200 {object} data_manage.ChartClassifyListResp
//// @router /classify/list [get]
//func (this *SandboxController) SandboxClassifyItems() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//
//	resp := new(sandbox.SandboxClassifyListResp)
//	sandboxClassifyId, _ := this.GetInt("SandboxClassifyId")
//
//	isShowMe, _ := this.GetBool("IsShowMe")
//	if isShowMe {
//		errMsg, err := sandboxService.GetSandboxClassifyListForMe(*this.SysUser, resp, sandboxClassifyId)
//		if err != nil {
//			br.Msg = errMsg
//			br.ErrMsg = err.Error()
//			return
//		}
//		// 移除没有权限的图表
//		//allNodes := sandboxService.HandleNoPermissionSandbox(resp.AllNodes, nil)
//		//resp.AllNodes = allNodes
//
//		br.Ret = 200
//		br.Success = true
//		br.Msg = "获取成功"
//		br.Data = resp
//		fmt.Println("source my classify")
//		return
//	}
//
//	rootList, err := sandbox.GetSandboxClassifyByParentId(sandboxClassifyId)
//	if err != nil && err.Error() != utils.ErrNoRow() {
//		br.Msg = "获取失败"
//		br.ErrMsg = "获取数据失败，Err:" + err.Error()
//		return
//	}
//
//	classifyAll, err := sandbox.GetSandboxClassifyByParentId(sandboxClassifyId)
//	if err != nil && err.Error() != utils.ErrNoRow() {
//		br.Msg = "获取失败"
//		br.ErrMsg = "获取数据失败，Err:" + err.Error()
//		return
//	}
//
//	sandboxAll, err := sandbox.GetSandboxItemsByClassifyId(sandboxClassifyId)
//	if err != nil && err.Error() != utils.ErrNoRow() {
//		br.Msg = "获取失败"
//		br.ErrMsg = "获取数据失败，Err:" + err.Error()
//		return
//	}
//
//	sandListMap := make(map[int][]*sandbox.SandboxClassifyItems)
//	for _, v := range sandboxAll {
//		if _, ok := sandListMap[v.SandboxClassifyId]; !ok {
//			list := make([]*sandbox.SandboxClassifyItems, 0)
//			list = append(list, v)
//			sandListMap[v.SandboxClassifyId] = list
//		} else {
//			sandListMap[v.SandboxClassifyId] = append(sandListMap[v.SandboxClassifyId], v)
//		}
//	}
//
//	nodeAll := make([]*sandbox.SandboxClassifyItems, 0)
//	for k := range rootList {
//		rootNode := rootList[k]
//		sandboxService.SandboxClassifyItemsMakeTree(this.SysUser, classifyAll, rootNode)
//		nodeAll = append(nodeAll, rootNode)
//	}
//	//for k := range nodeAll {
//	//
//	//}
//	newAll := sandboxService.SandboxItemsMakeTree(nodeAll, sandListMap, sandboxClassifyId)
//
//	resp.AllNodes = newAll
//	br.Ret = 200
//	br.Success = true
//	br.Msg = "获取成功"
//	br.Data = resp
//}

//// SandboxMove
//// @Title 移动沙盘接口
//// @Description 移动图表接口
//// @Success 200 {object} data_manage.MoveChartInfoReq
//// @router /move [post]
//func (this *SandboxController) SandboxMove() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//
//	sysUser := this.SysUser
//	if sysUser == nil {
//		br.Msg = "请登录"
//		br.ErrMsg = "请登录，SysUser Is Empty"
//		br.Ret = 408
//		return
//	}
//
//	var req sandbox.MoveSandboxReq
//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
//	if err != nil {
//		br.Msg = "参数解析异常！"
//		br.ErrMsg = "参数解析失败，Err:" + err.Error()
//		return
//	}
//
//	if req.SandboxId <= 0 {
//		br.Msg = "参数错误"
//		br.ErrMsg = "沙盘id小于等于0"
//		return
//	}
//
//	if req.SandboxClassifyId <= 0 {
//		br.Msg = "请选择分类"
//		return
//	}
//	//判断分类是否存在
//	count, _ := sandbox.GetSandboxClassifyCountById(req.SandboxClassifyId)
//	if count <= 0 {
//		br.Msg = "分类已被删除，不可移动，请刷新页面"
//		return
//	}
//
//	sandboxInfo, err := sandbox.GetSandboxById(req.SandboxId)
//	if err != nil {
//		br.Msg = "移动失败"
//		br.ErrMsg = "获取沙盘信息失败,Err:" + err.Error()
//		return
//	}
//
//	//如果改变了分类，那么移动该图表数据
//	if sandboxInfo.SandboxClassifyId != req.SandboxClassifyId {
//		//查询需要修改的分类下是否存在同一个图表名称
//		tmpSandboxInfo, tmpErr := sandbox.GetSandboxByClassifyIdAndName(req.SandboxClassifyId, sandboxInfo.Name)
//		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
//			br.Msg = "移动失败"
//			br.ErrMsg = "移动失败,Err:" + tmpErr.Error()
//			return
//		}
//		if tmpSandboxInfo != nil {
//			br.Msg = "移动失败，同一个分类下沙盘名称不允许重复"
//			br.ErrMsg = "移动失败，同一个分类下沙盘名称不允许重复"
//			return
//		}
//		err = sandbox.MoveSandbox(req.SandboxId, req.SandboxClassifyId)
//		if err != nil {
//			br.Msg = "移动失败"
//			br.ErrMsg = "移动失败,Err:" + err.Error()
//			return
//		}
//	}
//
//	//移动排序
//	updateCol := make([]string, 0)
//	//如果有传入 上一个兄弟节点分类id
//	if req.PrevSandboxId > 0 {
//		prevChartInfo, err := sandbox.GetSandboxById(req.PrevSandboxId)
//		if err != nil {
//			br.Msg = "移动失败"
//			br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
//			return
//		}
//
//		//如果是移动在两个兄弟节点之间
//		if req.NextSandboxId > 0 {
//			//下一个兄弟节点
//			nextChartInfo, err := sandbox.GetSandboxById(req.NextSandboxId)
//			if err != nil {
//				br.Msg = "移动失败"
//				br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
//				return
//			}
//			//如果上一个兄弟与下一个兄弟的排序权重是一致的，那么需要将下一个兄弟（以及下个兄弟的同样排序权重）的排序权重+2，自己变成上一个兄弟的排序权重+1
//			if prevChartInfo.Sort == nextChartInfo.Sort || prevChartInfo.Sort == sandboxInfo.Sort {
//				//变更兄弟节点的排序
//				updateSortStr := `sort + 2`
//				_ = sandbox.UpdateSandboxSortByClassifyId(prevChartInfo.SandboxClassifyId, prevChartInfo.Sort, prevChartInfo.SandboxId, updateSortStr)
//			} else {
//				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层，那么需要再加一层了
//				if nextChartInfo.Sort-prevChartInfo.Sort == 1 {
//					//变更兄弟节点的排序
//					updateSortStr := `sort + 1`
//					_ = sandbox.UpdateSandboxSortByClassifyId(prevChartInfo.SandboxClassifyId, prevChartInfo.Sort, prevChartInfo.SandboxId, updateSortStr)
//				}
//			}
//		}
//
//		sandboxInfo.Sort = prevChartInfo.Sort + 1
//		sandboxInfo.ModifyTime = time.Now()
//		updateCol = append(updateCol, "Sort", "ModifyTime")
//
//	} else {
//		firstClassify, err := sandbox.GetFirstSandboxByClassifyId(req.SandboxClassifyId)
//		if err != nil && err.Error() != utils.ErrNoRow() {
//			br.Msg = "移动失败"
//			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
//			return
//		}
//
//		//如果该分类下存在其他分类，且第一个其他分类的排序等于0，那么需要调整排序
//		if firstClassify != nil && firstClassify.Sort == 0 {
//			updateSortStr := ` sort + 1 `
//			_ = sandbox.UpdateSandboxSortByClassifyId(firstClassify.SandboxClassifyId, 0, firstClassify.SandboxId-1, updateSortStr)
//		}
//
//		sandboxInfo.Sort = 0 //那就是排在第一位
//		sandboxInfo.ModifyTime = time.Now()
//		updateCol = append(updateCol, "Sort", "ModifyTime")
//	}
//
//	//更新
//	if len(updateCol) > 0 {
//		err = sandboxInfo.Update(updateCol)
//		if err != nil {
//			br.Msg = "移动失败"
//			br.ErrMsg = "修改失败,Err:" + err.Error()
//			return
//		}
//	}
//
//	if err != nil {
//		br.Msg = "移动失败"
//		br.ErrMsg = "修改失败,Err:" + err.Error()
//		return
//	}
//
//	br.Ret = 200
//	br.Success = true
//	br.Msg = "移动成功"
//}

//// ChartClassifyMove
//// @Title 沙盘分类移动接口
//// @Description 沙盘分类移动接口
//// @Success 200 {object} data_manage.MoveChartClassifyReq
//// @router /classify/move [post]
//func (this *SandboxController) ChartClassifyMove() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//
//	sysUser := this.SysUser
//	if sysUser == nil {
//		br.Msg = "请登录"
//		br.ErrMsg = "请登录，SysUser Is Empty"
//		br.Ret = 408
//		return
//	}
//
//	var req sandbox.MoveSandboxClassifyReq
//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
//	if err != nil {
//		br.Msg = "参数解析异常！"
//		br.ErrMsg = "参数解析失败，Err:" + err.Error()
//		return
//	}
//
//	if req.ClassifyId <= 0 {
//		br.Msg = "参数错误"
//		br.ErrMsg = "分类id小于等于0"
//		return
//	}
//	//判断分类是否存在
//	sandboxClassifyInfo, err := sandbox.GetSandboxClassifyById(req.ClassifyId)
//	if err != nil {
//		br.Msg = "移动失败"
//		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
//		return
//	}
//
//	updateCol := make([]string, 0)
//
//	//判断上级id是否一致，如果不一致的话，那么需要移动该分类层级
//	if sandboxClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId != 0 {
//		parentChartClassifyInfo, err := sandbox.GetSandboxClassifyById(req.ParentClassifyId)
//		if err != nil {
//			br.Msg = "移动失败"
//			br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
//			return
//		}
//		sandboxClassifyInfo.ParentId = parentChartClassifyInfo.SandboxClassifyId
//		sandboxClassifyInfo.Level = parentChartClassifyInfo.Level + 1
//		sandboxClassifyInfo.ModifyTime = time.Now()
//		updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
//	} else if sandboxClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId == 0 {
//		//改为一级分类
//		sandboxClassifyInfo.ParentId = req.ParentClassifyId
//		sandboxClassifyInfo.Level = 1
//		sandboxClassifyInfo.ModifyTime = time.Now()
//		updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
//	}
//
//	//如果有传入 上一个兄弟节点分类id
//	if req.PrevClassifyId > 0 {
//		//上一个兄弟节点
//		prevClassify, err := sandbox.GetSandboxClassifyById(req.PrevClassifyId)
//		if err != nil {
//			br.Msg = "移动失败"
//			br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
//			return
//		}
//
//		//如果是移动在两个兄弟节点之间
//		if req.NextClassifyId > 0 {
//			//下一个兄弟节点
//			nextClassify, err := sandbox.GetSandboxClassifyById(req.NextClassifyId)
//			if err != nil {
//				br.Msg = "移动失败"
//				br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
//				return
//			}
//			//如果上一个兄弟与下一个兄弟的排序权重是一致的，那么需要将下一个兄弟（以及下个兄弟的同样排序权重）的排序权重+2，自己变成上一个兄弟的排序权重+1
//			if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == sandboxClassifyInfo.Sort {
//				//变更兄弟节点的排序
//				updateSortStr := `sort + 2`
//				_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, prevClassify.SandboxClassifyId, prevClassify.Sort, updateSortStr)
//			} else {
//				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层，那么需要再加一层了
//				if nextClassify.Sort-prevClassify.Sort == 1 {
//					//变更兄弟节点的排序
//					updateSortStr := `sort + 1`
//					_ = sandbox.UpdateSandboxClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
//				}
//			}
//		}
//
//		sandboxClassifyInfo.Sort = prevClassify.Sort + 1
//		sandboxClassifyInfo.ModifyTime = time.Now()
//		updateCol = append(updateCol, "Sort", "ModifyTime")
//
//	} else {
//		firstClassify, err := sandbox.GetFirstSandboxClassifyByParentId(sandboxClassifyInfo.ParentId)
//		if err != nil && err.Error() != utils.ErrNoRow() {
//			br.Msg = "移动失败"
//			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
//			return
//		}
//
//		//如果该分类下存在其他分类，且第一个其他分类的排序等于0，那么需要调整排序
//		if firstClassify != nil && firstClassify.Sort == 0 {
//			updateSortStr := ` sort + 1 `
//			_ = sandbox.UpdateSandboxClassifySortByParentId(firstClassify.ParentId, firstClassify.SandboxClassifyId-1, 0, updateSortStr)
//		}
//
//		sandboxClassifyInfo.Sort = 0 //那就是排在第一位
//		sandboxClassifyInfo.ModifyTime = time.Now()
//		updateCol = append(updateCol, "Sort", "ModifyTime")
//	}
//
//	//更新
//	if len(updateCol) > 0 {
//		err = sandboxClassifyInfo.Update(updateCol)
//		if err != nil {
//			br.Msg = "移动失败"
//			br.ErrMsg = "修改失败,Err:" + err.Error()
//			return
//		}
//	}
//	br.Ret = 200
//	br.Success = true
//	br.Msg = "移动成功"
//}

// SandboxClassifyItems
// @Title 获取所有沙盘分类接口-不包含沙盘
// @Description 获取所有沙盘分类接口-不包含沙盘
// @Param   IsShowMe   query   bool  true       "是否只看我的，true、false"
// @Success 200 {object} data_manage.ChartClassifyListResp
// @router /classifyList [get]
func (this *SandboxController) SandboxClassifyList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	resp := new(sandbox.SandboxClassifyListResp)

	rootList, err := sandbox.GetSandboxClassifyByParentId(0)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败，Err:" + err.Error()
		return
	}

	classifyAll, err := sandbox.GetSandboxClassifyAll()
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败，Err:" + err.Error()
		return
	}

	nodeAll := make([]*sandbox.SandboxClassifyItems, 0)
	for k := range rootList {
		rootNode := rootList[k]
		sandboxService.SandboxClassifyItemsMakeTree(this.SysUser, classifyAll, rootNode)
		nodeAll = append(nodeAll, rootNode)
	}

	resp.AllNodes = nodeAll
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// @Title 链接指标检测
// @Description 链接指标检测接口
// @Param	request	body data_manage.ChartClassifyDeleteCheckResp true "type json string"
// @Success 200 Ret=200 检测成功
// @router /link/check [post]
func (this *SandboxController) LinkEdbInfoCheck() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req sandbox.SandboxLinkCheckReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	resp := new(sandbox.SandboxLinkCheckResp)
	edbInfoList, err := data_manage.GetEdbInfoByIdList(req.EdbInfoIdList)
	if err != nil {
		br.Msg = "获取指标信息失败"
		br.ErrMsg = "获取指标信息失败,err:" + err.Error()
		return
	}
	edbList := make([]*sandbox.SandboxLinkCheckItem, 0)
	for _, v := range edbInfoList {
		tmp := &sandbox.SandboxLinkCheckItem{
			Id:         v.EdbInfoId,
			Name:       v.EdbName,
			UniqueCode: v.UniqueCode,
			ClassifyId: v.ClassifyId,
		}
		edbList = append(edbList, tmp)
	}

	chartList, err := data_manage.GetChartInfoByIdList(req.ChartInfoIdList)
	if err != nil {
		br.Msg = `获取失败`
		br.ErrMsg = `获取图表列表失败，ERR：` + err.Error()
		return
	}
	chartListTmp := make([]*sandbox.SandboxLinkCheckItem, 0)
	for _, v := range chartList {
		tmp := &sandbox.SandboxLinkCheckItem{
			Id:         v.ChartInfoId,
			Name:       v.ChartName,
			UniqueCode: v.UniqueCode,
			ClassifyId: v.ChartClassifyId,
		}
		chartListTmp = append(chartListTmp, tmp)
	}

	reportList, err := models.GetSimpleReportByIds(req.ReportIdList)
	if err != nil {
		br.Msg = `获取失败`
		br.ErrMsg = `获取报告列表失败，ERR：` + err.Error()
		return
	}
	reportListTmp := make([]*sandbox.SandboxLinkCheckItem, 0)
	for _, v := range reportList {
		tmp := &sandbox.SandboxLinkCheckItem{
			Id:         v.Id,
			Name:       v.Title,
			UniqueCode: v.ReportCode,
		}
		reportListTmp = append(reportListTmp, tmp)
	}
	resp.EdbInfoIdList = edbList
	resp.ChartInfoIdList = chartListTmp
	resp.ReportIdList = reportListTmp
	br.Ret = 200
	br.Msg = "检测成功"
	br.Success = true
	br.Data = resp
}
