Browse Source

Merge branch 'ETA_1.1.5'

ziwen 1 year ago
parent
commit
24dd979c13

+ 1850 - 292
controllers/sandbox/sandbox.go

@@ -4,14 +4,15 @@ 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"
-	"eta/eta_api/models/system"
 	sandboxService "eta/eta_api/services/sandbox"
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
 )
 
 // versionSize 版本列表第一页数据约定是:3条
@@ -31,115 +32,115 @@ type SandboxController struct {
 // @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
-}
+//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 逻辑导图版本列表(列表页第一页)
@@ -299,82 +300,82 @@ func (this *SandboxController) VersionList() {
 	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
-}
+//// 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 添加沙盘草稿
@@ -640,111 +641,111 @@ func (this *SandboxController) Delete() {
 	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
-}
+//// 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 逻辑导图列表(其他地方引用到的,莫名其妙要根据输入的关键字匹配品种)
@@ -799,7 +800,7 @@ func (this *SandboxController) ListByQuote() {
 	}
 
 	if list == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
-		list = make([]*sandbox.SandboxListItem, 0)
+		list = make([]*sandbox.Sandbox, 0)
 	}
 
 	page := paging.GetPaging(currentIndex, pageSize, total)
@@ -812,3 +813,1560 @@ func (this *SandboxController) ListByQuote() {
 	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
+	}
+
+	if item.SandboxClassifyName != req.SandboxClassifyName {
+		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.SandboxClassifyName)
+		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
+		}
+
+		//如果改变了分类,那么移动该图表数据
+		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
+			}
+		}
+	}
+
+	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,
+		}
+		//缩略图为空时不更新
+		var updateSandboxColumn = []string{}
+		if req.PicUrl == ""{
+			updateSandboxColumn = []string{"Content", "MindmapData", "ModifyTime", "SandboxClassifyId"}
+		} else {
+			updateSandboxColumn = []string{"Content", "MindmapData", "PicUrl", "ModifyTime", "SandboxClassifyId"}
+		}
+		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
+	}
+
+	//获取沙盘数据详情(已保存的)
+	sandboxVersionInfo, 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 = sandboxVersionInfo
+}
+
+//// 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
+	}
+	for _, v := range edbInfoList {
+		resp.EdbInfoIdList = append(resp.EdbInfoIdList, v.EdbInfoId)
+	}
+
+	chartList, err := data_manage.GetChartInfoByIdList(req.ChartInfoIdList)
+	if err != nil {
+		br.Msg = `获取失败`
+		br.ErrMsg = `获取图表列表失败,ERR:` + err.Error()
+		return
+	}
+	for _, v := range chartList {
+		resp.ChartInfoIdList = append(resp.ChartInfoIdList, v.ChartInfoId)
+	}
+
+	reportList, err := models.GetSimpleReportByIds(req.ReportIdList)
+	if err != nil {
+		br.Msg = `获取失败`
+		br.ErrMsg = `获取报告列表失败,ERR:` + err.Error()
+		return
+	}
+	for _, v := range reportList {
+		resp.ReportIdList = append(resp.ReportIdList, v.Id)
+	}
+
+	br.Ret = 200
+	br.Msg = "检测成功"
+	br.Success = true
+	br.Data = resp
+}

+ 4 - 3
models/db.go

