소스 검색

逻辑图接口

xyxie 6 달 전
부모
커밋
e79486c61f

+ 224 - 0
controllers/sandbox.go

@@ -0,0 +1,224 @@
+package controllers
+
+import (
+	"eta/eta_hub/models"
+	"eta/eta_hub/models/sandbox"
+	sandboxService "eta/eta_hub/services/sandbox"
+	"eta/eta_hub/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+// SandboxController 逻辑导图
+type SandboxController struct {
+	BaseAuthController
+}
+
+// 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")
+
+	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
+	}
+
+	nodeAll := make([]*sandbox.SandboxClassifyItems, 0)
+	for k := range rootList {
+		rootNode := rootList[k]
+		sandboxService.SandboxClassifyItemsMakeTreeV2(classifyAll, rootNode)
+		nodeAll = append(nodeAll, rootNode)
+	}
+
+	resp.AllNodes = nodeAll
+	br.Ret = 200
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @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 /list [get]
+func (this *SandboxController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	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 + `%' )`
+	}
+
+	//获取图表信息
+	condition += ` AND is_delete = 0 `
+	list, err := sandbox.GetSandboxListByCondition(condition, pars, startSize, pageSize)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		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.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.Msg = "获取成功"
+	br.Data = resp
+}
+
+// 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()
+	}()
+
+	sandboxId, _ := this.GetInt("SandboxId")
+	if sandboxId == 0 {
+		br.Msg = "缺少沙盘Id"
+		return
+	}
+
+	//获取沙盘数据详情(已保存的)
+	sandboxInfo, err := sandbox.GetSandboxById(sandboxId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	msg := "获取成功"
+	br.Ret = 200
+	br.Msg = msg
+	br.Data = sandboxInfo
+}
+
+// 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(classifyAll, rootNode)
+		nodeAll = append(nodeAll, rootNode)
+	}
+
+	resp.AllNodes = nodeAll
+	br.Ret = 200
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 6 - 0
models/report.go

