Browse Source

Merge remote-tracking branch 'origin/feature/gn_edb' into dm

Roc 6 months ago
parent
commit
f66423e60c

+ 2 - 2
controllers/data_manage/data_manage_permission/data_manage_permission.go

@@ -44,7 +44,7 @@ func (c *DataMangePermissionController) SetEdbChartPermission() {
 		return
 	}
 
-	if req.Source <= 0 || req.Source > 6 {
+	if req.Source <= 0 || req.Source > 7 {
 		br.Msg = "错误的来源"
 		br.IsSendEmail = false
 		return
@@ -223,7 +223,7 @@ func (c *DataMangePermissionController) GetEdbChartPermission() {
 	}
 
 	source, _ := c.GetInt("Source")
-	if source <= 0 || source > 6 {
+	if source <= 0 || source > 7 {
 		br.Msg = "错误的来源"
 		br.IsSendEmail = false
 		return

+ 4 - 4
controllers/data_manage/data_manage_permission/data_move.go

@@ -13,7 +13,7 @@ import (
 // EdbChartClassifyList
 // @Title 获取指标/图表分类列表数据接口
 // @Description 获取指标/图表分类列表数据接口
-// @Param   Source   query   int  false       "来源 :1:手工数据指标 2:钢联化工数据库 3:ETA指标库 4:ETA预测指标 5:图库 6:ETA表格"
+// @Param   Source   query   int  false       "来源 :1:手工数据指标 2:钢联化工数据库 3:ETA指标库 4:ETA预测指标 5:图库 6:ETA表格;7-计算指标"
 // @Param   SubSource   query   int  false       "子来源 :ETA表格中的各种表格类型,以及图表的来源(这个是后续的扩展方向)"
 // @Success 200 {object} data_manage.ChartListResp
 // @router /edb_chart/classify [get]
@@ -32,7 +32,7 @@ func (c *DataMangePermissionController) EdbChartClassifyList() {
 	}
 
 	source, _ := c.GetInt("Source")
-	if source <= 0 || source > 6 {
+	if source <= 0 || source > 7 {
 		br.Msg = "错误的来源"
 		br.IsSendEmail = false
 		return
@@ -82,7 +82,7 @@ func (c *DataMangePermissionController) SecretEdbChartClassifyList() {
 	}
 
 	source, _ := c.GetInt("Source")
-	if source <= 0 || source > 6 {
+	if source <= 0 || source > 7 {
 		br.Msg = "错误的来源"
 		br.IsSendEmail = false
 		return
@@ -155,7 +155,7 @@ func (c *DataMangePermissionController) MoveEdbChartList() {
 	}
 
 	source, _ := c.GetInt("Source")
-	if source <= 0 || source > 6 {
+	if source <= 0 || source > 7 {
 		br.Msg = "错误的来源"
 		br.IsSendEmail = false
 		return

+ 138 - 18
controllers/data_manage/edb_classify.go

@@ -9,6 +9,7 @@ import (
 	"eta_gn/eta_api/services/data"
 	"eta_gn/eta_api/services/data/data_manage_permission"
 	"eta_gn/eta_api/utils"
+	"fmt"
 	"sort"
 )
 
@@ -28,13 +29,26 @@ func (this *EdbClassifyController) ListV2() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, 0)
+	// 分类来源筛选
+	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+	edbType := utils.EdbTypeBase
+	if classifyType == utils.EdbClassifyTypeCalculate {
+		edbType = utils.EdbTypeCalculate
+	}
+
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType))
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
-	classifyAll, err := data_manage.GetEdbClassifyAll()
+	//classifyAll, err := data_manage.GetEdbClassifyAll()
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -66,7 +80,8 @@ func (this *EdbClassifyController) ListV2() {
 	for _, v := range confList {
 		noPermissionEdbInfoIdMap[v.EdbInfoId] = true
 	}
-	allEdbInfo, err := data_manage.GetEdbInfoAll(utils.EDB_INFO_TYPE)
+	//allEdbInfo, err := data_manage.GetEdbInfoAll(utils.EDB_INFO_TYPE)
+	allEdbInfo, err := data_manage.GetEdbInfoByTypes(utils.EDB_INFO_TYPE, edbType)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -139,6 +154,7 @@ func (this *EdbClassifyController) ListV2() {
 	br.Data = resp
 }
 
+// Items
 // @Title 获取所有分类接口-不包含指标
 // @Description 获取所有分类接口-不包含指标
 // @Success 200 {object} data_manage.EdbClassifyListResp
@@ -149,14 +165,27 @@ func (this *EdbClassifyController) Items() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, 0)
+	// 分类来源筛选
+	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+	//edbType := utils.EdbTypeBase
+	//if classifyType == utils.EdbClassifyTypeCalculate {
+	//	edbType = utils.EdbTypeCalculate
+	//}
+
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType))
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
-	classifyAll, err := data_manage.GetEdbClassifyAll()
+	//classifyAll, err := data_manage.GetEdbClassifyAll()
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -177,6 +206,7 @@ func (this *EdbClassifyController) Items() {
 	br.Data = resp
 }
 
+// AddEdbClassify
 // @Title 新增分类
 // @Description 新增分类接口
 // @Param	request	body data_manage.AddEdbClassifyReq true "type json string"
@@ -205,9 +235,16 @@ func (this *EdbClassifyController) AddEdbClassify() {
 		br.IsSendEmail = false
 		return
 	}
+	// 分类来源筛选
+	classifyType := req.ClassifyType
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
 
 	//添加指标
-	_, err, errMsg := data.AddEdbClassify(req.ClassifyName, req.ParentId, req.Level, 0, this.SysUser.AdminId, this.SysUser.AdminName, this.Lang)
+	_, err, errMsg := data.AddEdbClassify(req.ClassifyName, req.ParentId, req.Level, classifyType, this.SysUser.AdminId, this.SysUser.AdminName, this.Lang)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -258,6 +295,7 @@ func (this *EdbClassifyController) AddEdbClassify() {
 	br.IsAddLog = true
 }
 
+// EditEdbClassify
 // @Title 修改分类
 // @Description 修改分类接口
 // @Param	request	body data_manage.EditEdbClassifyReq true "type json string"
@@ -332,6 +370,7 @@ func (this *EdbClassifyController) EditEdbClassify() {
 	br.IsAddLog = true
 }
 
+// DeleteEdbClassifyCheck
 // @Title 删除检测接口
 // @Description 删除检测接口
 // @Param	request	body data_manage.ClassifyDeleteCheckReq true "type json string"
@@ -442,6 +481,7 @@ func (this *EdbClassifyController) DeleteEdbClassifyCheck() {
 	br.Data = resp
 }
 
+// DeleteEdbClassify
 // @Title 删除分类/指标
 // @Description 删除分类/指标接口
 // @Param	request	body data_manage.DeleteEdbClassifyReq true "type json string"
@@ -535,7 +575,15 @@ func (this *EdbClassifyController) EdbClassifyMove() {
 		return
 	}
 
-	err, errMsg := data.MoveEdbClassify(req, sysUser, 0)
+	// 分类来源筛选
+	classifyType := req.ClassifyType // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+
+	err, errMsg := data.MoveEdbClassify(req, sysUser, uint8(classifyType))
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -649,13 +697,26 @@ func (this *EdbClassifyController) ItemsV2() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, 0)
+	// 分类来源筛选
+	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+	//edbType := utils.EdbTypeBase
+	//if classifyType == utils.EdbClassifyTypeCalculate {
+	//	edbType = utils.EdbTypeCalculate
+	//}
+
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType))
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
-	classifyAll, err := data_manage.GetEdbClassifyAll()
+	//classifyAll, err := data_manage.GetEdbClassifyAll()
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -747,6 +808,7 @@ func (this *EdbClassifyController) ItemsV2() {
 	br.Data = resp
 }
 
+// ClassifyEdbInfoList
 // @Title 获取分类下指标接口
 // @Description 获取分类下指标接口
 // @Param   ClassifyId   query   int  true       "分类id"
@@ -785,7 +847,7 @@ func (this *EdbClassifyController) ClassifyEdbInfoList() {
 		noPermissionEdbInfoIdMap[v.EdbInfoId] = true
 	}
 
-	allEdbInfo, err := data_manage.GetEdbInfoByClassifyId(classifyId, 0, 0)
+	allEdbInfo, err := data_manage.GetEdbInfoByClassifyId(classifyId, utils.EDB_INFO_TYPE, 0)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -835,19 +897,32 @@ func (this *EdbClassifyController) ItemsV3() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, 0)
+	// 分类来源筛选
+	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+	//edbType := utils.EdbTypeBase
+	//if classifyType == utils.EdbClassifyTypeCalculate {
+	//	edbType = utils.EdbTypeCalculate
+	//}
+
+	// TODO:9级改造
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType))
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
-	rootTwoList, err := data_manage.GetEdbClassifyByParentIdTwo(0)
+	rootTwoList, err := data_manage.GetEdbClassifyByParentIdTwo(int8(classifyType))
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
-	classifyAll, err := data_manage.GetEdbClassifyAllV2(0)
+	classifyAll, err := data_manage.GetEdbClassifyAllV2(int8(classifyType))
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -963,6 +1038,18 @@ func (this *EdbClassifyController) SimpleList() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
+	// 分类来源筛选
+	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+	//edbType := utils.EdbTypeBase
+	//if classifyType == utils.EdbClassifyTypeCalculate {
+	//	edbType = utils.EdbTypeCalculate
+	//}
+
 	// 默认查一级分类和一级分类下的指标信息,
 	// 如果是 子级分类,查询该子级分类的下一级分类和指标信息
 	// 增加标识判断是文件夹还是指标列表