@@ -228,9 +228,10 @@ func initYb() {
 func initSandbox() {
 	//注册对象
 	orm.RegisterModel(
-		new(sandbox.Sandbox),        //沙盘主表
-		new(sandbox.SandboxVersion), //沙盘版本表
-		new(sandbox.SandboxDraft),   //沙盘草稿表
+		new(sandbox.Sandbox),         //沙盘主表
+		new(sandbox.SandboxVersion),  //沙盘版本表
+		new(sandbox.SandboxDraft),    //沙盘草稿表
+		new(sandbox.SandboxClassify), //沙盘分类表
 	)
 }
 

+ 11 - 0
models/sandbox/request/sandbox.go

@@ -26,3 +26,14 @@ type DeleteSandbox struct {
 type DeleteSandboxVersion struct {
 	SandboxVersionCode string `description:"沙盘版本code"`
 }
+
+// AddAndEditSandboxV2 添加/编辑沙盘的请求数据
+type AddAndEditSandboxV2 struct {
+	SandboxId         int    `description:"沙盘id"`
+	Name              string `description:"沙盘名称"`
+	Content           string `description:"沙盘内容"`
+	MindmapData       string `description:"思维导图内容"`
+	PicUrl            string `description:"沙盘图片地址"`
+	SvgData           string `description:"沙盘svg图片数据"`
+	SandboxClassifyId int    `description:"分类id"`
+}

+ 1 - 1
models/sandbox/response/sandbox.go

@@ -8,7 +8,7 @@ import (
 // SandboxListResp 沙盘列表返回数据
 type SandboxListResp struct {
 	Paging *paging.PagingItem
-	List   []*sandbox.SandboxListItem
+	List   []*sandbox.Sandbox
 }
 
 // SandboxVersionListResp 沙盘版本列表返回数据

+ 223 - 15
models/sandbox/sandbox.go

@@ -1,25 +1,47 @@
 package sandbox
 
 import (
+	"eta/eta_api/models/system"
+	"eta/eta_api/utils"
+	"fmt"
 	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"time"
 )
 
 // Sandbox 沙盘推演主表
+//type Sandbox struct {
+//	SandboxId           int       `orm:"column(sandbox_id);pk" description:"沙盘id"`
+//	Name                string    `description:"沙盘名称"`
+//	ChartPermissionId   int       `description:"品种id"`
+//	ChartPermissionName string    `description:"品种名称"`
+//	CurrVersion         int       `description:"当前版本"`
+//	Code                string    `description:"沙盘code"`
+//	Content             string    `description:"沙盘数据"`
+//	PicUrl              string    `description:"沙盘图片地址"`
+//	OpUserId            int       `description:"最近一次编辑操作的用户id"`
+//	OpUserName          string    `description:"最近一次编辑的用户名称(冗余字段,避免查表)"`
+//	IsDelete            int8      `description:"是否删除,0:未删除,1:已删除"`
+//	ModifyTime          time.Time `description:"修改时间"`
+//	CreateTime          time.Time `description:"创建时间"`
+//	SandboxClassifyId   int       `description:"分类id"`
+//	Sort                int       `description:"排序"`
+//}
+
 type Sandbox struct {
-	SandboxId           int       `orm:"column(sandbox_id);pk" description:"沙盘id"`
-	Name                string    `description:"沙盘名称"`
-	ChartPermissionId   int       `description:"品种id"`
-	ChartPermissionName string    `description:"品种名称"`
-	CurrVersion         int       `description:"当前版本"`
-	Code                string    `description:"沙盘code"`
-	Content             string    `description:"沙盘数据"`
-	PicUrl              string    `description:"沙盘图片地址"`
-	OpUserId            int       `description:"最近一次编辑操作的用户id"`
-	OpUserName          string    `description:"最近一次编辑的用户名称(冗余字段,避免查表)"`
-	IsDelete            int8      `description:"是否删除,0:未删除,1:已删除"`
-	ModifyTime          time.Time `description:"修改时间"`
-	CreateTime          time.Time `description:"创建时间"`
+	SandboxId         int       `orm:"column(sandbox_id);pk" description:"沙盘id"`
+	Name              string    `description:"沙盘名称"`
+	Code              string    `description:"沙盘code"`
+	Content           string    `description:"沙盘数据"`
+	MindmapData       string    `description:"思维导图数据"`
+	PicUrl            string    `description:"沙盘图片地址"`
+	SysUserId         int       `description:"作者id"`
+	SysUserName       string    `description:"作者名称"`
+	IsDelete          int8      `description:"是否删除,0:未删除,1:已删除"`
+	ModifyTime        time.Time `description:"修改时间"`
+	CreateTime        time.Time `description:"创建时间"`
+	SandboxClassifyId int       `description:"分类id"`
+	Sort              int       `description:"排序"`
 }
 
 // Update 沙盘字段变更
@@ -172,9 +194,9 @@ type SandboxListItem struct {
 }
 
 // GetList 获取沙盘列表页
-func GetList(condition string, pars []interface{}, startSize, pageSize int) (total int, list []*SandboxListItem, err error) {
+func GetList(condition string, pars []interface{}, startSize, pageSize int) (total int, list []*Sandbox, err error) {
 	o := orm.NewOrmUsingDB("data")
-	sql := "select a.sandbox_id,a.name,a.chart_permission_id,a.chart_permission_name,a.curr_version,a.code,a.pic_url,a.op_user_id,a.op_user_name,a.modify_time,a.create_time,b.version_code from sandbox as a join sandbox_version b on a.sandbox_id=b.sandbox_id and a.curr_version=b.curr_version where 1=1 AND a.is_delete = 0 "
+	sql := "select a.sandbox_id,a.name,a.code,a.pic_url,a.sys_user_id,a.sys_user_name,a.modify_time,a.create_time from sandbox as a where 1=1 AND a.is_delete = 0 "
 	sql += condition
 	sql += ` order by a.modify_time desc,a.sandbox_id desc`
 
@@ -193,3 +215,189 @@ type SandboxSaveResp struct {
 	*Sandbox
 	VersionCode string `description:"版本号"`
 }
+
+func GetSandboxAll() (list []*SandboxClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT sandbox_id,sandbox_classify_id,name AS sandbox_classify_name, sort
+		FROM sandbox `
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}
+
+// CheckOpSandboxPermission 判断沙盘操作权限
+func CheckOpSandboxPermission(sysUser *system.Admin, createUserId int) (ok bool) {
+	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN {
+		ok = true
+	}
+	// 如果图表创建人与当前操作人相同的话,那么就是允许操作
+	if ok == false && createUserId == sysUser.AdminId {
+		ok = true
+	}
+	// 如果图表权限id 是 1 ,那么允许编辑
+	if ok == false && sysUser.ChartPermission == 1 {
+		ok = true
+	}
+	return
+}
+
+// GetSandboxInfoByAdminId 获取所有我创建的沙盘,用于分类展示
+func GetSandboxInfoByAdminId(adminId int) (items []*SandboxClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT sandbox_id,sandbox_classify_id,name AS sandbox_classify_name,code,
+             sys_user_id,sys_user_name
+            FROM sandbox where sys_user_id = ? ORDER BY sort asc,create_time ASC `
+	_, err = o.Raw(sql, adminId).QueryRows(&items)
+	return
+}
+
+func GetSandboxClassify(sandboxClassifyId int) (sandbox_classify_id string, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT GROUP_CONCAT(t.sandbox_classify_id) AS sandbox_classify_id FROM (
+			SELECT a.sandbox_classify_id FROM sandbox_classify AS a 
+			WHERE a.sandbox_classify_id=?
+			UNION ALL
+			SELECT a.sandbox_classify_id FROM sandbox_classify AS a 
+			WHERE a.parent_id=? UNION ALL
+	SELECT
+		sandbox_classify_id 
+	FROM
+		sandbox_classify 
+WHERE
+	parent_id IN ( SELECT sandbox_classify_id FROM sandbox_classify WHERE parent_id = ? )
+			)AS t`
+	err = o.Raw(sql, sandboxClassifyId, sandboxClassifyId, sandboxClassifyId).QueryRow(&sandbox_classify_id)
+	return
+}
+
+type SandboxListItems struct {
+	Sandbox
+	ParentIds string
+}
+
+func GetSandboxListByCondition(condition string, pars []interface{}, startSize, pageSize int) (item []*SandboxListItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM sandbox WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += " ORDER BY create_time DESC LIMIT ?,? "
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&item)
+	return
+}
+
+func GetSandboxListCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count FROM sandbox WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+type SandboxListResp struct {
+	Paging *paging.PagingItem
+	List   []*SandboxListItems
+}
+
+func AddSandbox(item *Sandbox) (lastId int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	lastId, err = o.Insert(item)
+	return
+}
+
+func GetSandboxItemsByClassifyId(sandboxClassifyId int) (list []*SandboxClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT sandbox_id,sandbox_classify_id,name AS sandbox_classify_name, sort
+		FROM sandbox  WHERE sandbox_classify_id = ? AND is_delete = 0  ORDER BY sort `
+	_, err = o.Raw(sql, sandboxClassifyId).QueryRows(&list)
+	return
+}
+
+func GetSandboxAllParentByClassifyId(sandboxClassifyId int) (ids string, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT
+	GROUP_CONCAT(DISTINCT m.sandbox_classify_id  ORDER BY m.level) AS ids 
+FROM
+	(
+	SELECT
+		@id AS _id,(
+		SELECT
+			@id := parent_id 
+		FROM
+			sandbox_classify 
+		WHERE
+			sandbox_classify_id = _id 
+		) 
+	FROM
+		(
+		SELECT
+			@id :=(
+			SELECT
+				parent_id 
+			FROM
+				sandbox_classify 
+			WHERE
+				sandbox_classify_id = ? 
+			)) vm,
+		sandbox_classify m 
+	WHERE
+		@id IS NOT NULL 
+	) vm
+	INNER JOIN sandbox_classify m 
+WHERE
+	sandbox_classify_id = vm._id `
+	err = o.Raw(sql, sandboxClassifyId).QueryRow(&ids)
+	return
+}
+
+type MoveSandboxReq struct {
+	SandboxId         int `description:"沙盘ID"`
+	PrevSandboxId     int `description:"上一个沙盘ID"`
+	NextSandboxId     int `description:"下一个沙盘ID"`
+	SandboxClassifyId int `description:"分类id"`
+}
+
+func GetSandboxClassifyCountById(classifyId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT count(1) AS count FROM sandbox_classify WHERE sandbox_classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&count)
+	return
+}
+
+// GetSandboxByClassifyIdAndName 根据分类id和沙盘名获取图表信息
+func GetSandboxByClassifyIdAndName(classifyId int, name string) (item *Sandbox, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM sandbox WHERE sandbox_classify_id = ? and name=? `
+	err = o.Raw(sql, classifyId, name).QueryRow(&item)
+	return
+}
+
+func MoveSandbox(sandboxId, classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` UPDATE  sandbox
+			SET
+			  sandbox_classify_id = ?
+			WHERE sandbox_id = ?`
+	_, err = o.Raw(sql, classifyId, sandboxId).Exec()
+	return
+}
+
+// UpdateSandboxSortByClassifyId 根据沙盘id更新排序
+func UpdateSandboxSortByClassifyId(classifyId, nowSort, prevSandboxId int, updateSort string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` update sandbox set sort = ` + updateSort + ` WHERE sandbox_classify_id=?  AND `
+	if prevSandboxId > 0 {
+		sql += ` (sort > ? or (sandbox_id > ` + fmt.Sprint(prevSandboxId) + ` and sort = ` + fmt.Sprint(nowSort) + `))`
+	}
+	_, err = o.Raw(sql, classifyId, nowSort).Exec()
+	return
+}
+
+// GetFirstSandboxByClassifyId 获取当前分类下,且排序数相同 的排序第一条的数据
+func GetFirstSandboxByClassifyId(classifyId int) (item *Sandbox, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM sandbox WHERE sandbox_classify_id=? order by sort asc,sandbox_id asc limit 1`
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}

+ 163 - 9
models/sandbox/sandbox_classify.go

@@ -1,6 +1,7 @@
 package sandbox
 
 import (
+	"fmt"
 	"github.com/beego/beego/v2/client/orm"
 	"time"
 )
@@ -8,14 +9,16 @@ import (
 type SandboxClassify struct {
 	SandboxClassifyId   int       `orm:"column(sandbox_classify_id);pk"`
 	SandboxClassifyName string    `description:"分类名称"`
-	ParentId          int       `description:"父级id"`
-	HasData           int       `description:"是否含有指标数据"`
-	CreateTime        time.Time `description:"创建时间"`
-	ModifyTime        time.Time `description:"修改时间"`
-	SysUserId         int       `description:"创建人id"`
-	SysUserRealName   string    `description:"创建人姓名"`
-	Level             int       `description:"层级"`
-	Sort              int       `description:"排序字段,越小越靠前,默认值:10"`
+	ParentId            int       `description:"父级id"`
+	HasData             int       `description:"是否含有指标数据"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"修改时间"`
+	SysUserId           int       `description:"创建人id"`
+	SysUserRealName     string    `description:"创建人姓名"`
+	Level               int       `description:"层级"`
+	ChartPermissionId   int       `description:"品种id"`
+	ChartPermissionName string    `description:"品种名称"`
+	Sort                int       `description:"排序字段,越小越靠前,默认值:10"`
 }
 
 func AddSandboxClassify(item *SandboxClassify) (lastId int64, err error) {
@@ -48,7 +51,7 @@ type SandboxClassifyItems struct {
 	CreateTime          time.Time `description:"创建时间"`
 	ModifyTime          time.Time `description:"修改时间"`
 	SysUserId           int       `description:"创建人id"`
-	SysUserRealName     string    `description:"创建人姓名"`
+	SysUserName         string    `description:"创建人姓名"`
 	Level               int       `description:"层级"`
 	Sort                int       `description:"排序字段,越小越靠前,默认值:10"`
 	SandboxId           int       `description:"沙盘id"`
@@ -63,6 +66,8 @@ type AddSandboxClassifyReq struct {
 	SandboxClassifyName string `description:"分类名称"`
 	ParentId            int    `description:"父级id,第一级传0"`
 	Level               int    `description:"层级,第一级传0,其余传上一级的层级"`
+	ChartPermissionId   int    `description:"品种id"`
+	ChartPermissionName string `description:"品种名称"`
 }
 
 func GetSandboxClassifyCount(sandboxClassifyName string, parentId int) (count int, err error) {
@@ -90,4 +95,153 @@ func GetSandboxClassifyById(classifyId int) (item *SandboxClassify, err error) {
 	sql := `SELECT * FROM sandbox_classify WHERE sandbox_classify_id=? `
 	err = o.Raw(sql, classifyId).QueryRow(&item)
 	return
+}
+
+func EditSandboxClassify(classifyId int, sandboxClassifyName string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `UPDATE sandbox_classify SET sandbox_classify_name=?,modify_time=NOW() WHERE sandbox_classify_id=? `
+	_, err = o.Raw(sql, sandboxClassifyName, classifyId).Exec()
+	return
+}
+
+type SandboxClassifyDeleteCheckReq struct {
+	SandboxClassifyId int `description:"分类id"`
+}
+
+func GetSandboxInfoCountByClassifyId(classifyId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count FROM sandbox AS a
+				WHERE a.sandbox_classify_id IN(
+				SELECT t.sandbox_classify_id FROM 
+				(
+				SELECT rd.*
+				FROM (SELECT * FROM sandbox_classify WHERE parent_id IS NOT NULL) rd,
+					 (SELECT @pid := ?) pd 
+				WHERE FIND_IN_SET(parent_id, @pid) > 0 
+				  AND @pid := CONCAT(@pid, ',', sandbox_classify_id) 
+				UNION SELECT * FROM sandbox_classify WHERE sandbox_classify_id = @pid
+				)AS t
+				) `
+	err = o.Raw(sql, classifyId).QueryRow(&count)
+	return
+}
+
+type SandboxClassifyDeleteCheckResp struct {
+	DeleteStatus int    `description:"检测状态:0:默认值,如果为0,继续走其他校验,1:该分类下关联图表不可删除,2:确认删除当前目录及包含的子目录吗"`
+	TipsMsg      string `description:"提示信息"`
+}
+
+type DeleteSandboxClassifyReq struct {
+	SandboxClassifyId int `description:"分类id"`
+	SandboxId         int `description:"指标id"`
+}
+
+func DeleteSandboxClassify(classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` DELETE FROM sandbox_classify
+				WHERE sandbox_classify_id IN(
+				SELECT t.sandbox_classify_id FROM
+				(
+				SELECT rd.*
+				FROM (SELECT * FROM sandbox_classify WHERE parent_id IS NOT NULL) rd,
+				(SELECT @pid := ?) pd
+				WHERE FIND_IN_SET(parent_id, @pid) > 0
+				AND @pid := CONCAT(@pid, ',', sandbox_classify_id)
+				UNION SELECT * FROM sandbox_classify WHERE sandbox_classify_id = @pid
+				)AS t
+				) `
+	_, err = o.Raw(sql, classifyId).Exec()
+	return
+}
+
+// MoveSandboxClassifyReq 移动沙盘分类请求参数
+type MoveSandboxClassifyReq struct {
+	ClassifyId       int `description:"分类id"`
+	SandboxId        int `description:"沙盘ID"`
+	ParentClassifyId int `description:"父级分类id 移动沙盘时为目标分类id"`
+	PrevId           int `description:"上一个兄弟节点分类id"`
+	NextId           int `description:"下一个兄弟节点分类id"`
+	PrevType         int `description:"上一个兄弟节点类型 1分类 2沙盘 "`
+	NextType         int `description:"上一个兄弟节点类型 1分类 2沙盘 "`
+}
+
+// UpdateSandboxClassifySortByParentId 根据沙盘父类id更新排序
+func UpdateSandboxClassifySortByParentId(parentId, classifyId, nowSort int, updateSort string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` update sandbox_classify set sort = ` + updateSort + ` WHERE parent_id=? and sort > ? `
+	if classifyId > 0 {
+		sql += ` or ( sandbox_classify_id > ` + fmt.Sprint(classifyId) + ` and sort= ` + fmt.Sprint(nowSort) + `)`
+	}
+	_, err = o.Raw(sql, parentId, nowSort).Exec()
+	return
+}
+
+// GetFirstSandboxClassifyByParentId 获取当前父级沙盘分类下的排序第一条的数据
+func GetFirstSandboxClassifyByParentId(parentId int) (item *SandboxClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM sandbox_classify WHERE parent_id=? order by sort asc,sandbox_classify_id asc limit 1`
+	err = o.Raw(sql, parentId).QueryRow(&item)
+	return
+}
+
+// Update 更新沙盘分类基础信息
+func (sandboxClassify *SandboxClassify) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(sandboxClassify, cols...)
+	return
+}
+
+// GetSandboxClassifyAndInfoByParentId
+func GetSandboxClassifyAndInfoByParentId(parentId int) (items []*SandboxClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT
+	0 AS sandbox_id,
+	sandbox_classify_id,
+	sandbox_classify_name,
+	parent_id,
+	create_time,
+	modify_time,
+	sys_user_id,
+	sys_user_real_name AS sys_user_name,
+	sort,
+	level,
+	0 AS is_delete
+FROM
+	sandbox_classify 
+WHERE
+	parent_id = ? UNION ALL
+SELECT
+	sandbox_id,
+	sandbox_classify_id,
+	name AS sandbox_classify_name,
+	0 AS parent_id,
+	create_time,
+	modify_time,
+	sys_user_id,
+	sys_user_name,
+	sort,
+	0 AS level,
+	is_delete 
+FROM
+	sandbox 
+WHERE
+	sandbox_classify_id = ? AND is_delete = 0
+ORDER BY
+	sort ASC,
+	sandbox_classify_id ASC`
+	_, err = o.Raw(sql, parentId, parentId).QueryRows(&items)
+	return
+}
+
+type SandboxLinkCheckReq struct {
+	EdbInfoIdList   []int `description:"指标id列表"`
+	ChartInfoIdList []int `description:"图库id列表"`
+	ReportIdList    []int `description:"报告id列表"`
+}
+
+
+type SandboxLinkCheckResp struct {
+	EdbInfoIdList   []int `description:"指标id列表"`
+	ChartInfoIdList []int `description:"图库id列表"`
+	ReportIdList    []int `description:"报告id列表"`
 }

+ 88 - 16
routers/commentsRouter.go

@@ -4327,6 +4327,69 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
+        beego.ControllerComments{
+            Method: "AddSandboxClassify",
+            Router: `/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
+        beego.ControllerComments{
+            Method: "DeleteSandboxClassify",
+            Router: `/classify/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
+        beego.ControllerComments{
+            Method: "DeleteSandboxClassifyCheck",
+            Router: `/classify/delete/check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
+        beego.ControllerComments{
+            Method: "EditSandboxClassify",
+            Router: `/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
+        beego.ControllerComments{
+            Method: "SandboxClassifyItems",
+            Router: `/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
+        beego.ControllerComments{
+            Method: "ChartClassifyMove",
+            Router: `/classify/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
+        beego.ControllerComments{
+            Method: "SandboxClassifyList",
+            Router: `/classifyList`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
         beego.ControllerComments{
             Method: "Delete",
@@ -4338,8 +4401,8 @@ func init() {
 
     beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
         beego.ControllerComments{
-            Method: "AddSandboxDraft",
-            Router: `/draft/add`,
+            Method: "DeleteV2",
+            Router: `/deleteV2`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
             Filters: nil,
@@ -4347,8 +4410,17 @@ func init() {
 
     beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
         beego.ControllerComments{
-            Method: "ResetDraftToLastVersion",
-            Router: `/draft/reset`,
+            Method: "GetSandboxDetail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
+        beego.ControllerComments{
+            Method: "AddSandboxDraft",
+            Router: `/draft/add`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
             Filters: nil,
@@ -4365,17 +4437,17 @@ func init() {
 
     beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
         beego.ControllerComments{
-            Method: "List",
-            Router: `/list`,
-            AllowHTTPMethods: []string{"get"},
+            Method: "LinkEdbInfoCheck",
+            Router: `/link/check`,
+            AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
             Filters: nil,
             Params: nil})
 
     beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
         beego.ControllerComments{
-            Method: "ListByQuote",
-            Router: `/list_by_quote`,
+            Method: "ListV2",
+            Router: `/listV2`,
             AllowHTTPMethods: []string{"get"},
             MethodParams: param.Make(),
             Filters: nil,
@@ -4383,17 +4455,17 @@ func init() {
 
     beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
         beego.ControllerComments{
-            Method: "MarkEditStatus",
-            Router: `/mark`,
-            AllowHTTPMethods: []string{"post"},
+            Method: "ListByQuote",
+            Router: `/list_by_quote`,
+            AllowHTTPMethods: []string{"get"},
             MethodParams: param.Make(),
             Filters: nil,
             Params: nil})
 
     beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
         beego.ControllerComments{
-            Method: "Save",
-            Router: `/save`,
+            Method: "MarkEditStatus",
+            Router: `/mark`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
             Filters: nil,
@@ -4401,8 +4473,8 @@ func init() {
 
     beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/sandbox:SandboxController"],
         beego.ControllerComments{
-            Method: "DeleteVersion",
-            Router: `/version/delete`,
+            Method: "SaveV2",
+            Router: `/saveV2`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
             Filters: nil,

+ 516 - 299
services/sandbox/sandbox.go

@@ -2,7 +2,6 @@ package sandbox
 
 import (
 	"encoding/json"
-	"errors"
 	"eta/eta_api/models"
 	"eta/eta_api/models/company"
 	"eta/eta_api/models/sandbox"
@@ -15,215 +14,215 @@ import (
 )
 
 // AddSandbox 新增沙盘
-func AddSandbox(req request.AddAndEditSandbox, opUserId int, opUserName string, ignoreVariety bool) (resp *sandbox.SandboxSaveResp, err error) {
-	resp = new(sandbox.SandboxSaveResp)
-	// 获取产品权限详情
-	var permissionName string
-	if !ignoreVariety {
-		chartPermissionInfo, e := company.GetChartPermissionListById(req.ChartPermissionId)
-		if e != nil {
-			err = e
-			return
-		}
-		permissionName = chartPermissionInfo.PermissionName
-	}
-	//沙盘主表信息
-	sandboxInfo := &sandbox.Sandbox{
-		Name:                utils.TrimStr(req.Name),
-		ChartPermissionId:   req.ChartPermissionId,
-		ChartPermissionName: permissionName,
-		CurrVersion:         1,
-		Code:                GenerateCode(),
-		Content:             req.Content,
-		PicUrl:              utils.TrimStr(req.PicUrl),
-		OpUserId:            opUserId,
-		OpUserName:          opUserName,
-		IsDelete:            0,
-		ModifyTime:          time.Now(),
-		CreateTime:          time.Now(),
-	}
-	//沙盘版本表信息
-	sandboxVersionInfo := &sandbox.SandboxVersion{
-		Name:                sandboxInfo.Name,
-		ChartPermissionId:   sandboxInfo.ChartPermissionId,
-		ChartPermissionName: sandboxInfo.ChartPermissionName,
-		CurrVersion:         sandboxInfo.CurrVersion,
-		Content:             sandboxInfo.Content,
-		PicUrl:              sandboxInfo.PicUrl,
-		OpUserId:            sandboxInfo.OpUserId,
-		OpUserName:          sandboxInfo.OpUserName,
-		VersionCode:         GenerateVersionCode(sandboxInfo.SandboxId, sandboxInfo.CurrVersion),
-		IsDelete:            sandboxInfo.IsDelete,
-		CreateTime:          sandboxInfo.CreateTime,
-	}
-	//沙盘草稿表信息
-	sandboxDraftInfo := &sandbox.SandboxDraft{
-		Name:                sandboxInfo.Name,
-		ChartPermissionId:   sandboxInfo.ChartPermissionId,
-		ChartPermissionName: sandboxInfo.ChartPermissionName,
-		CurrVersion:         sandboxInfo.CurrVersion,
-		Content:             sandboxInfo.Content,
-		OpUserId:            sandboxInfo.OpUserId,
-		OpUserName:          sandboxInfo.OpUserName,
-		CreateTime:          sandboxInfo.CreateTime,
-	}
-
-	//新增沙盘
-	err = sandbox.AddNewSandbox(sandboxInfo, sandboxVersionInfo, sandboxDraftInfo)
-	if err != nil {
-		return
-	}
-	resp.Sandbox = sandboxInfo
-	resp.VersionCode = sandboxVersionInfo.VersionCode
-	return
-}
+//func AddSandbox(req request.AddAndEditSandbox, opUserId int, opUserName string, ignoreVariety bool) (resp *sandbox.SandboxSaveResp, err error) {
+//	resp = new(sandbox.SandboxSaveResp)
+//	// 获取产品权限详情
+//	var permissionName string
+//	if !ignoreVariety {
+//		chartPermissionInfo, e := company.GetChartPermissionListById(req.ChartPermissionId)
+//		if e != nil {
+//			err = e
+//			return
+//		}
+//		permissionName = chartPermissionInfo.PermissionName
+//	}
+//	//沙盘主表信息
+//	sandboxInfo := &sandbox.Sandbox{
+//		Name:                utils.TrimStr(req.Name),
+//		ChartPermissionId:   req.ChartPermissionId,
+//		ChartPermissionName: permissionName,
+//		CurrVersion:         1,
+//		Code:                GenerateCode(),
+//		Content:             req.Content,
+//		PicUrl:              utils.TrimStr(req.PicUrl),
+//		OpUserId:            opUserId,
+//		OpUserName:          opUserName,
+//		IsDelete:            0,
+//		ModifyTime:          time.Now(),
+//		CreateTime:          time.Now(),
+//	}
+//	//沙盘版本表信息
+//	sandboxVersionInfo := &sandbox.SandboxVersion{
+//		Name:                sandboxInfo.Name,
+//		ChartPermissionId:   sandboxInfo.ChartPermissionId,
+//		ChartPermissionName: sandboxInfo.ChartPermissionName,
+//		CurrVersion:         sandboxInfo.CurrVersion,
+//		Content:             sandboxInfo.Content,
+//		PicUrl:              sandboxInfo.PicUrl,
+//		OpUserId:            sandboxInfo.OpUserId,
+//		OpUserName:          sandboxInfo.OpUserName,
+//		VersionCode:         GenerateVersionCode(sandboxInfo.SandboxId, sandboxInfo.CurrVersion),
+//		IsDelete:            sandboxInfo.IsDelete,
+//		CreateTime:          sandboxInfo.CreateTime,
+//	}
+//	//沙盘草稿表信息
+//	sandboxDraftInfo := &sandbox.SandboxDraft{
+//		Name:                sandboxInfo.Name,
+//		ChartPermissionId:   sandboxInfo.ChartPermissionId,
+//		ChartPermissionName: sandboxInfo.ChartPermissionName,
+//		CurrVersion:         sandboxInfo.CurrVersion,
+//		Content:             sandboxInfo.Content,
+//		OpUserId:            sandboxInfo.OpUserId,
+//		OpUserName:          sandboxInfo.OpUserName,
+//		CreateTime:          sandboxInfo.CreateTime,
+//	}
+//
+//	//新增沙盘
+//	err = sandbox.AddNewSandbox(sandboxInfo, sandboxVersionInfo, sandboxDraftInfo)
+//	if err != nil {
+//		return
+//	}
+//	resp.Sandbox = sandboxInfo
+//	resp.VersionCode = sandboxVersionInfo.VersionCode
+//	return
+//}
 
 // UpdateSandbox 更新沙盘
-func UpdateSandbox(req request.AddAndEditSandbox, opUserId int, opUserName string, ignoreVariety bool) (resp *sandbox.SandboxSaveResp, err error, errMsg string) {
-	resp = new(sandbox.SandboxSaveResp)
-	// 获取沙盘版本信息
-	sandboxVersion, err := sandbox.GetSandboxVersionBySandboxVersionCode(req.SandboxVersionCode)
-	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
-			errMsg = "找不到该版本"
-			err = errors.New(errMsg)
-		}
-		return
-	}
-	// 获取沙盘主表信息
-	sandboxInfo, err := sandbox.GetSandboxById(sandboxVersion.SandboxId)
-	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
-			errMsg = "找不到该沙盘"
-			err = errors.New(errMsg)
-		}
-		return
-	}
-	//沙盘名称是否更改校验
-	var isUpdateName, isUpdateContent bool
-	if sandboxInfo.Name != utils.TrimStr(req.Name) {
-		isUpdateName = true
-	}
-
-	// 沙盘内容md5比对,不一致则代表有做更改
-	//if utils.MD5(sandboxInfo.Content) != utils.MD5(req.Content) {
-	//	isUpdateContent = true
-	//}
-	if checkoutContent(sandboxInfo.Content, req.Content) {
-		isUpdateContent = true
-	}
-
-	//如果沙盘名称和沙盘内容都没有做过修改,那么就不做保存
-	if isUpdateName == false && isUpdateContent == false {
-		return
-	}
-
-	// 获取产品权限详情
-	var permissionName string
-	if !ignoreVariety {
-		chartPermissionInfo, e := company.GetChartPermissionListById(req.ChartPermissionId)
-		if e != nil {
-			err = e
-			return
-		}
-		permissionName = chartPermissionInfo.PermissionName
-	}
-
-	//如果只更新了沙盘名称,那么只去修改最新版本的沙盘名称,而不去累计版本
-	if isUpdateName == true && isUpdateContent == false {
-		sandboxInfo.Name = utils.TrimStr(req.Name)
-		sandboxInfo.ChartPermissionId = req.ChartPermissionId
-		sandboxInfo.ChartPermissionName = permissionName
-		sandboxInfo.Content = req.Content
-		sandboxInfo.PicUrl = utils.TrimStr(req.PicUrl)
-		sandboxInfo.OpUserId = opUserId
-		sandboxInfo.OpUserName = opUserName
-		sandboxInfo.ModifyTime = time.Now()
-		var updateSandboxColumn = []string{"Name", "ChartPermissionId", "ChartPermissionName", "PicUrl", "OpUserId", "OpUserName", "ModifyTime"}
-
-		//沙盘版本表信息
-		sandboxVersionInfo, tmpErr := sandbox.GetSandboxVersionBySandbox2VersionId(sandboxInfo.SandboxId, sandboxInfo.CurrVersion)
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-		sandboxVersionInfo.Name = sandboxInfo.Name
-		sandboxVersionInfo.ChartPermissionId = sandboxInfo.ChartPermissionId
-		sandboxVersionInfo.ChartPermissionName = sandboxInfo.ChartPermissionName
-		sandboxVersionInfo.PicUrl = sandboxInfo.PicUrl
-		sandboxVersionInfo.OpUserId = sandboxInfo.OpUserId
-		sandboxVersionInfo.OpUserName = sandboxInfo.OpUserName
-		var updateSandboxVersionColumn = []string{"Name", "ChartPermissionId", "ChartPermissionName", "PicUrl", "OpUserId", "OpUserName"}
-
-		//沙盘草稿表信息
-		sandboxDraftInfo := &sandbox.SandboxDraft{
-			Name:                sandboxInfo.Name,
-			ChartPermissionId:   sandboxInfo.ChartPermissionId,
-			ChartPermissionName: sandboxInfo.ChartPermissionName,
-			CurrVersion:         sandboxInfo.CurrVersion,
-			Content:             sandboxInfo.Content,
-			OpUserId:            sandboxInfo.OpUserId,
-			OpUserName:          sandboxInfo.OpUserName,
-			CreateTime:          time.Now(),
-		}
-
-		//修改沙盘
-		err = sandbox.UpdateSandboxName(sandboxInfo, sandboxVersionInfo, sandboxDraftInfo, updateSandboxColumn, updateSandboxVersionColumn)
-		if err != nil {
-			return
-		}
-		resp.Sandbox = sandboxInfo
-		resp.VersionCode = sandboxVersionInfo.VersionCode
-	} else {
-		sandboxInfo.Name = utils.TrimStr(req.Name)
-		sandboxInfo.ChartPermissionId = req.ChartPermissionId
-		sandboxInfo.ChartPermissionName = permissionName
-		sandboxInfo.CurrVersion = sandboxInfo.CurrVersion + 1
-		sandboxInfo.Content = req.Content
-		sandboxInfo.PicUrl = utils.TrimStr(req.PicUrl)
-		sandboxInfo.OpUserId = opUserId
-		sandboxInfo.OpUserName = opUserName
-		sandboxInfo.ModifyTime = time.Now()
-
-		var updateSandbox = []string{"Name", "ChartPermissionId", "ChartPermissionName", "CurrVersion", "Content", "PicUrl", "OpUserId", "OpUserName", "ModifyTime"}
-
-		//沙盘版本表信息
-		sandboxVersionInfo := &sandbox.SandboxVersion{
-			Name:                sandboxInfo.Name,
-			ChartPermissionId:   sandboxInfo.ChartPermissionId,
-			ChartPermissionName: sandboxInfo.ChartPermissionName,
-			CurrVersion:         sandboxInfo.CurrVersion,
-			Content:             sandboxInfo.Content,
-			SvgData:             req.SvgData,
-			PicUrl:              sandboxInfo.PicUrl,
-			OpUserId:            sandboxInfo.OpUserId,
-			OpUserName:          sandboxInfo.OpUserName,
-			VersionCode:         GenerateVersionCode(sandboxInfo.SandboxId, sandboxInfo.CurrVersion),
-			IsDelete:            sandboxInfo.IsDelete,
-			CreateTime:          time.Now(),
-		}
-		//沙盘草稿表信息
-		sandboxDraftInfo := &sandbox.SandboxDraft{
-			Name:                sandboxInfo.Name,
-			ChartPermissionId:   sandboxInfo.ChartPermissionId,
-			ChartPermissionName: sandboxInfo.ChartPermissionName,
-			CurrVersion:         sandboxInfo.CurrVersion,
-			Content:             sandboxInfo.Content,
-			OpUserId:            sandboxInfo.OpUserId,
-			OpUserName:          sandboxInfo.OpUserName,
-			CreateTime:          time.Now(),
-		}
-
-		//修改沙盘
-		err = sandbox.UpdateSandbox(sandboxInfo, updateSandbox, sandboxVersionInfo, sandboxDraftInfo)
-		if err != nil {
-			return
-		}
-		resp.Sandbox = sandboxInfo
-		resp.VersionCode = sandboxVersionInfo.VersionCode
-	}
-	return
-}
+//func UpdateSandbox(req request.AddAndEditSandbox, opUserId int, opUserName string, ignoreVariety bool) (resp *sandbox.SandboxSaveResp, err error, errMsg string) {
+//	resp = new(sandbox.SandboxSaveResp)
+//	// 获取沙盘版本信息
+//	sandboxVersion, err := sandbox.GetSandboxVersionBySandboxVersionCode(req.SandboxVersionCode)
+//	if err != nil {
+//		if err.Error() == utils.ErrNoRow() {
+//			errMsg = "找不到该版本"
+//			err = errors.New(errMsg)
+//		}
+//		return
+//	}
+//	// 获取沙盘主表信息
+//	sandboxInfo, err := sandbox.GetSandboxById(sandboxVersion.SandboxId)
+//	if err != nil {
+//		if err.Error() == utils.ErrNoRow() {
+//			errMsg = "找不到该沙盘"
+//			err = errors.New(errMsg)
+//		}
+//		return
+//	}
+//	//沙盘名称是否更改校验
+//	var isUpdateName, isUpdateContent bool
+//	if sandboxInfo.Name != utils.TrimStr(req.Name) {
+//		isUpdateName = true
+//	}
+//
+//	// 沙盘内容md5比对,不一致则代表有做更改
+//	//if utils.MD5(sandboxInfo.Content) != utils.MD5(req.Content) {
+//	//	isUpdateContent = true
+//	//}
+//	if checkoutContent(sandboxInfo.Content, req.Content) {
+//		isUpdateContent = true
+//	}
+//
+//	//如果沙盘名称和沙盘内容都没有做过修改,那么就不做保存
+//	if isUpdateName == false && isUpdateContent == false {
+//		return
+//	}
+//
+//	// 获取产品权限详情
+//	var permissionName string
+//	if !ignoreVariety {
+//		chartPermissionInfo, e := company.GetChartPermissionListById(req.ChartPermissionId)
+//		if e != nil {
+//			err = e
+//			return
+//		}
+//		permissionName = chartPermissionInfo.PermissionName
+//	}
+//
+//	//如果只更新了沙盘名称,那么只去修改最新版本的沙盘名称,而不去累计版本
+//	if isUpdateName == true && isUpdateContent == false {
+//		sandboxInfo.Name = utils.TrimStr(req.Name)
+//		sandboxInfo.ChartPermissionId = req.ChartPermissionId
+//		sandboxInfo.ChartPermissionName = permissionName
+//		sandboxInfo.Content = req.Content
+//		sandboxInfo.PicUrl = utils.TrimStr(req.PicUrl)
+//		sandboxInfo.OpUserId = opUserId
+//		sandboxInfo.OpUserName = opUserName
+//		sandboxInfo.ModifyTime = time.Now()
+//		var updateSandboxColumn = []string{"Name", "ChartPermissionId", "ChartPermissionName", "PicUrl", "OpUserId", "OpUserName", "ModifyTime"}
+//
+//		//沙盘版本表信息
+//		sandboxVersionInfo, tmpErr := sandbox.GetSandboxVersionBySandbox2VersionId(sandboxInfo.SandboxId, sandboxInfo.CurrVersion)
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//		sandboxVersionInfo.Name = sandboxInfo.Name
+//		sandboxVersionInfo.ChartPermissionId = sandboxInfo.ChartPermissionId
+//		sandboxVersionInfo.ChartPermissionName = sandboxInfo.ChartPermissionName
+//		sandboxVersionInfo.PicUrl = sandboxInfo.PicUrl
+//		sandboxVersionInfo.OpUserId = sandboxInfo.OpUserId
+//		sandboxVersionInfo.OpUserName = sandboxInfo.OpUserName
+//		var updateSandboxVersionColumn = []string{"Name", "ChartPermissionId", "ChartPermissionName", "PicUrl", "OpUserId", "OpUserName"}
+//
+//		//沙盘草稿表信息
+//		sandboxDraftInfo := &sandbox.SandboxDraft{
+//			Name:                sandboxInfo.Name,
+//			ChartPermissionId:   sandboxInfo.ChartPermissionId,
+//			ChartPermissionName: sandboxInfo.ChartPermissionName,
+//			CurrVersion:         sandboxInfo.CurrVersion,
+//			Content:             sandboxInfo.Content,
+//			OpUserId:            sandboxInfo.OpUserId,
+//			OpUserName:          sandboxInfo.OpUserName,
+//			CreateTime:          time.Now(),
+//		}
+//
+//		//修改沙盘
+//		err = sandbox.UpdateSandboxName(sandboxInfo, sandboxVersionInfo, sandboxDraftInfo, updateSandboxColumn, updateSandboxVersionColumn)
+//		if err != nil {
+//			return
+//		}
+//		resp.Sandbox = sandboxInfo
+//		resp.VersionCode = sandboxVersionInfo.VersionCode
+//	} else {
+//		sandboxInfo.Name = utils.TrimStr(req.Name)
+//		sandboxInfo.ChartPermissionId = req.ChartPermissionId
+//		sandboxInfo.ChartPermissionName = permissionName
+//		sandboxInfo.CurrVersion = sandboxInfo.CurrVersion + 1
+//		sandboxInfo.Content = req.Content
+//		sandboxInfo.PicUrl = utils.TrimStr(req.PicUrl)
+//		sandboxInfo.OpUserId = opUserId
+//		sandboxInfo.OpUserName = opUserName
+//		sandboxInfo.ModifyTime = time.Now()
+//
+//		var updateSandbox = []string{"Name", "ChartPermissionId", "ChartPermissionName", "CurrVersion", "Content", "PicUrl", "OpUserId", "OpUserName", "ModifyTime"}
+//
+//		//沙盘版本表信息
+//		sandboxVersionInfo := &sandbox.SandboxVersion{
+//			Name:                sandboxInfo.Name,
+//			ChartPermissionId:   sandboxInfo.ChartPermissionId,
+//			ChartPermissionName: sandboxInfo.ChartPermissionName,
+//			CurrVersion:         sandboxInfo.CurrVersion,
+//			Content:             sandboxInfo.Content,
+//			SvgData:             req.SvgData,
+//			PicUrl:              sandboxInfo.PicUrl,
+//			OpUserId:            sandboxInfo.OpUserId,
+//			OpUserName:          sandboxInfo.OpUserName,
+//			VersionCode:         GenerateVersionCode(sandboxInfo.SandboxId, sandboxInfo.CurrVersion),
+//			IsDelete:            sandboxInfo.IsDelete,
+//			CreateTime:          time.Now(),
+//		}
+//		//沙盘草稿表信息
+//		sandboxDraftInfo := &sandbox.SandboxDraft{
+//			Name:                sandboxInfo.Name,
+//			ChartPermissionId:   sandboxInfo.ChartPermissionId,
+//			ChartPermissionName: sandboxInfo.ChartPermissionName,
+//			CurrVersion:         sandboxInfo.CurrVersion,
+//			Content:             sandboxInfo.Content,
+//			OpUserId:            sandboxInfo.OpUserId,
+//			OpUserName:          sandboxInfo.OpUserName,
+//			CreateTime:          time.Now(),
+//		}
+//
+//		//修改沙盘
+//		err = sandbox.UpdateSandbox(sandboxInfo, updateSandbox, sandboxVersionInfo, sandboxDraftInfo)
+//		if err != nil {
+//			return
+//		}
+//		resp.Sandbox = sandboxInfo
+//		resp.VersionCode = sandboxVersionInfo.VersionCode
+//	}
+//	return
+//}
 
 // AddSandboxDraft 新增沙盘草稿
 func AddSandboxDraft(sandboxId int, req request.AddAndEditSandbox, opUserId int, opUserName string) (sandboxDraftInfo *sandbox.SandboxDraft, err error) {
@@ -328,29 +327,29 @@ func UpdateSandboxEditMark(sandboxId, nowUserId, status int, nowUserName string)
 }
 
 // ResetDraftToLastVersion  重置沙盘草稿至最新版本
-func ResetDraftToLastVersion(sandboxId, opUserId int, opUserName string) (sandboxDraftInfo *sandbox.SandboxDraft, err error) {
-	// 获取沙盘主表信息
-	sandboxInfo, err := sandbox.GetSandboxById(sandboxId)
-	if err != nil {
-		return
-	}
-
-	//沙盘草稿表信息
-	sandboxDraftInfo = &sandbox.SandboxDraft{
-		SandboxId:           sandboxInfo.SandboxId,
-		Name:                sandboxInfo.Name,
-		ChartPermissionId:   sandboxInfo.ChartPermissionId,
-		ChartPermissionName: sandboxInfo.ChartPermissionName,
-		Content:             sandboxInfo.Content,
-		OpUserId:            opUserId,
-		OpUserName:          opUserName,
-		CreateTime:          time.Now(),
-	}
-
-	//新增沙盘草稿
-	err = sandbox.AddSandboxDraft(sandboxDraftInfo)
-	return
-}
+//func ResetDraftToLastVersion(sandboxId, opUserId int, opUserName string) (sandboxDraftInfo *sandbox.SandboxDraft, err error) {
+//	// 获取沙盘主表信息
+//	sandboxInfo, err := sandbox.GetSandboxById(sandboxId)
+//	if err != nil {
+//		return
+//	}
+//
+//	//沙盘草稿表信息
+//	sandboxDraftInfo = &sandbox.SandboxDraft{
+//		SandboxId:           sandboxInfo.SandboxId,
+//		Name:                sandboxInfo.Name,
+//		ChartPermissionId:   sandboxInfo.ChartPermissionId,
+//		ChartPermissionName: sandboxInfo.ChartPermissionName,
+//		Content:             sandboxInfo.Content,
+//		OpUserId:            opUserId,
+//		OpUserName:          opUserName,
+//		CreateTime:          time.Now(),
+//	}
+//
+//	//新增沙盘草稿
+//	err = sandbox.AddSandboxDraft(sandboxDraftInfo)
+//	return
+//}
 
 // DeleteSandbox 删除沙盘
 func DeleteSandbox(sandboxId int) (err error) {
@@ -367,74 +366,74 @@ func DeleteSandbox(sandboxId int) (err error) {
 }
 
 // DeleteSandboxVersion 删除沙盘版本
-func DeleteSandboxVersion(sandboxVersionCode string, opUserId int) (err error, errMsg string) {
-	// 获取沙盘版本信息
-	sandboxVersion, err := sandbox.GetSandboxVersionBySandboxVersionCode(sandboxVersionCode)
-	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
-			errMsg = "找不到该版本"
-			err = errors.New(errMsg)
-		}
-		return
-	}
-
-	/*key := fmt.Sprint(`crm:sandbox:edit:`, sandboxVersion.SandboxId)
-	nowOpUserId, _ := utils.Rc.RedisInt(key)
-	//如果当前有人操作,且获取当前操作人不是本人,那么不允许删除
-	if nowOpUserId > 0 && nowOpUserId != opUserId {
-		errMsg = "当前有其他人正在编辑,不允许删除该沙盘"
-		err = errors.New(errMsg)
-		return
-	}*/
-
-	markStatus, err := UpdateSandboxEditMark(sandboxVersion.SandboxId, opUserId, 2, "")
-	if err != nil {
-		errMsg = "查询标记状态失败"
-		err = errors.New("查询标记状态失败,Err:" + err.Error())
-		return
-	}
-	if markStatus.Status == 1 {
-		errMsg = fmt.Sprintf("当前%s正在编辑,不允许删除该沙盘", markStatus.Editor)
-		err = errors.New(errMsg)
-		return
-	}
-
-	// 获取沙盘主表信息
-	sandboxInfo, err := sandbox.GetSandboxById(sandboxVersion.SandboxId)
-	if err != nil {
-		return
-	}
-
-	// 删除最新版本,需要将上一个版本的给找出来覆盖
-	if sandboxVersion.CurrVersion == sandboxInfo.CurrVersion {
-		lastSandboxVersion, tmpErr := sandbox.GetLastSandboxVersionBySandbox2VersionId(sandboxInfo.SandboxId, sandboxVersion.CurrVersion)
-		if tmpErr != nil {
-			// 如果找不到,说明是删除整个沙盘,不仅仅是某个版本
-			if tmpErr.Error() == utils.ErrNoRow() {
-				sandboxInfo.IsDelete = 1
-				var updateSandboxColumn = []string{"IsDelete"}
-				err = sandboxInfo.Update(updateSandboxColumn)
-				return
-			}
-			err = tmpErr
-			return
-		} else {
-			//将当前沙盘信息修复到上一个版本
-			sandboxInfo.Content = lastSandboxVersion.Content
-			sandboxInfo.CurrVersion = lastSandboxVersion.CurrVersion
-			sandboxInfo.PicUrl = lastSandboxVersion.PicUrl
-			err = sandboxInfo.Update([]string{"Content", "CurrVersion", "PicUrl"})
-			if err != nil {
-				return
-			}
-		}
-	}
-	//将原来的版本标记删除
-	sandboxVersion.IsDelete = 1
-	err = sandboxVersion.Update([]string{"IsDelete"})
-
-	return
-}
+//func DeleteSandboxVersion(sandboxVersionCode string, opUserId int) (err error, errMsg string) {
+//	// 获取沙盘版本信息
+//	sandboxVersion, err := sandbox.GetSandboxVersionBySandboxVersionCode(sandboxVersionCode)
+//	if err != nil {
+//		if err.Error() == utils.ErrNoRow() {
+//			errMsg = "找不到该版本"
+//			err = errors.New(errMsg)
+//		}
+//		return
+//	}
+//
+//	/*key := fmt.Sprint(`crm:sandbox:edit:`, sandboxVersion.SandboxId)
+//	nowOpUserId, _ := utils.Rc.RedisInt(key)
+//	//如果当前有人操作,且获取当前操作人不是本人,那么不允许删除
+//	if nowOpUserId > 0 && nowOpUserId != opUserId {
+//		errMsg = "当前有其他人正在编辑,不允许删除该沙盘"
+//		err = errors.New(errMsg)
+//		return
+//	}*/
+//
+//	markStatus, err := UpdateSandboxEditMark(sandboxVersion.SandboxId, opUserId, 2, "")
+//	if err != nil {
+//		errMsg = "查询标记状态失败"
+//		err = errors.New("查询标记状态失败,Err:" + err.Error())
+//		return
+//	}
+//	if markStatus.Status == 1 {
+//		errMsg = fmt.Sprintf("当前%s正在编辑,不允许删除该沙盘", markStatus.Editor)
+//		err = errors.New(errMsg)
+//		return
+//	}
+//
+//	// 获取沙盘主表信息
+//	sandboxInfo, err := sandbox.GetSandboxById(sandboxVersion.SandboxId)
+//	if err != nil {
+//		return
+//	}
+//
+//	// 删除最新版本,需要将上一个版本的给找出来覆盖
+//	if sandboxVersion.CurrVersion == sandboxInfo.CurrVersion {
+//		lastSandboxVersion, tmpErr := sandbox.GetLastSandboxVersionBySandbox2VersionId(sandboxInfo.SandboxId, sandboxVersion.CurrVersion)
+//		if tmpErr != nil {
+//			// 如果找不到,说明是删除整个沙盘,不仅仅是某个版本
+//			if tmpErr.Error() == utils.ErrNoRow() {
+//				sandboxInfo.IsDelete = 1
+//				var updateSandboxColumn = []string{"IsDelete"}
+//				err = sandboxInfo.Update(updateSandboxColumn)
+//				return
+//			}
+//			err = tmpErr
+//			return
+//		} else {
+//			//将当前沙盘信息修复到上一个版本
+//			sandboxInfo.Content = lastSandboxVersion.Content
+//			sandboxInfo.CurrVersion = lastSandboxVersion.CurrVersion
+//			sandboxInfo.PicUrl = lastSandboxVersion.PicUrl
+//			err = sandboxInfo.Update([]string{"Content", "CurrVersion", "PicUrl"})
+//			if err != nil {
+//				return
+//			}
+//		}
+//	}
+//	//将原来的版本标记删除
+//	sandboxVersion.IsDelete = 1
+//	err = sandboxVersion.Update([]string{"IsDelete"})
+//
+//	return
+//}
 
 // GetSandboxVersionDetailByCode 获取沙盘的版本数据
 func GetSandboxVersionDetailByCode(sandboxVersionCode string) (sandboxVersionInfo *sandbox.SandboxVersion, err error) {
@@ -635,3 +634,221 @@ func checkoutContent(oldContent, reqContent string) (isUpdate bool) {
 
 	return
 }
+
+func sandboxClassifyHaveChild(allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) (childs []*sandbox.SandboxClassifyItems, yes bool) {
+	for _, v := range allNode {
+		if v.ParentId == node.SandboxClassifyId {
+			childs = append(childs, v)
+		}
+	}
+	if len(childs) > 0 {
+		yes = true
+	}
+	return
+}
+
+func SandboxClassifyItemsMakeTree(sysUser *system.Admin, allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) {
+
+	childs, _ := sandboxClassifyHaveChild(allNode, node) //判断节点是否有子节点并返回
+	if len(childs) > 0 {
+
+		node.Children = append(node.Children, childs[0:]...) //添加子节点
+		for _, v := range childs {                           //查询子节点的子节点,并添加到子节点
+			_, has := sandboxClassifyHaveChild(allNode, v)
+			if has {
+				SandboxClassifyItemsMakeTree(sysUser, allNode, v) //递归添加节点
+			} else {
+				childrenArr := make([]*sandbox.SandboxClassifyItems, 0)
+				v.Children = childrenArr
+			}
+		}
+	} else {
+		childrenArr := make([]*sandbox.SandboxClassifyItems, 0)
+		node.Children = childrenArr
+	}
+}
+
+// GetSandboxClassifyListForMe 获取我创建的沙盘
+func GetSandboxClassifyListForMe(adminInfo system.Admin, resp *sandbox.SandboxClassifyListResp, sandboxClassifyId int) (errMsg string, err error) {
+	rootList, err := sandbox.GetSandboxClassifyByParentId(sandboxClassifyId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "获取失败"
+		return
+	}
+
+	classifyAll, err := sandbox.GetSandboxClassifyByParentId(sandboxClassifyId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "获取失败"
+		return
+	}
+
+	sandboxAll, err := sandbox.GetSandboxInfoByAdminId(adminInfo.AdminId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "获取失败"
+		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]
+		SandboxClassifyItemsMakeTree(&adminInfo, classifyAll, rootNode)
+		nodeAll = append(nodeAll, rootNode)
+	}
+	//for k := range nodeAll {
+	//
+	//}
+	newAll := SandboxItemsMakeTree(nodeAll, sandListMap, sandboxClassifyId)
+	resp.AllNodes = newAll
+
+	return
+}
+
+// HandleNoPermissionSandbox 图表列表返回,将没有权限的图表移除
+func HandleNoPermissionSandbox(allNodes []*sandbox.SandboxClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*sandbox.SandboxClassifyItems) {
+	// 移除没有权限的图表
+	newAllNodes = make([]*sandbox.SandboxClassifyItems, 0)
+	for _, node := range allNodes {
+		// 二级分类
+		tmpNodeInfo := *node
+		tmpNodeList := make([]*sandbox.SandboxClassifyItems, 0)
+		if node.Children != nil {
+			for _, chartList := range node.Children {
+				tmpInfo := *chartList
+				tmpList := make([]*sandbox.SandboxClassifyItems, 0)
+
+				if chartList.Children != nil {
+					for _, chartInfo := range chartList.Children {
+						thirdInfo := *chartInfo
+						thirdList := make([]*sandbox.SandboxClassifyItems, 0)
+						// 如果指标不可见,那么就不返回该指标
+						if _, ok := noPermissionChartIdMap[chartInfo.SandboxId]; ok {
+							continue
+						}
+						tmpList = append(tmpList, chartInfo)
+
+						if chartInfo.Children != nil {
+							for _, thirdChart := range chartInfo.Children {
+								// 如果指标不可见,那么就不返回该指标
+								if _, ok := noPermissionChartIdMap[chartInfo.SandboxId]; ok {
+									continue
+								}
+								thirdList = append(thirdList, thirdChart)
+							}
+						}
+						thirdInfo.Children = thirdList
+						tmpList = append(tmpList, &thirdInfo)
+					}
+				}
+				tmpInfo.Children = tmpList
+				tmpNodeList = append(tmpNodeList, &tmpInfo)
+			}
+		}
+		tmpNodeInfo.Children = tmpNodeList
+		newAllNodes = append(newAllNodes, &tmpNodeInfo)
+	}
+
+	return
+}
+
+// AddSandboxV2 新增沙盘
+func AddSandboxV2(req request.AddAndEditSandboxV2, opUserId int, opUserName string) (resp *sandbox.SandboxSaveResp, err error) {
+	resp = new(sandbox.SandboxSaveResp)
+	//沙盘主表信息
+	sandboxInfo := &sandbox.Sandbox{
+		Name:              utils.TrimStr(req.Name),
+		Code:              GenerateCode(),
+		Content:           req.Content,
+		MindmapData:       req.MindmapData,
+		PicUrl:            utils.TrimStr(req.PicUrl),
+		SysUserId:         opUserId,
+		SysUserName:       opUserName,
+		IsDelete:          0,
+		ModifyTime:        time.Now(),
+		CreateTime:        time.Now(),
+		SandboxClassifyId: req.SandboxClassifyId,
+		Sort:              0,
+	}
+
+	//新增沙盘
+	id, err := sandbox.AddSandbox(sandboxInfo)
+	if err != nil {
+		return
+	}
+	sandboxInfo.SandboxId = int(id)
+	resp.Sandbox = sandboxInfo
+	return
+}
+
+
+func SandboxItemsMakeTree(allNode []*sandbox.SandboxClassifyItems, sandListMap map[int][]*sandbox.SandboxClassifyItems, sandboxClassifyId int) (nodeAll []*sandbox.SandboxClassifyItems){
+	for k := range allNode {
+		if len(allNode[k].Children) > 0 {
+			SandboxItemsMakeTree(allNode[k].Children, sandListMap, sandboxClassifyId)
+			allNode = append(allNode, sandListMap[allNode[k].ParentId]...)
+			nodeAll = allNode
+		} else if k == len(allNode)-1 {
+			allNode = append(allNode, sandListMap[allNode[k].ParentId]...)
+			nodeAll = allNode
+		}
+	}
+	if len(allNode) == 0 {
+		nodeAll = append(nodeAll, sandListMap[sandboxClassifyId]...)
+	}
+	return
+}
+
+func SandboxClassifyHaveChild(allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) (childs []*sandbox.SandboxClassifyItems, yes bool) {
+	for _, v := range allNode {
+		if v.ParentId == node.SandboxClassifyId {
+			childs = append(childs, v)
+		}
+	}
+	if len(childs) > 0 {
+		yes = true
+	}
+	return
+}
+
+func SandboxClassifyItemsMakeTreeV2(sysUser *system.Admin, allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) {
+
+	childs, _ := sandboxClassifyHaveChildV2(allNode, node) //判断节点是否有子节点并返回
+	if len(childs) > 0 {
+
+		node.Children = append(node.Children, childs[0:]...) //添加子节点
+		for _, v := range childs {                           //查询子节点的子节点,并添加到子节点
+			_, has := sandboxClassifyHaveChildV2(allNode, v)
+			if has {
+				SandboxClassifyItemsMakeTreeV2(sysUser, allNode, v) //递归添加节点
+			} else {
+				//childrenArr := make([]*sandbox.SandboxClassifyItems, 0)
+				//v.Children = childrenArr
+			}
+		}
+	} else {
+		//childrenArr := make([]*sandbox.SandboxClassifyItems, 0)
+		//node.Children = childrenArr
+	}
+}
+
+func sandboxClassifyHaveChildV2(allNode []*sandbox.SandboxClassifyItems, node *sandbox.SandboxClassifyItems) (childs []*sandbox.SandboxClassifyItems, yes bool) {
+	for _, v := range allNode {
+		if v.ParentId == node.SandboxClassifyId && node.SandboxId == 0 {
+			childs = append(childs, v)
+		}
+	}
+	if len(childs) > 0 {
+		yes = true
+	}
+	return
+}