@@ -90,6 +90,8 @@ type Report struct {
 	ReportLayout        int8      `description:"报告布局,1:常规布局,2:智能布局。默认:1"`
 	IsPublicPublish     int8      `description:"是否公开发布,1:是,2:否"`
 	ReportCreateTime    time.Time `description:"报告时间创建时间"`
+	DetailImgUrl        string    `description:"报告详情长图地址"`
+	DetailPdfUrl        string    `description:"报告详情PDF地址"`
 }
 
 type ReportListResp struct {
@@ -504,6 +506,8 @@ type ReportItem struct {
 	ReportCreateTime string               `description:"报告时间创建时间"`
 	ChapterList      []*ReportChapterItem `description:"章节列表"`
 	HasChapter       int                  `description:"是否有章节 0-否 1-是"`
+	DetailImgUrl     string               `description:"报告详情长图地址"`
+	DetailPdfUrl     string               `description:"报告详情PDF地址"`
 }
 
 func FormatReport2Item(origin *Report, chapterList []*ReportChapterItem) (item *ReportItem) {
@@ -550,6 +554,8 @@ func FormatReport2Item(origin *Report, chapterList []*ReportChapterItem) (item *
 	item.ReportCreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.ReportCreateTime)
 	item.ChapterList = chapterList
 	item.HasChapter = origin.HasChapter
+	item.DetailImgUrl = origin.DetailImgUrl
+	item.DetailPdfUrl = origin.DetailPdfUrl
 
 	return
 }

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

@@ -0,0 +1,40 @@
+package request
+
+// AddAndEditSandbox 添加/编辑沙盘的请求数据
+type AddAndEditSandbox struct {
+	SandboxId          int    `description:"沙盘id"`
+	SandboxVersionCode string `description:"沙盘版本code"`
+	Name               string `description:"沙盘名称"`
+	ChartPermissionId  int    `description:"品种权限id"`
+	Content            string `description:"沙盘内容"`
+	PicUrl             string `description:"沙盘图片地址"`
+	SvgData            string `description:"沙盘svg图片数据"`
+}
+
+// MarkEditSandbox 标记编辑沙盘的请求数据
+type MarkEditSandbox struct {
+	SandboxId int `description:"沙盘id"`
+	Status    int `description:"标记状态,1:编辑中,2:编辑完成"`
+}
+
+// DeleteSandbox 删除沙盘的请求数据
+type DeleteSandbox struct {
+	SandboxId int `description:"沙盘id"`
+}
+
+// DeleteSandboxVersion 删除沙盘版本的请求数据
+type DeleteSandboxVersion struct {
+	SandboxVersionCode string `description:"沙盘版本code"`
+}
+
+// AddAndEditSandboxV2 添加/编辑沙盘的请求数据
+type AddAndEditSandboxV2 struct {
+	SandboxId         int    `description:"沙盘id"`
+	Name              string `description:"沙盘名称"`
+	Content           string `description:"沙盘内容"`
+	Style             int    `description:"风格"`
+	MindmapData       string `description:"思维导图内容"`
+	PicUrl            string `description:"沙盘图片地址"`
+	SvgData           string `description:"沙盘svg图片数据"`
+	SandboxClassifyId int    `description:"分类id"`
+}

+ 18 - 0
models/sandbox/response/sandbox.go

@@ -0,0 +1,18 @@
+package response
+
+import (
+	"eta/eta_api/models/sandbox"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+// SandboxListResp 沙盘列表返回数据
+type SandboxListResp struct {
+	Paging *paging.PagingItem
+	List   []*sandbox.Sandbox
+}
+
+// SandboxVersionListResp 沙盘版本列表返回数据
+type SandboxVersionListResp struct {
+	Paging *paging.PagingItem
+	List   []*sandbox.SandboxVersionListItem
+}

+ 181 - 0
models/sandbox/sandbox.go

@@ -0,0 +1,181 @@
+package sandbox
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+type Sandbox struct {
+	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:"排序"`
+	Style             int       `description:"风格"`
+}
+
+// Update 沙盘字段变更
+func (sandbox *Sandbox) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(sandbox, cols...)
+	return
+}
+
+// GetSandboxById 根据沙盘id获取沙盘详情
+func GetSandboxById(sandboxId int) (sandboxInfo *Sandbox, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `select * from sandbox where sandbox_id = ? and is_delete = 0`
+	err = o.Raw(sql, sandboxId).QueryRow(&sandboxInfo)
+	return
+}
+
+// SandboxListItem 沙盘推演列表数据
+type SandboxListItem struct {
+	SandboxId int    `description:"沙盘id"`
+	Name      string `description:"沙盘名称"`
+	//ChartPermissionId   int    `description:"品种id"`
+	//ChartPermissionName string `description:"品种名称"`
+	//CurrVersion         int    `description:"当前版本"`
+	Code string `description:"沙盘code"`
+	//VersionCode         string `description:"沙盘版本code"`
+	//Content             string    `description:"沙盘数据"`
+	PicUrl string `description:"沙盘图片地址"`
+	//OpUserId   int    `description:"最近一次编辑操作的用户id"`
+	//OpUserName string `description:"最近一次编辑的用户名称(冗余字段,避免查表)"`
+	IsDelete int8 `description:"是否删除,0:未删除,1:已删除" json:"is_delete"`
+	//	CanEdit      bool      `description:"是否可编辑"`
+	//	Editor       string    `description:"编辑人"`
+	//	VersionTotal int       `description:"历史版本数量"`
+	ModifyTime time.Time `description:"修改时间"`
+	CreateTime time.Time `description:"创建时间"`
+
+	SysUserId         int    `description:"作者id"`
+	SysUserName       string `description:"作者名称"`
+	SandboxClassifyId int    `description:"分类id"`
+	Sort              int    `description:"排序"`
+	Style             int    `description:"风格"`
+}
+
+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 {
+	SandboxListItem
+	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 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
+}
+
+// ContentDataStruct 沙盘内容结构体
+type ContentDataStruct struct {
+	Cells []struct {
+		Data *NodeData `json:"data,omitempty"`
+	} `json:"cells"`
+}
+
+type NodeData struct {
+	LinkData []*LinkData `json:"linkData"`
+	LinkFold bool        `json:"linkFold"`
+}
+
+type LinkData struct {
+	RId          string       `json:"RId"`
+	Id           int          `json:"Id"`
+	Name         string       `json:"Name"`
+	Type         int          `json:"Type"`
+	Editing      bool         `json:"editing"`
+	DatabaseType int          `json:"databaseType"`
+	DetailParams DetailParams `json:"detailParams"`
+}
+
+type DetailParams struct {
+	Code       string `json:"code"`
+	Id         int    `json:"id"`
+	ClassifyId int    `json:"classifyId"`
+}

+ 285 - 0
models/sandbox/sandbox_classify.go

@@ -0,0 +1,285 @@
+package sandbox
+
+import (
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+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:"层级"`
+	ChartPermissionId   int       `description:"品种id"`
+	ChartPermissionName string    `description:"品种名称"`
+	Sort                int       `description:"排序字段,越小越靠前,默认值:10"`
+}
+
+func AddSandboxClassify(item *SandboxClassify) (lastId int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	lastId, err = o.Insert(item)
+	return
+}
+
+// GetSandboxClassifyByParentId
+func GetSandboxClassifyByParentId(parentId int) (items []*SandboxClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM sandbox_classify WHERE parent_id=? order by sort asc,sandbox_classify_id asc`
+	_, err = o.Raw(sql, parentId).QueryRows(&items)
+	return
+}
+
+// GetSandboxClassifyAll
+func GetSandboxClassifyAll() (items []*SandboxClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM sandbox_classify WHERE parent_id<>0 order by sort asc,sandbox_classify_id asc`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+type SandboxClassifyItems 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"`
+	SysUserName         string    `description:"创建人姓名"`
+	Level               int       `description:"层级"`
+	Sort                int       `description:"排序字段,越小越靠前,默认值:10"`
+	SandboxId           int       `description:"沙盘id"`
+	ChartPermissionId   int       `description:"品种id"`
+	ChartPermissionName string    `description:"品种名称"`
+	Children            []*SandboxClassifyItems
+}
+
+type SandboxClassifyListResp struct {
+	AllNodes []*SandboxClassifyItems
+}
+
+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) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT COUNT(1) AS count FROM sandbox_classify WHERE parent_id=? AND sandbox_classify_name=? `
+	err = o.Raw(sql, parentId, sandboxClassifyName).QueryRow(&count)
+	return
+}
+
+// GetSandboxClassifyMaxSort 获取沙盘分类下最大的排序数
+func GetSandboxClassifyMaxSort(parentId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT Max(sort) AS sort FROM sandbox_classify WHERE parent_id=? `
+	err = o.Raw(sql, parentId).QueryRow(&sort)
+	return
+}
+
+type EditSandboxClassifyReq struct {
+	SandboxClassifyName string `description:"分类名称"`
+	SandboxClassifyId   int    `description:"分类id"`
+	ChartPermissionId   int    `description:"品种id"`
+	ChartPermissionName string `description:"品种名称"`
+}
+
+func GetSandboxClassifyById(classifyId int) (item *SandboxClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM sandbox_classify WHERE sandbox_classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}
+
+func EditSandboxClassify(classifyId, ChartPermissionId int, sandboxClassifyName, ChartPermissionName string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `UPDATE sandbox_classify SET sandbox_classify_name=?,chart_permission_id = ?, chart_permission_name = ?, modify_time=NOW() WHERE sandbox_classify_id=? `
+	_, err = o.Raw(sql, sandboxClassifyName, ChartPermissionId, ChartPermissionName, 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
+				) AND a.is_delete = 0 `
+	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,
+	chart_permission_id,
+	chart_permission_name,
+	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,
+	chart_permission_id,
+	chart_permission_name,
+	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 SandboxLinkCheckItem struct {
+	Id         int    `description:"id"`
+	Name       string `description:"名称"`
+	UniqueCode string `description:"唯一编码"`
+	ClassifyId int    `description:"分类id"`
+}
+
+type SandboxLinkCheckResp struct {
+	EdbInfoIdList   []*SandboxLinkCheckItem `description:"指标id列表"`
+	ChartInfoIdList []*SandboxLinkCheckItem `description:"图库id列表"`
+	ReportIdList    []*SandboxLinkCheckItem `description:"报告id列表"`
+}
+
+// 获取所有子级分类id
+func GetSandboxClassifySubcategories(classifyId int) (Ids string, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT GROUP_CONCAT(sandbox_classify_id) AS ids
+FROM (
+SELECT @pv := ? AS sandbox_classify_id
+UNION ALL
+SELECT sc.sandbox_classify_id
+FROM sandbox_classify sc
+JOIN (SELECT @pv := ?) initial
+WHERE sc.parent_id = @pv
+) subcategories; `
+	err = o.Raw(sql, classifyId, classifyId).QueryRow(&Ids)
+	return
+}
+
+// UpdateSandboxClassifyChartPermissionById 根据沙盘id更新品种
+func UpdateSandboxClassifyChartPermissionById(ChartPermissionId int, ChartPermissionName, Ids string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` UPDATE sandbox_classify SET chart_permission_id = ?, chart_permission_name = ? WHERE sandbox_classify_id IN ( ` + Ids + ` ) `
+	_, err = o.Raw(sql, ChartPermissionId, ChartPermissionName).Exec()
+	return
+}