@@ -973,7 +1060,7 @@ func (this *EdbClassifyController) SimpleList() {
 	if isOnlyMe {
 		sysUserId = this.SysUser.AdminId
 	}
-	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, 0)
+	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, int8(classifyType))
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -1044,6 +1131,11 @@ func (this *EdbClassifyController) SimpleList() {
 		}
 
 		for _, v := range rootList {
+			// TODO:(基础指标分类是否加这个判断待定)分类设定了权限且无权限, 那么忽略掉该节点
+			if classifyType == utils.EdbClassifyTypeCalculate && v.IsJoinPermission == 1 && !utils.InArrayByInt(permissionClassifyIdList, v.ClassifyId) {
+				continue
+			}
+
 			// 数据权限
 			v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 			// 按钮权限
@@ -1101,8 +1193,20 @@ func (this *EdbClassifyController) ClassifyTree() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
+	// 分类来源筛选
+	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+	//edbType := utils.EdbTypeBase
+	//if classifyType == utils.EdbClassifyTypeCalculate {
+	//	edbType = utils.EdbTypeCalculate
+	//}
 
-	allList, err := data_manage.GetNormalEdbClassifyAll()
+	//allList, err := data_manage.GetNormalEdbClassifyAll()
+	allList, err := data_manage.GetAllEdbClassifyByType(classifyType)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -1120,14 +1224,30 @@ func (this *EdbClassifyController) ClassifyTree() {
 			return
 		}
 
-		for k, v := range allList {
+		//for k, v := range allList {
+		//	// 数据权限
+		//	v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+		//	// 按钮权限
+		//	button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+		//	allList[k].Button = button
+		//}
+		//nodeAll = data.GetClassifyTreeRecursive(allList, 0)
+		newNodes := make([]*data_manage.EdbClassifyItems, 0)
+		for _, v := range allList {
+			// TODO:(基础指标分类是否加这个判断待定)分类设定了权限且无权限, 那么忽略掉该节点
+			if classifyType == utils.EdbTypeCalculate && v.IsJoinPermission == 1 && !utils.InArrayByInt(permissionClassifyIdList, v.ClassifyId) {
+				continue
+			}
+			newNodes = append(newNodes, v)
+		}
+		for k, v := range newNodes {
 			// 数据权限
 			v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 			// 按钮权限
 			button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
-			allList[k].Button = button
+			newNodes[k].Button = button
 		}
-		nodeAll = data.GetClassifyTreeRecursive(allList, 0)
+		nodeAll = data.GetClassifyTreeRecursive(newNodes, 0)
 		//根据sort值排序
 		sortList = nodeAll
 		sort.Sort(sortList)

+ 352 - 0
controllers/data_manage/edb_collect.go

@@ -0,0 +1,352 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strings"
+	"time"
+)
+
+// EdbCollectController 指标收藏
+type EdbCollectController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 收藏列表-分页
+// @Description 收藏列表-分页
+// @Param   PageSize		query	int		false	"每页数据量"
+// @Param   CurrentIndex	query	int		false	"页码"
+// @Param   ClassifyId		query	int		false	"分类ID"
+// @Param   Keyword			query	string	false	"搜索关键词:指标ID/指标名称"
+// @Success Ret=200 保存成功
+// @router /edb_collect/list [get]
+func (this *EdbCollectController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	//resp := new(response.EdbInfoChartListResp)
+	resp := new(data_manage.CollectEdbInfoListResp)
+	resp.List = make([]*data_manage.CollectEdbInfoItem, 0)
+
+	// 分页
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	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 cond string
+	var pars []interface{}
+	cond += ` AND a.sys_user_id = ?`
+	pars = append(pars, sysUser.AdminId)
+
+	// 分类筛选
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId > 0 {
+		classifyIds, e := data.GetEdbCollectClassifyChildIds(classifyId, sysUser.AdminId, true)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取子分类IDs失败, %v", e)
+			return
+		}
+		if len(classifyIds) == 0 {
+			resp.Paging = page
+			br.Data = resp
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "获取成功"
+			return
+		}
+		cond += fmt.Sprintf(` AND a.edb_collect_classify_id IN (%s) `, utils.GetOrmInReplace(len(classifyIds)))
+		pars = append(pars, classifyIds)
+	}
+
+	// 获取当前账号的不可见指标
+	{
+		obj := data_manage.EdbInfoNoPermissionAdmin{}
+		list, e := obj.GetAllListByAdminId(sysUser.AdminId)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + e.Error()
+			return
+		}
+		var edbIds []int
+		for _, v := range list {
+			edbIds = append(edbIds, v.EdbInfoId)
+		}
+		edbLen := len(edbIds)
+		if edbLen > 0 {
+			cond += fmt.Sprintf(` AND a.edb_info_id NOT IN (%s)`, utils.GetOrmInReplace(edbLen))
+			pars = append(pars, edbIds)
+		}
+	}
+
+	// 关键词搜索
+	keywords := this.GetString("Keyword")
+	keywords = strings.TrimSpace(keywords)
+	if keywords != "" {
+		kw := fmt.Sprint("%", keywords, "%")
+		cond += fmt.Sprintf(` AND (b.edb_code LIKE ? OR b.edb_name LIKE ?)`)
+		pars = append(pars, kw, kw)
+	}
+
+	// 获取指标列表
+	dataCount, e := data_manage.GetCollectEdbInfoCount(cond, pars)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取收藏指标总数失败, %v", e)
+		return
+	}
+	if dataCount == 0 {
+		resp.Paging = page
+		br.Data = resp
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+	list, e := data_manage.GetCollectEdbInfoPageList(cond, pars, startSize, pageSize)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取收藏指标列表失败, %v", e)
+		return
+	}
+	for _, v := range list {
+		resp.List = append(resp.List, data_manage.FormatEdbInfo2CollectItem(v))
+	}
+
+	// 指标权限
+	//{
+	//	var edbClassifyIds []int
+	//	for _, v := range list {
+	//		edbClassifyIds = append(edbClassifyIds, v.ClassifyId)
+	//	}
+	//	classifyMap := make(map[int]*data_manage.EdbClassify)
+	//	classifyList, e := data_manage.GetEdbClassifyByIdList(edbClassifyIds)
+	//	if e != nil {
+	//		br.Msg = "获取失败"
+	//		br.ErrMsg = fmt.Sprintf("获取指标分类列表失败, %v", e)
+	//		return
+	//	}
+	//	for _, v := range classifyList {
+	//		classifyMap[v.ClassifyId] = v
+	//	}
+	//
+	//	// 获取所有有权限的指标和分类
+	//	authEdbIds, authEdbClassifyIds, e := data_manage_permission.GetUserEdbAndClassifyPermissionList(sysUser.AdminId, 0, 0)
+	//	if e != nil {
+	//		br.Msg = "获取失败"
+	//		br.ErrMsg = fmt.Sprintf("获取有权限的指标和分类失败, %v", e)
+	//		return
+	//	}
+	//
+	//	// 已被供应商暂停的指标编码
+	//	stopIndexCodes := make(map[string]bool)
+	//	{
+	//		var indexCodes []string
+	//		for _, v := range list {
+	//			if v.Source == utils.DATA_SOURCE_MYSTEEL_CHEMICAL {
+	//				indexCodes = append(indexCodes, v.EdbCode)
+	//			}
+	//		}
+	//		if len(indexCodes) > 0 {
+	//			stopIndexes, e := data_manage.GetNotIsSupplierStopIndexByCodeList(indexCodes, 1)
+	//			if e != nil {
+	//				br.Msg = "获取失败"
+	//				br.ErrMsg = fmt.Sprintf("获取供应商停更的指标失败, %v", e)
+	//				return
+	//			}
+	//			for _, v := range stopIndexes {
+	//				stopIndexCodes[v.IndexCode] = true
+	//			}
+	//		}
+	//	}
+	//
+	//	for _, v := range list {
+	//		// 权限按钮
+	//		if c, ok := classifyMap[v.ClassifyId]; ok {
+	//			v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, c.IsJoinPermission, v.EdbInfoId, v.ClassifyId, authEdbIds, authEdbClassifyIds)
+	//			v.Button = data.GetEdbOpButton(sysUser, v.SysUserId, v.EdbType, v.EdbInfoType, v.HaveOperaAuth)
+	//		}
+	//		// 供应商停用
+	//		if v.Source == utils.DATA_SOURCE_MYSTEEL_CHEMICAL {
+	//			if _, ok := stopIndexCodes[v.EdbCode]; ok {
+	//				v.IsSupplierStop = 1
+	//			}
+	//		}
+	//	}
+	//}
+	page = paging.GetPaging(currentIndex, pageSize, int(dataCount))
+	resp.Paging = page
+	//resp.List = list
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Collect
+// @Title 新增收藏
+// @Description 新增收藏
+// @Param	request	body data_manage.EdbCollectReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /edb_collect/collect [post]
+func (this *EdbCollectController) Collect() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		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 data_manage.EdbCollectReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常: %v", e)
+		return
+	}
+	if req.EdbInfoId <= 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	edbItem, e := data_manage.GetEdbInfoById(req.EdbInfoId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "指标不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取指标信息失败: %v", e)
+		return
+	}
+
+	// 校验是否重复添加至同一个分类
+	collectOb := new(data_manage.EdbCollect)
+	{
+		cond := fmt.Sprintf(" AND %s = ? AND %s = ? AND %s = ?", collectOb.Cols().SysUserId, collectOb.Cols().EdbCollectClassifyId, collectOb.Cols().EdbInfoId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, sysUser.AdminId, req.ClassifyId, req.EdbInfoId)
+		total, e := collectOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取分类下同指标失败, %v", e)
+			return
+		}
+		if total > 0 {
+			br.Msg = "该指标已收藏至该分类,请勿重复收藏"
+			return
+		}
+	}
+
+	// 保存收藏
+	collectOb.EdbCollectClassifyId = req.ClassifyId
+	collectOb.EdbInfoId = edbItem.EdbInfoId
+	collectOb.EdbCode = edbItem.EdbCode
+	collectOb.SysUserId = sysUser.AdminId
+	collectOb.SysRealName = sysUser.RealName
+	collectOb.CreateTime = time.Now().Local()
+	collectOb.ModifyTime = time.Now().Local()
+	if e = collectOb.Create(); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("新增指标收藏失败: %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// CancelCollect
+// @Title 取消收藏
+// @Description 取消收藏
+// @Param	request	body data_manage.EdbCollectReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /edb_collect/cancel_collect [post]
+func (this *EdbCollectController) CancelCollect() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		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 data_manage.EdbCollectReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常: %v", e)
+		return
+	}
+	if req.EdbInfoId <= 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	// 取消收藏
+	collectOb := new(data_manage.EdbCollect)
+	cond := fmt.Sprintf("%s = ? AND %s = ? AND %s = ?", collectOb.Cols().SysUserId, collectOb.Cols().EdbCollectClassifyId, collectOb.Cols().EdbInfoId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, sysUser.AdminId, req.ClassifyId, req.EdbInfoId)
+	if e := collectOb.RemoveByCondition(cond, pars); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("取消收藏失败: %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 455 - 0
controllers/data_manage/edb_collect_classify.go

@@ -0,0 +1,455 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// EdbCollectClassifyController 指标收藏分类
+type EdbCollectClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 分类列表-含指标
+// @Description 分类列表-含指标
+// @Param   ParentId  query  int  false  "父级ID"
+// @Success 200 {object} data_manage.EdbCollectClassifyListItem
+// @router /edb_collect/classify/list [get]
+func (this *EdbCollectClassifyController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	parentId, _ := this.GetInt("ParentId")
+
+	resp := make([]*data_manage.EdbCollectClassifyListItem, 0)
+	// 查询分类
+	classifyOb := new(data_manage.EdbCollectClassify)
+	{
+		cond := fmt.Sprintf(" AND %s = ? AND %s = ?", classifyOb.Cols().ParentId, classifyOb.Cols().SysUserId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, parentId, sysUser.AdminId)
+		list, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", classifyOb.Cols().Sort))
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取子分类失败, %v", e)
+			return
+		}
+		for _, v := range list {
+			resp = append(resp, &data_manage.EdbCollectClassifyListItem{
+				NodeType:     1,
+				ClassifyId:   v.EdbCollectClassifyId,
+				ClassifyName: v.ClassifyName,
+				ParentId:     v.ParentId,
+				Level:        v.Level,
+				Sort:         v.Sort,
+				UniqueCode:   v.UniqueCode,
+			})
+		}
+	}
+
+	// 查询分类下收藏的指标
+	{
+		list, e := data_manage.GetCollectEdbInfoByClassifyId(parentId)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取分类下指标失败, %v", e)
+			return
+		}
+		for _, v := range list {
+			resp = append(resp, &data_manage.EdbCollectClassifyListItem{
+				NodeType:   2,
+				EdbInfoId:  v.EdbInfoId,
+				EdbCode:    v.EdbCode,
+				EdbName:    v.EdbName,
+				ParentId:   parentId,
+				Sort:       v.Sort,
+				UniqueCode: v.UniqueCode,
+			})
+		}
+	}
+	sort.Slice(resp, func(i, j int) bool {
+		return resp[i].Sort < resp[j].Sort
+	})
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Tree
+// @Title 分类树
+// @Description 分类树
+// @Success 200 {object} data_manage.EdbCollectClassifyItem
+// @router /edb_collect/classify/tree [get]
+func (this *EdbCollectClassifyController) Tree() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	// 获取所有分类
+	classifyOb := new(data_manage.EdbCollectClassify)
+	cond := fmt.Sprintf(" AND %s = ?", classifyOb.Cols().SysUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, sysUser.AdminId)
+	list, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC, %s ASC", classifyOb.Cols().ParentId, classifyOb.Cols().Sort))
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取分类列表失败, %v", e)
+		return
+	}
+	items := make([]*data_manage.EdbCollectClassifyItem, 0)
+	for _, v := range list {
+		items = append(items, v.Format2Item())
+	}
+	tree := data.GetEdbCollectClassifyTreeRecursive(items, 0)
+
+	br.Data = tree
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Add
+// @Title 新增分类
+// @Description 新增分类
+// @Param	request	body data_manage.EdbCollectClassifyAddReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /edb_collect/classify/add [post]
+func (this *EdbCollectClassifyController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		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 data_manage.EdbCollectClassifyAddReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常: %v", e)
+		return
+	}
+	req.ClassifyName = strings.TrimSpace(req.ClassifyName)
+	if req.ClassifyName == "" {
+		br.Msg = "请输入名称"
+		return
+	}
+	classifyOb := new(data_manage.EdbCollectClassify)
+
+	// 校验分类名称
+	//{
+	//	cond := fmt.Sprintf(" AND %s = ? AND %s = ?", classifyOb.Cols().ParentId, classifyOb.Cols().ClassifyName)
+	//	pars := make([]interface{}, 0)
+	//	pars = append(pars, req.ParentId, req.ClassifyName)
+	//	count, e := classifyOb.GetCountByCondition(cond, pars)
+	//	if e != nil {
+	//		br.Msg = "操作失败"
+	//		br.ErrMsg = fmt.Sprintf("获取分类名称重复数失败, %v", e)
+	//		return
+	//	}
+	//	if count > 0 {
+	//		br.Msg = "分类名称已存在"
+	//		return
+	//	}
+	//}
+
+	// 层级路径
+	var levelPath string
+	var rootId int
+	if req.ParentId > 0 {
+		parent, e := classifyOb.GetItemById(req.ParentId)
+		if e != nil {
+			br.Msg = "上级分类有误"
+			br.ErrMsg = fmt.Sprintf("获取上级分类失败, %v", e)
+			return
+		}
+		levelPath = parent.LevelPath
+		rootId = parent.RootId
+	}
+
+	sortMax, e := classifyOb.GetSortMax(req.ParentId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类最大排序失败, %v", e)
+		return
+	}
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	classifyOb.ParentId = req.ParentId
+	classifyOb.ClassifyName = req.ClassifyName
+	classifyOb.Level = req.Level + 1
+	classifyOb.Sort = sortMax + 1
+	classifyOb.SysUserId = sysUser.AdminId
+	classifyOb.SysUserRealName = sysUser.RealName
+	classifyOb.UniqueCode = utils.MD5(classifyOb.TableName() + "_" + timestamp)
+	classifyOb.CreateTime = time.Now().Local()
+	classifyOb.ModifyTime = time.Now().Local()
+	if e = classifyOb.Create(); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("新增分类失败, %v", e)
+		return
+	}
+	if req.ParentId > 0 {
+		classifyOb.LevelPath = fmt.Sprintf("%s,%d", levelPath, classifyOb.EdbCollectClassifyId)
+		classifyOb.RootId = rootId
+	} else {
+		classifyOb.LevelPath = fmt.Sprint(classifyOb.EdbCollectClassifyId)
+		classifyOb.RootId = classifyOb.EdbCollectClassifyId
+	}
+	if e = classifyOb.Update([]string{classifyOb.Cols().LevelPath, classifyOb.Cols().RootId}); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
+		return
+	}
+
+	br.Data = classifyOb.Format2Item()
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Edit
+// @Title 编辑分类
+// @Description 编辑分类
+// @Param	request	body data_manage.EdbCollectClassifyEditReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /edb_collect/classify/edit [post]
+func (this *EdbCollectClassifyController) Edit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		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 data_manage.EdbCollectClassifyEditReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常: %v", e)
+		return
+	}
+	if req.ClassifyId < 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+	req.ClassifyName = strings.TrimSpace(req.ClassifyName)
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+
+	classifyOb := new(data_manage.EdbCollectClassify)
+	classifyItem, e := classifyOb.GetItemById(req.ClassifyId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "分类不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
+		return
+	}
+
+	// 校验分类名称
+	//{
+	//	cond := fmt.Sprintf(" AND %s <> ? AND %s = ?", classifyOb.Cols().PrimaryId, classifyOb.Cols().ClassifyName)
+	//	pars := make([]interface{}, 0)
+	//	pars = append(pars, req.ClassifyId, req.ClassifyName)
+	//	count, e := classifyOb.GetCountByCondition(cond, pars)
+	//	if e != nil {
+	//		br.Msg = "操作失败"
+	//		br.ErrMsg = fmt.Sprintf("获取分类名称重复数失败, %v", e)
+	//		return
+	//	}
+	//	if count > 0 {
+	//		br.Msg = "分类名称已存在"
+	//		return
+	//	}
+	//}
+	classifyItem.ClassifyName = req.ClassifyName
+	classifyItem.ModifyTime = time.Now().Local()
+	updateCols := []string{classifyOb.Cols().ClassifyName, classifyOb.Cols().ModifyTime}
+	if e = classifyItem.Update(updateCols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
+		return
+	}
+
+	br.Data = classifyItem.Format2Item()
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Remove
+// @Title 删除分类
+// @Description 删除分类
+// @Param	request	body data_manage.EdbCollectClassifyRemoveReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /edb_collect/classify/remove [post]
+func (this *EdbCollectClassifyController) Remove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		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 data_manage.EdbCollectClassifyRemoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.ClassifyId < 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	classifyOb := new(data_manage.EdbCollectClassify)
+	_, e := classifyOb.GetItemById(req.ClassifyId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "操作成功"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
+		return
+	}
+
+	// 获取子分类IDs
+	classifyIds, e := data.GetEdbCollectClassifyChildIds(req.ClassifyId, sysUser.AdminId, true)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取子分类IDs失败, %v", e)
+		return
+	}
+	if len(classifyIds) == 0 {
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "操作成功"
+		return
+	}
+
+	// 移除所有子分类以及子分类所收藏的指标
+	if e = classifyOb.RemoveClassifyAndCollect(classifyIds); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("移除分类及收藏失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// TODO:Move
+// @Title 移动分类
+// @Description 移动分类
+// @Param	request	body data_manage.EdbCollectClassifyMoveReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /edb_collect/classify/move [post]
+func (this *EdbCollectClassifyController) Move() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		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 data_manage.BaseFromThsHfClassifyMoveReq
+	//if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+	//	br.Msg = "参数解析异常"
+	//	br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+	//	return
+	//}
+	//if req.ClassifyId <= 0 && req.ItemId <= 0 {
+	//	br.Msg = "请选择分类或指标"
+	//	return
+	//}
+	//
+	//err, errMsg := data.ThsHfMoveClassify(req, sysUser)
+	//if errMsg != `` {
+	//	br.Msg = errMsg
+	//	br.ErrMsg = errMsg
+	//	if err != nil {
+	//		br.ErrMsg = err.Error()
+	//	} else {
+	//		br.IsSendEmail = false
+	//	}
+	//	return
+	//}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 15 - 3
controllers/data_manage/edb_info.go

@@ -3390,6 +3390,7 @@ func (this *EdbInfoController) EdbInfoFilter() {
 // @Param   IsAddPredictEdb   query   bool  false       "是否查询添加预测指标"
 // @Param   PageSize   query   int  true       "每页数据条数"
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   EdbType   query   int  false       "指标类型:0-基础和计算;1-基础指标;2-计算指标"
 // @Success 200 {object} data_manage.EdbInfoList
 // @router /edb_info/filter_by_es [get]
 func (this *EdbInfoController) EdbInfoFilterByEs() {
@@ -3426,6 +3427,8 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 
 	isAddPredictEdb, _ := this.GetBool("IsAddPredictEdb") //是否查询添加预测指标
 
+	edbType, _ := this.GetInt("EdbType", 0) // 指标类型:0-基础和计算;1-基础指标;2-计算指标
+
 	var edbInfoList []*data_manage.EdbInfoList
 	var err error
 
@@ -3455,10 +3458,10 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 
 		// 普通的搜索
 		if !isAddPredictEdb {
-			total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 0, frequency, noPermissionEdbInfoIdList)
+			total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 0, frequency, noPermissionEdbInfoIdList, edbType)
 		} else {
 			// 允许添加预测指标的搜索
-			total, edbInfoList, err = elastic.SearchAddPredictEdbInfoData(utils.DATA_INDEX_NAME, keyWord, noPermissionEdbInfoIdList, startSize, pageSize)
+			total, edbInfoList, err = elastic.SearchAddPredictEdbInfoData(utils.DATA_INDEX_NAME, keyWord, noPermissionEdbInfoIdList, startSize, pageSize, edbType)
 		}
 		isEs = true
 	} else {
@@ -4813,6 +4816,8 @@ func (this *EdbInfoController) AllEdbInfoByEs() {
 
 	isAddPredictEdb, _ := this.GetBool("IsAddPredictEdb") //是否查询添加预测指标
 
+	edbType, _ := this.GetInt("EdbType", 0) // 指标类型:0-基础和计算;1-基础指标;2-计算指标
+
 	var edbInfoList []*data_manage.EdbInfoList
 	var err error
 
@@ -4841,7 +4846,7 @@ func (this *EdbInfoController) AllEdbInfoByEs() {
 		keyWordArr = append(keyWordArr, newKeyWord...)
 
 		// 普通的搜索
-		total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, -1, frequency, noPermissionEdbInfoIdList)
+		total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, -1, frequency, noPermissionEdbInfoIdList, edbType)
 		isEs = true
 	} else {
 		var condition string
@@ -5422,6 +5427,13 @@ func (this *EdbInfoController) EdbChartList() {
 	condition += ` AND edb_info_type = ? `
 	pars = append(pars, 0)
 
+	// 指标类型
+	edbType, _ := this.GetInt("EdbType", 0)
+	if edbType > 0 {
+		condition += ` AND edb_type = ? `
+		pars = append(pars, edbType)
+	}
+
 	// 分类筛选
 	classifyId, _ := this.GetInt("ClassifyId")
 	if classifyId > 0 {

+ 1 - 1
controllers/data_manage/predict_edb_info.go

@@ -1189,7 +1189,7 @@ func (this *PredictEdbInfoController) FilterByEs() {
 		if isOnlyMe {
 			total, edbInfoList, err = elastic.SearchEdbInfoDataByAdminId(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 1, frequency, this.SysUser.AdminId)
 		} else {
-			total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 1, frequency, noPermissionEdbInfoIdList)
+			total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 1, frequency, noPermissionEdbInfoIdList, 0)
 		}
 		isEs = true
 	} else {

+ 9 - 0
models/data_manage/edb_classify.go

@@ -382,6 +382,7 @@ type MoveEdbClassifyReq struct {
 	EdbInfoId        int `description:"指标ID, 如果指标ID有值,则移动对象为指标,否则认为移动对象为分类"`
 	PrevEdbInfoId    int `description:"上一个指标ID"`
 	NextEdbInfoId    int `description:"下一个指标ID"`
+	ClassifyType     int `description:"分类类型:0-指标库;2-计算指标"`
 }
 
 // GetFirstEdbClassifyByParentId 获取当前父级分类下,且排序数相同 的排序第一条的数据
@@ -676,3 +677,11 @@ func GetEdbClassifyRootIdsByClassifyIds(classifyIds []int) (items []int, err err
 
 	return
 }
+
+// GetChildEdbClassifyByClassifyType 根据类型获取非顶级分类
+func GetChildEdbClassifyByClassifyType(classifyType int) (items []*EdbClassifyItems, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM edb_classify WHERE parent_id <> 0 AND classify_type = ? ORDER BY sort ASC,classify_id ASC`
+	err = o.Raw(sql, classifyType).Find(&items).Error
+	return
+}

+ 226 - 0
models/data_manage/edb_collect.go

@@ -0,0 +1,226 @@
+package data_manage
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strings"
+	"time"
+)
+
+// EdbCollect 指标收藏
+type EdbCollect struct {
+	EdbCollectId         int       `gorm:"primaryKey;autoIncrement;column:edb_collect_id;type:int(10) unsigned;not null"`
+	EdbCollectClassifyId int       `gorm:"index:idx_classify_id;column:edb_collect_classify_id;type:int(10) unsigned;not null;default:0"` // 指标收藏分类ID
+	EdbInfoId            int       `gorm:"column:edb_info_id;type:int(10) unsigned;not null;default:0"`                                   // 指标ID
+	EdbCode              string    `gorm:"column:edb_code;type:varchar(255);not null;default:''"`                                         // 指标编码
+	SysUserId            int       `gorm:"column:sys_user_id;type:int(10) unsigned;not null;default:0"`                                   // 创建人ID
+	SysRealName          string    `gorm:"column:sys_real_name;type:int(10) unsigned;not null;default:0"`                                 // 创建人姓名
+	Sort                 int       `gorm:"column:sort;type:int(10);default:0"`                                                            // 排序
+	CreateTime           time.Time `gorm:"column:create_time;type:datetime"`                                                              // 创建时间
+	ModifyTime           time.Time `gorm:"column:modify_time;type:datetime"`                                                              // 更新时间
+}
+
+func (m *EdbCollect) TableName() string {
+	return "edb_collect"
+}
+
+type EdbCollectCols struct {
+	PrimaryId            string
+	EdbCollectClassifyId string
+	EdbInfoId            string
+	EdbCode              string
+	SysUserId            string
+	SysRealName          string
+	Sort                 string
+	CreateTime           string
+	ModifyTime           string
+}
+
+func (m *EdbCollect) Cols() EdbCollectCols {
+	return EdbCollectCols{
+		PrimaryId:            "edb_collect_id",
+		EdbCollectClassifyId: "edb_collect_classify_id",
+		EdbInfoId:            "edb_info_id",
+		EdbCode:              "edb_code",
+		SysUserId:            "sys_user_id",
+		SysRealName:          "sys_real_name",
+		Sort:                 "sort",
+		CreateTime:           "create_time",
+		ModifyTime:           "modify_time",
+	}
+}
+
+func (m *EdbCollect) Create() (err error) {
+	err = global.DmSQL["data"].Create(m).Error
+	return
+}
+
+func (m *EdbCollect) CreateMulti(items []*EdbCollect) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	err = global.DmSQL["data"].CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (m *EdbCollect) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Select(cols).Updates(m).Error
+	return
+}
+
+func (m *EdbCollect) Remove() (err error) {
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
+	err = global.DmSQL["data"].Exec(sql, m.EdbCollectId).Error
+	return
+}
+
+func (m *EdbCollect) MultiRemove(ids []int) (err error) {
+	if len(ids) == 0 {
+		return
+	}
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
+	err = global.DmSQL["data"].Exec(sql, ids).Error
+	return
+}
+
+func (m *EdbCollect) RemoveByCondition(condition string, pars []interface{}) (err error) {
+	if condition == "" {
+		return
+	}
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), condition)
+	err = global.DmSQL["data"].Exec(sql, pars...).Error
+	return
+}
+
+func (m *EdbCollect) GetItemById(id int) (item *EdbCollect, err error) {
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
+	err = global.DmSQL["data"].Raw(sql, id).First(&item).Error
+	return
+}
+
+func (m *EdbCollect) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *EdbCollect, err error) {
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).First(&item).Error
+	return
+}
+
+func (m *EdbCollect) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+func (m *EdbCollect) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*EdbCollect, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *EdbCollect) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*EdbCollect, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetCollectEdbInfoByClassifyId 获取分类下收藏的指标信息
+func GetCollectEdbInfoByClassifyId(classifyId int) (items []*EdbInfo, err error) {
+	sql := `SELECT b.* FROM edb_collect AS a JOIN edb_info AS b ON a.edb_info_id = b.edb_info_id WHERE a.edb_collect_classify_id = ? ORDER BY a.sort ASC`
+	err = global.DmSQL["data"].Raw(sql, classifyId).Find(&items).Error
+	return
+}
+
+// EdbCollectReq 加入/取消收藏
+type EdbCollectReq struct {
+	ClassifyId int `description:"分类ID"`
+	EdbInfoId  int `description:"指标ID"`
+}
+
+// GetCollectEdbInfoCount 获取收藏的指标信息总数
+func GetCollectEdbInfoCount(condition string, pars []interface{}) (total int64, err error) {
+	sql := fmt.Sprintf(`SELECT COUNT(1) AS ct FROM (
+	  SELECT b.* FROM edb_collect AS a JOIN edb_info AS b ON a.edb_info_id = b.edb_info_id
+	  WHERE 1=1 %s
+	  ORDER BY a.create_time DESC
+	) AS sub`, condition)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&total).Error
+	return
+}
+
+// GetCollectEdbInfoPageList 获取收藏的指标信息列表-分页
+func GetCollectEdbInfoPageList(condition string, pars []interface{}, startSize, pageSize int) (list []*CollectEdbInfoQuery, err error) {
+	sql := fmt.Sprintf(`SELECT b.*, a.edb_collect_classify_id AS collect_classify_id FROM edb_collect AS a JOIN edb_info AS b ON a.edb_info_id = b.edb_info_id
+	  WHERE 1=1 %s
+	  ORDER BY a.create_time DESC LIMIT ?,?`, condition)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error
+	return
+}
+
+type CollectEdbInfoQuery struct {
+	EdbInfo
+	CollectClassifyId int `gorm:"column:collect_classify_id" description:"收藏分类ID"`
+}
+
+// CollectEdbInfoItem 收藏列表指标信息
+type CollectEdbInfoItem struct {
+	EdbInfoId         int    `description:"指标ID"`
+	EdbInfoType       int    `description:"指标类型:0-普通指标; 1-预测指标"`
+	EdbType           int    `description:"指标类型:1-基础指标; 2-计算指标"`
+	Source            int    `description:"来源ID"`
+	SourceName        string `description:"来源名称"`
+	EdbCode           string `description:"指标编码"`
+	EdbName           string `description:"指标名称"`
+	Frequency         string `description:"频率"`
+	Unit              string `description:"单位"`
+	UniqueCode        string `description:"唯一编码"`
+	ChartImage        string `description:"图表图片"`
+	ClassifyId        int    `description:"指标分类ID"`
+	CollectClassifyId int    `description:"收藏分类ID"`
+}
+
+func FormatEdbInfo2CollectItem(origin *CollectEdbInfoQuery) (item *CollectEdbInfoItem) {
+	item = new(CollectEdbInfoItem)
+	item.EdbInfoId = origin.EdbInfoId
+	item.EdbInfoType = origin.EdbInfoType
+	item.EdbType = origin.EdbType
+	item.Source = origin.Source
+	item.SourceName = origin.SourceName
+	item.EdbCode = origin.EdbCode
+	item.EdbName = origin.EdbName
+	item.Frequency = origin.Frequency
+	item.Unit = origin.Unit
+	item.UniqueCode = origin.UniqueCode
+	item.ChartImage = origin.ChartImage
+	item.ClassifyId = origin.ClassifyId
+	item.CollectClassifyId = origin.CollectClassifyId
+	return
+}
+
+// CollectEdbInfoListResp 收藏指标分页列表相应
+type CollectEdbInfoListResp struct {
+	Paging *paging.PagingItem
+	List   []*CollectEdbInfoItem
+}

+ 249 - 0
models/data_manage/edb_collect_classify.go

@@ -0,0 +1,249 @@
+package data_manage
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// EdbCollectClassify 指标收藏分类
+type EdbCollectClassify struct {
+	EdbCollectClassifyId int       `gorm:"primaryKey;autoIncrement;column:edb_collect_classify_id;type:int(10) unsigned;not null"`
+	ClassifyName         string    `gorm:"column:classify_name;type:varchar(255);not null;default:''"`     // 分类名称
+	ParentId             int       `gorm:"column:parent_id;type:int(10) unsigned;not null;default:0"`      // 父级Id
+	SysUserId            int       `gorm:"column:sys_user_id;type:int(10) unsigned;not null;default:0"`    // 创建人Id
+	SysUserRealName      string    `gorm:"column:sys_user_real_name;type:varchar(128);not null"`           // 创建人姓名
+	UniqueCode           string    `gorm:"unique;column:unique_code;type:varchar(64);not null;default:''"` // 唯一编码
+	Level                int       `gorm:"column:level;type:int(10) unsigned;not null;default:0"`          // 层级
+	Sort                 int       `gorm:"column:sort;type:int(10) unsigned;not null;default:0"`           // 排序
+	RootId               int       `gorm:"column:root_id;type:int(10) unsigned;not null;default:0"`        // 顶级Id
+	LevelPath            string    `gorm:"column:level_path;type:varchar(255);not null;default:''"`        // 层级路径,逗号分隔
+	CreateTime           time.Time `gorm:"column:create_time;type:datetime"`                               // 创建时间
+	ModifyTime           time.Time `gorm:"column:modify_time;type:datetime"`                               // 修改时间
+}
+
+func (m *EdbCollectClassify) TableName() string {
+	return "edb_collect_classify"
+}
+
+type EdbCollectClassifyCols struct {
+	PrimaryId       string
+	ClassifyName    string
+	ParentId        string
+	SysUserId       string
+	SysUserRealName string
+	UniqueCode      string
+	Level           string
+	Sort            string
+	RootId          string
+	LevelPath       string
+	CreateTime      string
+	ModifyTime      string
+}
+
+func (m *EdbCollectClassify) Cols() EdbCollectClassifyCols {
+	return EdbCollectClassifyCols{
+		PrimaryId:       "edb_collect_classify_id",
+		ClassifyName:    "classify_name",
+		ParentId:        "parent_id",
+		SysUserId:       "sys_user_id",
+		SysUserRealName: "sys_user_real_name",
+		UniqueCode:      "unique_code",
+		Level:           "level",
+		Sort:            "sort",
+		RootId:          "root_id",
+		LevelPath:       "level_path",
+		CreateTime:      "create_time",
+		ModifyTime:      "modify_time",
+	}
+}
+
+func (m *EdbCollectClassify) Create() (err error) {
+	err = global.DmSQL["data"].Create(m).Error
+	return
+}
+
+func (m *EdbCollectClassify) CreateMulti(items []*EdbCollectClassify) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	err = global.DmSQL["data"].CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (m *EdbCollectClassify) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Select(cols).Updates(m).Error
+	return
+}
+
+func (m *EdbCollectClassify) Remove() (err error) {
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
+	err = global.DmSQL["data"].Exec(sql, m.EdbCollectClassifyId).Error
+	return
+}
+
+func (m *EdbCollectClassify) MultiRemove(ids []int) (err error) {
+	if len(ids) == 0 {
+		return
+	}
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
+	err = global.DmSQL["data"].Exec(sql, ids).Error
+	return
+}
+
+func (m *EdbCollectClassify) RemoveByCondition(condition string, pars []interface{}) (err error) {
+	if condition == "" {
+		return
+	}
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), condition)
+	err = global.DmSQL["data"].Exec(sql, pars...).Error
+	return
+}
+
+func (m *EdbCollectClassify) GetItemById(id int) (item *EdbCollectClassify, err error) {
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
+	err = global.DmSQL["data"].Raw(sql, id).First(&item).Error
+	return
+}
+
+func (m *EdbCollectClassify) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *EdbCollectClassify, err error) {
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).First(&item).Error
+	return
+}
+
+func (m *EdbCollectClassify) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+func (m *EdbCollectClassify) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*EdbCollectClassify, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *EdbCollectClassify) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*EdbCollectClassify, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *EdbCollectClassify) GetSortMax(parentId int) (sort int, err error) {
+	sql := fmt.Sprintf(`SELECT COALESCE(MAX(%s), 0) FROM %s WHERE %s = ?`, m.Cols().Sort, m.TableName(), m.Cols().ParentId)
+	err = global.DmSQL["data"].Raw(sql, parentId).Scan(&sort).Error
+	return
+}
+
+// EdbCollectClassifyItem 指标收藏分类
+type EdbCollectClassifyItem struct {
+	ClassifyId   int                       `description:"收藏ID"`
+	ClassifyName string                    `description:"指标收藏分类ID"`
+	ParentId     int                       `description:"指标ID"`
+	Level        int                       `description:"指标ID"`
+	Sort         int                       `description:"指标ID"`
+	LevelPath    string                    `description:"层级路径"`
+	UniqueCode   string                    `description:"唯一编码"`
+	Children     []*EdbCollectClassifyItem `description:"子分类"`
+}
+
+func (m *EdbCollectClassify) Format2Item() (item *EdbCollectClassifyItem) {
+	item = new(EdbCollectClassifyItem)
+	item.ClassifyId = m.EdbCollectClassifyId
+	item.ClassifyName = m.ClassifyName
+	item.ParentId = m.ParentId
+	item.Level = m.Level
+	item.Sort = m.Sort
+	item.LevelPath = m.LevelPath
+	item.UniqueCode = m.UniqueCode
+	//item.Children = make([]*EdbCollectClassifyItem, 0)
+	return
+}
+
+// EdbCollectClassifyListItem 指标收藏分类列表
+type EdbCollectClassifyListItem struct {
+	NodeType     int                           `description:"类型: 1-分类; 2-指标"`
+	ClassifyId   int                           `description:"分类ID"`
+	ClassifyName string                        `description:"分类名称"`
+	EdbInfoId    int                           `description:"指标ID"`
+	EdbCode      string                        `description:"指标编码"`
+	EdbName      string                        `description:"指标名称"`
+	ParentId     int                           `description:"父级ID"`
+	Level        int                           `description:"层级"`
+	Sort         int                           `description:"排序"`
+	UniqueCode   string                        `description:"唯一编码, 指标的话用indexCode"`
+	Children     []*EdbCollectClassifyListItem `description:"子分类"`
+}
+
+// EdbCollectClassifyAddReq 新增分类
+type EdbCollectClassifyAddReq struct {
+	ClassifyName string `description:"分类名称"`
+	ParentId     int    `description:"父级ID"`
+	Level        int    `description:"层级"`
+}
+
+// EdbCollectClassifyEditReq 编辑分类
+type EdbCollectClassifyEditReq struct {
+	ClassifyId   int    `description:"分类ID"`
+	ClassifyName string `description:"分类名称"`
+}
+
+// EdbCollectClassifyRemoveReq 删除分类
+type EdbCollectClassifyRemoveReq struct {
+	ClassifyId int `description:"分类ID"`
+}
+
+// RemoveClassifyAndCollect 移除分类及收藏
+func (m *EdbCollectClassify) RemoveClassifyAndCollect(classifyIds []int) (err error) {
+	if len(classifyIds) == 0 {
+		return
+	}
+	tx := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.Cols().PrimaryId, utils.GetOrmInReplace(len(classifyIds)))
+	e := tx.Exec(sql, classifyIds).Error
+	if e != nil {
+		err = fmt.Errorf("remove classify err: %v", e)
+		return
+	}
+
+	collectOb := new(EdbCollect)
+	sql = fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, collectOb.TableName(), collectOb.Cols().EdbCollectClassifyId, utils.GetOrmInReplace(len(classifyIds)))
+	e = tx.Exec(sql, classifyIds).Error
+	if e != nil {
+		err = fmt.Errorf("remove collect err: %v", e)
+		return
+	}
+	return
+}

+ 8 - 0
models/data_manage/edb_info.go

@@ -2011,3 +2011,11 @@ func getThsHfAllDataByMongo(edbInfoId, source, subSource int, startDataTime stri
 
 	return
 }
+
+// GetEdbInfoByTypes 根据类型获取所有指标
+func GetEdbInfoByTypes(edbInfoType, edbType int) (items []*EdbClassifyItems, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT edb_info_id,classify_id,edb_name_source AS classify_name,edb_name_en AS classify_name_en,unique_code,source_name,source,sys_user_id,sys_user_real_name,start_date,edb_code,edb_type FROM edb_info WHERE edb_info_type = ? AND edb_type = ? order by sort asc,edb_info_id asc`
+	err = o.Raw(sql, edbInfoType, edbType).Scan(&items).Error
+	return
+}

+ 81 - 0
routers/commentsRouter.go

@@ -3877,6 +3877,87 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/edb_collect/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/edb_collect/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/edb_collect/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Move",
+            Router: `/edb_collect/classify/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Remove",
+            Router: `/edb_collect/classify/remove`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Tree",
+            Router: `/edb_collect/classify/tree`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectController"],
+        beego.ControllerComments{
+            Method: "CancelCollect",
+            Router: `/edb_collect/cancel_collect`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectController"],
+        beego.ControllerComments{
+            Method: "Collect",
+            Router: `/edb_collect/collect`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbCollectController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/edb_collect/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoController"],
         beego.ControllerComments{
             Method: "BaiinfoClassify",

+ 2 - 0
routers/router.go

@@ -179,6 +179,8 @@ func init() {
 				&data_manage.EdbInfoRelationController{},
 				&data_manage.FactorEdbSeriesController{},
 				&data_manage.SciHqDataController{},
+				&data_manage.EdbCollectController{},
+				&data_manage.EdbCollectClassifyController{},
 			),
 		),
 		web.NSNamespace("/my_chart",

+ 18 - 4
services/data/data_manage_permission/data_move.go

@@ -95,16 +95,20 @@ func GetEdbChartClassifyList(source, subSource int) (resp data_manage.EdbChartCl
 			resp.List = append(resp.List, &item)
 		}
 
-	case 3:
+	case 3, 7:
 		//ETA指标库
 		//rootList, e := data_manage.GetEdbClassifyByParentId(0, 0)
 		//if e != nil && !utils.IsErrNoRow(e) {
 		//	err = e
 		//	return
 		//}
-
+		// 这里拆分指标库和计算指标
+		classifyType := utils.EdbClassifyTypeBase
+		if source == 7 {
+			classifyType = utils.EdbClassifyTypeCalculate
+		}
 		// 考虑到后面可以会迭代到10层, 这里直接用递归处理
-		classifyAll, e := data_manage.GetAllEdbClassifyByType(0)
+		classifyAll, e := data_manage.GetAllEdbClassifyByType(classifyType)
 		if e != nil && !utils.IsErrNoRow(e) {
 			err = e
 			return
@@ -300,7 +304,7 @@ func GetMoveEdbChartList(source, subSource, userId int, keyword, classify string
 				CreateUserName: v.SysUserRealName,
 			})
 		}
-	case 3, 4: //ETA指标库、ETA预测指标
+	case 3, 4, 7: //ETA指标库、ETA预测指标、指标加工
 		if keyword != `` {
 			condition += " AND (edb_code like ? OR edb_name like ? OR edb_name_en like ? OR sys_user_real_name like ? ) "
 			pars = utils.GetLikeKeywordPars(pars, keyword, 4)
@@ -320,6 +324,16 @@ func GetMoveEdbChartList(source, subSource, userId int, keyword, classify string
 		condition += ` AND edb_info_type = ? `
 		pars = append(pars, edbInfoType)
 
+		// 指标加工
+		if source != 4 {
+			edbType := 1
+			if source == 7 {
+				edbType = 2
+			}
+			condition += ` AND edb_type = ? `
+			pars = append(pars, edbType)
+		}
+
 		total, err = data_manage.GetEdbInfoByConditionCount(condition, pars)
 		if err != nil {
 			return

+ 11 - 3
services/data/data_manage_permission/edb_permission.go

@@ -61,13 +61,17 @@ func SetEdbChartPermission(source, subSource, userId int, authUserList []int, is
 	dataList := make([]data_manage_permission.DataItem, 0)
 
 	switch source {
-	case 3, 4:
+	case 3, 4, 7:
 		//ETA指标库、ETA预测指标
 		if source == 3 {
 			content += `(ETA指标库)`
-		} else {
+		}
+		if source == 4 {
 			content += `(ETA预测指标)`
 		}
+		if source == 7 {
+			content += `(ETA计算指标)`
+		}
 
 		tmpList, tmpErr := data_manage.GetEdbInfoListByEdbInfoId(dataIdList)
 		if tmpErr != nil {
@@ -503,12 +507,16 @@ func GetEdbChartClassifyIdListPermissionByUserId(source, subSource, userId int)
 // @return err error
 func GetUserIdListPermissionByDataId(source, subSource, dataId int) (idList []int, err error) {
 	switch source {
-	case 3, 4:
+	case 3, 4, 7:
 		// ETA指标库、ETA预测指标
 		edbInfoType := 0
 		if source == 4 {
 			edbInfoType = 1
 		}
+		//edbType := 1
+		//if source == 7 {
+		//	edbType = 2
+		//}
 		idList, err = data_manage_permission.GetPermissionUserIdListByEdbId(dataId, edbInfoType)
 	case 5:
 		// 图库

+ 2 - 2
services/data/edb_classify.go

@@ -320,8 +320,8 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 	}
 
 	// 层级校验
-	if level > 6 {
-		errMsg = `最高只支持添加6级分类`
+	if level > 9 {
+		errMsg = `最高只支持添加9级分类`
 		return
 	}
 

+ 58 - 0
services/data/edb_collect.go

@@ -0,0 +1,58 @@
+package data
+
+import (
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+// GetEdbCollectClassifyTreeRecursive 递归获取分类树形结构
+func GetEdbCollectClassifyTreeRecursive(list []*data_manage.EdbCollectClassifyItem, parentId int) []*data_manage.EdbCollectClassifyItem {
+	res := make([]*data_manage.EdbCollectClassifyItem, 0)
+	for _, v := range list {
+		if v.ParentId == parentId {
+			t := GetEdbCollectClassifyTreeRecursive(list, v.ClassifyId)
+			if len(t) > 0 {
+				v.Children = t
+			}
+			res = append(res, v)
+		}
+	}
+	return res
+}
+
+// GetEdbCollectClassifyChildIds 获取分类的子分类IDs
+func GetEdbCollectClassifyChildIds(classifyId, adminId int, selfInclude bool) (classifyIds []int, err error) {
+	// DM就不用FIND_IN_SET去查了, 从分类的LevelPath中遍历出来
+	exists := make(map[int]bool)
+	if selfInclude {
+		exists[classifyId] = true
+		classifyIds = append(classifyIds, classifyId)
+	}
+	classifyOb := new(data_manage.EdbCollectClassify)
+	cond := fmt.Sprintf(` AND %s = ?`, classifyOb.Cols().SysUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	list, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf(`%s ASC`, classifyOb.Cols().Sort))
+	if e != nil {
+		err = fmt.Errorf("获取用户收藏分类失败, %v", e)
+		return
+	}
+	strClassifyId := strconv.Itoa(classifyId)
+	for _, v := range list {
+		if v.LevelPath == "" {
+			continue
+		}
+		if exists[v.EdbCollectClassifyId] {
+			continue
+		}
+		pathArr := strings.Split(v.LevelPath, ",")
+		if len(pathArr) > 0 && utils.InArrayByStr(pathArr, strClassifyId) {
+			classifyIds = append(classifyIds, v.EdbCollectClassifyId)
+			exists[v.EdbCollectClassifyId] = true
+		}
+	}
+	return
+}

+ 20 - 2
services/elastic/elastic.go

@@ -87,7 +87,7 @@ func EsAddOrEditEdbInfoData(indexName, docId string, item *data_manage.EdbInfoLi
 }
 
 // SearchEdbInfoData 查询es中的指标数据
-func SearchEdbInfoData(indexName, keywordStr string, from, size, filterSource, source int, edbInfoType int8, frequency string, noPermissionEdbInfoIdList []int) (total int64, list []*data_manage.EdbInfoList, err error) {
+func SearchEdbInfoData(indexName, keywordStr string, from, size, filterSource, source int, edbInfoType int8, frequency string, noPermissionEdbInfoIdList []int, edbType int) (total int64, list []*data_manage.EdbInfoList, err error) {
 	list = make([]*data_manage.EdbInfoList, 0)
 	defer func() {
 		if err != nil {
@@ -257,6 +257,15 @@ func SearchEdbInfoData(indexName, keywordStr string, from, size, filterSource, s
 		})
 	}
 
+	// 指标类型:0-基础+计算;1-基础指标;2-计算指标
+	if edbType >= 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"EdbType": edbType,
+			},
+		})
+	}
+
 	//普通指标
 	//mustMap = append(mustMap, map[string]interface{}{
 	//	"term": map[string]interface{}{
@@ -622,7 +631,7 @@ func SearchEdbInfoDataBak(indexName, keywordStr string, from, size, filterSource
 }
 
 // SearchAddPredictEdbInfoData 查询允许添加预测指标的数据
-func SearchAddPredictEdbInfoData(indexName, keywordStr string, noPermissionEdbInfoIdList []int, from, size int) (total int64, list []*data_manage.EdbInfoList, err error) {
+func SearchAddPredictEdbInfoData(indexName, keywordStr string, noPermissionEdbInfoIdList []int, from, size, edbType int) (total int64, list []*data_manage.EdbInfoList, err error) {
 	list = make([]*data_manage.EdbInfoList, 0)
 	defer func() {
 		if err != nil {
@@ -661,6 +670,15 @@ func SearchAddPredictEdbInfoData(indexName, keywordStr string, noPermissionEdbIn
 		},
 	})
 
+	// 指标类型: 1-基础指标; 2-计算指标
+	if edbType > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"EdbType": edbType,
+			},
+		})
+	}
+
 	//关键字匹配
 	//shouldMap := map[string]interface{}{
 	//	"should": []interface{}{

+ 13 - 0
utils/constants.go

@@ -478,3 +478,16 @@ const (
 
 // MultiAddNum 批量插入的数据量
 const MultiAddNum = 500
+
+const EdbClassifyMaxLevel = 9 // 指标库分类最大层级
+
+const (
+	EdbClassifyTypeBase      = 0 // 指标分类-指标库
+	EdbClassifyTypePredict   = 1 // 指标分类-预测指标
+	EdbClassifyTypeCalculate = 2 // 指标分类-计算指标
+)
+
+const (
+	EdbTypeBase      = 1 // 指标类型-基础指标
+	EdbTypeCalculate = 2 // 指标类型-计算指标
+)