+ 36 - 0
routers/commentsRouter.go

@@ -304,6 +304,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:SandboxController"],
+        beego.ControllerComments{
+            Method: "SandboxClassifyItems",
+            Router: `/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:SandboxController"],
+        beego.ControllerComments{
+            Method: "SandboxClassifyList",
+            Router: `/classifyList`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:SandboxController"],
+        beego.ControllerComments{
+            Method: "GetSandboxDetail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:SandboxController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:SandboxController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_hub/controllers:SmartReportController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:SmartReportController"],
         beego.ControllerComments{
             Method: "Approve",

+ 5 - 0
routers/router.go

@@ -83,6 +83,11 @@ func init() {
 				&controllers.ResourceDealWithController{},
 			),
 		),
+		web.NSNamespace("/sandbox",
+			web.NSInclude(
+				&controllers.SandboxController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 198 - 0
services/sandbox/sandbox.go

@@ -0,0 +1,198 @@
+package sandbox
+
+import (
+	"eta/eta_hub/models/sandbox"
+)
+
+// ContentStruct 沙盘内容结构体
+type ContentStruct struct {
+	Cells []struct {
+		Attrs struct {
+			Line struct {
+				SourceMarker    bool   `json:"sourceMarker"`
+				Stroke          string `json:"stroke"`
+				StrokeDasharray string `json:"strokeDasharray"`
+			} `json:"line"`
+			Rect struct {
+				Fill            string      `json:"fill"`
+				Stroke          string      `json:"stroke"`
+				StrokeDasharray interface{} `json:"strokeDasharray"`
+				StrokeWidth     int64       `json:"strokeWidth"`
+			} `json:"rect"`
+			Text struct {
+				Fill       string  `json:"fill"`
+				FontSize   float64 `json:"fontSize"`
+				FontWeight string  `json:"fontWeight"`
+				LineHeight float64 `json:"lineHeight"`
+				Text       string  `json:"text"`
+				TextWrap   struct {
+					Text  string `json:"text"`
+					Width int64  `json:"width"`
+				} `json:"textWrap"`
+			} `json:"text"`
+		} `json:"attrs"`
+		Data struct {
+			Key string `json:"key"`
+		} `json:"data"`
+		ID    string `json:"id"`
+		Ports struct {
+			Groups struct {
+				Port_bottom struct {
+					Attrs struct {
+						Circle struct {
+							Fill        string `json:"fill"`
+							Magnet      bool   `json:"magnet"`
+							R           int64  `json:"r"`
+							Stroke      string `json:"stroke"`
+							StrokeWidth int64  `json:"strokeWidth"`
+						} `json:"circle"`
+					} `json:"attrs"`
+					Position string `json:"position"`
+					ZIndex   int64  `json:"zIndex"`
+				} `json:"port-bottom"`
+				Port_left struct {
+					Attrs struct {
+						Circle struct {
+							Fill        string `json:"fill"`
+							Magnet      bool   `json:"magnet"`
+							R           int64  `json:"r"`
+							Stroke      string `json:"stroke"`
+							StrokeWidth int64  `json:"strokeWidth"`
+						} `json:"circle"`
+					} `json:"attrs"`
+					Position string `json:"position"`
+					ZIndex   int64  `json:"zIndex"`
+				} `json:"port-left"`
+				Port_right struct {
+					Attrs struct {
+						Circle struct {
+							Fill        string `json:"fill"`
+							Magnet      bool   `json:"magnet"`
+							R           int64  `json:"r"`
+							Stroke      string `json:"stroke"`
+							StrokeWidth int64  `json:"strokeWidth"`
+						} `json:"circle"`
+					} `json:"attrs"`
+					Position string `json:"position"`
+					ZIndex   int64  `json:"zIndex"`
+				} `json:"port-right"`
+				Port_top struct {
+					Attrs struct {
+						Circle struct {
+							Fill        string `json:"fill"`
+							Magnet      bool   `json:"magnet"`
+							R           int64  `json:"r"`
+							Stroke      string `json:"stroke"`
+							StrokeWidth int64  `json:"strokeWidth"`
+						} `json:"circle"`
+					} `json:"attrs"`
+					Position string `json:"position"`
+					ZIndex   int64  `json:"zIndex"`
+				} `json:"port-top"`
+			} `json:"groups"`
+			Items []struct {
+				Group string `json:"group"`
+				ID    string `json:"id"`
+			} `json:"items"`
+		} `json:"ports"`
+		Position struct {
+			X float64 `json:"x"`
+			Y float64 `json:"y"`
+		} `json:"position"`
+		Shape string `json:"shape"`
+		Size  struct {
+			Height float64 `json:"height"`
+			Width  float64 `json:"width"`
+		} `json:"size"`
+		Source struct {
+			Cell string `json:"cell"`
+			Port string `json:"port"`
+		} `json:"source"`
+		Target struct {
+			Cell string `json:"cell"`
+			Port string `json:"port"`
+		} `json:"target"`
+		ZIndex int64 `json:"zIndex"`
+	} `json:"cells"`
+}
+
+type SendBoxNodeData struct {
+	linkData []SandBoxLinkData `json:"linkData"`
+	linkFold bool              `json:"linkFold"`
+}
+
+type SandBoxLinkData struct {
+	RId          string              `json:"RId"`
+	Id           int                 `json:"Id"`
+	Name         string              `json:"Name"`
+	Type         int                 `json:"Type"`
+	Editing      bool                `json:"editing"`
+	DatabaseType int                 `json:"databaseType"`
+	DetailParams SandBoxDetailParams `json:"detailParams"`
+}
+
+type SandBoxDetailParams struct {
+	Code       string `json:"code"`
+	Id         int    `json:"id"`
+	ClassifyId int    `json:"classifyId"`
+}
+
+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(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(allNode, v) //递归添加节点
+			} else {
+				childrenArr := make([]*sandbox.SandboxClassifyItems, 0)
+				v.Children = childrenArr
+			}
+		}
+	} else {
+		childrenArr := make([]*sandbox.SandboxClassifyItems, 0)
+		node.Children = childrenArr
+	}
+}
+
+func SandboxClassifyItemsMakeTreeV2(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(allNode, v) //递归添加节点
+			}
+		}
+	}
+}
+
+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
+}