浏览代码

Merge branch 'debug' of http://8.136.199.33:3000/eta_gn_server/eta_api into bzq/knowledge_add_viewpoint_cf

zqbao 3 月之前
父节点
当前提交
ad0cd256d7
共有 100 个文件被更改,包括 14354 次插入1946 次删除
  1. 2 1
      cache/replace_edb_info.go
  2. 56 65
      controllers/data_manage/chart_classify.go
  3. 295 148
      controllers/data_manage/chart_info.go
  4. 722 0
      controllers/data_manage/chart_info_share.go
  5. 354 0
      controllers/data_manage/collect_chart.go
  6. 515 0
      controllers/data_manage/collect_chart_classify.go
  7. 189 0
      controllers/data_manage/collect_edb.go
  8. 31 30
      controllers/data_manage/collect_edb_classify.go
  9. 13 10
      controllers/data_manage/correlation/correlation_chart_classify.go
  10. 9 20
      controllers/data_manage/correlation/correlation_chart_info.go
  11. 7 18
      controllers/data_manage/cross_variety/chart_info.go
  12. 3 10
      controllers/data_manage/cross_variety/classify.go
  13. 462 0
      controllers/data_manage/data_approve/data_approve.go
  14. 179 0
      controllers/data_manage/data_approve/data_approve_flow.go
  15. 2 2
      controllers/data_manage/data_manage_permission/data_move.go
  16. 45 18
      controllers/data_manage/edb_classify.go
  17. 289 124
      controllers/data_manage/edb_info.go
  18. 391 192
      controllers/data_manage/edb_info_calculate.go
  19. 902 0
      controllers/data_manage/edb_info_share.go
  20. 2 2
      controllers/data_manage/excel/balance_table.go
  21. 0 13
      controllers/data_manage/excel/custom_analysis_edb.go
  22. 0 58
      controllers/data_manage/excel/excel_info.go
  23. 5 27
      controllers/data_manage/future_good/future_good_chart_classify.go
  24. 9 9
      controllers/data_manage/future_good/future_good_chart_info.go
  25. 0 404
      controllers/data_manage/future_good/future_good_edb_info.go
  26. 3 3
      controllers/data_manage/future_good/future_good_profit_chart_info.go
  27. 5 25
      controllers/data_manage/line_equation/line_chart_classify.go
  28. 6 17
      controllers/data_manage/line_equation/line_chart_info.go
  29. 6 17
      controllers/data_manage/line_feature/chart_info.go
  30. 5 25
      controllers/data_manage/line_feature/classify.go
  31. 0 27
      controllers/data_manage/manual.go
  32. 0 244
      controllers/data_manage/multiple_graph_config.go
  33. 2 11
      controllers/data_manage/my_chart.go
  34. 4 4
      controllers/data_manage/predict_edb_classify.go
  35. 23 11
      controllers/data_manage/predict_edb_info.go
  36. 587 0
      controllers/data_manage/public_chart.go
  37. 625 0
      controllers/data_manage/public_chart_classify.go
  38. 667 0
      controllers/data_manage/public_edb.go
  39. 794 0
      controllers/data_manage/public_edb_classify.go
  40. 13 10
      controllers/data_manage/range_analysis/chart_classify.go
  41. 5 16
      controllers/data_manage/range_analysis/chart_info.go
  42. 1 1
      controllers/data_manage/wind_data.go
  43. 704 0
      controllers/fix.go
  44. 37 35
      controllers/knowledge/resource.go
  45. 28 13
      controllers/message.go
  46. 7 0
      controllers/report_v2.go
  47. 0 4
      controllers/resource.go
  48. 0 14
      controllers/sys_admin.go
  49. 3 0
      models/business_conf.go
  50. 262 23
      models/data_manage/chart_classify.go
  51. 71 0
      models/data_manage/chart_edb_mapping.go
  52. 201 65
      models/data_manage/chart_info.go
  53. 10 1
      models/data_manage/chart_info_resp.go
  54. 291 0
      models/data_manage/chart_info_share.go
  55. 365 0
      models/data_manage/collect_chart.go
  56. 280 0
      models/data_manage/collect_chart_classify.go
  57. 73 16
      models/data_manage/collect_edb.go
  58. 0 0
      models/data_manage/collect_edb_classify.go
  59. 252 0
      models/data_manage/data_approve/data_approve.go
  60. 198 0
      models/data_manage/data_approve/data_approve_flow.go
  61. 118 0
      models/data_manage/data_approve/data_approve_message.go
  62. 90 0
      models/data_manage/data_approve/data_approve_node.go
  63. 152 0
      models/data_manage/data_approve/data_approve_record.go
  64. 83 0
      models/data_manage/data_approve/data_approve_relation.go
  65. 21 0
      models/data_manage/data_approve/request/approve.go
  66. 23 0
      models/data_manage/data_approve/request/approve_flow.go
  67. 5 0
      models/data_manage/data_approve/request/approve_message.go
  68. 90 0
      models/data_manage/data_approve/response/approve.go
  69. 47 0
      models/data_manage/data_approve/response/approve_flow.go
  70. 25 0
      models/data_manage/data_approve/response/approve_message.go
  71. 224 20
      models/data_manage/edb_classify.go
  72. 256 108
      models/data_manage/edb_info.go
  73. 48 0
      models/data_manage/edb_info_calculate_mapping.go
  74. 311 0
      models/data_manage/edb_info_share.go
  75. 1 0
      models/data_manage/edb_source.go
  76. 58 0
      models/data_manage/excel/excel_edb_mapping.go
  77. 3 3
      models/data_manage/multiple_graph_config.go
  78. 38 15
      models/data_manage/multiple_graph_config_chart_mapping.go
  79. 48 0
      models/data_manage/predict_edb_conf.go
  80. 400 0
      models/data_manage/public_chart_classify.go
  81. 77 0
      models/data_manage/public_chart_info.go
  82. 397 0
      models/data_manage/public_edb_classify.go
  83. 85 0
      models/data_manage/public_edb_info.go
  84. 32 0
      models/data_manage/request/chart_info_share.go
  85. 24 0
      models/data_manage/request/collect_edb.go
  86. 32 0
      models/data_manage/request/edb_info_share.go
  87. 57 0
      models/data_manage/request/public_chart.go
  88. 57 0
      models/data_manage/request/public_edb.go
  89. 11 0
      models/data_manage/response/chart.go
  90. 16 0
      models/data_manage/response/chart_info_share.go
  91. 16 0
      models/data_manage/response/edb_info_share.go
  92. 2 2
      models/report_v2.go
  93. 540 0
      routers/commentsRouter.go
  94. 15 0
      routers/router.go
  95. 662 53
      services/data/chart_classify.go
  96. 2 2
      services/data/chart_info.go
  97. 29 8
      services/data/chart_info_elastic.go
  98. 2 2
      services/data/chart_info_excel_balance.go
  99. 189 0
      services/data/chart_info_share.go
  100. 58 0
      services/data/collect_chart.go

+ 2 - 1
cache/replace_edb_info.go

@@ -7,10 +7,11 @@ import (
 )
 
 // 将替换指标操作加入到队列中
-func AddReplaceEdbInfo(oldEdbInfo, newEdbInfo *data_manage.EdbInfo) bool {
+func AddReplaceEdbInfo(oldEdbInfo, newEdbInfo *data_manage.EdbInfo, userId int) bool {
 	record := new(data_manage.ReplaceEdbInfoItem)
 	record.OldEdbInfo = oldEdbInfo
 	record.NewEdbInfo = newEdbInfo
+	record.UserId = userId
 	if utils.Re == nil {
 		err := utils.Rc.LPush(utils.CACHE_KEY_REPLACE_EDB, record)
 

+ 56 - 65
controllers/data_manage/chart_classify.go

@@ -21,7 +21,6 @@ type ChartClassifyController struct {
 // ChartClassifyListV2
 // @Title 图表分类列表
 // @Description 图表分类列表接口
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Success 200 {object} data_manage.ChartClassifyListResp
 // @router /chart_classify/list [get]
 func (this *ChartClassifyController) ChartClassifyListV2() {
@@ -47,26 +46,6 @@ func (this *ChartClassifyController) ChartClassifyListV2() {
 		}
 	}
 
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		errMsg, err := getChartClassifyListForMe(*this.SysUser, resp)
-		if err != nil {
-			br.Msg = errMsg
-			br.ErrMsg = err.Error()
-			return
-		}
-		// 移除没有权限的图表
-		allNodes := data.HandleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap, this.SysUser.AdminId)
-		resp.AllNodes = allNodes
-
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
-		fmt.Println("source my classify")
-		return
-	}
-
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取
 	key := utils.CACHE_CHART_CLASSIFY
 	if utils.Re == nil {
@@ -89,21 +68,21 @@ func (this *ChartClassifyController) ChartClassifyListV2() {
 		}
 	}
 
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
-	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
+	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
-	allChartInfo, err := data_manage.GetChartInfoAll([]int{utils.CHART_SOURCE_DEFAULT})
+	allChartInfo, err := data_manage.GetChartInfoAll([]int{utils.CHART_SOURCE_DEFAULT}, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -162,13 +141,13 @@ func (this *ChartClassifyController) ChartClassifyListV2() {
 
 // getChartClassifyListForMe 获取我创建的图表
 func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT, adminInfo.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
-	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
+	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT, adminInfo.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
@@ -221,14 +200,14 @@ func (this *ChartClassifyController) ChartClassifyItems() {
 		this.ServeJSON()
 	}()
 
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
-	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
+	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -447,16 +426,10 @@ func (this *ChartClassifyController) DeleteChartClassifyCheck() {
 		}
 		count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
 		if err != nil {
-			br.Msg = "判断图表名称是否存在失败"
-			br.ErrMsg = "判断图表名称是否存在失败,Err:" + err.Error()
+			br.Msg = "判断分类下是否存在图表失败"
+			br.ErrMsg = "判断分类下是否存在图表失败,Err:" + err.Error()
 			return
 		}
-		//count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		//if err != nil {
-		//	br.Msg = "删除失败"
-		//	br.ErrMsg = "分类下是否含有指标失败,Err:" + err.Error()
-		//	return
-		//}
 
 		if count > 0 {
 			deleteStatus = 1
@@ -475,6 +448,26 @@ func (this *ChartClassifyController) DeleteChartClassifyCheck() {
 			deleteStatus = 2
 			tipsMsg = "确认删除当前目录及包含的子目录吗"
 		}
+	} else if req.ChartInfoId > 0 {
+		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
+		if err != nil {
+			br.Msg = "获取图表信息失败"
+			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+			return
+		}
+
+		// 公开状态校验
+		switch chartInfo.PublicStatus {
+		case utils.DataPublicSuccess:
+			deleteStatus = 1
+			tipsMsg = "当前图表已经公开,请撤销公开后删除"
+			return
+		case utils.DataPublicCommit:
+			deleteStatus = 1
+			tipsMsg = "当前图表已经提交申请公开,请撤销审批单后删除"
+			return
+		}
+
 	}
 	if deleteStatus == 0 {
 		tipsMsg = "可删除,进行删除操作"
@@ -579,12 +572,6 @@ func (this *ChartClassifyController) DeleteChartClassify() {
 			br.ErrMsg = "判断图表名称是否存在失败,Err:" + err.Error()
 			return
 		}
-		//count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		//if err != nil && !utils.IsErrNoRow(err) {
-		//	br.Msg = "删除失败"
-		//	br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
-		//	return
-		//}
 
 		if count > 0 {
 			br.Msg = "该目录下存在关联指标,不可删除"
@@ -622,6 +609,24 @@ func (this *ChartClassifyController) DeleteChartClassify() {
 			return
 		}
 
+		if chartInfo.SysUserId != this.SysUser.AdminId {
+			br.Msg = "没有该图表的操作权限"
+			br.IsSendEmail = false
+			return
+		}
+
+		// 公开状态校验
+		switch chartInfo.PublicStatus {
+		case utils.DataPublicSuccess:
+			br.Msg = "当前图表已经公开,请撤销公开后删除"
+			br.IsSendEmail = false
+			return
+		case utils.DataPublicCommit:
+			br.Msg = "当前图表已经提交申请公开,请撤销审批单后删除"
+			br.IsSendEmail = false
+			return
+		}
+
 		chartClassifyItem, err := data_manage.GetChartClassifyById(chartInfo.ChartClassifyId)
 		if err != nil {
 			br.Msg = "获取失败"
@@ -682,7 +687,7 @@ func (this *ChartClassifyController) DeleteChartClassify() {
 		}
 		//删除ES
 		{
-			go data.EsDeleteChartInfo(req.ChartInfoId)
+			go data.DeleteChartInfoToEs(req.ChartInfoId)
 			// 删除MY ETA 图表 es数据
 			//go data.EsDeleteMyChartInfoByChartInfoId(req.ChartInfoId)
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)
@@ -933,7 +938,6 @@ func (this *ChartClassifyController) ChartClassifyMove() {
 // ChartClassifyChartListV2
 // @Title 根据图表分类获取图表列表
 // @Description 根据图表分类获取图表列表接口
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   ChartClassifyId   query   bool  true       "图片分类id"
 // @Success 200 {object} data_manage.ChartClassifyListResp
 // @router /chart_classify/chart/list [get]
@@ -975,26 +979,6 @@ func (this *ChartClassifyController) ChartClassifyChartListV2() {
 		}
 	}
 
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		allChartInfo, err := data_manage.GetChartInfoByAdminIdAndClassify([]int{utils.CHART_SOURCE_DEFAULT}, sysUser.AdminId, chartClassifyId)
-		if err != nil && !utils.IsErrNoRow(err) {
-			br.Msg = "获取失败"
-			br.ErrMsg = "获取全部数据失败,Err:" + err.Error()
-			return
-		}
-		// 移除没有权限的图表
-		allNodes := data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap, this.SysUser.AdminId)
-		resp.AllNodes = allNodes
-
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
-		fmt.Println("source my classify")
-		return
-	}
-
 	allChartInfo, err := data_manage.GetChartInfoAllByClassifyId(utils.CHART_SOURCE_DEFAULT, chartClassifyId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
@@ -1004,8 +988,15 @@ func (this *ChartClassifyController) ChartClassifyChartListV2() {
 	// 移除没有权限的图表
 	allNodes := data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap, this.SysUser.AdminId)
 
+	editShareChartInfoIdMap, err := data.GetAllEditSharedChartInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取所有有编辑权限的分享图表失败,Err:" + err.Error()
+		return
+	}
+
 	for k, item := range allNodes {
-		item.Button = data.GetChartOpButton(this.SysUser, item.SysUserId, item.HaveOperaAuth)
+		item.Button = data.GetChartOpButton(this.SysUser, item.SysUserId, item.ChartInfoId, item.HaveOperaAuth, editShareChartInfoIdMap)
 		item.Button.AddButton = false
 		item.Button.OpButton = false
 		item.Button.DeleteButton = false

+ 295 - 148
controllers/data_manage/chart_info.go

@@ -5,12 +5,14 @@ import (
 	"eta_gn/eta_api/controllers"
 	"eta_gn/eta_api/models"
 	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/data_manage/request"
 	"eta_gn/eta_api/models/data_manage/response"
 	"eta_gn/eta_api/models/system"
 	"eta_gn/eta_api/services"
 	"eta_gn/eta_api/services/data"
 	"eta_gn/eta_api/services/data/data_manage_permission"
 	"eta_gn/eta_api/services/data/excel"
+	"eta_gn/eta_api/services/elastic"
 	"eta_gn/eta_api/services/eta_forum"
 	"eta_gn/eta_api/utils"
 	"fmt"
@@ -91,7 +93,7 @@ func (this *ChartInfoController) ChartInfoSave() {
 	}
 
 	//修改es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -445,7 +447,7 @@ func (this *ChartInfoController) ChartEnInfoEdit() {
 		return
 	}
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -643,7 +645,7 @@ func (this *ChartInfoController) ChartInfoBaseEdit() {
 		return
 	}
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -886,7 +888,7 @@ func (this *ChartInfoController) ChartInfoMove() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(req.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(req.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(req.ChartInfoId)
 
@@ -2027,7 +2029,6 @@ func (this *ChartInfoController) ChartInfoEdbInfoDetail() {
 // @Title 图表模糊搜索
 // @Description 图表模糊搜索接口
 // @Param   KeyWord   query   string  true       "图表名称"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Success 200 {object} data_manage.ChartInfo
 // @router /chart_info/search [get]
 func (this *ChartInfoController) ChartInfoSearch() {
@@ -2062,12 +2063,7 @@ func (this *ChartInfoController) ChartInfoSearch() {
 	//		return
 	//	}
 	//}
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	showSysId := 0
-	if isShowMe {
-		showSysId = sysUser.AdminId
-	}
+	showSysId := sysUser.AdminId
 
 	var keyWordArr []string
 	keyWordArr = append(keyWordArr, keyWord)
@@ -2152,7 +2148,9 @@ func (this *ChartInfoController) ChartInfoSearch() {
 // @Title 图表模糊搜索(从es获取)
 // @Description  图表模糊搜索(从es获取)
 // @Param   Keyword   query   string  true       "图表名称"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Param   ChartAuth   query   int  false       "图表权限:0-全部;1-我的;2-公共"
+// @Param   ChartCollect   query   int  false       "图表收藏状态:0-全部;1-已收藏"
+// @Param   ClassifyId   query   int  false       "父级分类id"
 // @Success 200 {object} data_manage.ChartInfo
 // @router /chart_info/search_by_es [get]
 func (this *ChartInfoController) ChartInfoSearchByEs() {
@@ -2161,6 +2159,7 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
+	resp := data_manage.ChartInfoListByEsRespV2{}
 
 	sysUser := this.SysUser
 	if sysUser == nil {
@@ -2182,149 +2181,178 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 	startSize = paging.StartIndex(currentIndex, pageSize)
 
 	keyword := this.GetString("Keyword")
-
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	showSysId := 0
-	if isShowMe {
-		showSysId = sysUser.AdminId
+	if keyword == `` {
+		keyword = this.GetString("KeyWord")
 	}
 
-	var searchList []*data_manage.ChartInfo
+	showSysId := sysUser.AdminId
+
+	var searchList []*data_manage.ChartInfoView
 	var total int64
 	var err error
 
-	// 获取当前账号的不可见指标
-	noPermissionChartIdList := make([]int, 0)
-	{
-		obj := data_manage.EdbInfoNoPermissionAdmin{}
-		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && !utils.IsErrNoRow(err) {
-			br.Msg = "获取失败"
-			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
-			return
-		}
-		for _, v := range confList {
-			noPermissionChartIdList = append(noPermissionChartIdList, v.ChartInfoId)
+	chartAuth, _ := this.GetInt("ChartAuth", 0) // 图表权限范围,0-全部;1-我的;2-公共
+
+	chartCollect, _ := this.GetInt("ChartCollect", 0) // 图表收藏状态:0-全部;1-已收藏
+
+	// 筛选分类id列表
+	searchClassifyIdList := make([]int, 0)
+	searchPublicClassifyIdList := make([]int, 0)
+	// 父级分类id
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId > 0 {
+		switch chartAuth {
+		case 1: // 1-我的;2-公共
+			allChildClassifyItemList, err, _ := data.GetAllChartChildClassifyByParentId(classifyId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取图表分类信息失败,Err:" + err.Error()
+				return
+			}
+			searchClassifyIdList = append(searchClassifyIdList, classifyId)
+			for _, v := range allChildClassifyItemList {
+				searchClassifyIdList = append(searchClassifyIdList, v.ChartClassifyId)
+			}
+		case 2: // 1-我的;2-公共
+			obj := data_manage.ChartPublicClassify{}
+			allChildClassifyItemList, err, _ := obj.GetAllChildClassifyByParentId(classifyId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取图表分类信息失败,Err:" + err.Error()
+				return
+			}
+			searchPublicClassifyIdList = append(searchPublicClassifyIdList, classifyId)
+			for _, v := range allChildClassifyItemList {
+				searchPublicClassifyIdList = append(searchPublicClassifyIdList, v.ChartPublicClassifyId)
+			}
+
 		}
 	}
 
-	// 是否走ES
-	isEs := false
-	if keyword != "" {
-		searchList, total, err = data.EsSearchChartInfo(keyword, showSysId, []int{utils.CHART_SOURCE_DEFAULT}, noPermissionChartIdList, startSize, pageSize)
-		isEs = true
-	} else {
-		total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, []int{utils.CHART_SOURCE_DEFAULT}, noPermissionChartIdList, startSize, pageSize)
-		if err != nil && !utils.IsErrNoRow(err) {
+	// 收藏的指标id
+	collectChartInfoIdList := make([]int, 0)
+	if chartCollect == 1 {
+		collectChartInfoIdList, err = data_manage.GetUserAllCollectChartInfoIdList(this.SysUser.AdminId)
+		if err != nil {
 			br.Msg = "获取失败"
-			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+			br.ErrMsg = "获取收藏指标配置数据失败,Err:" + err.Error()
 			return
 		}
 	}
 
-	finalList := make([]*data_manage.ChartInfoMore, 0)
-	if len(searchList) > 0 {
-		// 涉及分类id
-		classifyIdList := make([]int, 0)
-		// 图表id
-		chartInfoIdList := make([]int, 0)
+	sortMap := make(map[string]string)
+	// 如果没有搜索关键词,则默认根据图表创建时间倒序排序
+	if keyword == `` {
+		sortMap["ChartInfoId"] = `desc`
+	}
 
-		chartInfoIds := ""
-		chartEdbMap := make(map[int][]*data_manage.ChartEdbInfoMapping)
+	// 是否走ES
+	total, searchList, err = elastic.SearchChartInfoDataV2(keyword, showSysId, chartAuth, []int{utils.CHART_SOURCE_DEFAULT}, collectChartInfoIdList, searchClassifyIdList, searchPublicClassifyIdList, sortMap, startSize, pageSize)
 
-		for _, v := range searchList {
-			chartInfoIds += strconv.Itoa(v.ChartInfoId) + ","
-			classifyIdList = append(classifyIdList, v.ChartClassifyId)
-			chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
+	if len(searchList) <= 0 {
+		searchList = make([]*data_manage.ChartInfoView, 0)
+		page := paging.GetPaging(currentIndex, pageSize, int(total))
+		resp.Paging = page
+		resp.List = searchList
+
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = resp
+		return
+	}
+
+	// 涉及分类id
+	classifyIdList := make([]int, 0)
+	// 图表id
+	chartInfoIdList := make([]int, 0)
+
+	for _, v := range searchList {
+		classifyIdList = append(classifyIdList, v.ChartClassifyId)
+		chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
+	}
+
+	// 当前列表中的分类map
+	chartClassifyMap := make(map[int]*data_manage.ChartClassify)
+
+	// 图表分类
+	{
+		chartClassifyList, err := data_manage.GetChartClassifyByIdList(classifyIdList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取图表分类失败,Err:" + err.Error()
+			return
 		}
-		if chartInfoIds != "" {
-			chartInfoIds = strings.Trim(chartInfoIds, ",")
-			//判断是否需要展示英文标识
-			edbList, e := data_manage.GetChartEdbMappingListByChartInfoIds(chartInfoIds)
-			if e != nil {
-				br.Msg = "获取失败"
-				br.ErrMsg = "获取图表,指标信息失败,Err:" + e.Error()
-				return
-			}
-			for _, v := range edbList {
-				chartEdbMap[v.ChartInfoId] = append(chartEdbMap[v.ChartInfoId], v)
-			}
+		for _, v := range chartClassifyList {
+			chartClassifyMap[v.ChartClassifyId] = v
 		}
-		// 当前列表中的分类map
-		chartClassifyMap := make(map[int]*data_manage.ChartClassify)
+	}
 
-		// 图表分类
-		{
-			chartClassifyList, err := data_manage.GetChartClassifyByIdList(classifyIdList)
-			if err != nil {
-				br.Msg = "获取失败"
-				br.ErrMsg = "获取图表分类失败,Err:" + err.Error()
-				return
-			}
-			for _, v := range chartClassifyList {
-				chartClassifyMap[v.ChartClassifyId] = v
-			}
+	// 查询收藏
+	collectEdbMap := make(map[int][]int)
+	collectNameEdbMap := make(map[int][]string)
+	{
+		obj := data_manage.ChartCollect{}
+		collectList, err := obj.GetItemsByUserIdAndChartInfoIdList(this.SysUser.AdminId, chartInfoIdList)
+		if err != nil {
+			br.Msg = "获取指标信息失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
 		}
-		// 图表
-		if isEs {
-			// 当前列表中的图表map
-			chartInfoMap := make(map[int]*data_manage.ChartInfo)
-			tmpChartList, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
-			if err != nil {
-				br.Msg = "获取失败"
-				br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
-				return
-			}
-			for _, tmpChartInfo := range tmpChartList {
-				chartInfoMap[tmpChartInfo.ChartInfoId] = tmpChartInfo
+		for _, v := range collectList {
+			collectIdList, ok := collectEdbMap[v.ChartInfoId]
+			if !ok {
+				collectIdList = make([]int, 0)
 			}
-			for _, v := range searchList {
-				// 图表权限
-				chartViewInfo, ok := chartInfoMap[v.ChartInfoId]
-				if !ok {
-					continue
-				}
-				v.IsJoinPermission = chartViewInfo.IsJoinPermission
+			collectEdbMap[v.ChartInfoId] = append(collectIdList, v.ChartCollectClassifyId)
+
+			collectNameList, ok := collectNameEdbMap[v.ChartInfoId]
+			if !ok {
+				collectNameList = make([]string, 0)
 			}
+			collectNameEdbMap[v.ChartInfoId] = append(collectNameList, v.ClassifyName)
 		}
 
-		// 已授权图表和分类id
-		permissionChartIdList, permissionClassifyIdList, err := data_manage_permission.GetUserChartAndClassifyPermissionList(sysUser.AdminId, 0, 0)
+	}
+
+	// 图表
+	{
+		// 当前列表中的图表map
+		chartInfoMap := make(map[int]*data_manage.ChartInfo)
+		tmpChartList, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
 		if err != nil {
 			br.Msg = "获取失败"
-			br.ErrMsg = "已授权图表和分类id失败,Err:" + err.Error()
+			br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
 			return
 		}
-
+		for _, tmpChartInfo := range tmpChartList {
+			chartInfoMap[tmpChartInfo.ChartInfoId] = tmpChartInfo
+		}
 		for _, v := range searchList {
-			tmp := new(data_manage.ChartInfoMore)
-			tmp.ChartInfo = *v
-			//判断是否需要展示英文标识
-			if edbTmpList, ok := chartEdbMap[v.ChartInfoId]; ok {
-				tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, edbTmpList, v.Source, v.ChartType)
+			if collectIdList, ok := collectEdbMap[v.ChartInfoId]; ok {
+				v.CollectClassifyIdList = collectIdList
+			} else {
+				v.CollectClassifyIdList = []int{}
 			}
 
-			// 图表权限
-			if currClassify, ok := chartClassifyMap[v.ChartClassifyId]; ok {
-				tmp.HaveOperaAuth = data_manage_permission.CheckChartPermissionByPermissionIdList(v.IsJoinPermission, currClassify.IsJoinPermission, v.ChartInfoId, v.ChartClassifyId, permissionChartIdList, permissionClassifyIdList)
+			if collectNameList, ok := collectNameEdbMap[v.ChartInfoId]; ok {
+				v.CollectClassifyNameList = collectNameList
+			} else {
+				v.CollectClassifyNameList = []string{}
 			}
 
-			finalList = append(finalList, tmp)
+			// 图表权限
+			if chartViewInfo, ok := chartInfoMap[v.ChartInfoId]; ok {
+				v.IsJoinPermission = chartViewInfo.IsJoinPermission
+			}
+			v.HaveOperaAuth = true
 		}
 	}
-	//新增搜索词记录
-	{
-		searchKeyword := new(data_manage.SearchKeyword)
-		searchKeyword.KeyWord = keyword
-		searchKeyword.CreateTime = time.Now()
-		go data_manage.AddSearchKeyword(searchKeyword)
-	}
 
 	page := paging.GetPaging(currentIndex, pageSize, int(total))
-	resp := data_manage.ChartInfoListByEsResp{
+	resp = data_manage.ChartInfoListByEsRespV2{
 		Paging: page,
-		List:   finalList,
+		List:   searchList,
 	}
 	br.Ret = 200
 	br.Success = true
@@ -2442,7 +2470,7 @@ func (this *ChartInfoController) ChartInfoImageSet() {
 		}
 
 		//修改es数据
-		go data.EsAddOrEditChartInfo(req.ChartInfoId)
+		go data.AddOrEditChartInfoToEs(req.ChartInfoId)
 		//修改my eta es数据
 		go data.EsAddOrEditMyChartInfoByChartInfoId(req.ChartInfoId)
 	}
@@ -3089,26 +3117,26 @@ func (this *ChartInfoController) CopyChartInfo() {
 	//	return
 	//}
 	//判断图表是否存在
-	var condition string
-	var pars []interface{}
-	condition += " AND chart_classify_id=? "
-	pars = append(pars, req.ChartClassifyId)
-
-	condition += " AND chart_name=? AND source = ? "
-	pars = append(pars, req.ChartName, utils.CHART_SOURCE_DEFAULT)
+	//var condition string
+	//var pars []interface{}
+	//condition += " AND chart_classify_id=? "
+	//pars = append(pars, req.ChartClassifyId)
 
-	count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
-	if err != nil {
-		br.Msg = "判断图表名称是否存在失败"
-		br.ErrMsg = "判断图表名称是否存在失败,Err:" + err.Error()
-		return
-	}
+	//condition += " AND chart_name=? AND source = ? "
+	//pars = append(pars, req.ChartName, utils.CHART_SOURCE_DEFAULT)
 
-	if count > 0 {
-		br.Msg = "图表已存在,请重新填写"
-		br.IsSendEmail = false
-		return
-	}
+	//count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
+	//if err != nil {
+	//	br.Msg = "判断图表名称是否存在失败"
+	//	br.ErrMsg = "判断图表名称是否存在失败,Err:" + err.Error()
+	//	return
+	//}
+	//
+	//if count > 0 {
+	//	br.Msg = "图表已存在,请重新填写"
+	//	br.IsSendEmail = false
+	//	return
+	//}
 
 	//获取原图表关联的指标信息列表
 	edbMappingList, err := data_manage.GetChartEdbMappingList(req.ChartInfoId)
@@ -3230,7 +3258,7 @@ func (this *ChartInfoController) CopyChartInfo() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartInfo.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
 
@@ -4231,7 +4259,7 @@ func (this *ChartInfoController) ChartInfoImgSetBySvg() {
 		}
 
 		//修改es数据
-		go data.EsAddOrEditChartInfo(chartInfoId)
+		go data.AddOrEditChartInfoToEs(chartInfoId)
 		//修改my eta es数据
 		go data.EsAddOrEditMyChartInfoByChartInfoId(chartInfoId)
 	}
@@ -4246,12 +4274,131 @@ func (this *ChartInfoController) ChartInfoImgSetBySvg() {
 	return
 }
 
-// 修复ES中的指标和图表数据
-//func init() {
-//	// 更新ES中的指标数据
-//	data.AddOrEditAllEdbInfoToEs()
-//	// 更新es中的图表数据
-//	data.AddAllChartInfo()
-//
-//	fmt.Println("全部es数据修复完成")
-//}
+// BatchMove
+// @Title 图表批量移动接口
+// @Description 图表批量移动接口
+// @Param	request	body request.MoveChartClassifyReq true "type json string"
+// @Success Ret=200 移动成功
+// @router /chart_info/batch_move [post]
+func (this *ChartInfoController) BatchMove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.MoveChartClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.NewClassifyId <= 0 {
+		br.Msg = `请选择要转移的新分类`
+		br.IsSendEmail = false
+		return
+	}
+
+	classifyItem, err := data_manage.GetChartClassifyById(req.NewClassifyId)
+	if err != nil {
+		br.Msg = "获取指标分类失败!"
+		br.ErrMsg = "获取指标分类失败!" + err.Error()
+		return
+	}
+	if classifyItem.SysUserId != this.SysUser.AdminId {
+		br.Msg = `您没有权限移动指标到该分类!`
+		br.IsSendEmail = false
+		return
+	}
+
+	chartInfoIdList := make([]int, 0)
+	if req.IsSelectAll {
+		// 获取指标
+		chartInfoList, err := data.GetAllChartInfoListBySearchPublicChartReq(req.SearchPublicChartReq, this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取指标列表失败!"
+			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
+			return
+		}
+		// 如果有过滤指标,那么就过滤吧
+		if len(req.NoChartIdList) > 0 {
+			noChartIdMap := make(map[int]bool)
+			for _, v := range req.NoChartIdList {
+				noChartIdMap[v] = true
+			}
+
+			for _, chartInfo := range chartInfoList {
+				if _, ok := noChartIdMap[chartInfo.ChartInfoId]; !ok {
+
+					if chartInfo.SysUserId != this.SysUser.AdminId {
+						br.Msg = `您没有权限移动该指标!`
+						br.IsSendEmail = false
+						return
+					}
+
+					// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
+					chartInfoIdList = append(chartInfoIdList, chartInfo.ChartInfoId)
+				}
+			}
+		} else {
+			for _, chartInfo := range chartInfoList {
+				chartInfoIdList = append(chartInfoIdList, chartInfo.ChartInfoId)
+				for _, v := range chartInfoList {
+					if v.SysUserId != this.SysUser.AdminId {
+						br.Msg = `您没有权限移动该指标!`
+						br.IsSendEmail = false
+						return
+					}
+				}
+			}
+		}
+	} else {
+		chartInfoList, err := data_manage.GetChartInfoViewByIdList(req.ChartIdList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range chartInfoList {
+			if v.SysUserId != this.SysUser.AdminId {
+				br.Msg = `您没有权限移动该指标!`
+				br.IsSendEmail = false
+				return
+			}
+		}
+		chartInfoIdList = req.ChartIdList
+	}
+
+	num := len(chartInfoIdList)
+	if num <= 0 {
+		br.Msg = `请选择要移动的指标!`
+		br.IsSendEmail = false
+		return
+	}
+	if num > 100 {
+		br.Msg = `最多只能选择100条指标!`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 开始批量修改指标分类
+	if len(chartInfoIdList) > 0 {
+		err = data_manage.UpdateClassifyIdByChartInfoIdList(chartInfoIdList, req.NewClassifyId)
+		if err != nil {
+			br.Msg = `指标移动失败!`
+			br.ErrMsg = `指标移动失败,ERR:` + err.Error()
+			return
+		}
+
+		// 还得修改ES呢
+		for _, v := range chartInfoIdList {
+			data.AddOrEditChartInfoToEs(v)
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 722 - 0
controllers/data_manage/chart_info_share.go

@@ -0,0 +1,722 @@
+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/models/data_manage/request"
+	"eta_gn/eta_api/models/data_manage/response"
+	"eta_gn/eta_api/models/system"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/services/elastic"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// ChartInfoShareController 数据管理
+type ChartInfoShareController struct {
+	controllers.BaseAuthController
+}
+
+// UserList
+// @Title 获取图表设置共享的详情
+// @Description 获取图表详情接口
+// @Param   ChartInfoId   query   int  true       "图表id"
+// @Success 200 {object} response.ChartInfoShareUserResp
+// @router /chart_info/share/user_list [get]
+func (c *ChartInfoShareController) UserList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	chartInfoId, _ := c.GetInt("ChartInfoId")
+	if chartInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+	chartInfo, err := data_manage.GetChartInfoById(chartInfoId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		return
+	}
+
+	if chartInfo.SysUserId != sysUser.AdminId {
+		br.Msg = "您没有权限设置共享"
+		br.ErrMsg = "您没有权限设置共享,ChartInfoId:" + strconv.Itoa(chartInfoId)
+		br.IsSendEmail = false
+		return
+	}
+
+	resp := response.ChartInfoShareUserResp{}
+
+	obj := data_manage.ChartInfoShare{}
+	list, err := obj.GetListByChartInfoId(chartInfoId)
+	if err != nil {
+		br.Msg = `获取失败`
+		br.ErrMsg = `获取失败:` + err.Error()
+		return
+	}
+	resp.List = list
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// Save
+// @Title 单个图表设置共享
+// @Description 单个图表设置共享
+// @Param	request	body request.SetChartInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.ChartInfo
+// @router /chart_info/share/save [post]
+func (c *ChartInfoShareController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.SetChartInfoShareReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartInfoId <= 0 {
+		br.Msg = `请选择图表`
+		br.IsSendEmail = false
+		return
+	}
+
+	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
+	if err != nil {
+		br.Msg = "查找图表失败"
+		br.ErrMsg = "查找图表失败,Err:" + err.Error()
+		return
+	}
+	if chartItem.ChartInfoId <= 0 {
+		br.Msg = "图表不存在"
+		br.ErrMsg = "图表不存在,ChartInfoId:" + strconv.Itoa(req.ChartInfoId)
+		br.IsSendEmail = false
+		return
+	}
+	if chartItem.SysUserId != c.SysUser.AdminId {
+		br.Msg = "您没有权限设置共享"
+		br.ErrMsg = "您没有权限设置共享,EdbInfoId:" + strconv.Itoa(req.ChartInfoId)
+		br.IsSendEmail = false
+		return
+	}
+
+	obj := data_manage.ChartInfoShare{}
+	err = obj.SaveChartInfoShare([]int{req.ChartInfoId}, req.UserIdList, req.ShareType)
+	if err != nil {
+		br.Msg = `保存失败`
+		br.ErrMsg = `保存失败:` + err.Error()
+		return
+	}
+
+	// 更新es
+	data.AddOrEditChartInfoToEs(req.ChartInfoId)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// Tree
+// @Title 获取共享图表的分类/图表树
+// @Description 获取共享图表的分类/图表树
+// @Success 200 {object} response.ChartShareListResp
+// @router /chart_info/share/tree [get]
+func (c *ChartInfoShareController) Tree() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	resp := response.ChartShareListResp{}
+
+	// 我共享的
+	{
+		sendList, err := data.GetAllShareChartListByFromUserId(sysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取我共享的图表列表信息失败,Err:" + err.Error()
+			return
+		}
+		nodeList, err := data.GetChartClassifyItemListByShareChartInfoQueryList(sendList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取我共享出去的图表列表分类结构信息失败,Err:" + err.Error()
+			return
+		}
+
+		var sortList data_manage.UserShareChartClassifyItemList
+		sortList = nodeList
+
+		sort.Sort(sortList)
+		resp.Send = sortList
+	}
+
+	// 我收到的
+	{
+		sendList, err := data.GetAllShareChartListByReceivedUserId(sysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取我共享的图表列表信息失败,Err:" + err.Error()
+			return
+		}
+		nodeList, err := data.GetChartClassifyItemListByShareChartInfoQueryList(sendList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取我收到共享的图表列表分类结构信息失败,Err:" + err.Error()
+			return
+		}
+
+		receivedMap := make(map[int]int)
+		var receivedList data_manage.UserShareChartClassifyItemList
+		for _, v := range nodeList {
+			index, ok := receivedMap[v.SysUserId]
+			if !ok {
+				index = len(receivedMap)
+				item := &data_manage.UserShareChartClassifyItem{
+					UserId:              v.SysUserId,
+					UserName:            v.SysUserRealName,
+					ChartInfoId:         0,
+					ChartClassifyId:     v.SysUserId,
+					ChartClassifyName:   v.SysUserRealName,
+					ChartClassifyNameEn: v.SysUserRealName,
+					ParentId:            0,
+					Level:               0,
+					Sort:                0,
+					UniqueCode:          utils.MD5(fmt.Sprint(v.SysUserId, "_", v.SysUserRealName)),
+					Source:              0,
+					SourceName:          "",
+					SysUserId:           v.SysUserId,
+					SysUserRealName:     v.SysUserRealName,
+					DateType:            0,
+					StartDate:           "",
+					EndDate:             "",
+					ChartType:           0,
+					Calendar:            "",
+					SeasonStartDate:     "",
+					SeasonEndDate:       "",
+					Children:            []*data_manage.UserShareChartClassifyItem{},
+					Button:              data_manage.ChartClassifyItemsButton{},
+					IsJoinPermission:    0,
+					HaveOperaAuth:       true,
+					ChartClassifyIdPath: "",
+				}
+				receivedList = append(receivedList, item)
+			}
+			receivedList[index].Children = append(receivedList[index].Children, v)
+			receivedMap[v.SysUserId] = index
+		}
+		sort.Sort(receivedList)
+		resp.Received = receivedList
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// List
+// @Title 图表列表接口
+// @Description 图表列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyId   query   int  true       "分类id"
+// @Param   FilterSource   query   int  false       "共享图表的列表数据来源,0:我共享的;1:别人共享给我的"
+// @Param   ClassifyId   query   int  false       "分类id"
+// @Param   UserId   query   int  false       "所属用户id"
+// @Success 200 {object} response.ChartInfoChartListResp
+// @router /chart_info/share/list [get]
+func (c *ChartInfoShareController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	// 分页
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+	filterSource, _ := c.GetInt("FilterSource")
+
+	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{}
+	condition += ` AND source = ? `
+	pars = append(pars, utils.CHART_TYPE_CURVE)
+
+	// 用户筛选
+	userId, _ := c.GetInt("UserId")
+	if userId > 0 {
+		condition += ` AND b.sys_user_id = ?  `
+		pars = append(pars, userId)
+	}
+
+	// 分类筛选
+	classifyId, _ := c.GetInt("ClassifyId")
+	if classifyId > 0 {
+		childClassify, e, _ := data.GetChildChartClassifyByClassifyId(classifyId)
+		if e != nil && !utils.IsErrNoRow(e) {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取分类信息失败, GetChartClassify,Err:" + e.Error()
+			return
+		}
+		var classifyIds []int
+		for _, v := range childClassify {
+			classifyIds = append(classifyIds, v.ChartClassifyId)
+		}
+		condition += fmt.Sprintf(` AND b.chart_classify_id IN (%s) `, utils.GetOrmInReplace(len(classifyIds)))
+		pars = append(pars, classifyIds)
+	}
+
+	switch filterSource {
+	case 1: // 别人共享给我的
+		condition += ` AND a.sys_user_id = ? AND b.sys_user_id != ?  `
+		pars = append(pars, sysUser.AdminId, sysUser.AdminId)
+	default: // 我共享的
+		condition += ` AND b.sys_user_id = ? `
+		pars = append(pars, sysUser.AdminId)
+	}
+
+	obj := data_manage.ChartInfoShare{}
+
+	dataCount, respList, err := obj.GetShareChartInfoListPageList(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取分享图表列表失败, %v", err)
+		return
+	}
+
+	editShareEdbInfoIdMap, err := data.GetAllEditSharedChartInfoIdMapByReceivedUserId(c.SysUser.AdminId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+		return
+	}
+	for _, chartInfo := range respList {
+		chartInfo.HaveOperaAuth = true
+		button := data.GetChartOpButton(c.SysUser, chartInfo.SysUserId, chartInfo.ChartInfoId, chartInfo.HaveOperaAuth, editShareEdbInfoIdMap)
+		chartInfo.Button.IsEdit = button.OpButton
+		chartInfo.Button.IsCopy = button.DeleteButton
+	}
+
+	page = paging.GetPaging(currentIndex, pageSize, int(dataCount))
+
+	resp := response.ChartInfoChartListResp{
+		Paging: page,
+		List:   respList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ListByEs
+// @Title 图表筛选接口
+// @Description 图表筛选接口
+// @Success 200 {object} data_manage.ChartInfoList
+// @Param	request	body request.SearchChartInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.ChartInfoFilterDataResp
+// @router /chart_info/share/list/es [post]
+func (c *ChartInfoShareController) ListByEs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.SearchChartInfoShareReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	pageSize := req.PageSize
+	currentIndex := req.CurrentIndex
+
+	var total int64
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	keyword := req.Keyword
+	keyword = strings.TrimSpace(keyword) //移除字符串首尾空格
+
+	sourceList := []int{utils.CHART_TYPE_CURVE}
+
+	// 图表分享状态:1-未共享;2-已共享。可多选,多选用英文,隔开;默认是未全部
+	chartShareList := req.ChartShareList
+	if len(chartShareList) <= 0 {
+		chartShareList = []int{}
+	}
+	chartShare := 0 // 0:全部,1:未共享,2:已共享
+	lenChartShareList := len(chartShareList)
+	if len(chartShareList) > 0 {
+		if lenChartShareList > 1 {
+			chartShare = 0
+		} else {
+			chartShare = chartShareList[0]
+		}
+	}
+
+	// 图表类型
+	chartTypeList := req.ChartTypeList
+
+	// 直图表所属分类id
+	chartClassifyIdList := req.ClassifyIdList
+
+	chartAuth := 1 // 选择范围是:只有我的图表
+
+	var chartInfoList []*data_manage.ChartInfoView
+
+	sortMap := make(map[string]string)
+	// 如果没有搜索关键词,则默认根据图表编码倒序排序
+	if keyword == `` {
+		sortMap["ChartInfoId"] = `desc`
+	}
+	total, chartInfoList, err = elastic.SearchChartInfoDataByShared(keyword, startSize, pageSize, chartShare, sourceList, chartTypeList, chartClassifyIdList, chartAuth, c.SysUser.AdminId, sortMap)
+	if err != nil {
+		chartInfoList = make([]*data_manage.ChartInfoView, 0)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+
+	// 因为是ES查找的,所以需要重新查一下图表的信息,主要是为了把是否授权字段找出来
+	if len(chartInfoList) > 0 {
+		sysUserIdList := make([]int, 0)
+		chartInfoIdList := make([]int, 0)
+		for _, v := range chartInfoList {
+			v.ConvertToResp()
+			v.HaveOperaAuth = true
+			chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
+
+			if v.SharedUserIdList != nil && len(v.SharedUserIdList) > 0 {
+				sysUserIdList = append(sysUserIdList, v.SharedUserIdList...)
+			}
+		}
+
+		// 获取图表数据
+		tmpChartList, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
+			return
+		}
+		chartInfoMap := make(map[int]*data_manage.ChartInfo)
+		for _, v := range tmpChartList {
+			chartInfoMap[v.ChartInfoId] = v
+		}
+
+		// 获取用户数据
+		sysUserMap := make(map[int]string)
+		if len(sysUserIdList) > 0 {
+			sysUserList, err := system.GetAdminListByIdList(sysUserIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取分享用户列表失败,Err:" + err.Error()
+				return
+			}
+
+			for _, v := range sysUserList {
+				sysUserMap[v.AdminId] = v.RealName
+			}
+		}
+
+		for _, v := range chartInfoList {
+			tmpChartInfo, ok := chartInfoMap[v.ChartInfoId]
+			if !ok {
+				continue
+			}
+			v.IsJoinPermission = tmpChartInfo.IsJoinPermission
+
+			// 分享人
+			shareUserName := ``
+			shareUserNameList := make([]string, 0)
+			shareUserNameMap := make(map[int]bool)
+			for _, userId := range v.SharedUserIdList {
+				userName, ok := sysUserMap[userId]
+				if !ok {
+					continue
+				}
+				if _, ok = shareUserNameMap[userId]; ok {
+					continue
+				}
+				shareUserNameMap[userId] = true
+				shareUserNameList = append(shareUserNameList, userName)
+			}
+			if len(shareUserNameList) > 0 {
+				shareUserName = strings.Join(shareUserNameList, `,`)
+			}
+			v.SharedUserName = shareUserName
+
+		}
+	}
+
+	resp := data_manage.ChartInfoFilterDataResp{
+		Paging: page,
+		List:   chartInfoList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// BatchSave
+// @Title 批量图表设置共享
+// @Description 批量图表设置共享
+// @Param	request	body request.SetChartSharePermissionReq true "type json string"
+// @Success 200 {object} data_manage.ChartInfo
+// @router /chart_info/share/batch_save [post]
+func (c *ChartInfoShareController) BatchSave() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.SetChartSharePermissionReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	// 选中的图表id列表
+	selectChartInfoIdList := make([]int, 0)
+
+	// 选择所有图表,所以需要通过es获取数据
+	if req.IsSelectAll {
+		allEsChartInfoIdList, err := getAllChartInfoIdListByShared(req, c.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "设置失败!"
+			br.ErrMsg = "设置失败,Err:" + err.Error()
+			return
+		}
+
+		if len(req.NoChartIdList) <= 0 {
+			selectChartInfoIdList = allEsChartInfoIdList
+		} else {
+			noChartIdMap := make(map[int]bool)
+			for _, v := range req.NoChartIdList {
+				noChartIdMap[v] = true
+			}
+
+			for _, v := range allEsChartInfoIdList {
+				if _, ok := noChartIdMap[v]; !ok {
+					// 如果不在未选中的图表id列表中,那么就加入到选中的图表id列表
+					selectChartInfoIdList = append(selectChartInfoIdList, v)
+				}
+			}
+		}
+	} else {
+		selectChartInfoIdList = req.ChartIdList
+	}
+
+	num := len(selectChartInfoIdList)
+
+	if num > 30 {
+		br.Msg = `图表数量不能超过30个`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 设置
+	if num > 0 {
+
+		obj := data_manage.ChartInfoShare{}
+		err = obj.SaveChartInfoShare(selectChartInfoIdList, req.UserIdList, req.ShareType)
+		if err != nil {
+			br.Msg = `保存失败`
+			br.ErrMsg = `保存失败:` + err.Error()
+			return
+		}
+
+		// 更新es
+		for _, chartInfoId := range selectChartInfoIdList {
+			data.AddOrEditChartInfoToEs(chartInfoId)
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// getAllChartInfoIdListByShared
+// @Description: 获取所有的图表id列表
+// @author: Roc
+// @datetime 2024-12-10 17:51:35
+// @param req request.SetChartSharePermissionReq
+// @param userId int
+// @return chartInfoIdList []int
+// @return err error
+func getAllChartInfoIdListByShared(req request.SetChartSharePermissionReq, userId int) (chartInfoIdList []int, err error) {
+	keyword := req.Keyword
+	keyword = strings.TrimSpace(keyword) //移除字符串首尾空格
+
+	//图表来源
+	sourceList := []int{utils.CHART_TYPE_CURVE}
+
+	// 图表分享状态:1-未共享;2-已共享。可多选,多选用英文,隔开;默认是未共享
+	chartShareList := req.ChartShareList
+	if len(chartShareList) <= 0 {
+		chartShareList = []int{1}
+	}
+	chartShare := 1 // 0:全部,1:未共享,2:已共享
+	lenChartShareList := len(chartShareList)
+	if len(chartShareList) > 0 {
+		if lenChartShareList > 1 {
+			chartShare = 0
+		} else {
+			chartShare = chartShareList[0]
+		}
+	}
+
+	// 图表类型
+	chartTypeList := req.ChartTypeList
+
+	// 图表分享状态:1-未共享;2-已共享。可多选,多选用英文,隔开;默认是未共享
+	chartClassifyIdList := req.ClassifyIdList
+
+	chartAuth := 1 // 选择范围是:只有我的图表
+
+	sortMap := make(map[string]string)
+	// 如果没有搜索关键词,则默认根据图表编码倒序排序
+	if keyword == `` {
+		sortMap["ChartInfoId"] = `desc`
+	}
+	_, chartInfoList, err := getAllChartInfoDataByShared(keyword, 1, chartShare, sourceList, chartTypeList, chartClassifyIdList, chartAuth, userId, sortMap)
+	if err != nil {
+		return
+	}
+
+	// 返回图表id列表
+	for _, v := range chartInfoList {
+		chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
+	}
+
+	return
+}
+
+// getAllChartInfoDataByShared
+// @Description: 获取所有的图表列表(设置共享的时候)
+// @author: Roc
+// @datetime 2024-12-10 17:51:18
+// @param keyword string
+// @param currPage int
+// @param chartShare int
+// @param sourceList []int
+// @param classifyIdList []int
+// @param chartAuth int
+// @param sysUserId int
+// @param sortMap map[string]string
+// @return total int64
+// @return list []*data_manage.ChartInfoView
+// @return err error
+func getAllChartInfoDataByShared(keyword string, currPage, chartShare int, sourceList, chartTypeList, classifyIdList []int, chartAuth, sysUserId int, sortMap map[string]string) (total int64, list []*data_manage.ChartInfoView, err error) {
+	// 每页获取数据的数量
+	pageSize := 5000
+	var startSize int
+	if currPage <= 0 {
+		currPage = 1
+	}
+	startSize = paging.StartIndex(currPage, pageSize)
+
+	total, list, err = elastic.SearchChartInfoDataByShared(keyword, startSize, pageSize, chartShare, sourceList, chartTypeList, classifyIdList, chartAuth, sysUserId, sortMap)
+	if err != nil {
+		return
+	}
+
+	page := paging.GetPaging(currPage, pageSize, int(total))
+	if !page.IsEnd {
+		_, nextList, tmpErr := getAllChartInfoDataByShared(keyword, page.NextIndex, chartShare, sourceList, chartTypeList, classifyIdList, chartAuth, sysUserId, sortMap)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		list = append(list, nextList...)
+	}
+
+	return
+}

+ 354 - 0
controllers/data_manage/collect_chart.go

@@ -0,0 +1,354 @@
+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"
+	"sort"
+	"strings"
+	"time"
+)
+
+// ChartCollectController 图表收藏
+type ChartCollectController 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 /chart_collect/list [get]
+func (this *ChartCollectController) 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.ChartInfoChartListResp)
+	resp := new(data_manage.CollectChartInfoListResp)
+	resp.List = make([]*data_manage.CollectChartInfoItem, 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.GetChartCollectClassifyChildIds(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.chart_collect_classify_id IN (%s) `, utils.GetOrmInReplace(len(classifyIds)))
+		pars = append(pars, classifyIds)
+	}
+
+	// 关键词搜索
+	keywords := this.GetString("Keyword")
+	keywords = strings.TrimSpace(keywords)
+	if keywords != "" {
+		kw := fmt.Sprint("%", keywords, "%")
+		cond += fmt.Sprintf(` AND (b.chart_code LIKE ? OR b.chart_name LIKE ?)`)
+		pars = append(pars, kw, kw)
+	}
+
+	// 获取图表列表
+	dataCount, e := data_manage.GetCollectChartInfoCount(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.GetCollectChartInfoPageList(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.FormatChartInfo2CollectItem(v))
+	}
+	sort.Slice(resp.List, func(i, j int) bool {
+		return resp.List[i].Sort < resp.List[j].Sort
+	})
+
+	page = paging.GetPaging(currentIndex, pageSize, int(dataCount))
+	resp.Paging = page
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Collect
+// @Title 新增收藏
+// @Description 新增收藏
+// @Param	request	body data_manage.ChartCollectReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /chart_collect/collect [post]
+func (this *ChartCollectController) 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.ChartCollectReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常: %v", e)
+		return
+	}
+	if req.ChartInfoId <= 0 {
+		br.Msg = "请选择图表"
+		return
+	}
+
+	chartItem, e := data_manage.GetChartInfoById(req.ChartInfoId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "图表不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取图表信息失败: %v", e)
+		return
+	}
+	if chartItem.ChartInfoId <= 0 {
+		br.Msg = "图表不存在, 请刷新页面"
+		br.IsSendEmail = false
+		return
+	}
+
+	collectOb := new(data_manage.ChartCollect)
+
+	// 待添加的分类配置
+	addList := make([]*data_manage.ChartCollect, 0)
+	for _, classifyId := range req.ClassifyIdList {
+		addList = append(addList, &data_manage.ChartCollect{
+			ChartCollectClassifyId: classifyId,
+			ChartInfoId:            req.ChartInfoId,
+			SysUserId:              sysUser.AdminId,
+			SysRealName:            sysUser.RealName,
+			CreateTime:             time.Now().Local(),
+			ModifyTime:             time.Now().Local(),
+		})
+
+	}
+
+	cond := fmt.Sprintf(" %s = ? AND %s = ?", collectOb.Cols().SysUserId, collectOb.Cols().ChartInfoId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, sysUser.AdminId, req.ChartInfoId)
+
+	// 清除原有保存收藏配置,并新增保存收藏
+	e = collectOb.RemoveAndCreateMulti(cond, pars, addList)
+	if 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.ChartCollectReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /chart_collect/cancel_collect [post]
+func (this *ChartCollectController) 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.ChartCollectReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常: %v", e)
+		return
+	}
+	if req.ChartInfoId <= 0 {
+		br.Msg = "请选择图表"
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	// 取消收藏
+	collectOb := new(data_manage.ChartCollect)
+	cond := fmt.Sprintf("%s = ? AND %s = ? AND %s = ?", collectOb.Cols().SysUserId, collectOb.Cols().ChartCollectClassifyId, collectOb.Cols().ChartInfoId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, sysUser.AdminId, req.ClassifyId, req.ChartInfoId)
+	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 = "操作成功"
+}
+
+// Move
+// @Title 移动收藏
+// @Description 移动收藏
+// @Success 200 {object} data_manage.ChartCollectMoveReq
+// @router /chart_collect/move [post]
+func (this *ChartCollectController) 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.ChartCollectMoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
+		return
+	}
+
+	var newSort int
+	if req.PrevChartInfoId <= 0 {
+		firstOne, err := data_manage.GetChartCollectSort(sysUser.AdminId, req.ClassifyId, 0)
+		if err != nil {
+			br.Msg = "获取数据失败!"
+			br.ErrMsg = "获取数据失败,GetMyChartClassifyMapping,Err:" + err.Error()
+			return
+		}
+		newSort = firstOne.Sort - 1
+	} else if req.NextChartInfoId <= 0 {
+		lastOne, err := data_manage.GetChartCollectSort(sysUser.AdminId, req.ClassifyId, 1)
+		if err != nil {
+			br.Msg = "获取数据失败!"
+			br.ErrMsg = "获取数据失败,GetMyChartClassifyMapping,Err:" + err.Error()
+			return
+		}
+		newSort = lastOne.Sort + 1
+	} else {
+		preMapItem, err := data_manage.GetChartCollectByChartInfoId(sysUser.AdminId, req.PrevChartInfoId, req.ClassifyId)
+		if err != nil {
+			br.Msg = "获取数据失败!"
+			br.ErrMsg = "获取数据失败,GetMyChartClassifyMapping,Err:" + err.Error()
+			return
+		}
+		nextMapItem, err := data_manage.GetChartCollectByChartInfoId(sysUser.AdminId, req.NextChartInfoId, req.ClassifyId)
+		if err != nil {
+			br.Msg = "获取数据失败!"
+			br.ErrMsg = "获取数据失败,GetMyChartClassifyMapping,Err:" + err.Error()
+			return
+		}
+		newSort = (preMapItem.Sort + nextMapItem.Sort) / 2
+
+		newSort = preMapItem.Sort + 1
+		var updateSortStr string
+		if preMapItem.Sort == nextMapItem.Sort {
+			updateSortStr = `sort + 2`
+		} else if nextMapItem.Sort-preMapItem.Sort == 1 {
+			updateSortStr = `sort + 1`
+		}
+		if updateSortStr != `` {
+			_ = data_manage.UpdateChartCollectSortByClassifyId(req.ClassifyId, preMapItem.Sort, preMapItem.ChartCollectId, updateSortStr)
+		}
+	}
+	if e := data_manage.UpdateChartCollectMove(newSort, sysUser.AdminId, req.ChartInfoId, req.ClassifyId); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新图表收藏失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 515 - 0
controllers/data_manage/collect_chart_classify.go

@@ -0,0 +1,515 @@
+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"
+)
+
+// ChartCollectClassifyController 图表收藏分类
+type ChartCollectClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 分类列表-含图表
+// @Description 分类列表-含图表
+// @Param   ParentId  query  int  false  "父级ID"
+// @Success 200 {object} data_manage.ChartCollectClassifyListItem
+// @router /chart_collect/classify/list [get]
+func (this *ChartCollectClassifyController) 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.ChartCollectClassifyListItem, 0)
+	// 查询分类
+	classifyOb := new(data_manage.ChartCollectClassify)
+	{
+		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.ChartCollectClassifyListItem{
+				NodeType:     1,
+				ClassifyId:   v.ChartCollectClassifyId,
+				ClassifyName: v.ClassifyName,
+				ParentId:     v.ParentId,
+				Level:        v.Level,
+				Sort:         v.Sort,
+				UniqueCode:   v.UniqueCode,
+			})
+		}
+	}
+
+	// 查询分类下收藏的图表
+	{
+		list, e := data_manage.GetCollectChartInfoByClassifyId(parentId)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取分类下图表失败, %v", e)
+			return
+		}
+		for _, v := range list {
+			resp = append(resp, &data_manage.ChartCollectClassifyListItem{
+				NodeType:    2,
+				ChartInfoId: v.ChartInfoId,
+				ChartName:   v.ChartName,
+				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.ChartCollectClassifyItem
+// @router /chart_collect/classify/tree [get]
+func (this *ChartCollectClassifyController) 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.ChartCollectClassify)
+	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.ChartCollectClassifyItem, 0)
+	for _, v := range list {
+		items = append(items, v.Format2Item())
+	}
+	tree := data.GetChartCollectClassifyTreeRecursive(items, 0)
+
+	br.Data = tree
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Add
+// @Title 新增分类
+// @Description 新增分类
+// @Param	request	body data_manage.ChartCollectClassifyAddReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /chart_collect/classify/add [post]
+func (this *ChartCollectClassifyController) 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.ChartCollectClassifyAddReq
+	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.ChartCollectClassify)
+
+	//校验分类名称
+	{
+		cond := fmt.Sprintf(" AND %s = ? AND %s = ? AND %s = ? ", classifyOb.Cols().ParentId, classifyOb.Cols().ClassifyName, classifyOb.Cols().SysUserId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.ParentId, req.ClassifyName, this.SysUser.AdminId)
+		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.ChartCollectClassifyId)
+		classifyOb.RootId = rootId
+	} else {
+		classifyOb.LevelPath = fmt.Sprint(classifyOb.ChartCollectClassifyId)
+		classifyOb.RootId = classifyOb.ChartCollectClassifyId
+	}
+	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.ChartCollectClassifyEditReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /chart_collect/classify/edit [post]
+func (this *ChartCollectClassifyController) 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.ChartCollectClassifyEditReq
+	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.ChartCollectClassify)
+	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 = ? AND %s = ? AND %s = ? ", classifyOb.Cols().PrimaryId, classifyOb.Cols().ParentId, classifyOb.Cols().ClassifyName, classifyOb.Cols().SysUserId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, classifyItem.ChartCollectClassifyId, classifyItem.ParentId, req.ClassifyName, this.SysUser.AdminId)
+		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.ChartCollectClassifyRemoveReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /chart_collect/classify/remove [post]
+func (this *ChartCollectClassifyController) 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.ChartCollectClassifyRemoveReq
+	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.ChartCollectClassify)
+	_, 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.GetChartCollectClassifyChildIds(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 = "操作成功"
+}
+
+// Move
+// @Title 移动分类
+// @Description 移动分类
+// @Param	request	body data_manage.ChartCollectClassifyMoveReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /chart_collect/classify/move [post]
+func (this *ChartCollectClassifyController) 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.ChartCollectClassifyMoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
+		return
+	}
+
+	classifyOb := new(data_manage.ChartCollectClassify)
+	item, e := classifyOb.GetItemById(req.ClassifyId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "分类不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
+		return
+	}
+
+	updateCol := make([]string, 0)
+	//如果有传入 上一个兄弟节点分类id
+	if req.PrevClassifyId > 0 {
+		prevClassify, err := data_manage.GetChartCollectClassifyById(sysUser.AdminId, req.PrevClassifyId)
+		if err != nil {
+			br.Msg = "移动失败"
+			br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
+			return
+		}
+
+		//如果是移动在两个兄弟节点之间
+		if req.NextClassifyId > 0 {
+			//下一个兄弟节点
+			nextClassify, err := data_manage.GetChartCollectClassifyById(sysUser.AdminId, req.NextClassifyId)
+			if err != nil {
+				br.Msg = "移动失败"
+				br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
+				return
+			}
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == item.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+				_ = data_manage.UpdateChartCollectClassifySortByClassifyId(sysUser.AdminId, prevClassify.ChartCollectClassifyId, prevClassify.Sort, updateSortStr)
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextClassify.Sort-prevClassify.Sort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+					_ = data_manage.UpdateChartCollectClassifySortByClassifyId(sysUser.AdminId, 0, prevClassify.Sort, updateSortStr)
+				}
+			}
+		}
+
+		item.Sort = prevClassify.Sort + 1
+		item.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		firstClassify, err := data_manage.GetFirstChartCollectClassifyByAdminId(sysUser.AdminId)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "移动失败"
+			br.ErrMsg = "获取获取当前账号下的排序第一条的分类信息失败,Err:" + err.Error()
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.ChartCollectClassifyId > 0 && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateChartCollectClassifySortByClassifyId(sysUser.AdminId, firstClassify.ChartCollectClassifyId-1, 0, updateSortStr)
+		}
+
+		item.Sort = 0 //那就是排在第一位
+		item.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	if len(updateCol) > 0 {
+		if e = item.Update(updateCol); e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
+			return
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 189 - 0
controllers/data_manage/edb_collect.go → controllers/data_manage/collect_edb.go

@@ -5,11 +5,13 @@ import (
 	"eta_gn/eta_api/controllers"
 	"eta_gn/eta_api/models"
 	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/data_manage/request"
 	"eta_gn/eta_api/services/data"
 	"eta_gn/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"sort"
+	"strconv"
 	"strings"
 	"time"
 )
@@ -368,3 +370,190 @@ func (this *EdbCollectController) Move() {
 	br.Success = true
 	br.Msg = "操作成功"
 }
+
+// BatchCollect
+// @Title 批量收藏
+// @Description 批量收藏
+// @Param	request	body data_manage.EdbCollectReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /edb_collect/batch_collect [post]
+func (this *EdbCollectController) BatchCollect() {
+	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 request.BatchEdbCollectReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常: %v", err)
+		return
+	}
+	cacheKey := "CACHE_EDB_INFO_COLLECT_" + strconv.Itoa(sysUser.AdminId)
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	defer func() {
+		utils.Rc.Delete(cacheKey)
+	}()
+
+	if len(req.CollectClassifyIdList) <= 0 {
+		br.Msg = "请选择需要收藏的分类"
+		br.IsSendEmail = false
+		return
+	}
+	// 选中的指标id列表
+	edbInfoList := make([]*data_manage.EdbInfoList, 0)
+
+	// 选择所有指标,所以需要通过es获取数据
+	if req.IsSelectAll {
+		tmpEdbInfoList, err, errMsg := data.GetAllGeneralEdbInfoListByGeneralEdbEsSearchReq(req.GeneralEdbEsSearchReq, this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取指标列表失败!"
+			if errMsg != `` {
+				br.Msg = errMsg
+			}
+			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
+			return
+		}
+
+		// 如果有过滤指标,那么就过滤吧
+		if len(req.NoEdbIdList) > 0 {
+			noEdbIdMap := make(map[int]bool)
+			for _, v := range req.NoEdbIdList {
+				noEdbIdMap[v] = true
+			}
+
+			for _, v := range tmpEdbInfoList {
+				if _, ok := noEdbIdMap[v.EdbInfoId]; !ok {
+					// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
+					edbInfoList = append(edbInfoList, v)
+				}
+			}
+		} else {
+			edbInfoList = tmpEdbInfoList
+		}
+
+		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+		if len(edbInfoList) > 0 {
+
+			edbInfoIdList := make([]int, 0)
+			for _, v := range edbInfoList {
+				v.ConvertToResp()
+				v.EdbNameAlias = v.EdbName
+				v.HaveOperaAuth = true
+				edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+			}
+
+			tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+				return
+			}
+			edbInfoMap := make(map[int]*data_manage.EdbInfo)
+			for _, v := range tmpEdbList {
+				edbInfoMap[v.EdbInfoId] = v
+			}
+
+			for _, v := range edbInfoList {
+				tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]
+				if !ok {
+					continue
+				}
+				v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
+			}
+		}
+	} else {
+		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+		if len(req.EdbIdList) > 0 {
+			edbInfoList, err = data_manage.GetEdbInfoListByCond(` AND edb_info_id in (?) `, []interface{}{req.EdbIdList})
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+				return
+			}
+		}
+	}
+
+	if len(edbInfoList) <= 0 {
+		br.Msg = `请选择指标`
+		return
+	}
+
+	edbInfoIdList := make([]int, 0)
+	for _, v := range edbInfoList {
+		edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+	}
+
+	collectOb := new(data_manage.EdbCollect)
+
+	cond := fmt.Sprintf(" AND %s = ? AND %s in (?) ", collectOb.Cols().SysUserId, collectOb.Cols().EdbInfoId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, sysUser.AdminId, edbInfoIdList)
+
+	collectList, err := collectOb.GetItemsByCondition(cond, pars, []string{}, ``)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取收藏列表列表,Err:" + err.Error()
+		return
+	}
+	collectEdbClassifyMap := make(map[int]map[int]bool)
+	for _, v := range collectList {
+		edbClassifyMap, ok := collectEdbClassifyMap[v.EdbInfoId]
+		if !ok {
+			edbClassifyMap = make(map[int]bool)
+		}
+		edbClassifyMap[v.EdbCollectClassifyId] = true
+		collectEdbClassifyMap[v.EdbInfoId] = edbClassifyMap
+	}
+
+	// 待添加的分类配置
+	addList := make([]*data_manage.EdbCollect, 0)
+	for _, edbInfo := range edbInfoList {
+		for _, classifyId := range req.CollectClassifyIdList {
+			edbClassifyMap, ok := collectEdbClassifyMap[edbInfo.EdbInfoId]
+			if ok {
+				if _, ok2 := edbClassifyMap[classifyId]; ok2 {
+					// 如果当前收藏分类下,存在该指标的收藏记录,那么就跳过
+					continue
+				}
+			}
+			addList = append(addList, &data_manage.EdbCollect{
+				EdbCollectClassifyId: classifyId,
+				EdbInfoId:            edbInfo.EdbInfoId,
+				EdbCode:              edbInfo.EdbCode,
+				SysUserId:            sysUser.AdminId,
+				SysRealName:          sysUser.RealName,
+				CreateTime:           time.Now().Local(),
+				ModifyTime:           time.Now().Local(),
+			})
+		}
+
+	}
+
+	// 并新增保存收藏
+	err = collectOb.CreateMulti(addList)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("新增指标批量收藏失败: %v", err)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 31 - 30
controllers/data_manage/edb_collect_classify.go → controllers/data_manage/collect_edb_classify.go

@@ -180,21 +180,21 @@ func (this *EdbCollectClassifyController) Add() {
 	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
-	//	}
-	//}
+	{
+		cond := fmt.Sprintf(" AND %s = ? AND %s = ? AND %s = ? ", classifyOb.Cols().ParentId, classifyOb.Cols().ClassifyName, classifyOb.Cols().SysUserId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.ParentId, req.ClassifyName, this.SysUser.AdminId)
+		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
@@ -301,21 +301,22 @@ func (this *EdbCollectClassifyController) Edit() {
 	}
 
 	// 校验分类名称
-	//{
-	//	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
-	//	}
-	//}
+	{
+		cond := fmt.Sprintf(" AND %s != ?  AND %s = ? AND %s = ? AND %s = ? ", classifyOb.Cols().PrimaryId, classifyOb.Cols().ParentId, classifyOb.Cols().ClassifyName, classifyOb.Cols().SysUserId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, classifyItem.EdbCollectClassifyId, classifyItem.ParentId, req.ClassifyName, this.SysUser.AdminId)
+		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}

+ 13 - 10
controllers/data_manage/correlation/correlation_chart_classify.go

@@ -23,7 +23,6 @@ type CorrelationChartClassifyController struct {
 // ChartClassifyList
 // @Title 相关性图表分类列表
 // @Description 相关性图表分类列表接口
-// @Param   IsShowMe   query   bool  false       "是否只看我的,true、false"
 // @Param   ParentId   query   bool  false       "父级ID"
 // @Param   Source   query   int  false       "图表类型,3:相关性,4:滚动相关性"
 // @Success 200 {object} data_manage.ChartClassifyListResp
@@ -54,13 +53,12 @@ func (this *CorrelationChartClassifyController) ChartClassifyList() {
 	//	}
 	//}
 
-	isShowMe, _ := this.GetBool("IsShowMe")
 	parentId, _ := this.GetInt("ParentId")
 	source, _ := this.GetInt("Source", utils.CHART_SOURCE_CORRELATION)
 
 	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
 	// 查询分类节点
-	rootList, err := data_manage.GetChartClassifyByParentId(parentId, utils.CHART_SOURCE_CORRELATION)
+	rootList, err := data_manage.GetChartClassifyByParentId(parentId, utils.CHART_SOURCE_CORRELATION, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -105,10 +103,7 @@ func (this *CorrelationChartClassifyController) ChartClassifyList() {
 			return
 		}
 
-		var adminId int
-		if isShowMe {
-			adminId = this.SysUser.AdminId
-		}
+		adminId := this.SysUser.AdminId
 
 		charts, e := data_manage.GetChartInfoBySourceAndParentId(source, parentId, adminId)
 		if e != nil {
@@ -116,10 +111,18 @@ func (this *CorrelationChartClassifyController) ChartClassifyList() {
 			br.ErrMsg = fmt.Sprintf("获取图表信息失败, Err: %v", e)
 			return
 		}
+
+		editShareChartInfoIdMap, err := data.GetAllEditSharedChartInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有编辑权限的分享图表失败,Err:" + err.Error()
+			return
+		}
+
 		for _, v := range charts {
 			// 操作按钮权限
 			v.HaveOperaAuth = data_manage_permission.CheckChartPermissionByPermissionIdList(v.IsJoinPermission, currClassify.IsJoinPermission, v.ChartInfoId, v.ChartClassifyId, permissionEdbIdList, permissionClassifyIdList)
-			button := data.GetChartOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+			button := data.GetChartOpButton(this.SysUser, v.SysUserId, v.ChartInfoId, v.HaveOperaAuth, editShareChartInfoIdMap)
 			button.AddButton = false //不管有没有权限,图表都是没有添加按钮的
 			v.Button = button
 			v.ParentId = parentId
@@ -154,7 +157,7 @@ func (this *CorrelationChartClassifyController) ChartClassifyItems() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_CORRELATION)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_CORRELATION, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -500,7 +503,7 @@ func (this *CorrelationChartClassifyController) DeleteChartClassify() {
 		}
 		//删除ES
 		{
-			go data.EsDeleteChartInfo(chartInfo.ChartInfoId)
+			go data.DeleteChartInfoToEs(chartInfo.ChartInfoId)
 			// 删除MY ETA 图表 es数据
 			//go data.EsDeleteMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)

+ 9 - 20
controllers/data_manage/correlation/correlation_chart_info.go

@@ -427,7 +427,7 @@ func (this *CorrelationChartInfoController) Move() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(req.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(req.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(req.ChartInfoId)
 
@@ -459,7 +459,6 @@ func (this *CorrelationChartInfoController) Move() {
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
 // @Param   ChartClassifyId   query   int  true       "分类id"
 // @Param   Keyword   query   string  true       "搜索关键词"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "图表类型,3:相关性,4:滚动相关性"
 // @Success 200 {object} data_manage.ChartListResp
 // @router /chart_info/list [get]
@@ -520,12 +519,8 @@ func (this *CorrelationChartInfoController) List() {
 		condition += ` AND  ( chart_name LIKE '%` + keyword + `%' )`
 	}
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		condition += ` AND sys_user_id = ? `
-		pars = append(pars, sysUser.AdminId)
-	}
+	condition += ` AND sys_user_id = ? `
+	pars = append(pars, sysUser.AdminId)
 
 	// 获取当前账号的不可见指标
 	noPermissionChartIdList := make([]int, 0)
@@ -1443,7 +1438,7 @@ func (this *CorrelationChartInfoController) Copy() {
 			}
 		}
 
-		go data.EsAddOrEditChartInfo(chartInfoId)
+		go data.AddOrEditChartInfoToEs(chartInfoId)
 	}
 
 	// 新增操作日志
@@ -1839,7 +1834,7 @@ func (this *CorrelationChartInfoController) EnInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -1877,7 +1872,6 @@ func (this *CorrelationChartInfoController) EnInfoEdit() {
 // @Title 图表模糊搜索(从es获取)
 // @Description  图表模糊搜索(从es获取)
 // @Param   Keyword   query   string  true       "图表名称"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "来源,3:相关性,4:滚动相关性,默认0:全部"
 // @Success 200 {object} data_manage.ChartInfo
 // @router /chart_info/search_by_es [get]
@@ -1909,12 +1903,7 @@ func (this *CorrelationChartInfoController) SearchByEs() {
 
 	keyword := this.GetString("Keyword")
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	showSysId := 0
-	if isShowMe {
-		showSysId = sysUser.AdminId
-	}
+	showSysId := sysUser.AdminId
 
 	source, _ := this.GetInt("Source")
 	sourceList := make([]int, 0)
@@ -2117,7 +2106,7 @@ func (this *CorrelationChartInfoController) BaseInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -2492,7 +2481,7 @@ func (this *CorrelationChartInfoController) MultiFactorAdd() {
 		}
 	}
 
-	go data.EsAddOrEditChartInfo(chartInfoId)
+	go data.AddOrEditChartInfoToEs(chartInfoId)
 
 	// 操作日志
 	{
@@ -2828,7 +2817,7 @@ func (this *CorrelationChartInfoController) MultiFactorEdit() {
 
 	// ES
 	go func() {
-		data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+		data.AddOrEditChartInfoToEs(chartInfo.ChartInfoId)
 		data.EsAddOrEditMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
 	}()
 

+ 7 - 18
controllers/data_manage/cross_variety/chart_info.go

@@ -33,7 +33,6 @@ type ChartInfoController struct {
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
 // @Param   ChartClassifyId   query   int  true       "分类id"
 // @Param   Keyword   query   string  true       "搜索关键词"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "图表类型,10:跨品种分析
 // @Success 200 {object} data_manage.ChartListResp
 // @router /chart_info/list [get]
@@ -94,12 +93,8 @@ func (c *ChartInfoController) List() {
 		condition += ` AND  ( chart_name LIKE '%` + keyword + `%' )`
 	}
 
-	//只看我的
-	isShowMe, _ := c.GetBool("IsShowMe")
-	if isShowMe {
-		condition += ` AND sys_user_id = ? `
-		pars = append(pars, sysUser.AdminId)
-	}
+	condition += ` AND sys_user_id = ? `
+	pars = append(pars, sysUser.AdminId)
 
 	// 获取当前账号的不可见指标
 	noPermissionChartIdList := make([]int, 0)
@@ -996,7 +991,7 @@ func (c *ChartInfoController) Move() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(req.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(req.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(req.ChartInfoId)
 
@@ -1188,7 +1183,7 @@ func (c *ChartInfoController) EnInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -1309,7 +1304,7 @@ func (c *ChartInfoController) DeleteChart() {
 	}
 	//删除ES
 	{
-		go data.EsDeleteChartInfo(chartInfo.ChartInfoId)
+		go data.DeleteChartInfoToEs(chartInfo.ChartInfoId)
 		// 删除MY ETA 图表 es数据
 		go data.EsDeleteMyChartInfoByMyChartIds(myIds)
 	}
@@ -1389,7 +1384,6 @@ func (c *ChartInfoController) DeleteChart() {
 // @Title 图表模糊搜索(从es获取)
 // @Description  图表模糊搜索(从es获取)
 // @Param   Keyword   query   string  true       "图表名称"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "来源,3:拟合方程,4:滚动拟合方程,默认0:全部"
 // @Success 200 {object} data_manage.ChartInfo
 // @router /chart_info/search_by_es [get]
@@ -1424,12 +1418,7 @@ func (c *ChartInfoController) SearchByEs() {
 		keyword = c.GetString("KeyWord")
 	}
 
-	//只看我的
-	isShowMe, _ := c.GetBool("IsShowMe")
-	showSysId := 0
-	if isShowMe {
-		showSysId = sysUser.AdminId
-	}
+	showSysId := sysUser.AdminId
 
 	sourceList := []int{utils.CHART_SOURCE_CROSS_HEDGING}
 
@@ -1868,7 +1857,7 @@ func (c *ChartInfoController) BaseInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 

+ 3 - 10
controllers/data_manage/cross_variety/classify.go

@@ -19,7 +19,6 @@ type ClassifyController struct {
 // List
 // @Title 跨品种分析分类列表
 // @Description 跨品种分析分类列表接口
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "图表类型,3:跨品种分析,4:滚动跨品种分析"
 // @Success 200 {object} data_manage.ChartClassifyListResp
 // @router /classify/list [get]
@@ -46,21 +45,19 @@ func (c *ClassifyController) List() {
 		}
 	}
 
-	isShowMe, _ := c.GetBool("IsShowMe")
-
 	source, _ := c.GetInt("Source")
 	if source <= 0 {
 		source = utils.CHART_SOURCE_CROSS_HEDGING
 	}
 
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_CROSS_HEDGING)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_CROSS_HEDGING, c.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
-	allChartInfo, err := data_manage.GetChartInfoAll([]int{source})
+	allChartInfo, err := data_manage.GetChartInfoAll([]int{source}, c.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -69,10 +66,6 @@ func (c *ClassifyController) List() {
 
 	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
 	for _, v := range allChartInfo {
-		if !isShowMe {
-			chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
-			continue
-		}
 		if v.SysUserId != c.SysUser.AdminId {
 			continue
 		}
@@ -387,7 +380,7 @@ func (c *ClassifyController) DeleteChartClassify() {
 		}
 		//删除ES
 		{
-			go data.EsDeleteChartInfo(chartInfo.ChartInfoId)
+			go data.DeleteChartInfoToEs(chartInfo.ChartInfoId)
 			// 删除MY ETA 图表 es数据
 			//go data.EsDeleteMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)

+ 462 - 0
controllers/data_manage/data_approve/data_approve.go

@@ -0,0 +1,462 @@
+package data_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/data_manage/data_approve/request"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	dataApproveServ "eta_gn/eta_api/services/data/data_approve"
+	"eta_gn/eta_api/utils"
+	"fmt"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+// DataApproveController
+// @Description: 数据资产审批
+type DataApproveController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 审批列表
+// @Description 审批列表
+// @Param   PageSize			query	int		true	"每页数据条数"
+// @Param   CurrentIndex		query	int		true	"当前页页码"
+// @Param   DataType			query   int     true	"审批类型;1:指标审批;2:图表审批"
+// @Param   ListType			query   int     true	"列表类型:1-待处理;2-已处理;3-我发起的"
+// @Param   ClassifyId			query	int		false	"分类ID"
+// @Param   Keyword				query	string	false	"搜索关键词"
+// @Param   ApproveState		query	int		false	"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"
+// @Param   TimeType			query	int		false	"时间类型:1-提交时间;2-处理时间;3-审批时间"
+// @Param   StartTime			query	string	false	"开始时间"
+// @Param   EndTime				query	string	false	"结束时间"
+// @Param   SortField			query	int		false	"排序字段:1-提交时间;2-处理时间;3-审批时间"
+// @Param   SortRule			query	int		false	"排序方式: 1-正序; 2-倒序(默认)"
+// @Success 200 {object} report_approve.DataApproveListResp
+// @router /list [get]
+func (this *DataApproveController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	dataType, _ := this.GetInt("DataType", utils.DataApproveTypeEdb)
+	listType, _ := this.GetInt("ListType")
+	approveState, _ := this.GetInt("ApproveState")
+	timeType, _ := this.GetInt("TimeType")
+	startTime := this.GetString("StartTime")
+	endTime := this.GetString("EndTime")
+	sortField, _ := this.GetInt("SortField")
+	sortRule, _ := this.GetInt("SortRule")
+	keyword := this.GetString("Keyword")
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize10
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize := paging.StartIndex(currentIndex, pageSize)
+
+	var list []*response.DataApproveItemOrmResp
+	var total int
+	var msg string
+	var err error
+
+	switch listType {
+	case 1:
+		list, total, msg, err = dataApproveServ.ProcessingDataApprove(sysUser.AdminId, dataType, timeType, sortField, sortRule, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 2:
+		list, total, msg, err = dataApproveServ.SolvedDataApprove(sysUser.AdminId, dataType, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 3:
+		list, total, msg, err = dataApproveServ.MyApplyDataApproves(sysUser.AdminId, dataType, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	default:
+		br.Msg = "列表类型错误"
+		return
+	}
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批列表失败"
+		}
+		br.ErrMsg = "获取审批列表失败, Err: " + err.Error()
+		return
+	}
+
+	resp := new(response.DataApproveListResp)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.List = list
+	resp.Paging = page
+
+	br.Msg = "获取审批列表成功"
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+}
+
+// Approve
+// @Title 通过审批
+// @Description 通过审批
+// @Param	request	body report_approve.DataApprovePassReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /approve [post]
+func (this *DataApproveController) Approve() {
+	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 request.DataApprovePassReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.DataApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, DataApproveId: %d", req.DataApproveId)
+		return
+	}
+
+	// 通过审批
+	msg, err := dataApproveServ.PassDataApprove(req.DataApproveId, sysUser.AdminId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "通过审批失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Detail
+// @Title 审批详情
+// @Description 审批详情
+// @Param   DataApproveId  query  int  true  "审批ID"
+// @Success 200 {object} report_approve.DataApproveDetail
+// @router /detail [get]
+func (this *DataApproveController) Detail() {
+	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
+	}
+	approveId, _ := this.GetInt("DataApproveId")
+	if approveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, DataApproveId: %d", approveId)
+		return
+	}
+
+	resp, msg, err := dataApproveServ.GetApproveDetail(approveId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批详情失败"
+		}
+		br.ErrMsg = "获取审批详情失败, Err: " + err.Error()
+		return
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Refuse
+// @Title 驳回审批
+// @Description 驳回审批
+// @Param	request	body request.DataApproveRefuseReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /refuse [post]
+func (this *DataApproveController) Refuse() {
+	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 request.DataApproveRefuseReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.DataApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, DataApproveId: %d", req.DataApproveId)
+		return
+	}
+	maxStrLen := 500
+	approveLen := len([]rune(req.ApproveRemark))
+	if approveLen > maxStrLen {
+		br.Msg = fmt.Sprintf("审批驳回原因不能超过%d字", maxStrLen)
+		return
+	}
+	msg, err := dataApproveServ.DataApproveRefuse(req.DataApproveId, sysUser.AdminId, req.ApproveRemark)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "驳回审批失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Cancel
+// @Title 撤销审批
+// @Description 撤销审批
+// @Param	request	body report_approve.DataApproveCancelReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /cancel [post]
+func (this *DataApproveController) Cancel() {
+	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 request.DataApproveCancelReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.DataApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, DataApproveId: %d", req.DataApproveId)
+		return
+	}
+
+	// 撤销审批
+	msg, e := dataApproveServ.DataApproveCancel(req.DataApproveId, sysUser.AdminId, sysUser.RealName)
+	if e != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "撤销审批失败, Err: " + e.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// MessageList
+// @Title 审批消息列表
+// @Description 审批消息列表
+// @Param   PageSize			query	int		true	"每页数据条数"
+// @Param   CurrentIndex		query	int		true	"当前页页码"
+// @Param   DataType			query   int     true	"审批类型;1:指标审批;2:图表审批"
+// @Success 200 {object} report_approve.DataApproveMessageListResp
+// @router /message/list [get]
+func (this *DataApproveController) MessageList() {
+	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
+	}
+	currentIndex, _ := this.GetInt("currentIndex")
+	pageSize, _ := this.GetInt("pageSize")
+	dataType, _ := this.GetInt("DataType", utils.DataApproveTypeEdb)
+
+	// 分页
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	resp := new(response.DataApproveMessageListResp)
+	resp.List = make([]*response.DataApproveMessageItem, 0)
+	list, total, unRead, msg, err := dataApproveServ.GetDataApproveMessage(sysUser.AdminId, dataType, startSize, pageSize)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批消息失败"
+		}
+		br.ErrMsg = "获取审批消息失败, Err: " + err.Error()
+		return
+	}
+	resp.List = list
+	resp.UnreadTotal = unRead
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// MessageRead
+// @Title 消息已读
+// @Description 消息已读
+// @Param	request	body report_approve.DataApproveMessageReadReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /message/read [post]
+func (this *DataApproveController) MessageRead() {
+	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 request.DataApproveMessageReadReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.MessageId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, MessageId: %d", req.MessageId)
+		return
+	}
+
+	msg, err := dataApproveServ.ReadBiMessage(req.MessageId, sysUser.AdminId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "消息已读失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// CheckApproveOpen
+// @Title 校验是否开启审批
+// @Description 校验是否开启审批
+// @Param	request	body report_approve.DataApproveCheckApproveOpenReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /check_open [post]
+func (this *DataApproveController) CheckApproveOpen() {
+	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 request.DataApproveCheckApproveOpenReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+
+	// 校验是否开启了审批流
+	opening, e := dataApproveServ.CheckOpenApprove(req.DataType)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验数据资产是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+	br.Data = opening
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 179 - 0
controllers/data_manage/data_approve/data_approve_flow.go

@@ -0,0 +1,179 @@
+package data_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/data_manage/data_approve/request"
+	DataApprove "eta_gn/eta_api/services/data/data_approve"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+type DataApproveFlowController struct {
+	controllers.BaseAuthController
+}
+
+// Save
+// @Title 保存审批流
+// @Description 保存审批流
+// @Param	request	body request.DataApproveFlowSaveReq true "type json string"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/save [post]
+func (c *DataApproveFlowController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req *request.DataApproveFlowSaveReq
+	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析失败"
+		br.ErrMsg = "参数解析失败, err:" + err.Error()
+		return
+	}
+	//req.FlowName = strings.TrimSpace(req.FlowName)
+	req.FlowName = `审批`
+	switch req.DataType {
+	case 1:
+		req.FlowName = "指标审批"
+	case 2:
+		req.FlowName = "图表审批"
+
+	}
+	if req.FlowName == "" {
+		br.Msg = "审批流名称不能为空"
+		return
+	}
+
+	if len([]rune(req.FlowName)) > 20 {
+		br.Msg = "审批流名称最多输入20个字符"
+		return
+	}
+	if req.DataType <= 0 {
+		br.Msg = "请选择审批类型"
+		return
+	}
+
+	ok, msg, err := DataApprove.SaveDataApproveFlow(req)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "编辑审批流失败"
+		}
+		br.ErrMsg = "编辑审批流失败, err:" + err.Error()
+		return
+	}
+	if !ok {
+		br.Msg = msg
+		return
+	}
+
+	// 设置审批忽略人
+	{
+		ignoreApproveUserIdStr := ``
+		if len(req.IgnoreApproveUserIdList) > 0 {
+			ignoreApproveUserIdStr = utils.Implode(req.IgnoreApproveUserIdList)
+		}
+		switch req.DataType {
+		case utils.DataApproveTypeEdb:
+			err = models.UpdateBusinessConfMulti([]models.BusinessConfUpdate{
+				{ConfKey: models.IgnoreEdbApproveUserId, ConfVal: ignoreApproveUserIdStr},
+			})
+		case utils.DataApproveTypeChart:
+			err = models.UpdateBusinessConfMulti([]models.BusinessConfUpdate{
+				{ConfKey: models.IgnoreChartApproveUserId, ConfVal: ignoreApproveUserIdStr},
+			})
+		}
+		if err != nil {
+			utils.FileLog.Error(fmt.Sprintf("更新审批忽略人配置失败,审批类型:%d,忽略人信息:%s, err:%s", req.DataType, ignoreApproveUserIdStr, err.Error()))
+		}
+	}
+
+	br.Msg = "编辑审批流成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// Detail
+// @Title 审批流详情
+// @Description 审批流详情
+// @Param	request	body request.DataApproveFlowRemoveResp true "type json string"
+// @Param   DataType			query	int		false	"排序字段:1-指标审批;2-图表审批"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/detail [get]
+func (c *DataApproveFlowController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	dataType, _ := c.GetInt("DataType")
+	if dataType <= 0 {
+		br.Msg = "审批流不存在"
+		return
+	}
+	detail, msg, err := DataApprove.GetDataApproveFlowDetail(dataType)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批流详情失败"
+		}
+		br.ErrMsg = "获取审批流详情失败, err:" + err.Error()
+		return
+	}
+	if detail == nil {
+		br.Msg = "审批流不存在"
+		return
+	}
+
+	ignoreApproveUserIdList := []int{}
+	{
+		var businessConf *models.BusinessConf
+		switch dataType {
+		case utils.DataApproveTypeEdb:
+			businessConf, err = models.GetBusinessConfByKey(models.IgnoreEdbApproveUserId)
+		case utils.DataApproveTypeChart:
+			businessConf, err = models.GetBusinessConfByKey(models.IgnoreChartApproveUserId)
+		}
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取商家配置失败, Err: " + err.Error()
+			return
+		}
+		if businessConf.ConfVal != `` {
+			tmpIgnoreUserIdStrList := strings.Split(businessConf.ConfVal, `,`)
+			for _, v := range tmpIgnoreUserIdStrList {
+				userId, tmpErr := strconv.Atoi(v)
+				if tmpErr != nil {
+					continue
+				}
+				ignoreApproveUserIdList = append(ignoreApproveUserIdList, userId)
+			}
+		}
+	}
+
+	detail.IgnoreApproveUserIdList = ignoreApproveUserIdList
+
+	br.Data = detail
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取审批流详情成功"
+}

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

@@ -46,7 +46,7 @@ func (c *DataMangePermissionController) EdbChartClassifyList() {
 		return
 	}
 
-	list, err := data_manage_permission.GetEdbChartClassifyList(source, subSource)
+	list, err := data_manage_permission.GetEdbChartClassifyList(source, subSource, c.SysUser.AdminId)
 	if err != nil {
 		//br.Success = true
 		br.Msg = "获取失败"
@@ -96,7 +96,7 @@ func (c *DataMangePermissionController) SecretEdbChartClassifyList() {
 		return
 	}
 
-	resp, err := data_manage_permission.GetEdbChartClassifyList(source, subSource)
+	resp, err := data_manage_permission.GetEdbChartClassifyList(source, subSource, c.SysUser.AdminId)
 	if err != nil {
 		//br.Success = true
 		br.Msg = "获取失败"

+ 45 - 18
controllers/data_manage/edb_classify.go

@@ -41,14 +41,14 @@ func (this *EdbClassifyController) ListV2() {
 		edbType = utils.EdbTypeCalculate
 	}
 
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType))
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 	//classifyAll, err := data_manage.GetEdbClassifyAll()
-	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType)
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -96,6 +96,12 @@ func (this *EdbClassifyController) ListV2() {
 			br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
 			return
 		}
+		editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+			return
+		}
 		for _, v := range allEdbInfo {
 			// 如果指标不可见,那么就不返回该指标
 			if _, ok := noPermissionEdbInfoIdMap[v.EdbInfoId]; ok {
@@ -106,7 +112,7 @@ func (this *EdbClassifyController) ListV2() {
 				v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
 			}
 
-			button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+			button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbInfoId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth, editShareEdbInfoIdMap)
 			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 			v.Button = button
 			edbInfoMap[v.ClassifyId] = append(edbInfoMap[v.ClassifyId], v)
@@ -177,7 +183,7 @@ func (this *EdbClassifyController) Items() {
 	//	edbType = utils.EdbTypeCalculate
 	//}
 
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType))
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -185,7 +191,7 @@ func (this *EdbClassifyController) Items() {
 	}
 
 	//classifyAll, err := data_manage.GetEdbClassifyAll()
-	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType)
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -244,7 +250,7 @@ func (this *EdbClassifyController) AddEdbClassify() {
 	}
 
 	//添加指标
-	_, err, errMsg := data.AddEdbClassify(req.ClassifyName, req.ParentId, req.Level, classifyType, this.SysUser.AdminId, this.SysUser.AdminName, this.Lang)
+	_, err, errMsg := data.AddEdbClassify(req.ClassifyName, req.ParentId, req.Level, classifyType, this.SysUser.AdminId, this.SysUser.RealName, this.Lang)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -709,14 +715,14 @@ func (this *EdbClassifyController) ItemsV2() {
 	//	edbType = utils.EdbTypeCalculate
 	//}
 
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType))
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 	//classifyAll, err := data_manage.GetEdbClassifyAll()
-	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType)
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -880,13 +886,19 @@ func (this *EdbClassifyController) ClassifyEdbInfoList() {
 			br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
 			return
 		}
+		editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+			return
+		}
 		for _, v := range allEdbInfo {
 			// 如果指标不可见,那么就不返回该指标
 			if _, ok := noPermissionEdbInfoIdMap[v.EdbInfoId]; ok {
 				continue
 			}
 			v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
-			button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+			button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbInfoId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth, editShareEdbInfoIdMap)
 			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 			v.Button = button
 
@@ -926,7 +938,7 @@ func (this *EdbClassifyController) ItemsV3() {
 	//}
 
 	// TODO:9级改造
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType))
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -1070,13 +1082,14 @@ func (this *EdbClassifyController) SimpleList() {
 	// 如果是 子级分类,查询该子级分类的下一级分类和指标信息
 	// 增加标识判断是文件夹还是指标列表
 	parentId, _ := this.GetInt("ParentId")
-	isOnlyMe, _ := this.GetBool("IsOnlyMe")
 	// 如果选择了只看我的,那么只查询归属于我的账号
-	sysUserId := 0
-	if isOnlyMe {
-		sysUserId = this.SysUser.AdminId
+	sysUserId := this.SysUser.AdminId
+
+	// 如果是数据查看,那么就看所有的指标和分类
+	if classifyType == utils.EdbClassifyTypeBase {
+		sysUserId = 0
 	}
-	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, int8(classifyType))
+	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, int8(classifyType), sysUserId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -1138,13 +1151,21 @@ func (this *EdbClassifyController) SimpleList() {
 				br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
 				return
 			}
+
+			editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+				return
+			}
+
 			for _, v := range allEdbInfo {
 				// 如果指标不可见,那么就不返回该指标
 				if _, ok := noPermissionEdbInfoIdMap[v.EdbInfoId]; ok {
 					continue
 				}
 				v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, currClassify.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
-				button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+				button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbInfoId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth, editShareEdbInfoIdMap)
 				button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 				v.Button = button
 				v.Children = make([]*data_manage.EdbClassifyItems, 0)
@@ -1238,10 +1259,16 @@ func (this *EdbClassifyController) ClassifyTree() {
 	//	edbType = utils.EdbTypeCalculate
 	//}
 
+	sysUserId := this.SysUser.AdminId
+	// 基础指标(数据查看)默认是所有分类
+	if classifyType == utils.EdbClassifyTypeBase {
+		sysUserId = 0
+	}
+
 	allList := make([]*data_manage.EdbClassifyItems, 0)
 	if classifyType == utils.EdbClassifyTypeOrigin {
 		// 基础指标+计算指标
-		list, e := data_manage.GetEdbClassifyByClassifyTypes([]int{utils.EdbClassifyTypeBase, utils.EdbClassifyTypeCalculate})
+		list, e := data_manage.GetEdbClassifyByClassifyTypes([]int{utils.EdbClassifyTypeBase, utils.EdbClassifyTypeCalculate}, sysUserId)
 		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "获取失败"
 			br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
@@ -1250,7 +1277,7 @@ func (this *EdbClassifyController) ClassifyTree() {
 		allList = list
 	} else {
 		// 单一类型
-		list, err := data_manage.GetAllEdbClassifyByType(classifyType)
+		list, err := data_manage.GetAllEdbClassifyByType(classifyType, sysUserId)
 		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()

+ 289 - 124
controllers/data_manage/edb_info.go

@@ -634,8 +634,15 @@ func (this *EdbInfoController) EdbInfoList() {
 		}
 	}
 
+	editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserIdAndEdbInfoIdList(this.SysUser.AdminId, []int{edbInfoItem.EdbInfoId})
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+		return
+	}
+
 	// 按钮校验
-	button := data.GetEdbOpButton(this.SysUser, edbInfoItem.SysUserId, edbInfoItem.EdbType, edbInfoItem.EdbInfoType, edbInfoItem.HaveOperaAuth)
+	button := data.GetEdbOpButton(this.SysUser, edbInfoItem.SysUserId, edbInfoItem.EdbInfoId, edbInfoItem.EdbType, edbInfoItem.EdbInfoType, edbInfoItem.HaveOperaAuth, editShareEdbInfoIdMap)
 	button.AddButton = false
 	edbInfoItem.Button = button
 	edbInfoItem.DataList = make([]*data_manage.EdbData, 0)
@@ -894,8 +901,15 @@ func (this *EdbInfoController) EdbInfoEdit() {
 		}
 	}
 
+	editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserIdAndEdbInfoIdList(this.SysUser.AdminId, []int{edbInfo.EdbInfoId})
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+		return
+	}
+
 	// 编辑权限校验
-	button := data.GetEdbOpButton(this.SysUser, edbInfo.SysUserId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth)
+	button := data.GetEdbOpButton(this.SysUser, edbInfo.SysUserId, edbInfo.EdbInfoId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth, editShareEdbInfoIdMap)
 	if !button.OpButton {
 		br.Msg = "无权限操作"
 		br.IsSendEmail = false
@@ -1409,9 +1423,15 @@ func (this *EdbInfoController) EdbInfoMove() {
 			return
 		}
 	}
+	editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserIdAndEdbInfoIdList(this.SysUser.AdminId, []int{edbInfo.EdbInfoId})
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+		return
+	}
 
 	// 移动权限校验
-	button := data.GetEdbOpButton(this.SysUser, edbInfo.SysUserId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth)
+	button := data.GetEdbOpButton(this.SysUser, edbInfo.SysUserId, edbInfo.EdbInfoId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth, editShareEdbInfoIdMap)
 	if !button.MoveButton {
 		br.Msg = "无权限操作"
 		br.IsSendEmail = false
@@ -1736,13 +1756,16 @@ func (this *EdbInfoController) EdbInfoFilter() {
 // EdbInfoFilterByEs
 // @Title 指标筛选接口
 // @Description 指标筛选接口
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   PageSize   query   int  true       "每页数据条数"
 // @Param   KeyWord   query   string  false       "搜索关键词:指标ID/指标名称"
 // @Param   FilterSource   query   int  false       "搜索来源:1:其他搜索,2:累计值转月值搜索,3:变频,4:基础指标,5:同比"
 // @Param   Frequency   query   string  false       "频度"
-// @Param   IsAddPredictEdb   query   bool  false       "是否查询添加预测指标"
-// @Param   PageSize   query   int  true       "每页数据条数"
-// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
-// @Param   EdbType   query   int  false       "指标类型:0-基础和计算;1-基础指标;2-计算指标"
+// @Param   Source   query   int  true       "来源"
+// @Param   EdbType   query   string  false       "指标类型:0-基础和计算;1-基础指标;2-计算指标;3-衍生指标"
+// @Param   EdbAuth   query   int  false       "指标权限:0-全部;1-我的;2-公共"
+// @Param   EdbCollect   query   int  false       "指标收藏状态:0-全部;1-已收藏"
+// @Param   ClassifyId   query   int  false       "父级分类id"
 // @Success 200 {object} data_manage.EdbInfoList
 // @router /edb_info/filter_by_es [get]
 func (this *EdbInfoController) EdbInfoFilterByEs() {
@@ -1767,6 +1790,9 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 	startSize = paging.StartIndex(currentIndex, pageSize)
 
 	keyWord := this.GetString("KeyWord")
+	if keyWord == `` {
+		keyWord = this.GetString("Keyword")
+	}
 	keyWord = strings.TrimSpace(keyWord) //移除字符串首尾空格
 	filterSource, _ := this.GetInt("FilterSource")
 	if filterSource <= 0 {
@@ -1777,95 +1803,38 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 
 	frequency := this.GetString("Frequency") //频度
 
-	isAddPredictEdb, _ := this.GetBool("IsAddPredictEdb") //是否查询添加预测指标
+	edbTypeStr := this.GetString("EdbType", "0") // 指标类型:0-基础和计算;1-基础指标;2-计算指标;3-预测指标
 
-	edbType, _ := this.GetInt("EdbType", 0) // 指标类型:0-基础和计算;1-基础指标;2-计算指标
+	edbAuth, _ := this.GetInt("EdbAuth", 0) // 指标权限范围,0-全部;1-我的;2-公共
+
+	edbCollect, _ := this.GetInt("EdbCollect", 0) // 指标收藏状态:0-全部;1-已收藏
+
+	// 父级分类id
+	classifyId, _ := this.GetInt("ClassifyId")
 
 	var edbInfoList []*data_manage.EdbInfoList
 	var err error
 
-	// 无权限指标 和 无权限指标分类id
-	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, err := data_manage_permission.GetUserAllEdbAndClassifyNoPermissionList(this.SysUser.AdminId, utils.EDB_INFO_TYPE, edbType)
+	// 获取es搜索参数
+	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, collectEdbInfoIdList, searchClassifyIdList, searchPublicClassifyIdList, edbTypeList, edbInfoType, edbAuth, searchUserId, frequencyList, err, errMsg := data.GetGeneralEdbEsSearchParams(edbTypeStr, frequency, this.SysUser.AdminId, edbAuth, edbCollect, classifyId)
 	if err != nil {
 		br.Msg = "获取失败"
-		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = "获取失败:" + err.Error()
 		return
 	}
 
-	// 是否走ES
-	isEs := false
-	if keyWord != "" {
-		var keyWordArr []string
-		keyWordArr = append(keyWordArr, keyWord)
-
-		newKeyWord := strings.Split(keyWord, " ")
-		keyWordArr = append(keyWordArr, newKeyWord...)
-
-		// 普通的搜索
-		if !isAddPredictEdb {
-			total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 0, frequency, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, edbType)
-		} else {
-			// 允许添加预测指标的搜索
-			total, edbInfoList, err = elastic.SearchAddPredictEdbInfoData(utils.DATA_INDEX_NAME, keyWord, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, startSize, pageSize, edbType)
-		}
-		isEs = true
-	} else {
-		var condition string
-		var pars []interface{}
-		// 普通指标
-		condition += ` AND edb_info_type = ? `
-		pars = append(pars, 0)
-
-		// 无权限指标id
-		lenNoPermissionEdbInfoIdList := len(noPermissionEdbInfoIdList)
-		if lenNoPermissionEdbInfoIdList > 0 {
-			condition += ` AND edb_info_id  not in (` + utils.GetOrmInReplace(lenNoPermissionEdbInfoIdList) + `) `
-			pars = append(pars, noPermissionEdbInfoIdList)
-		}
-		// 无权限指标分类id
-		lenNoPermissionEdbClassifyIdList := len(noPermissionEdbClassifyIdList)
-		if lenNoPermissionEdbClassifyIdList > 0 {
-			condition += ` AND classify_id  not in (` + utils.GetOrmInReplace(lenNoPermissionEdbClassifyIdList) + `) `
-			pars = append(pars, noPermissionEdbClassifyIdList)
-		}
-
-		switch filterSource {
-		case 2:
-			condition += ` AND frequency='月度' `
-		case 3:
-			condition += ` AND frequency <> '日度' `
-		case 4:
-			condition += ` AND edb_type = 1 `
-		case 5:
-			condition += ` AND source = 6 ` //来源(同比值)
-		case 6:
-			condition += ` AND frequency != ? `
-			pars = append(pars, "年度")
-		}
-
-		//频度
-		if frequency != "" {
-			condition += ` AND frequency = ? `
-			pars = append(pars, frequency)
-		}
-
-		if source > 0 && filterSource != 5 {
-			condition += ` AND source = ? `
-			pars = append(pars, source)
-		}
-		// 查询只允许添加预测指标的搜索
-		if isAddPredictEdb {
-			condition += ` AND frequency in ("日度","周度","月度") `
-		}
+	sortMap := make(map[string]string)
+	// 如果没有搜索关键词,则默认根据指标编码倒序排序
+	if keyWord == `` {
+		sortMap["EdbInfoId"] = `desc`
+	}
 
-		// 基础指标/计算指标
-		if edbType > 0 {
-			condition += ` AND edb_type = ? `
-			pars = append(pars, edbType)
-		}
+	// 普通的搜索
+	total, edbInfoList, err = elastic.SearchEdbInfoData(keyWord, startSize, pageSize, filterSource, source, frequencyList, []string{}, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, collectEdbInfoIdList, searchClassifyIdList, searchPublicClassifyIdList, edbTypeList, edbInfoType, edbAuth, searchUserId, sortMap)
 
-		total, edbInfoList, err = data_manage.GetEdbInfoFilterList(condition, pars, startSize, pageSize)
-	}
 	if err != nil {
 		edbInfoList = make([]*data_manage.EdbInfoList, 0)
 	}
@@ -1875,15 +1844,15 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 	edbInfoListLen := len(edbInfoList)
 
 	classifyIdList := make([]int, 0)
-	for i := 0; i < edbInfoListLen; i++ {
-		edbInfoList[i].ConvertToResp()
-		edbInfoList[i].EdbNameAlias = edbInfoList[i].EdbName
-		classifyIdList = append(classifyIdList, edbInfoList[i].ClassifyId)
+	for _, v := range edbInfoList {
+		v.ConvertToResp()
+		v.EdbNameAlias = v.EdbName
+		classifyIdList = append(classifyIdList, v.ClassifyId)
 	}
 
 	// 当前列表中的分类map
 	classifyMap := make(map[int]*data_manage.EdbClassify)
-	if edbInfoListLen > 0 {
+	if len(classifyIdList) > 0 {
 		classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList)
 		if err != nil {
 			br.Msg = "获取失败"
@@ -1902,15 +1871,20 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 			br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
 			return
 		}
+		editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+			return
+		}
 
-		// 如果是ES的话,需要重新查一下指标的信息,主要是为了把是否授权字段找出来
-		if isEs {
+		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+		{
 			edbInfoIdList := make([]int, 0)
-			for i := 0; i < edbInfoListLen; i++ {
-				edbInfoIdList = append(edbInfoIdList, edbInfoList[i].EdbInfoId)
-				tmpEdbInfo := edbInfoList[i]
+			for _, tmpEdbInfo := range edbInfoList {
+				edbInfoIdList = append(edbInfoIdList, tmpEdbInfo.EdbInfoId)
 				if currClassify, ok := classifyMap[tmpEdbInfo.ClassifyId]; ok {
-					edbInfoList[i].HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(tmpEdbInfo.IsJoinPermission, currClassify.IsJoinPermission, tmpEdbInfo.EdbInfoId, tmpEdbInfo.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
+					tmpEdbInfo.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(tmpEdbInfo.IsJoinPermission, currClassify.IsJoinPermission, tmpEdbInfo.EdbInfoId, tmpEdbInfo.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
 				}
 			}
 
@@ -1925,21 +1899,61 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 				edbInfoMap[v.EdbInfoId] = v
 			}
 
-			for i := 0; i < edbInfoListLen; i++ {
-				tmpEdbInfo, ok := edbInfoMap[edbInfoList[i].EdbInfoId]
+			// 查询收藏
+			collectEdbMap := make(map[int][]int)
+			collectNameEdbMap := make(map[int][]string)
+			{
+				obj := data_manage.EdbCollect{}
+				collectList, err := obj.GetItemsByUserIdAndEdbInfoIdList(this.SysUser.AdminId, edbInfoIdList)
+				if err != nil {
+					br.Msg = "获取指标信息失败"
+					br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+					return
+				}
+				for _, v := range collectList {
+					collectIdList, ok := collectEdbMap[v.EdbInfoId]
+					if !ok {
+						collectIdList = make([]int, 0)
+					}
+					collectEdbMap[v.EdbInfoId] = append(collectIdList, v.EdbCollectClassifyId)
+
+					collectNameList, ok := collectNameEdbMap[v.EdbInfoId]
+					if !ok {
+						collectNameList = make([]string, 0)
+					}
+					collectNameEdbMap[v.EdbInfoId] = append(collectNameList, v.ClassifyName)
+				}
+
+			}
+
+			for _, v := range edbInfoList {
+				if collectIdList, ok := collectEdbMap[v.EdbInfoId]; ok {
+					v.CollectClassifyIdList = collectIdList
+				} else {
+					v.CollectClassifyIdList = []int{}
+				}
+
+				if collectNameList, ok := collectNameEdbMap[v.EdbInfoId]; ok {
+					v.CollectClassifyNameList = collectNameList
+				} else {
+					v.CollectClassifyNameList = []string{}
+				}
+				tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]
 				if !ok {
 					continue
 				}
-				edbInfoList[i].IsJoinPermission = tmpEdbInfo.IsJoinPermission
+				v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
 			}
 		}
 
 		// 权限校验
-		for i := 0; i < edbInfoListLen; i++ {
-			tmpEdbInfoItem := edbInfoList[i]
+		for _, tmpEdbInfoItem := range edbInfoList {
 			if currClassify, ok := classifyMap[tmpEdbInfoItem.ClassifyId]; ok {
-				edbInfoList[i].HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(tmpEdbInfoItem.IsJoinPermission, currClassify.IsJoinPermission, tmpEdbInfoItem.EdbInfoId, tmpEdbInfoItem.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
+				tmpEdbInfoItem.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(tmpEdbInfoItem.IsJoinPermission, currClassify.IsJoinPermission, tmpEdbInfoItem.EdbInfoId, tmpEdbInfoItem.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
 			}
+			// 权限校验
+			tmpEdbInfoItem.Button = data.GetEdbOpButton(this.SysUser, tmpEdbInfoItem.SysUserId, tmpEdbInfoItem.EdbInfoId, tmpEdbInfoItem.EdbType, tmpEdbInfoItem.EdbInfoType, tmpEdbInfoItem.HaveOperaAuth, editShareEdbInfoIdMap)
+
 		}
 	}
 
@@ -1952,13 +1966,6 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 			}
 		}
 	}
-	//新增搜索词记录
-	{
-		searchKeyword := new(data_manage.SearchKeyword)
-		searchKeyword.KeyWord = keyWord
-		searchKeyword.CreateTime = time.Now()
-		go data_manage.AddSearchKeyword(searchKeyword)
-	}
 
 	// 不返回无权限的指标
 	respList := make([]*data_manage.EdbInfoList, 0)
@@ -3216,8 +3223,13 @@ func (this *EdbInfoController) AllEdbInfoByEs() {
 		newKeyWord := strings.Split(keyWord, " ")
 		keyWordArr = append(keyWordArr, newKeyWord...)
 
+		frequencyList := make([]string, 0)
+		if frequency != `` {
+			frequencyList = []string{frequency}
+		}
+
 		// 普通的搜索
-		total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, -1, frequency, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, edbType)
+		total, edbInfoList, err = elastic.SearchEdbInfoData(keyWord, startSize, pageSize, filterSource, source, frequencyList, []string{}, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, []int{}, []int{}, []int{}, []int{1, 2}, -1, 0, this.SysUser.AdminId, map[string]string{})
 		isEs = true
 	} else {
 		var condition string
@@ -3655,7 +3667,8 @@ func (this *EdbInfoController) EdbChartAdminList() {
 // EdbSourceList
 // @Title 指标来源列表
 // @Description 指标来源列表
-// @Param   IsBase   query   int  false	"是否为基础指标: 1-是"
+// @Param   IsBase   query   int  false	"是否为基础指标: 1-基础指标,2:计算指标"
+// @Param   EdbInfoType   query   int  false	"指标类型,0:指标库;1:预测指标,默认:0"
 // @Success 200 {object} data_manage.EdbInfoListResp
 // @router /edb_source/list [get]
 func (this *EdbInfoController) EdbSourceList() {
@@ -3668,12 +3681,22 @@ func (this *EdbInfoController) EdbSourceList() {
 		this.ServeJSON()
 	}()
 	isBase, _ := this.GetInt("IsBase", 0)
+	edbInfoType, _ := this.GetInt("EdbInfoType", 0)
 
-	cond := ``
-	if isBase > 0 {
-		cond = ` AND is_base = 1`
-	}
 	pars := make([]interface{}, 0)
+	cond := ` AND edb_info_type = ? `
+	pars = append(pars, edbInfoType)
+
+	// 计算类型
+	switch isBase {
+	case 1:
+		cond += ` AND is_base = ? `
+		pars = append(pars, 1)
+	case 2:
+		cond += ` AND is_base = ? `
+		pars = append(pars, 2)
+	}
+
 	list, e := data_manage.GetEdbSourceItemsByCondition(cond, pars, []string{}, "")
 	if e != nil {
 		br.Msg = "获取失败"
@@ -3807,11 +3830,19 @@ func (this *EdbInfoController) EdbChartList() {
 	pars = append(pars, 0)
 
 	// 指标类型
-	edbType, _ := this.GetInt("EdbType", 0)
+	edbType, _ := this.GetInt("EdbType", 1)
 	if edbType > 0 {
 		condition += ` AND edb_type = ? `
 		pars = append(pars, edbType)
 	}
+	switch edbType {
+	case utils.EdbTypeBase:
+		condition += ` AND edb_type = ? `
+		pars = append(pars, edbType)
+	case utils.EdbTypeCalculate:
+		condition += ` AND edb_type = ? AND sys_user_id = ? `
+		pars = append(pars, edbType, sysUser.AdminId)
+	}
 
 	// 分类筛选
 	classifyId, _ := this.GetInt("ClassifyId")
@@ -3837,13 +3868,6 @@ func (this *EdbInfoController) EdbChartList() {
 		pars = append(pars, adminId)
 	}
 
-	// 只看我的
-	isOnlyMe, _ := this.GetBool("IsOnlyMe")
-	if isOnlyMe {
-		condition += ` AND sys_user_id = ? `
-		pars = append(pars, sysUser.AdminId)
-	}
-
 	// 无权限指标 和 无权限指标分类id
 	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, err := data_manage_permission.GetUserAllEdbAndClassifyNoPermissionList(this.SysUser.AdminId, utils.EDB_INFO_TYPE, edbType)
 	if err != nil {
@@ -3910,6 +3934,12 @@ func (this *EdbInfoController) EdbChartList() {
 					}
 				}
 			}
+			editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+				return
+			}
 
 			for _, v := range list {
 				if currClassify, ok := classifyMap[v.ClassifyId]; ok {
@@ -3920,7 +3950,7 @@ func (this *EdbInfoController) EdbChartList() {
 						continue
 					}
 
-					v.Button = data.GetEdbOpButton(sysUser, v.SysUserId, v.EdbType, v.EdbInfoType, v.HaveOperaAuth)
+					v.Button = data.GetEdbOpButton(sysUser, v.SysUserId, v.EdbInfoId, v.EdbType, v.EdbInfoType, v.HaveOperaAuth, editShareEdbInfoIdMap)
 				}
 
 				respList = append(respList, v)
@@ -3993,9 +4023,15 @@ func (this *EdbInfoController) Modify() {
 			return
 		}
 	}
+	editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+		return
+	}
 
 	// 编辑权限校验
-	button := data.GetEdbOpButton(this.SysUser, edbInfo.SysUserId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth)
+	button := data.GetEdbOpButton(this.SysUser, edbInfo.SysUserId, edbInfo.EdbInfoId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth, editShareEdbInfoIdMap)
 	if !button.OpButton {
 		br.Msg = "无权限操作"
 		return
@@ -4597,3 +4633,132 @@ func (this *EdbInfoController) ChartImageSetBySvg() {
 	br.Success = true
 	br.Msg = "保存成功"
 }
+
+// BatchMoveEdb
+// @Title 指标批量移动接口
+// @Description 指标批量移动接口
+// @Param	request	body request.MoveEdbClassifyReq true "type json string"
+// @Success Ret=200 移动成功
+// @router /edb_info/batch_move [post]
+func (this *EdbInfoController) BatchMoveEdb() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.MoveEdbClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.NewClassifyId <= 0 {
+		br.Msg = `请选择要转移的新分类`
+		br.IsSendEmail = false
+		return
+	}
+
+	classifyItem, err := data_manage.GetEdbClassifyById(req.NewClassifyId)
+	if err != nil {
+		br.Msg = "获取指标分类失败!"
+		br.ErrMsg = "获取指标分类失败!" + err.Error()
+		return
+	}
+	if classifyItem.SysUserId != this.SysUser.AdminId {
+		br.Msg = `您没有权限移动指标到该分类!`
+		br.IsSendEmail = false
+		return
+	}
+
+	edbInfoIdList := make([]int, 0)
+	if req.IsSelectAll {
+		// 获取指标
+		edbInfoList, err := data.GetAllEdbInfoListBySearchPublicEdbReq(req.SearchPublicEdbReq, this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取指标列表失败!"
+			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
+			return
+		}
+		// 如果有过滤指标,那么就过滤吧
+		if len(req.NoEdbIdList) > 0 {
+			noEdbIdMap := make(map[int]bool)
+			for _, v := range req.NoEdbIdList {
+				noEdbIdMap[v] = true
+			}
+
+			for _, edbInfo := range edbInfoList {
+				if _, ok := noEdbIdMap[edbInfo.EdbInfoId]; !ok {
+
+					if edbInfo.SysUserId != this.SysUser.AdminId {
+						br.Msg = `您没有权限移动该指标!`
+						br.IsSendEmail = false
+						return
+					}
+
+					// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
+					edbInfoIdList = append(edbInfoIdList, edbInfo.EdbInfoId)
+				}
+			}
+		} else {
+			for _, edbInfo := range edbInfoList {
+				edbInfoIdList = append(edbInfoIdList, edbInfo.EdbInfoId)
+				for _, v := range edbInfoList {
+					if v.SysUserId != this.SysUser.AdminId {
+						br.Msg = `您没有权限移动该指标!`
+						br.IsSendEmail = false
+						return
+					}
+				}
+			}
+		}
+	} else {
+		edbInfoList, err := data_manage.GetEdbInfoListByCond(` AND edb_info_id in (?) `, []interface{}{req.EdbIdList})
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range edbInfoList {
+			if v.SysUserId != this.SysUser.AdminId {
+				br.Msg = `您没有权限移动该指标!`
+				br.IsSendEmail = false
+				return
+			}
+		}
+		edbInfoIdList = req.EdbIdList
+	}
+
+	num := len(edbInfoIdList)
+	if num <= 0 {
+		br.Msg = `请选择要移动的指标!`
+		br.IsSendEmail = false
+		return
+	}
+	if num > 100 {
+		br.Msg = `最多只能选择100条指标!`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 开始批量修改指标分类
+	if len(edbInfoIdList) > 0 {
+		err = data_manage.UpdateClassifyIdByEdbInfoIdList(edbInfoIdList, req.NewClassifyId)
+		if err != nil {
+			br.Msg = `指标移动失败!`
+			br.ErrMsg = `指标移动失败,ERR:` + err.Error()
+			return
+		}
+
+		// 还得修改ES呢
+		for _, v := range edbInfoIdList {
+			data.AddOrEditEdbInfoToEs(v)
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 391 - 192
controllers/data_manage/edb_info_calculate.go

@@ -5,16 +5,17 @@ import (
 	"eta_gn/eta_api/controllers"
 	"eta_gn/eta_api/models"
 	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/data_manage/request"
 	"eta_gn/eta_api/services/data"
 	"eta_gn/eta_api/services/data/data_manage_permission"
+	"eta_gn/eta_api/services/elastic"
 	"eta_gn/eta_api/utils"
 	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"net/url"
 	"strconv"
 	"strings"
 	"time"
-
-	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // 计算指标
@@ -1068,76 +1069,6 @@ func (this *ChartInfoController) CalculateBatchReset() {
 	br.IsAddLog = true
 }
 
-//累计值转月值
-//func init() {
-//	fmt.Println("start CalculateBatchSave")
-//	req := new(data_manage.EdbInfoCalculateBatchSaveReq)
-//	req.EdbInfoId = 100282
-//
-//	randStr := utils.GetRandDigit(4)
-//	edbCode := `C` + time.Now().Format("060102") + randStr
-//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
-//	fromEdbInfo, _ := data_manage.GetEdbInfoById(req.EdbInfoId)
-//	data_manage.AddCalculateLjzzy(req, fromEdbInfo, edbCode, uniqueCode, 1, "rdluck")
-//	fmt.Println("end CalculateBatchSave")
-//	return
-//}
-
-////同比值
-//func init() {
-//	fmt.Println("start AddCalculateTbz")
-//	req := new(data_manage.EdbInfoCalculateBatchSaveReq)
-//	req.EdbInfoId = 100092
-//
-//	randStr := utils.GetRandDigit(4)
-//	edbCode := `C` + time.Now().Format("060102") + randStr
-//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
-//	fromEdbInfo, _ := data_manage.GetEdbInfoById(req.EdbInfoId)
-//
-//	data_manage.AddCalculateTbz(req, fromEdbInfo, edbCode, uniqueCode, 1, "rdluck")
-//	fmt.Println("end AddCalculateTbz")
-//	return
-//}
-//同差值
-
-//func init() {
-//	fmt.Println("start AddCalculateTbz")
-//	req := new(data_manage.EdbInfoCalculateBatchSaveReq)
-//	req.EdbInfoId = 100092
-//
-//	randStr := utils.GetRandDigit(4)
-//	edbCode := `C` + time.Now().Format("060102") + randStr
-//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
-//	fromEdbInfo, _ := data_manage.GetEdbInfoById(req.EdbInfoId)
-//
-//	data_manage.AddCalculateTcz(req, fromEdbInfo, edbCode, uniqueCode, 1, "rdluck")
-//
-//	fmt.Println("end AddCalculateTbz")
-//	return
-//}
-
-//N数值移动平均计算
-//func init() {
-//	fmt.Println("start AddCalculateTbz")
-//	req := new(data_manage.EdbInfoCalculateBatchSaveReq)
-//	req.FromEdbInfoId = 100081
-//
-//	randStr := utils.GetRandDigit(4)
-//	edbCode := `C` + time.Now().Format("060102") + randStr
-//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
-//	fromEdbInfo, _ := data_manage.GetEdbInfoById(req.FromEdbInfoId)
-//	formulaInt := 3
-//	fmt.Println("edbCode:", edbCode)
-//	data_manage.AddCalculateNszydpjjs(req, fromEdbInfo, edbCode, uniqueCode, 1, "rdluck", formulaInt)
-//
-//	fmt.Println("end AddCalculateTbz")
-//	return
-//}
-
 // ExecPythonCode
 // @Title 执行python代码
 // @Description 执行python代码接口
@@ -2161,8 +2092,8 @@ func (this *ChartInfoController) CalculateMultiChoice() {
 	//来源类型,1:中文,2:英文
 	frequency := this.GetString("Frequency")
 	keyword := this.GetString("Keyword")
-	sysUserIds := this.GetString("SysUserIds")
-	classifyIds := this.GetString("ClassifyIds")
+	//sysUserIds := this.GetString("SysUserIds")
+	//classifyIds := this.GetString("ClassifyIds")
 	edbInfoIds := this.GetString("EdbInfoIds")
 	selectAll, _ := this.GetBool("SelectAll")
 	notFrequency := this.GetString("NotFrequency")
@@ -2184,48 +2115,34 @@ func (this *ChartInfoController) CalculateMultiChoice() {
 
 	if selectAll {
 		// 如果勾了列表全选,那么EdbCode传的就是排除的code
-
-		condition := ` AND edb_info_type = ? `
-		pars := make([]interface{}, 0)
-		pars = append(pars, edbInfoType)
-
-		if classifyIds != "" {
-			classifyIdsArr := strings.Split(classifyIds, ",")
-			condition += ` AND classify_id IN (` + utils.GetOrmInReplace(len(classifyIdsArr)) + `) `
-			pars = append(pars, classifyIdsArr)
-		}
-
-		if frequency != "" {
-			frequencyArr := strings.Split(frequency, ",")
-			condition += ` AND frequency IN (` + utils.GetOrmInReplace(len(frequencyArr)) + `) `
-			pars = append(pars, frequencyArr)
-		}
-		if notFrequency != "" {
-			notFrequencyArr := strings.Split(notFrequency, ",")
-			condition += ` AND frequency NOT IN (` + utils.GetOrmInReplace(len(notFrequencyArr)) + `) `
-			pars = append(pars, notFrequencyArr)
-		}
-
-		if sysUserIds != "" {
-			sysUserIdSlice := strings.Split(sysUserIds, ",")
-			condition += ` AND sys_user_id IN (` + utils.GetOrmInReplace(len(sysUserIdSlice)) + `)`
-			pars = append(pars, sysUserIdSlice)
-		}
-
-		if keyword != "" {
-			keyWordArr := strings.Split(keyword, " ")
-
-			if len(keyWordArr) > 0 {
-				for _, v := range keyWordArr {
-					condition += ` AND CONCAT(edb_name,edb_code) LIKE ?`
-					pars = append(pars, utils.GetLikeKeyword(v))
-				}
+		edbTypeStr := `0`
+		if edbInfoType == 1 {
+			edbTypeStr = `3`
+		}
+		sortMap := make(map[string]string)
+		// 如果没有搜索关键词,则默认根据指标编码倒序排序
+		if keyword == `` {
+			sortMap["EdbInfoId"] = `desc`
+		}
+		generalEdbEsSearchReq := request.GeneralEdbEsSearchReq{
+			FilterSource: 0,
+			//ClassifyId:   0,
+			Source:       0,
+			EdbAuth:      0,
+			EdbCollect:   0,
+			Frequency:    frequency,
+			NotFrequency: notFrequency,
+			EdbType:      edbTypeStr,
+			Keyword:      keyword,
+			KeyWord:      keyword,
+		}
+		edbList, err, errMsg := data.GetAllGeneralEdbInfoListByGeneralEdbEsSearchReq(generalEdbEsSearchReq, this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取指标列表失败!"
+			if errMsg != `` {
+				br.Msg = errMsg
 			}
-		}
-		edbList, e := data_manage.GetEdbInfoListByCond(condition, pars)
-		if e != nil {
-			br.Msg = "获取指标列表失败"
-			br.ErrMsg = "获取指标列表失败,Err:" + e.Error()
+			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
 			return
 		}
 
@@ -2349,8 +2266,8 @@ func (this *ChartInfoController) CalculateMultiSearch() {
 	//来源类型,1:中文,2:英文
 	frequency := this.GetString("Frequency")
 	keyword := this.GetString("Keyword")
-	sysUserIds := this.GetString("SysUserIds")
-	classifyIds := this.GetString("ClassifyIds")
+	keyword = strings.TrimSpace(keyword)
+	//classifyIds := this.GetString("ClassifyIds")
 
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
@@ -2368,90 +2285,45 @@ func (this *ChartInfoController) CalculateMultiSearch() {
 
 	var edbIdArr []int
 
-	condition := ` AND edb_info_type = ? `
-	pars := make([]interface{}, 0)
-	pars = append(pars, edbInfoType)
-
-	if classifyIds != "" {
-		classifyIdsArr := strings.Split(classifyIds, ",")
-		condition += ` AND classify_id IN (` + utils.GetOrmInReplace(len(classifyIdsArr)) + `) `
-		pars = append(pars, classifyIdsArr)
-	}
-
-	if frequency != "" {
-		frequencyArr := strings.Split(frequency, ",")
-		condition += ` AND frequency IN (` + utils.GetOrmInReplace(len(frequencyArr)) + `) `
-		pars = append(pars, frequencyArr)
-	}
+	notFrequencyList := make([]string, 0)
 	if notFrequency != "" {
-		notFrequencyArr := strings.Split(notFrequency, ",")
-		condition += ` AND frequency NOT IN (` + utils.GetOrmInReplace(len(notFrequencyArr)) + `) `
-		pars = append(pars, notFrequencyArr)
-	}
-	if sysUserIds != "" {
-		sysUserIdSlice := strings.Split(sysUserIds, ",")
-		condition += ` AND sys_user_id IN (` + utils.GetOrmInReplace(len(sysUserIdSlice)) + `)`
-		pars = append(pars, sysUserIdSlice)
+		notFrequencyList = strings.Split(notFrequency, ",")
 	}
 
-	if keyword != "" {
-		keyWordArr := strings.Split(keyword, " ")
-
-		if len(keyWordArr) > 0 {
-			for _, v := range keyWordArr {
-				condition += ` AND CONCAT(edb_name,edb_code) LIKE ?`
-				pars = append(pars, utils.GetLikeKeyword(v))
-			}
+	source := 0
+	edbAuth := 0
+	edbCollect := 0
+	edbTypeStr := `0`
+	if edbInfoType == 1 {
+		edbTypeStr = `3`
+	}
+	// 获取es搜索参数
+	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, collectEdbInfoIdList, searchClassifyIdList, searchPublicClassifyIdList, edbTypeList, edbInfoType, edbAuth, searchUserId, frequencyList, err, errMsg := data.GetGeneralEdbEsSearchParams(edbTypeStr, frequency, this.SysUser.AdminId, edbAuth, edbCollect, 0)
+	if err != nil {
+		br.Msg = "获取失败"
+		if errMsg != `` {
+			br.Msg = errMsg
 		}
+		br.ErrMsg = "获取失败:" + err.Error()
+		return
 	}
 
-	total, e := data_manage.GetEdbInfoByConditionCount(condition, pars)
-	if e != nil {
-		br.Msg = "获取指标列表总数失败"
-		br.ErrMsg = "获取指标列表总数失败,Err:" + e.Error()
-		return
+	sortMap := make(map[string]string)
+	// 如果没有搜索关键词,则默认根据指标编码倒序排序
+	if keyword == `` {
+		sortMap["EdbInfoId"] = `desc`
 	}
 
+	// 普通的搜索
+	total, edbList, err := elastic.SearchEdbInfoData(keyword, startSize, pageSize, 0, source, frequencyList, notFrequencyList, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, collectEdbInfoIdList, searchClassifyIdList, searchPublicClassifyIdList, edbTypeList, edbInfoType, edbAuth, searchUserId, sortMap)
+
 	searchItemList := make([]data_manage.CalculateMultiEdbSearchItem, 0)
-	page := paging.GetPaging(currentIndex, pageSize, total)
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
 	resp := new(data_manage.CalculateMultiEdbSearchResp)
 
-	edbList, e := data_manage.GetEdbInfoListByCondition(condition, pars, startSize, pageSize, "")
-	if e != nil {
-		br.Msg = "获取指标列表失败"
-		br.ErrMsg = "获取指标列表失败,Err:" + e.Error()
-		return
-	}
-
 	if len(edbList) > 0 {
-		classifyIdList := make([]int, 0)
 		for _, v := range edbList {
 			edbIdArr = append(edbIdArr, v.EdbInfoId)
-			classifyIdList = append(classifyIdList, v.ClassifyId)
-		}
-
-		// 当前列表中的分类map
-		classifyMap := make(map[int]*data_manage.EdbClassify)
-		{
-			classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList)
-			if err != nil {
-				if err != nil {
-					br.Msg = "获取失败"
-					br.ErrMsg = "获取分类列表失败,Err:" + err.Error()
-					return
-				}
-			}
-			for _, v := range classifyList {
-				classifyMap[v.ClassifyId] = v
-			}
-		}
-
-		// 获取所有有权限的指标和分类
-		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(this.SysUser.AdminId, 0, 0)
-		if err != nil {
-			br.Msg = "获取失败"
-			br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
-			return
 		}
 
 		list, err := data_manage.GetEdbInfoByIdList(edbIdArr)
@@ -2461,10 +2333,6 @@ func (this *ChartInfoController) CalculateMultiSearch() {
 			return
 		}
 		for _, info := range list {
-			var haveOperaAuth bool
-			if currClassify, ok := classifyMap[info.ClassifyId]; ok {
-				haveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(info.IsJoinPermission, currClassify.IsJoinPermission, info.EdbInfoId, info.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
-			}
 			searchItem := data_manage.CalculateMultiEdbSearchItem{
 				Frequency:       info.Frequency,
 				Unit:            info.Unit,
@@ -2477,7 +2345,7 @@ func (this *ChartInfoController) CalculateMultiSearch() {
 				SysUserId:       info.SysUserId,
 				EndDate:         utils.TimeToFormatDate(info.EndDate),
 				EndValue:        info.EndValue,
-				HaveOperaAuth:   haveOperaAuth,
+				HaveOperaAuth:   true,
 				EdbInfoType:     info.EdbInfoType,
 			}
 			searchItemList = append(searchItemList, searchItem)
@@ -2491,3 +2359,334 @@ func (this *ChartInfoController) CalculateMultiSearch() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+//func (this *ChartInfoController) CalculateMultiChoiceBak() {
+//	br := new(models.BaseResponse).Init()
+//	defer func() {
+//		this.Data["json"] = br
+//		this.ServeJSON()
+//	}()
+//
+//	//来源类型,1:中文,2:英文
+//	frequency := this.GetString("Frequency")
+//	keyword := this.GetString("Keyword")
+//	sysUserIds := this.GetString("SysUserIds")
+//	classifyIds := this.GetString("ClassifyIds")
+//	edbInfoIds := this.GetString("EdbInfoIds")
+//	selectAll, _ := this.GetBool("SelectAll")
+//	notFrequency := this.GetString("NotFrequency")
+//	edbInfoType, _ := this.GetInt("EdbInfoType", 0)
+//	var edbIdArr []int
+//	var filterEdbIds []int
+//	if edbInfoIds != "" {
+//		arr := strings.Split(edbInfoIds, ",")
+//		for _, v := range arr {
+//			t, e := strconv.Atoi(v)
+//			if e != nil {
+//				br.Msg = "参数有误"
+//				br.ErrMsg = fmt.Sprintf("指标ID有误, %s", v)
+//				return
+//			}
+//			filterEdbIds = append(filterEdbIds, t)
+//		}
+//	}
+//
+//	if selectAll {
+//		// 如果勾了列表全选,那么EdbCode传的就是排除的code
+//
+//		condition := ` AND edb_info_type = ? `
+//		pars := make([]interface{}, 0)
+//		pars = append(pars, edbInfoType)
+//
+//		if classifyIds != "" {
+//			classifyIdsArr := strings.Split(classifyIds, ",")
+//			condition += ` AND classify_id IN (` + utils.GetOrmInReplace(len(classifyIdsArr)) + `) `
+//			pars = append(pars, classifyIdsArr)
+//		}
+//
+//		if frequency != "" {
+//			frequencyArr := strings.Split(frequency, ",")
+//			condition += ` AND frequency IN (` + utils.GetOrmInReplace(len(frequencyArr)) + `) `
+//			pars = append(pars, frequencyArr)
+//		}
+//		if notFrequency != "" {
+//			notFrequencyArr := strings.Split(notFrequency, ",")
+//			condition += ` AND frequency NOT IN (` + utils.GetOrmInReplace(len(notFrequencyArr)) + `) `
+//			pars = append(pars, notFrequencyArr)
+//		}
+//
+//		if sysUserIds != "" {
+//			sysUserIdSlice := strings.Split(sysUserIds, ",")
+//			condition += ` AND sys_user_id IN (` + utils.GetOrmInReplace(len(sysUserIdSlice)) + `)`
+//			pars = append(pars, sysUserIdSlice)
+//		}
+//
+//		if keyword != "" {
+//			keyWordArr := strings.Split(keyword, " ")
+//
+//			if len(keyWordArr) > 0 {
+//				for _, v := range keyWordArr {
+//					condition += ` AND CONCAT(edb_name,edb_code) LIKE ?`
+//					pars = append(pars, utils.GetLikeKeyword(v))
+//				}
+//			}
+//		}
+//		edbList, e := data_manage.GetEdbInfoListByCond(condition, pars)
+//		if e != nil {
+//			br.Msg = "获取指标列表失败"
+//			br.ErrMsg = "获取指标列表失败,Err:" + e.Error()
+//			return
+//		}
+//
+//		filterLen := len(filterEdbIds)
+//		for _, v := range edbList {
+//			// 全选-排除传入的指标
+//			if filterLen > 0 && utils.InArrayByInt(filterEdbIds, v.EdbInfoId) {
+//				continue
+//			}
+//			edbIdArr = append(edbIdArr, v.EdbInfoId)
+//		}
+//	} else {
+//		//未勾选全选EdbCode就是需要的code
+//		edbIdStrArr := strings.Split(edbInfoIds, ",")
+//		for _, v := range edbIdStrArr {
+//			id, e := strconv.Atoi(v)
+//			if e != nil {
+//				br.Msg = "获取指标列表失败"
+//				br.ErrMsg = "获取指标列表失败,Err:" + e.Error()
+//				return
+//			}
+//			edbIdArr = append(edbIdArr, id)
+//		}
+//	}
+//
+//	if len(edbIdArr) > 100 {
+//		br.Msg = "最多只能选择100个指标"
+//		return
+//	}
+//
+//	if len(edbIdArr) <= 0 {
+//		br.Msg = "无符合指标或指标代码错误"
+//		return
+//	}
+//
+//	list, err := data_manage.GetEdbInfoByIdList(edbIdArr)
+//	if err != nil && !utils.IsErrNoRow(err) {
+//		br.Msg = "获取指标列表失败"
+//		br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
+//		return
+//	}
+//
+//	searchItemList := make([]data_manage.EdbInfoBase, 0)
+//
+//	resp := new(data_manage.CalculateMultiChoiceResp)
+//
+//	if len(list) > 0 {
+//		// 当前列表中的分类map
+//		classifyMap := make(map[int]*data_manage.EdbClassify)
+//		{
+//			classifyIdList := make([]int, 0)
+//			for _, info := range list {
+//				classifyIdList = append(classifyIdList, info.ClassifyId)
+//			}
+//			classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList)
+//			if err != nil {
+//				if err != nil {
+//					br.Msg = "获取失败"
+//					br.ErrMsg = "获取分类列表失败,Err:" + err.Error()
+//					return
+//				}
+//			}
+//
+//			for _, v := range classifyList {
+//				classifyMap[v.ClassifyId] = v
+//			}
+//		}
+//
+//		// 获取所有有权限的指标和分类
+//		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(this.SysUser.AdminId, 0, 0)
+//		if err != nil {
+//			br.Msg = "获取失败"
+//			br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
+//			return
+//		}
+//		for _, info := range list {
+//			var haveOperaAuth bool
+//			if currClassify, ok := classifyMap[info.ClassifyId]; ok {
+//				haveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(info.IsJoinPermission, currClassify.IsJoinPermission, info.EdbInfoId, info.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
+//			}
+//			searchItem := data_manage.EdbInfoBase{
+//				Frequency:     info.Frequency,
+//				Unit:          info.Unit,
+//				UnitEn:        info.UnitEn,
+//				EdbName:       info.EdbName,
+//				EdbNameEn:     info.EdbNameEn,
+//				EdbInfoId:     info.EdbInfoId,
+//				ClassifyId:    info.ClassifyId,
+//				HaveOperaAuth: haveOperaAuth,
+//				EdbInfoType:   info.EdbInfoType,
+//			}
+//			searchItemList = append(searchItemList, searchItem)
+//		}
+//	}
+//
+//	resp.SearchItem = searchItemList
+//
+//	br.Ret = 200
+//	br.Success = true
+//	br.Msg = "获取成功"
+//	br.Data = resp
+//}
+
+//func (this *ChartInfoController) CalculateMultiSearchBak() {
+//	br := new(models.BaseResponse).Init()
+//	defer func() {
+//		this.Data["json"] = br
+//		this.ServeJSON()
+//	}()
+//
+//	//来源类型,1:中文,2:英文
+//	frequency := this.GetString("Frequency")
+//	keyword := this.GetString("Keyword")
+//	sysUserIds := this.GetString("SysUserIds")
+//	classifyIds := this.GetString("ClassifyIds")
+//
+//	pageSize, _ := this.GetInt("PageSize")
+//	currentIndex, _ := this.GetInt("CurrentIndex")
+//	notFrequency := this.GetString("NotFrequency")
+//	edbInfoType, _ := this.GetInt("EdbInfoType", 0)
+//
+//	var startSize int
+//	if pageSize <= 0 {
+//		pageSize = utils.PageSize50
+//	}
+//	if currentIndex <= 0 {
+//		currentIndex = 1
+//	}
+//	startSize = utils.StartIndex(currentIndex, pageSize)
+//
+//	var edbIdArr []int
+//
+//	condition := ` AND edb_info_type = ? `
+//	pars := make([]interface{}, 0)
+//	pars = append(pars, edbInfoType)
+//
+//	if classifyIds != "" {
+//		classifyIdsArr := strings.Split(classifyIds, ",")
+//		condition += ` AND classify_id IN (` + utils.GetOrmInReplace(len(classifyIdsArr)) + `) `
+//		pars = append(pars, classifyIdsArr)
+//	}
+//
+//	if frequency != "" {
+//		frequencyArr := strings.Split(frequency, ",")
+//		condition += ` AND frequency IN (` + utils.GetOrmInReplace(len(frequencyArr)) + `) `
+//		pars = append(pars, frequencyArr)
+//	}
+//	if notFrequency != "" {
+//		notFrequencyArr := strings.Split(notFrequency, ",")
+//		condition += ` AND frequency NOT IN (` + utils.GetOrmInReplace(len(notFrequencyArr)) + `) `
+//		pars = append(pars, notFrequencyArr)
+//	}
+//	if sysUserIds != "" {
+//		sysUserIdSlice := strings.Split(sysUserIds, ",")
+//		condition += ` AND sys_user_id IN (` + utils.GetOrmInReplace(len(sysUserIdSlice)) + `)`
+//		pars = append(pars, sysUserIdSlice)
+//	}
+//
+//	if keyword != "" {
+//		keyWordArr := strings.Split(keyword, " ")
+//
+//		if len(keyWordArr) > 0 {
+//			for _, v := range keyWordArr {
+//				condition += ` AND CONCAT(edb_name,edb_code) LIKE ?`
+//				pars = append(pars, utils.GetLikeKeyword(v))
+//			}
+//		}
+//	}
+//
+//	total, e := data_manage.GetEdbInfoByConditionCount(condition, pars)
+//	if e != nil {
+//		br.Msg = "获取指标列表总数失败"
+//		br.ErrMsg = "获取指标列表总数失败,Err:" + e.Error()
+//		return
+//	}
+//
+//	searchItemList := make([]data_manage.CalculateMultiEdbSearchItem, 0)
+//	page := paging.GetPaging(currentIndex, pageSize, total)
+//	resp := new(data_manage.CalculateMultiEdbSearchResp)
+//
+//	edbList, e := data_manage.GetEdbInfoListByCondition(condition, pars, startSize, pageSize, "")
+//	if e != nil {
+//		br.Msg = "获取指标列表失败"
+//		br.ErrMsg = "获取指标列表失败,Err:" + e.Error()
+//		return
+//	}
+//
+//	if len(edbList) > 0 {
+//		classifyIdList := make([]int, 0)
+//		for _, v := range edbList {
+//			edbIdArr = append(edbIdArr, v.EdbInfoId)
+//			classifyIdList = append(classifyIdList, v.ClassifyId)
+//		}
+//
+//		// 当前列表中的分类map
+//		classifyMap := make(map[int]*data_manage.EdbClassify)
+//		{
+//			classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList)
+//			if err != nil {
+//				if err != nil {
+//					br.Msg = "获取失败"
+//					br.ErrMsg = "获取分类列表失败,Err:" + err.Error()
+//					return
+//				}
+//			}
+//			for _, v := range classifyList {
+//				classifyMap[v.ClassifyId] = v
+//			}
+//		}
+//
+//		// 获取所有有权限的指标和分类
+//		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(this.SysUser.AdminId, 0, 0)
+//		if err != nil {
+//			br.Msg = "获取失败"
+//			br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
+//			return
+//		}
+//
+//		list, err := data_manage.GetEdbInfoByIdList(edbIdArr)
+//		if err != nil && !utils.IsErrNoRow(err) {
+//			br.Msg = "获取指标列表失败"
+//			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
+//			return
+//		}
+//		for _, info := range list {
+//			var haveOperaAuth bool
+//			if currClassify, ok := classifyMap[info.ClassifyId]; ok {
+//				haveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(info.IsJoinPermission, currClassify.IsJoinPermission, info.EdbInfoId, info.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
+//			}
+//			searchItem := data_manage.CalculateMultiEdbSearchItem{
+//				Frequency:       info.Frequency,
+//				Unit:            info.Unit,
+//				UnitEn:          info.UnitEn,
+//				EdbName:         info.EdbName,
+//				EdbNameEn:       info.EdbNameEn,
+//				EdbInfoId:       info.EdbInfoId,
+//				ClassifyId:      info.ClassifyId,
+//				SysUserRealName: info.SysUserRealName,
+//				SysUserId:       info.SysUserId,
+//				EndDate:         utils.TimeToFormatDate(info.EndDate),
+//				EndValue:        info.EndValue,
+//				HaveOperaAuth:   haveOperaAuth,
+//				EdbInfoType:     info.EdbInfoType,
+//			}
+//			searchItemList = append(searchItemList, searchItem)
+//		}
+//	}
+//
+//	resp.SearchItem = searchItemList
+//	resp.Paging = page
+//	br.Ret = 200
+//	br.Success = true
+//	br.Msg = "获取成功"
+//	br.Data = resp
+//}

+ 902 - 0
controllers/data_manage/edb_info_share.go

@@ -0,0 +1,902 @@
+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/models/data_manage/request"
+	"eta_gn/eta_api/models/data_manage/response"
+	"eta_gn/eta_api/models/system"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/services/elastic"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strconv"
+	"strings"
+)
+
+// TODO 取消共享的时候,需要清除对应用户的收藏状态
+
+// EdbInfoShareController 数据管理
+type EdbInfoShareController struct {
+	controllers.BaseAuthController
+}
+
+// UserList
+// @Title 获取指标设置共享的详情
+// @Description 获取指标详情接口
+// @Param   EdbInfoId   query   int  true       "指标id"
+// @Success 200 {object} response.EdbInfoShareUserResp
+// @router /edb_info/share/user_list [get]
+func (c *EdbInfoShareController) UserList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	edbInfoId, _ := c.GetInt("EdbInfoId")
+	if edbInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+	edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	if edbInfo.SysUserId != sysUser.AdminId {
+		br.Msg = "您没有权限设置共享"
+		br.ErrMsg = "您没有权限设置共享,EdbInfoId:" + strconv.Itoa(edbInfo.EdbInfoId)
+		br.IsSendEmail = false
+		return
+	}
+
+	resp := response.EdbInfoShareUserResp{}
+
+	obj := data_manage.EdbInfoShare{}
+	list, err := obj.GetListByEdbInfoId(edbInfoId)
+	if err != nil {
+		br.Msg = `获取失败`
+		br.ErrMsg = `获取失败:` + err.Error()
+		return
+	}
+	resp.List = list
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// Save
+// @Title 单个指标设置共享
+// @Description 单个指标设置共享
+// @Param	request	body request.SetEdbInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfo
+// @router /edb_info/share/save [post]
+func (c *EdbInfoShareController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.SetEdbInfoShareReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.EdbInfoId <= 0 {
+		br.Msg = `请选择指标`
+		br.IsSendEmail = false
+		return
+	}
+	edbItem, err := data_manage.GetEdbInfoById(req.EdbInfoId)
+	if err != nil {
+		br.Msg = "查找指标失败"
+		br.ErrMsg = "查找指标失败,Err:" + err.Error()
+		return
+	}
+	if edbItem.EdbInfoId <= 0 {
+		br.Msg = "指标不存在"
+		br.ErrMsg = "指标不存在,ChartInfoId:" + strconv.Itoa(req.EdbInfoId)
+		br.IsSendEmail = false
+		return
+	}
+	if edbItem.SysUserId != c.SysUser.AdminId {
+		br.Msg = "您没有权限设置共享"
+		br.ErrMsg = "您没有权限设置共享,EdbInfoId:" + strconv.Itoa(req.EdbInfoId)
+		br.IsSendEmail = false
+		return
+	}
+
+	// 如果指标未公开,则判断是否被其他用户使用
+	if edbItem.PublicStatus != utils.DataPublicSuccess {
+		checkUserIdList := []int{sysUser.AdminId}
+		if len(req.UserIdList) > 0 {
+			checkUserIdList = append(checkUserIdList, req.UserIdList...)
+		}
+		noReferenced, otherUserIdList, err, tips := data.CheckEdbReferencedByOthers(edbItem.EdbInfoType, []int{edbItem.EdbInfoId}, checkUserIdList)
+		if err != nil {
+			br.Msg = "保存失败"
+			if tips != "" {
+				br.Msg = tips
+			}
+			br.ErrMsg = "设置指标共享失败,查找指标的关联用户失败,Err:" + err.Error()
+			return
+		}
+
+		if !noReferenced {
+			userNameStr := ``
+			if len(otherUserIdList) > 0 {
+				userNameList := make([]string, 0)
+				userList, err := system.GetAdminListByIdList(otherUserIdList)
+				if err != nil {
+					br.Msg = "保存失败"
+					if tips != "" {
+						br.Msg = tips
+					}
+					br.ErrMsg = "设置指标共享失败,查找用户信息失败,Err:" + err.Error()
+					return
+				}
+				for _, userInfo := range userList {
+					userNameList = append(userNameList, userInfo.RealName)
+				}
+				userNameStr = strings.Join(userNameList, ",")
+			}
+			msg := `指标被其他用户使用,无法设置共享`
+			if userNameStr != "" {
+				msg = fmt.Sprintf(`指标被用户%s使用,无法设置共享`, userNameStr)
+			}
+			if tips != "" {
+				msg = fmt.Sprintf(`%s,用户为:%s,无法设置共享`, tips, userNameStr)
+			}
+			br.Msg = msg
+			br.ErrMsg = "指标被其他用户共享,无法设置共享,EdbInfoId:" + strconv.Itoa(req.EdbInfoId)
+			br.IsSendEmail = false
+			return
+		}
+	}
+
+	obj := data_manage.EdbInfoShare{}
+	err = obj.SaveEdbInfoShare([]int{req.EdbInfoId}, req.UserIdList, req.ShareType)
+	if err != nil {
+		br.Msg = `保存失败`
+		br.ErrMsg = `保存失败:` + err.Error()
+		return
+	}
+
+	// 更新es
+	data.AddOrEditEdbInfoToEs(req.EdbInfoId)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// Tree
+// @Title 获取共享指标的分类/指标树
+// @Description 获取共享指标的分类/指标树
+// @Success 200 {object} response.EdbShareListResp
+// @router /edb_info/share/tree [get]
+func (c *EdbInfoShareController) Tree() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	resp := response.EdbShareListResp{}
+
+	// 我共享的
+	{
+		sendList, err := data.GetAllShareEdbListByFromUserId(sysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取我共享的指标列表信息失败,Err:" + err.Error()
+			return
+		}
+		nodeList, err := data.GetEdbClassifyItemListByShareEdbInfoQueryList(sendList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取我共享出去的指标列表分类结构信息失败,Err:" + err.Error()
+			return
+		}
+		resp.Send = nodeList
+	}
+
+	// 我收到的
+	{
+		sendList, err := data.GetAllShareEdbListByReceivedUserId(sysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取我共享的指标列表信息失败,Err:" + err.Error()
+			return
+		}
+		nodeList, err := data.GetEdbClassifyItemListByShareEdbInfoQueryList(sendList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取我收到共享的指标列表分类结构信息失败,Err:" + err.Error()
+			return
+		}
+
+		receivedMap := make(map[int]int)
+		var receivedList data_manage.UserShareEdbClassifyItemList
+		for _, v := range nodeList {
+			index, ok := receivedMap[v.SysUserId]
+			if !ok {
+				index = len(receivedMap)
+				item := &data_manage.UserShareEdbClassifyItem{
+					UserId:           v.SysUserId,
+					UserName:         v.SysUserRealName,
+					EdbInfoId:        0,
+					ClassifyId:       v.SysUserId,
+					ClassifyName:     v.SysUserRealName,
+					ClassifyType:     0,
+					ClassifyNameEn:   "",
+					ParentId:         0,
+					RootId:           0,
+					Level:            0,
+					Sort:             0,
+					UniqueCode:       utils.MD5(fmt.Sprint(v.SysUserId, "_", v.SysUserRealName)),
+					Source:           0,
+					SourceName:       "",
+					SysUserId:        v.SysUserId,
+					SysUserRealName:  v.SysUserRealName,
+					StartDate:        "",
+					EdbCode:          "",
+					EdbType:          0,
+					Children:         []*data_manage.UserShareEdbClassifyItem{},
+					Button:           data_manage.EdbClassifyItemsButton{},
+					IsJoinPermission: 0,
+					HaveOperaAuth:    true,
+					ClassifyIdPath:   "",
+				}
+				receivedList = append(receivedList, item)
+			}
+			receivedList[index].Children = append(receivedList[index].Children, v)
+			receivedMap[v.SysUserId] = index
+		}
+
+		resp.Received = receivedList
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// List
+// @Title 指标列表接口
+// @Description 指标列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyId   query   int  true       "分类id"
+// @Param   FilterSource   query   int  false       "共享指标的列表数据来源,0:我共享的;1:别人共享给我的"
+// @Success 200 {object} response.EdbInfoChartListResp
+// @router /edb_info/share/list [get]
+func (c *EdbInfoShareController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	// 分页
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+	filterSource, _ := c.GetInt("FilterSource")
+
+	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{}
+	condition += ` AND edb_info_type = ? `
+	pars = append(pars, 0)
+
+	// 指标类型
+	edbType, _ := c.GetInt("EdbType", 0)
+	if edbType > 0 {
+		condition += ` AND edb_type = ? `
+		pars = append(pars, edbType)
+	}
+
+	// 用户筛选
+	userId, _ := c.GetInt("UserId")
+	if userId > 0 {
+		condition += ` AND b.sys_user_id = ?  `
+		pars = append(pars, userId)
+	}
+
+	// 分类筛选
+	classifyId, _ := c.GetInt("ClassifyId")
+	if classifyId > 0 {
+		childClassify, e, _ := data.GetChildClassifyByClassifyId(classifyId)
+		if e != nil && !utils.IsErrNoRow(e) {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
+			return
+		}
+		var classifyIds []int
+		for _, v := range childClassify {
+			classifyIds = append(classifyIds, v.ClassifyId)
+		}
+		condition += fmt.Sprintf(` AND b.classify_id IN (%s) `, utils.GetOrmInReplace(len(classifyIds)))
+		pars = append(pars, classifyIds)
+	}
+
+	switch filterSource {
+	case 1: // 别人共享给我的
+		condition += ` AND a.sys_user_id = ? AND b.sys_user_id != ?  `
+		pars = append(pars, sysUser.AdminId, sysUser.AdminId)
+	default: // 我共享的
+		condition += ` AND b.sys_user_id = ? `
+		pars = append(pars, sysUser.AdminId)
+	}
+
+	obj := data_manage.EdbInfoShare{}
+
+	dataCount, respList, err := obj.GetShareEdbInfoListPageList(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取分享指标列表失败, %v", err)
+		return
+	}
+
+	editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(c.SysUser.AdminId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+		return
+	}
+	for _, edbInfo := range respList {
+		edbInfo.HaveOperaAuth = true
+		edbInfo.Button = data.GetEdbOpButton(c.SysUser, edbInfo.SysUserId, edbInfo.EdbInfoId, edbInfo.EdbType, edbInfo.EdbInfoType, edbInfo.HaveOperaAuth, editShareEdbInfoIdMap)
+	}
+
+	page = paging.GetPaging(currentIndex, pageSize, int(dataCount))
+
+	resp := response.EdbInfoChartListResp{
+		Paging: page,
+		List:   respList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ListByEs
+// @Title 指标筛选接口
+// @Description 指标筛选接口
+// @Success 200 {object} data_manage.EdbInfoList
+// @Param	request	body request.SearchEdbInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfoFilterDataResp
+// @router /edb_info/share/list/es [post]
+func (c *EdbInfoShareController) ListByEs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.SearchEdbInfoShareReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	pageSize := req.PageSize
+	currentIndex := req.CurrentIndex
+
+	var total int64
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	keyword := req.Keyword
+	keyword = strings.TrimSpace(keyword) //移除字符串首尾空格
+
+	//指标来源
+	sourceList := req.SourceList
+
+	edbInfoType := 0                             // 普通指标
+	edbTypeList := []int{utils.EdbTypeCalculate} // 普通指标中的计算指标
+
+	// 指标分享状态:1-未共享;2-已共享。可多选,多选用英文,隔开;默认是未全部
+	edbShareList := req.EdbShareList
+	if len(edbShareList) <= 0 {
+		edbShareList = []int{}
+	}
+	edbShare := 0 // 0:全部,1:未共享,2:已共享
+	lenEdbShareList := len(edbShareList)
+	if len(edbShareList) > 0 {
+		if lenEdbShareList > 1 {
+			edbShare = 0
+		} else {
+			edbShare = edbShareList[0]
+		}
+	}
+
+	// 直指标所属分类id
+	edbClassifyIdList := req.ClassifyIdList
+
+	edbAuth := 1 // 选择范围是:只有我的指标
+
+	var edbInfoList []*data_manage.EdbInfoList
+
+	sortMap := make(map[string]string)
+	// 如果没有搜索关键词,则默认根据指标编码倒序排序
+	if keyword == `` {
+		sortMap["EdbInfoId"] = `desc`
+	}
+	total, edbInfoList, err = elastic.SearchEdbInfoDataByShared(keyword, startSize, pageSize, edbShare, sourceList, edbClassifyIdList, edbTypeList, edbInfoType, edbAuth, c.SysUser.AdminId, sortMap)
+	if err != nil {
+		edbInfoList = make([]*data_manage.EdbInfoList, 0)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+
+	edbInfoListLen := len(edbInfoList)
+
+	// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+	if len(edbInfoList) > 0 {
+		sysUserIdList := make([]int, 0)
+		edbInfoIdList := make([]int, 0)
+		for _, v := range edbInfoList {
+			v.ConvertToResp()
+			v.EdbNameAlias = v.EdbName
+			v.HaveOperaAuth = true
+			edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+
+			if v.SharedUserIdList != nil && len(v.SharedUserIdList) > 0 {
+				sysUserIdList = append(sysUserIdList, v.SharedUserIdList...)
+			}
+		}
+
+		// 获取指标数据
+		tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+			return
+		}
+		edbInfoMap := make(map[int]*data_manage.EdbInfo)
+		for _, v := range tmpEdbList {
+			edbInfoMap[v.EdbInfoId] = v
+		}
+
+		// 获取用户数据
+		sysUserMap := make(map[int]string)
+		if len(sysUserIdList) > 0 {
+			sysUserList, err := system.GetAdminListByIdList(sysUserIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取分享用户列表失败,Err:" + err.Error()
+				return
+			}
+
+			for _, v := range sysUserList {
+				sysUserMap[v.AdminId] = v.RealName
+			}
+		}
+
+		for _, v := range edbInfoList {
+			tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]
+			if !ok {
+				continue
+			}
+			v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
+
+			// 分享人
+			shareUserName := ``
+			shareUserNameList := make([]string, 0)
+			shareUserNameMap := make(map[int]bool)
+			for _, userId := range v.SharedUserIdList {
+				userName, ok := sysUserMap[userId]
+				if !ok {
+					continue
+				}
+				if _, ok = shareUserNameMap[userId]; ok {
+					continue
+				}
+				shareUserNameMap[userId] = true
+				shareUserNameList = append(shareUserNameList, userName)
+			}
+
+			if len(shareUserNameList) > 0 {
+				shareUserName = strings.Join(shareUserNameList, `,`)
+			}
+			v.SharedUserName = shareUserName
+
+		}
+	}
+
+	for i := 0; i < edbInfoListLen; i++ {
+		for j := 0; j < edbInfoListLen; j++ {
+			if (edbInfoList[i].EdbNameAlias == edbInfoList[j].EdbNameAlias) &&
+				(edbInfoList[i].EdbInfoId != edbInfoList[j].EdbInfoId) &&
+				!(strings.Contains(edbInfoList[i].EdbName, edbInfoList[i].SourceName)) {
+				edbInfoList[i].EdbName = edbInfoList[i].EdbName + "(" + edbInfoList[i].SourceName + ")"
+			}
+		}
+	}
+
+	resp := data_manage.EdbInfoFilterDataResp{
+		Paging: page,
+		List:   edbInfoList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// BatchSave
+// @Title 批量指标设置共享
+// @Description 批量指标设置共享
+// @Param	request	body request.SetEdbSharePermissionReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfo
+// @router /edb_info/share/batch_save [post]
+func (c *EdbInfoShareController) BatchSave() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.SetEdbSharePermissionReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	// 选中的指标id列表
+	selectEdbInfoIdList := make([]int, 0)
+
+	// 选择所有指标,所以需要通过es获取数据
+	if req.IsSelectAll {
+		allEsEdbInfoIdList, err := getAllEdbInfoIdListByShared(req, c.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "设置失败!"
+			br.ErrMsg = "设置失败,Err:" + err.Error()
+			return
+		}
+
+		if len(req.NoEdbIdList) <= 0 {
+			selectEdbInfoIdList = allEsEdbInfoIdList
+		} else {
+			noEdbIdMap := make(map[int]bool)
+			for _, v := range req.NoEdbIdList {
+				noEdbIdMap[v] = true
+			}
+
+			for _, v := range allEsEdbInfoIdList {
+				if _, ok := noEdbIdMap[v]; !ok {
+					// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
+					selectEdbInfoIdList = append(selectEdbInfoIdList, v)
+				}
+			}
+		}
+	} else {
+		selectEdbInfoIdList = req.EdbIdList
+	}
+
+	num := len(selectEdbInfoIdList)
+	if num <= 0 {
+		br.Msg = `请选择指标`
+		br.IsSendEmail = false
+		return
+	}
+	if num > 30 {
+		br.Msg = `指标数量不能超过30个`
+		br.IsSendEmail = false
+		return
+	}
+
+	edbInfoList, err := data_manage.GetEdbInfoListByEdbInfoId(selectEdbInfoIdList)
+	if err != nil {
+		br.Msg = "设置失败!"
+		br.ErrMsg = "设置失败,Err:" + err.Error()
+		return
+	}
+
+	{
+		checkBaseEdbInfoIdList := make([]int, 0)
+		checkCalculateEdbInfoIdList := make([]int, 0)
+
+		for _, edbItem := range edbInfoList {
+			// 设置公开的可以忽略
+			if edbItem.PublicStatus == utils.DataPublicSuccess {
+				continue
+			}
+
+			if edbItem.EdbInfoType == utils.EDB_INFO_TYPE {
+				checkBaseEdbInfoIdList = append(checkBaseEdbInfoIdList, edbItem.EdbInfoId)
+			} else if edbItem.EdbInfoType == utils.PREDICT_EDB_INFO_TYPE {
+				checkCalculateEdbInfoIdList = append(checkCalculateEdbInfoIdList, edbItem.EdbInfoId)
+			}
+		}
+
+		checkUserIdList := []int{sysUser.AdminId}
+		if len(req.UserIdList) > 0 {
+			checkUserIdList = append(checkUserIdList, req.UserIdList...)
+		}
+
+		// 普通指标
+		{
+			noReferenced, otherUserIdList, err, tips := data.CheckEdbReferencedByOthers(utils.EDB_INFO_TYPE, checkBaseEdbInfoIdList, checkUserIdList)
+			if err != nil {
+				br.Msg = "保存失败"
+				if tips != "" {
+					br.Msg = tips
+				}
+				br.ErrMsg = "设置指标共享失败,查找指标的关联用户失败,Err:" + err.Error()
+				return
+			}
+
+			if !noReferenced {
+				userNameStr := ``
+				if len(otherUserIdList) > 0 {
+					userNameList := make([]string, 0)
+					userList, err := system.GetAdminListByIdList(otherUserIdList)
+					if err != nil {
+						br.Msg = "保存失败"
+						if tips != "" {
+							br.Msg = tips
+						}
+						br.ErrMsg = "设置指标共享失败,查找用户信息失败,Err:" + err.Error()
+						return
+					}
+					for _, userInfo := range userList {
+						userNameList = append(userNameList, userInfo.RealName)
+					}
+					userNameStr = strings.Join(userNameList, ",")
+				}
+				msg := `指标被其他用户使用,无法设置共享`
+				if userNameStr != "" {
+					msg = fmt.Sprintf(`指标被用户%s使用,无法设置共享`, userNameStr)
+				}
+				if tips != "" {
+					msg = fmt.Sprintf(`%s,用户为:%s,无法设置共享`, tips, userNameStr)
+				}
+				br.Msg = msg
+				br.ErrMsg = "指标被其他用户共享,无法设置共享"
+				br.IsSendEmail = false
+				return
+			}
+		}
+
+		// 预测指标
+		{
+			noReferenced, otherUserIdList, err, tips := data.CheckEdbReferencedByOthers(utils.PREDICT_EDB_INFO_TYPE, checkCalculateEdbInfoIdList, checkUserIdList)
+			if err != nil {
+				br.Msg = "保存失败"
+				if tips != "" {
+					br.Msg = tips
+				}
+				br.ErrMsg = "设置指标共享失败,查找指标的关联用户失败,Err:" + err.Error()
+				return
+			}
+
+			if !noReferenced {
+				userNameStr := ``
+				if len(otherUserIdList) > 0 {
+					userNameList := make([]string, 0)
+					userList, err := system.GetAdminListByIdList(otherUserIdList)
+					if err != nil {
+						br.Msg = "保存失败"
+						if tips != "" {
+							br.Msg = tips
+						}
+						br.ErrMsg = "设置指标共享失败,查找用户信息失败,Err:" + err.Error()
+						return
+					}
+					for _, userInfo := range userList {
+						userNameList = append(userNameList, userInfo.RealName)
+					}
+					userNameStr = strings.Join(userNameList, ",")
+				}
+				msg := `指标被其他用户使用,无法设置共享`
+				if userNameStr != "" {
+					msg = fmt.Sprintf(`指标被用户%s使用,无法设置共享`, userNameStr)
+				}
+				if tips != "" {
+					msg = fmt.Sprintf(`%s,用户为:%s,无法设置共享`, tips, userNameStr)
+				}
+				br.Msg = msg
+				br.ErrMsg = "指标被其他用户共享,无法设置共享"
+				br.IsSendEmail = false
+				return
+			}
+		}
+	}
+
+	// 设置
+	obj := data_manage.EdbInfoShare{}
+	err = obj.SaveEdbInfoShare(selectEdbInfoIdList, req.UserIdList, req.ShareType)
+	if err != nil {
+		br.Msg = `保存失败`
+		br.ErrMsg = `保存失败:` + err.Error()
+		return
+	}
+
+	// 更新es
+	for _, edbInfoId := range selectEdbInfoIdList {
+		data.AddOrEditEdbInfoToEs(edbInfoId)
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// getAllEdbInfoIdListByShared
+// @Description: 获取所有的指标id列表
+// @author: Roc
+// @datetime 2024-12-04 15:43:14
+// @param req request.SetEdbChartPermissionReq
+// @param userId int
+// @return edbInfoIdList []int
+// @return err error
+func getAllEdbInfoIdListByShared(req request.SetEdbSharePermissionReq, userId int) (edbInfoIdList []int, err error) {
+	keyword := req.Keyword
+	keyword = strings.TrimSpace(keyword) //移除字符串首尾空格
+
+	//指标来源
+	sourceList := req.SourceList
+
+	edbInfoType := 0                             // 普通指标
+	edbTypeList := []int{utils.EdbTypeCalculate} // 普通指标中的计算指标
+
+	// 指标分享状态:1-未共享;2-已共享。可多选,多选用英文,隔开;默认是未共享
+	edbShareList := req.EdbShareList
+	if len(edbShareList) <= 0 {
+		edbShareList = []int{1}
+	}
+	edbShare := 1 // 0:全部,1:未共享,2:已共享
+	lenEdbShareList := len(edbShareList)
+	if len(edbShareList) > 0 {
+		if lenEdbShareList > 1 {
+			edbShare = 0
+		} else {
+			edbShare = edbShareList[0]
+		}
+	}
+
+	// 指标分享状态:1-未共享;2-已共享。可多选,多选用英文,隔开;默认是未共享
+	edbClassifyIdList := req.ClassifyIdList
+
+	edbAuth := 1 // 选择范围是:只有我的指标
+
+	sortMap := make(map[string]string)
+	// 如果没有搜索关键词,则默认根据指标编码倒序排序
+	if keyword == `` {
+		sortMap["EdbInfoId"] = `desc`
+	}
+	_, edbInfoList, err := getAllEdbInfoDataByShared(keyword, 1, edbShare, sourceList, edbClassifyIdList, edbTypeList, edbInfoType, edbAuth, userId, sortMap)
+	if err != nil {
+		return
+	}
+
+	// 返回指标id列表
+	for _, v := range edbInfoList {
+		edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+	}
+
+	return
+}
+
+// getAllEdbInfoDataByShared
+// @Description: 获取所有的指标列表(设置共享的时候)
+// @author: Roc
+// @datetime 2024-12-04 15:27:53
+// @param keyword string
+// @param currPage int
+// @param edbShare int
+// @param sourceList []int
+// @param classifyIdList []int
+// @param edbTypeList []int
+// @param edbInfoType int
+// @param edbAuth int
+// @param sysUserId int
+// @param sortMap map[string]string
+// @return total int64
+// @return list []*data_manage.EdbInfoList
+// @return err error
+func getAllEdbInfoDataByShared(keyword string, currPage, edbShare int, sourceList, classifyIdList, edbTypeList []int, edbInfoType, edbAuth, sysUserId int, sortMap map[string]string) (total int64, list []*data_manage.EdbInfoList, err error) {
+	// 每页获取数据的数量
+	pageSize := 5000
+	var startSize int
+	if currPage <= 0 {
+		currPage = 1
+	}
+	startSize = paging.StartIndex(currPage, pageSize)
+
+	total, list, err = elastic.SearchEdbInfoDataByShared(keyword, startSize, pageSize, edbShare, sourceList, classifyIdList, edbTypeList, edbInfoType, edbAuth, sysUserId, sortMap)
+	if err != nil {
+		return
+	}
+
+	page := paging.GetPaging(currPage, pageSize, int(total))
+	if !page.IsEnd {
+		_, nextList, tmpErr := getAllEdbInfoDataByShared(keyword, page.NextIndex, edbShare, sourceList, classifyIdList, edbTypeList, edbInfoType, edbAuth, sysUserId, sortMap)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		list = append(list, nextList...)
+	}
+
+	return
+}

+ 2 - 2
controllers/data_manage/excel/balance_table.go

@@ -878,7 +878,7 @@ func (c *ExcelInfoController) DeleteBalanceChart() {
 		}
 		//删除ES
 		{
-			go data.EsDeleteChartInfo(req.ChartInfoId)
+			go data.DeleteChartInfoToEs(req.ChartInfoId)
 			// 删除MY ETA 图表 es数据
 			//go data.EsDeleteMyChartInfoByChartInfoId(req.ChartInfoId)
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)
@@ -1685,7 +1685,7 @@ func (this *ExcelInfoController) BalanceChartInfoBaseEdit() {
 		return
 	}
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 

+ 0 - 13
controllers/data_manage/excel/custom_analysis_edb.go

@@ -461,16 +461,3 @@ func (c *CustomAnalysisController) EdbRefresh() {
 	br.Success = true
 	br.Msg = "刷新成功"
 }
-
-//func init() {
-//	excelInfo, err := excelModel.GetExcelInfoById(160)
-//	if err != nil {
-//		fmt.Println("查找excel失败:", err)
-//		return
-//	}
-//	_, err, _ = excel.GenerateExcelCustomAnalysisExcel(excelInfo)
-//	if err != nil {
-//		fmt.Println("生成excel失败:", err)
-//		return
-//	}
-//}

文件差异内容过多而无法显示
+ 0 - 58
controllers/data_manage/excel/excel_info.go


+ 5 - 27
controllers/data_manage/future_good/future_good_chart_classify.go

@@ -8,7 +8,6 @@ import (
 	"eta_gn/eta_api/models/system"
 	"eta_gn/eta_api/services/data"
 	"eta_gn/eta_api/utils"
-	"fmt"
 	"time"
 )
 
@@ -20,7 +19,6 @@ type FutureGoodChartClassifyController struct {
 // ChartClassifyList
 // @Title 商品价格图表分类列表
 // @Description 商品价格图表分类列表接口
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Success 200 {object} data_manage.ChartClassifyListResp
 // @router /chart_classify/list [get]
 func (this *FutureGoodChartClassifyController) ChartClassifyList() {
@@ -46,34 +44,14 @@ func (this *FutureGoodChartClassifyController) ChartClassifyList() {
 		}
 	}
 
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		errMsg, err := getChartClassifyListForMe(*this.SysUser, resp)
-		if err != nil {
-			br.Msg = errMsg
-			br.ErrMsg = err.Error()
-			return
-		}
-		// 移除没有权限的图表
-		allNodes := data.HandleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap, this.SysUser.AdminId)
-		resp.AllNodes = allNodes
-
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
-		fmt.Println("source my classify")
-		return
-	}
-
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
-	allChartInfo, err := data_manage.GetChartInfoAll([]int{utils.CHART_SOURCE_FUTURE_GOOD, utils.CHART_SOURCE_FUTURE_GOOD_PROFIT})
+	allChartInfo, err := data_manage.GetChartInfoAll([]int{utils.CHART_SOURCE_FUTURE_GOOD, utils.CHART_SOURCE_FUTURE_GOOD_PROFIT}, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -107,7 +85,7 @@ func (this *FutureGoodChartClassifyController) ChartClassifyList() {
 
 // getChartClassifyListForMe 获取我创建的图表
 func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD, adminInfo.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
@@ -149,7 +127,7 @@ func (this *FutureGoodChartClassifyController) ChartClassifyItems() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -494,7 +472,7 @@ func (this *FutureGoodChartClassifyController) DeleteChartClassify() {
 		}
 		//删除ES
 		{
-			go data.EsDeleteChartInfo(req.ChartInfoId)
+			go data.DeleteChartInfoToEs(req.ChartInfoId)
 			// 删除MY ETA 图表 es数据
 			//go data.EsDeleteMyChartInfoByChartInfoId(req.ChartInfoId)
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)

+ 9 - 9
controllers/data_manage/future_good/future_good_chart_info.go

@@ -265,7 +265,7 @@ func (this *FutureGoodChartInfoController) ChartInfoSave() {
 	}
 
 	//修改es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -552,7 +552,7 @@ func (this *FutureGoodChartInfoController) ChartInfoAdd() {
 	// 添加指标引用记录
 	_ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartInfo)
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartInfoId)
+	go data.AddOrEditChartInfoToEs(chartInfoId)
 
 	//新增操作日志
 	{
@@ -763,7 +763,7 @@ func (this *FutureGoodChartInfoController) ChartInfoEdit() {
 	_ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartItem)
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -959,7 +959,7 @@ func (this *FutureGoodChartInfoController) ChartEnInfoEdit() {
 		return
 	}
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -1171,7 +1171,7 @@ func (this *FutureGoodChartInfoController) ChartInfoMove() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(req.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(req.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(req.ChartInfoId)
 
@@ -2473,7 +2473,7 @@ func (this *FutureGoodChartInfoController) ChartInfoImageSet() {
 		}
 
 		//修改es数据
-		go data.EsAddOrEditChartInfo(req.ChartInfoId)
+		go data.AddOrEditChartInfoToEs(req.ChartInfoId)
 		//修改my eta es数据
 		go data.EsAddOrEditMyChartInfoByChartInfoId(req.ChartInfoId)
 	}
@@ -2726,7 +2726,7 @@ func (this *FutureGoodChartInfoController) CopyChartInfo() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartInfo.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
 
@@ -3419,7 +3419,7 @@ func (this *FutureGoodChartInfoController) BaseInfoEdit() {
 		return
 	}
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -3500,7 +3500,7 @@ func (this *FutureGoodChartInfoController) ChartInfoImgSetBySvg() {
 		}
 
 		//修改es数据
-		go data.EsAddOrEditChartInfo(chartInfoId)
+		go data.AddOrEditChartInfoToEs(chartInfoId)
 		//修改my eta es数据
 		go data.EsAddOrEditMyChartInfoByChartInfoId(chartInfoId)
 	}

+ 0 - 404
controllers/data_manage/future_good/future_good_edb_info.go

@@ -334,407 +334,3 @@ func (this *FutureGoodEdbInfoController) FutureGoodEdbExchangeList() {
 	br.Msg = "获取成功"
 	br.Data = list
 }
-
-//func init() {
-//	var condition string
-//	var pars []interface{}
-//
-//	condition += ` AND parent_id = ? `
-//	pars = append(pars, 0)
-//
-//	list, err := future_good2.GetFutureGoodEdbInfoList(condition, pars)
-//	if err != nil && !utils.IsErrNoRow(err) {
-//		fmt.Println("err:", err)
-//		return
-//	}
-//
-//	monthMap := map[string]string{
-//		`(1月`:  "(Jan",
-//		`(2月`:  "(Feb",
-//		`(3月`:  "(Mar",
-//		`(4月`:  "(Apr",
-//		`(5月`:  "(May",
-//		`(6月`:  "(Jun",
-//		`(7月`:  "(Jul",
-//		`(8月`:  "(Aug",
-//		`(9月`:  "(Sep",
-//		`(10月`: "(Oct",
-//		`(11月`: "(Nov",
-//		`(12月`: "(Dec",
-//	}
-//	for _, v := range list {
-//		fmt.Println(v)
-//		var tmpCondition string
-//		var tmpPars []interface{}
-//
-//		tmpCondition += ` AND parent_id = ? `
-//		tmpPars = append(tmpPars, v.FutureGoodEdbInfoId)
-//		tmpList, tmpErr := future_good2.GetFutureGoodEdbInfoList(tmpCondition, tmpPars)
-//		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
-//			fmt.Println("err:", tmpErr)
-//			return
-//		}
-//
-//		for _, child := range tmpList {
-//			child.FutureGoodEdbNameEn = strings.Replace(child.FutureGoodEdbNameEn, v.FutureGoodEdbName, v.FutureGoodEdbNameEn, -1)
-//
-//			for k, month := range monthMap {
-//				if strings.Contains(child.FutureGoodEdbNameEn, k) {
-//					child.FutureGoodEdbNameEn = strings.Replace(child.FutureGoodEdbNameEn, k, month, -1)
-//					fmt.Println(child.FutureGoodEdbNameEn)
-//					//os.Exit(-1)
-//					child.Update([]string{"FutureGoodEdbNameEn"})
-//				}
-//			}
-//		}
-//	}
-//
-//	fmt.Println("end")
-//}
-
-//func init() {
-//
-//	edbCodeMap := map[string]string{
-//		//"沪深300指数期货": "IF",
-//		//"上证50指数期货": "IH",
-//		//"中证500指数期货": "IC",
-//		//"中证1000指数期货": "IM",
-//		//"2年期国债期货": "TS",
-//		//"5年期国债期货": "TF",
-//		"10年期国债期货": "T",
-//	}
-//	//T03
-//	suffix := "M.CFE"
-//	monthList := []string{"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"}
-//	monthStrList := []string{"(1月)", "(2月)", "(3月)", "(4月)", "(5月)", "(6月)", "(7月)", "(8月)", "(9月)", "(10月)", "(11月)", "(12月)"}
-//
-//	for k, v := range edbCodeMap {
-//		code := v + "CFE"
-//		tmpFutureGoodEdbInfo := &future_good2.FutureGoodEdbInfo{
-//			//FutureGoodEdbInfoId: 0,
-//			FutureGoodEdbCode:   code,
-//			FutureGoodEdbName:   k,
-//			FutureGoodEdbNameEn: k,
-//			ParentId:            0,
-//			Exchange:            "中金所",
-//			Month:               0,
-//			StartDate:           "",
-//			EndDate:             "",
-//			MinValue:            0,
-//			MaxValue:            0,
-//			LatestValue:         0,
-//			//LatestDate:          time.Time{},
-//			ServerUrl:  "",
-//			CreateTime: time.Now(),
-//			ModifyTime: time.Now(),
-//		}
-//		err := future_good2.AddFutureGoodEdbInfo(tmpFutureGoodEdbInfo)
-//		if err != nil {
-//			fmt.Println("添加指标:", k, "失败,err:", err)
-//			continue
-//		}
-//
-//		for index, month := range monthList {
-//			code2 := v + month + suffix
-//			name := tmpFutureGoodEdbInfo.FutureGoodEdbName + monthStrList[index]
-//			tmpFutureGoodEdbInfo2 := &future_good2.FutureGoodEdbInfo{
-//				//FutureGoodEdbInfoId: 0,
-//				FutureGoodEdbCode:   code2,
-//				FutureGoodEdbName:   name,
-//				FutureGoodEdbNameEn: name,
-//				ParentId:            tmpFutureGoodEdbInfo.FutureGoodEdbInfoId,
-//				Exchange:            "中金所",
-//				Month:               0,
-//				StartDate:           "",
-//				EndDate:             "",
-//				MinValue:            0,
-//				MaxValue:            0,
-//				LatestValue:         0,
-//				//LatestDate:          time.Time{},
-//				ServerUrl:  "",
-//				CreateTime: time.Now(),
-//				ModifyTime: time.Now(),
-//			}
-//			err = future_good2.AddFutureGoodEdbInfo(tmpFutureGoodEdbInfo2)
-//			if err != nil {
-//				fmt.Println("添加子指标:", name, "失败,err:", err)
-//				continue
-//			}
-//		}
-//	}
-//
-//	fmt.Println("end")
-//}
-
-//func init() {
-//	var condition string
-//	var pars []interface{}
-//
-//	condition += ` AND parent_id > ? AND start_date= ? `
-//	pars = append(pars, 0, "0000-00-00")
-//
-//	list, err := future_good2.GetFutureGoodEdbInfoList(condition, pars)
-//	if err != nil && !utils.IsErrNoRow(err) {
-//		fmt.Println("err:", err)
-//		return
-//	}
-//
-//	for _, v := range list {
-//		fmt.Println(v)
-//		resp, err := future_good.AddEdbData(v.FutureGoodEdbCode)
-//		if err != nil {
-//			fmt.Println(v.FutureGoodEdbName, "添加 异常 ,err:", err)
-//			continue
-//		}
-//		if resp.Ret != 200 {
-//			fmt.Println(v.FutureGoodEdbName, "添加 失败 ,msg:", resp.Msg, ";errMsg:", resp.ErrMsg)
-//		}
-//	}
-//
-//	fmt.Println("end")
-//}
-
-//func init() {
-//	var condition string
-//	var pars []interface{}
-//
-//	condition += ` AND parent_id = ? AND start_date= ? `
-//	pars = append(pars, 0, "0000-00-00")
-//
-//	list, err := future_good2.GetFutureGoodEdbInfoList(condition, pars)
-//	if err != nil && !utils.IsErrNoRow(err) {
-//		fmt.Println("err:", err)
-//		return
-//	}
-//
-//	for _, v := range list {
-//		fmt.Println(v)
-//		//v.FutureGoodEdbCode = strings.Replace(v.FutureGoodEdbCode, ".", "ZL.", -1)
-//		//v.Update([]string{"FutureGoodEdbCode"})
-//		resp, err := future_good.AddEdbData(v.FutureGoodEdbCode)
-//		if err != nil {
-//			fmt.Println(v.FutureGoodEdbName, "添加 异常 ,err:", err)
-//			continue
-//		}
-//		if resp.Ret != 200 {
-//			fmt.Println(v.FutureGoodEdbName, "添加 失败 ,msg:", resp.Msg, ";errMsg:", resp.ErrMsg)
-//		}
-//	}
-//
-//	fmt.Println("end")
-//}
-
-// 添加海外交易所
-//func init() {
-//	exchangeName := `新加坡证券(SGX)`
-//	suffix := ".SGX"
-//	type TmpStruct struct {
-//		Name  string
-//		Code  string
-//		Year  int
-//		Month int
-//	}
-//	str := `TSI铁矿石指数	FEF	SGX	2612`
-//	list := make([]TmpStruct, 0)
-//
-//	strList := strings.Split(str, `
-//`)
-//	//fmt.Println(strList)
-//	for _, v := range strList {
-//		v = strings.TrimPrefix(v, "\t")
-//		tmp := strings.Split(v, `	`)
-//		fmt.Println(tmp)
-//
-//		year, err := strconv.Atoi(tmp[3][0:2])
-//		if err != nil {
-//			fmt.Println(err)
-//			return
-//		}
-//		//fmt.Println(year)
-//		month, err := strconv.Atoi(tmp[3][2:4])
-//		if err != nil {
-//			fmt.Println(err)
-//			return
-//		}
-//		//fmt.Println(month)
-//
-//		tmpStruct := TmpStruct{
-//			Name:  tmp[0],
-//			Code:  tmp[1],
-//			Year:  year,
-//			Month: month,
-//		}
-//		list = append(list, tmpStruct)
-//	}
-//
-//	//T03
-//	//suffix := ".CMX"
-//	//1、@CL0W.NMX[NYMEX美原油电子盘主力(持仓量)合约]
-//	//2、@CL23J.NMX[NYMEX美原油电子盘2304]
-//	//yearList := []int{2023, 2024, 2025, 2026, 2027, 2028}
-//	monthList := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
-//	startMonth := 3
-//	//endMonth := 5
-//
-//	monthCodeStrList := []string{"F", "G", "H", "J", "K", "M", "N", "Q", "U", "V", "X", "Z"}
-//	//monthStrList := []string{"(1月)", "(2月)", "(3月)", "(4月)", "(5月)", "(6月)", "(7月)", "(8月)", "(9月)", "(10月)", "(11月)", "(12月)"}
-//
-//	for k, v := range list {
-//		yearList := make([]int, 0)
-//		for i := 23; i <= v.Year; i++ {
-//			yearList = append(yearList, i+2000)
-//		}
-//		//fmt.Println(yearList)
-//		//return
-//		endMonth := v.Month
-//
-//		code := v.Code + `0W` + suffix
-//		tmpFutureGoodEdbInfo := &future_good2.FutureGoodEdbInfo{
-//			//FutureGoodEdbInfoId: 0,
-//			FutureGoodEdbCode:   code,
-//			FutureGoodEdbName:   v.Name,
-//			FutureGoodEdbNameEn: v.Name,
-//			ParentId:            0,
-//			RegionType:          `海外`,
-//			Exchange:            exchangeName,
-//			Year:                0,
-//			Month:               0,
-//			StartDate:           "",
-//			EndDate:             "",
-//			MinValue:            0,
-//			MaxValue:            0,
-//			LatestValue:         0,
-//			//LatestDate:          time.Time{},
-//			ServerUrl:  "",
-//			CreateTime: time.Now(),
-//			ModifyTime: time.Now(),
-//		}
-//		err := future_good2.AddFutureGoodEdbInfo(tmpFutureGoodEdbInfo)
-//		if err != nil {
-//			fmt.Println("添加指标:", k, "失败,err:", err)
-//			continue
-//		}
-//
-//		lastYearIndex := len(yearList) - 1
-//		for yearIndex, year := range yearList {
-//			for index, month := range monthList {
-//				// 如果第一年的开始月份早于约定的开始月份,那么就退出这个循环,进入下一个循环
-//				if yearIndex == 0 && month < startMonth {
-//					continue
-//				}
-//				// 如果最一年的结束月份晚于约定的开始月份,那么就退出这个循环,进入下一个循环
-//				if lastYearIndex == yearIndex && month > endMonth {
-//					break
-//				}
-//				monthStr := strconv.Itoa(month)
-//				if month < 10 {
-//					monthStr = `0` + monthStr
-//				}
-//				yearStr := strconv.Itoa(year - 2000)
-//				yearMonthStr := yearStr + monthStr
-//
-//				code2 := v.Code + yearStr + monthCodeStrList[index] + suffix
-//				name := tmpFutureGoodEdbInfo.FutureGoodEdbName + `(` + yearMonthStr + `)`
-//				tmpFutureGoodEdbInfo2 := &future_good2.FutureGoodEdbInfo{
-//					//FutureGoodEdbInfoId: 0,
-//					FutureGoodEdbCode:   code2,
-//					FutureGoodEdbName:   name,
-//					FutureGoodEdbNameEn: name,
-//					ParentId:            tmpFutureGoodEdbInfo.FutureGoodEdbInfoId,
-//					RegionType:          `海外`,
-//					Exchange:            exchangeName,
-//					Year:                year,
-//					Month:               month,
-//					StartDate:           "",
-//					EndDate:             "",
-//					MinValue:            0,
-//					MaxValue:            0,
-//					LatestValue:         0,
-//					//LatestDate:          time.Time{},
-//					ServerUrl:  "",
-//					CreateTime: time.Now(),
-//					ModifyTime: time.Now(),
-//				}
-//				err = future_good2.AddFutureGoodEdbInfo(tmpFutureGoodEdbInfo2)
-//				if err != nil {
-//					fmt.Println("添加子指标:", name, "失败,err:", err)
-//					continue
-//				}
-//			}
-//		}
-//
-//	}
-//
-//	fmt.Println("end")
-//}
-
-// 刷新海外交易所数据
-//func init() {
-//	var condition string
-//	var pars []interface{}
-//
-//	//condition += ` AND parent_id > ? AND start_date= ? `
-//	condition += ` AND region_type = ? AND start_date= ?  AND exchange = ? `
-//	pars = append(pars, "海外", "0000-00-00", "伦敦金属(LME)")
-//	//condition += ` AND region_type = ? AND start_date= ?  `
-//	//pars = append(pars, "海外", "0000-00-00")
-//
-//	list, err := future_good2.GetFutureGoodEdbInfoList(condition, pars)
-//	if err != nil && !utils.IsErrNoRow(err) {
-//		fmt.Println("err:", err)
-//		return
-//	}
-//
-//	errIdList := make([]string, 0)
-//	for _, v := range list {
-//		fmt.Println(v)
-//		resp, err := future_good.AddEdbData(v.FutureGoodEdbCode)
-//		if err != nil {
-//			fmt.Println(v.FutureGoodEdbName, "添加 异常 ,err:", err)
-//			continue
-//		}
-//		if resp.Ret != 200 {
-//			errIdList = append(errIdList, fmt.Sprint(v.FutureGoodEdbInfoId))
-//			fmt.Println(v.FutureGoodEdbName, "添加 失败 ,msg:", resp.Msg, ";errMsg:", resp.ErrMsg)
-//		}
-//	}
-//
-//	fmt.Println("end")
-//	fmt.Println(strings.Join(errIdList, ","))
-//}
-
-// 刷新海外交易所数据
-//func init() {
-//	var condition string
-//	var pars []interface{}
-//
-//	//condition += ` AND parent_id > ? AND start_date= ? `
-//	condition += ` AND region_type = ? AND parent_id != 0 and future_good_edb_type = 1`
-//	pars = append(pars, "海外")
-//	//condition += ` AND region_type = ? AND start_date= ?  `
-//	//pars = append(pars, "海外", "0000-00-00")
-//
-//	list, err := future_good2.GetFutureGoodEdbInfoList(condition, pars)
-//	if err != nil && !utils.IsErrNoRow(err) {
-//		fmt.Println("err:", err)
-//		return
-//	}
-//	for _, v := range list {
-//		//fmt.Println(v.FutureGoodEdbName)
-//		tmpList := strings.Split(v.FutureGoodEdbName, "(")
-//		//fmt.Println(tmpList)
-//		//fmt.Println(tmpList[1])
-//		year, err := strconv.Atoi(tmpList[1][0:2])
-//		if err != nil {
-//			fmt.Println(err)
-//			return
-//		}
-//		v.Year = year + 2000
-//		err = v.Update([]string{"Year"})
-//		if err != nil {
-//			fmt.Println(err)
-//			return
-//		}
-//	}
-//	fmt.Println("end")
-//}

+ 3 - 3
controllers/data_manage/future_good/future_good_profit_chart_info.go

@@ -335,7 +335,7 @@ func (this *FutureGoodChartInfoController) ProfitChartInfoAdd() {
 	// 添加指标引用记录
 	_ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartInfo)
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartInfo.ChartInfoId)
 
 	//新增操作日志
 	{
@@ -669,7 +669,7 @@ func (this *FutureGoodChartInfoController) ProfitChartInfoEdit() {
 	// 添加指标引用记录
 	_ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartItem)
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -858,7 +858,7 @@ func copyProfitChartInfo(oldChartInfo *data_manage.ChartInfo, chartClassifyId in
 	//保存图表与指标的关系
 	_ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartInfo)
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartInfo.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
 

+ 5 - 25
controllers/data_manage/line_equation/line_chart_classify.go

@@ -19,7 +19,6 @@ type LineEquationChartClassifyController struct {
 // ChartClassifyList
 // @Title 拟合方程图表分类列表
 // @Description 拟合方程图表分类列表接口
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "图表类型,3:拟合方程,4:滚动拟合方程"
 // @Success 200 {object} data_manage.ChartClassifyListResp
 // @router /chart_classify/list [get]
@@ -46,31 +45,16 @@ func (this *LineEquationChartClassifyController) ChartClassifyList() {
 		}
 	}
 
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		errMsg, err := getChartClassifyListForMe(*this.SysUser, resp)
-		if err != nil {
-			br.Msg = errMsg
-			br.ErrMsg = err.Error()
-			return
-		}
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
-		return
-	}
-
 	source := utils.CHART_SOURCE_LINE_EQUATION
 
-	rootList, err := data_manage.GetChartClassifyByParentId(0, source)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, source, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
-	allChartInfo, err := data_manage.GetChartInfoAll([]int{source})
+	allChartInfo, err := data_manage.GetChartInfoAll([]int{source}, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -79,10 +63,6 @@ func (this *LineEquationChartClassifyController) ChartClassifyList() {
 
 	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
 	for _, v := range allChartInfo {
-		if !isShowMe {
-			chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
-			continue
-		}
 		if v.SysUserId != this.SysUser.AdminId {
 			continue
 		}
@@ -112,7 +92,7 @@ func (this *LineEquationChartClassifyController) ChartClassifyList() {
 // getChartClassifyListForMe 获取我创建的图表
 func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
 	// 获取所有的分类
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_EQUATION)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_EQUATION, adminInfo.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
@@ -154,7 +134,7 @@ func (this *LineEquationChartClassifyController) ChartClassifyItems() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_EQUATION)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_EQUATION, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -500,7 +480,7 @@ func (this *LineEquationChartClassifyController) DeleteChartClassify() {
 		}
 		//删除ES
 		{
-			go data.EsDeleteChartInfo(chartInfo.ChartInfoId)
+			go data.DeleteChartInfoToEs(chartInfo.ChartInfoId)
 			// 删除MY ETA 图表 es数据
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)
 		}

+ 6 - 17
controllers/data_manage/line_equation/line_chart_info.go

@@ -505,7 +505,7 @@ func (this *LineEquationChartInfoController) Move() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(req.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(req.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(req.ChartInfoId)
 
@@ -537,7 +537,6 @@ func (this *LineEquationChartInfoController) Move() {
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
 // @Param   ChartClassifyId   query   int  true       "分类id"
 // @Param   Keyword   query   string  true       "搜索关键词"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "图表类型,3:拟合方程,4:滚动拟合方程"
 // @Success 200 {object} data_manage.ChartListResp
 // @router /chart_info/list [get]
@@ -598,12 +597,8 @@ func (this *LineEquationChartInfoController) List() {
 		condition += ` AND  ( chart_name LIKE '%` + keyword + `%' )`
 	}
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		condition += ` AND sys_user_id = ? `
-		pars = append(pars, sysUser.AdminId)
-	}
+	condition += ` AND sys_user_id = ? `
+	pars = append(pars, sysUser.AdminId)
 
 	// 获取当前账号的不可见指标
 	noPermissionChartIdList := make([]int, 0)
@@ -1506,7 +1501,7 @@ func (this *LineEquationChartInfoController) EnInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -1544,7 +1539,6 @@ func (this *LineEquationChartInfoController) EnInfoEdit() {
 // @Title 图表模糊搜索(从es获取)
 // @Description  图表模糊搜索(从es获取)
 // @Param   Keyword   query   string  true       "图表名称"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "来源,3:拟合方程,4:滚动拟合方程,默认0:全部"
 // @Success 200 {object} data_manage.ChartInfo
 // @router /chart_info/search_by_es [get]
@@ -1576,12 +1570,7 @@ func (this *LineEquationChartInfoController) SearchByEs() {
 
 	keyword := this.GetString("Keyword")
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	showSysId := 0
-	if isShowMe {
-		showSysId = sysUser.AdminId
-	}
+	showSysId := sysUser.AdminId
 
 	sourceList := []int{utils.CHART_SOURCE_LINE_EQUATION}
 
@@ -1756,7 +1745,7 @@ func (this *LineEquationChartInfoController) BaseInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 

+ 6 - 17
controllers/data_manage/line_feature/chart_info.go

@@ -1554,7 +1554,7 @@ func (this *LineFeaturesChartInfoController) Move() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(req.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(req.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(req.ChartInfoId)
 
@@ -1586,7 +1586,6 @@ func (this *LineFeaturesChartInfoController) Move() {
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
 // @Param   ChartClassifyId   query   int  true       "分类id"
 // @Param   Keyword   query   string  true       "搜索关键词"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "图表类型,3:统计特征,4:滚动统计特征"
 // @Success 200 {object} data_manage.ChartListResp
 // @router /chart_info/list [get]
@@ -1642,12 +1641,8 @@ func (this *LineFeaturesChartInfoController) List() {
 		condition += ` AND  ( chart_name LIKE '%` + keyword + `%' )`
 	}
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		condition += ` AND sys_user_id = ? `
-		pars = append(pars, sysUser.AdminId)
-	}
+	condition += ` AND sys_user_id = ? `
+	pars = append(pars, sysUser.AdminId)
 
 	// 获取当前账号的不可见指标
 	noPermissionChartIdList := make([]int, 0)
@@ -2638,7 +2633,7 @@ func (this *LineFeaturesChartInfoController) EnInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -2676,7 +2671,6 @@ func (this *LineFeaturesChartInfoController) EnInfoEdit() {
 // @Title 图表模糊搜索(从es获取)
 // @Description  图表模糊搜索(从es获取)
 // @Param   Keyword   query   string  true       "图表名称"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "来源,3:统计特征,4:滚动统计特征,默认0:全部"
 // @Success 200 {object} data_manage.ChartInfo
 // @router /chart_info/search_by_es [get]
@@ -2708,12 +2702,7 @@ func (this *LineFeaturesChartInfoController) SearchByEs() {
 
 	keyword := this.GetString("Keyword")
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	showSysId := 0
-	if isShowMe {
-		showSysId = sysUser.AdminId
-	}
+	showSysId := sysUser.AdminId
 
 	sourceList := []int{utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY}
 
@@ -2890,7 +2879,7 @@ func (this *LineFeaturesChartInfoController) BaseInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 

+ 5 - 25
controllers/data_manage/line_feature/classify.go

@@ -19,7 +19,6 @@ type LineFeaturesChartClassifyController struct {
 // ChartClassifyList
 // @Title 统计特征图表分类列表
 // @Description 统计特征图表分类列表接口
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "图表类型,3:统计特征,4:滚动统计特征"
 // @Success 200 {object} data_manage.ChartClassifyListResp
 // @router /chart_classify/list [get]
@@ -46,31 +45,16 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyList() {
 		}
 	}
 
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		errMsg, err := getChartClassifyListForMe(*this.SysUser, resp)
-		if err != nil {
-			br.Msg = errMsg
-			br.ErrMsg = err.Error()
-			return
-		}
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
-		return
-	}
-
 	source := utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION
 
-	rootList, err := data_manage.GetChartClassifyByParentId(0, source)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, source, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
-	allChartInfo, err := data_manage.GetChartInfoAll([]int{utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY})
+	allChartInfo, err := data_manage.GetChartInfoAll([]int{utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY}, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -79,10 +63,6 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyList() {
 
 	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
 	for _, v := range allChartInfo {
-		if !isShowMe {
-			chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
-			continue
-		}
 		if v.SysUserId != this.SysUser.AdminId {
 			continue
 		}
@@ -112,7 +92,7 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyList() {
 // getChartClassifyListForMe 获取我创建的图表
 func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
 	// 获取所有的分类
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, adminInfo.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
@@ -154,7 +134,7 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyItems() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -500,7 +480,7 @@ func (this *LineFeaturesChartClassifyController) DeleteChartClassify() {
 		}
 		//删除ES
 		{
-			go data.EsDeleteChartInfo(chartInfo.ChartInfoId)
+			go data.DeleteChartInfoToEs(chartInfo.ChartInfoId)
 			// 删除MY ETA 图表 es数据
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)
 		}

+ 0 - 27
controllers/data_manage/manual.go

@@ -627,30 +627,3 @@ func (this *ManualController) AllClassifyList() {
 	br.Msg = "获取成功"
 	br.Data = list
 }
-
-//func init() {
-//	fmt.Println("start")
-//	adminId:=137
-//	setList, err := data_manage.GetManualUserSetClassify(adminId)
-//	if err != nil {
-//		fmt.Println("err:", err)
-//		return
-//	}
-//	listLen := len(setList)
-//	classifyArr := make([]string, 0)
-//	for i := 0; i < listLen; i++ {
-//		classifyArr = append(classifyArr, strconv.Itoa(setList[i].ClassifyId))
-//	}
-//	classifyIdStr := strings.Join(classifyArr, ",")
-//	condition := ""
-//	if classifyIdStr != "" {
-//		condition += ` AND classify_id IN(` + classifyIdStr + `)`
-//	}
-//	items, err := data_manage.GetManualClassifyAllByCondition(condition)
-//	if err != nil {
-//		fmt.Println("err:", err)
-//		return
-//	}
-//	fmt.Println(items)
-//	fmt.Println("end")
-//}

+ 0 - 244
controllers/data_manage/multiple_graph_config.go

@@ -1598,247 +1598,3 @@ func (this *ChartInfoController) GetMultipleGraphConfig() {
 	br.Data = resp
 	br.IsAddLog = true
 }
-
-//	func init() {
-//		//correlationChart := new(data_manage.ChartInfoCorrelation)
-//
-//		condition := ` AND source = 3 `
-//		list, err := data_manage.GetChartListByCondition(condition, []interface{}{}, 0, 1000)
-//		if err != nil {
-//			fmt.Println("err:", err)
-//			return
-//		}
-//		timeNowFormat := time.Now().Format(utils.FormatDate)
-//		for _, v := range list {
-//			item, tmpErr := data_manage.GetMultipleGraphConfigChartMappingByChartIdAndSource(v.ChartInfoId)
-//			if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
-//				fmt.Println("tmpErr:", tmpErr)
-//				continue
-//			}
-//			if item == nil {
-//				correlationChart := new(data_manage.ChartInfoCorrelation)
-//				e := correlationChart.GetItemById(v.ChartInfoId)
-//				if e != nil {
-//					fmt.Println("获取历史配置失败:", e)
-//					continue
-//				}
-//				day, _ := utils.GetDaysBetween2Date(utils.FormatDate, timeNowFormat, correlationChart.StartDate.Format(utils.FormatDate))
-//				req := request.SaveMultipleGraphConfigReq{
-//					MultipleGraphConfigId: 0,
-//					EdbInfoIdA:            correlationChart.EdbInfoIdFirst,
-//					EdbInfoIdB:            correlationChart.EdbInfoIdSecond,
-//					Curve:                 data_manage.CurveConfig{},
-//					Correlation: data_manage.CorrelationConfig{
-//						LeadValue:      correlationChart.LeadValue,
-//						LeadUnit:       correlationChart.LeadUnit,
-//						CalculateValue: day,
-//						CalculateUnit:  "天",
-//					},
-//					RollingCorrelation: []data_manage.RollingCorrelationConfig{
-//						{}, {},
-//					},
-//				}
-//				curveStrByte, _ := json.Marshal(req.Curve)
-//				correlationStrByte, _ := json.Marshal(req.Correlation)
-//				rollingCorrelationStrByte, _ := json.Marshal(req.RollingCorrelation)
-//
-//				multipleGraphConfig := &data_manage.MultipleGraphConfig{
-//					//MultipleGraphConfigId: 0,
-//					EdbInfoIdA:         req.EdbInfoIdA,
-//					EdbInfoIdB:         req.EdbInfoIdB,
-//					Curve:              string(curveStrByte),
-//					Correlation:        string(correlationStrByte),
-//					RollingCorrelation: string(rollingCorrelationStrByte),
-//					SysUserId:          v.SysUserId,
-//					SysUserRealName:    v.SysUserRealName,
-//					ModifyTime:         v.ModifyTime,
-//					CreateTime:         v.CreateTime,
-//				}
-//				err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
-//
-//				if err != nil {
-//					fmt.Println(v.ChartInfoId, "创建配置失败:", err)
-//					continue
-//				}
-//
-//				multipleGraphConfigChartMapping := &data_manage.MultipleGraphConfigChartMapping{
-//					//Id:                    0,
-//					MultipleGraphConfigId: multipleGraphConfig.MultipleGraphConfigId,
-//					ChartInfoId:           v.ChartInfoId,
-//					Source:                2,
-//					ModifyTime:            time.Now(),
-//					CreateTime:            time.Now(),
-//				}
-//				err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
-//				if err != nil {
-//					fmt.Println(v.ChartInfoId, "保存配置与图表的关联关系失败:", err)
-//				}
-//
-//				correlationChart.CalculateUnit = "天"
-//				correlationChart.CalculateValue = day
-//				err = correlationChart.Update([]string{"CalculateUnit", "CalculateValue"})
-//				if err != nil {
-//					fmt.Println(v.ChartInfoId, "修复历史数据失败:", err)
-//				}
-//			}
-//		}
-//	}
-
-// 修复相关性图表与滚动相关性图表的强关联关系
-//func init() {
-//	condition := ` AND source =  ? `
-//	pars := []interface{}{utils.CHART_SOURCE_ROLLING_CORRELATION}
-//	list, err := data_manage.GetChartListByCondition(condition, pars, 0, 1000)
-//	if err != nil {
-//		fmt.Println("err:", err)
-//		return
-//	}
-//	for _, chartInfo := range list {
-//		multipleGraphConfigChartMapping, e := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfo.ChartInfoId)
-//		if e != nil {
-//			fmt.Println(chartInfo.ChartInfoId, ";获取滚动相关性图表的配置信息失败, Err:"+e.Error())
-//			continue
-//		}
-//		baseChartMultipleGraphConfigChartMapping, e := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(multipleGraphConfigChartMapping.MultipleGraphConfigId, 2)
-//		if e != nil {
-//			fmt.Println(chartInfo.ChartInfoId, ";获取相关性图表的配置信息失败, Err:"+e.Error())
-//			continue
-//		}
-//		baseChartCorrelationChart := new(data_manage.ChartInfoCorrelation)
-//		if e := baseChartCorrelationChart.GetItemById(baseChartMultipleGraphConfigChartMapping.ChartInfoId); e != nil {
-//			fmt.Println(chartInfo.ChartInfoId, ";获取基础相关性图表信息失败, Err:"+e.Error())
-//			continue
-//		}
-//
-//		// 自己的配置
-//		selfChartCorrelationChart := new(data_manage.ChartInfoCorrelation)
-//		if e := selfChartCorrelationChart.GetItemById(chartInfo.ChartInfoId); e != nil {
-//			fmt.Println(chartInfo.ChartInfoId, ";获取自己的相关性图表信息失败, Err:"+e.Error())
-//			continue
-//		}
-//
-//		selfChartCorrelationChart.BaseCalculateUnit = baseChartCorrelationChart.CalculateUnit
-//		selfChartCorrelationChart.BaseCalculateValue = baseChartCorrelationChart.CalculateValue
-//		err = selfChartCorrelationChart.Update([]string{"BaseCalculateUnit", "BaseCalculateValue"})
-//		if err != nil {
-//			fmt.Println(chartInfo.ChartInfoId, ";更新相关性图表信息失败, Err:"+err.Error())
-//			continue
-//		}
-//	}
-//
-//}
-
-// 修复相关性图表与滚动相关性图表的强关联关系
-//func init() {
-//	{
-//		condition := ` AND source =  ? `
-//		pars := []interface{}{utils.CHART_SOURCE_ROLLING_CORRELATION}
-//		list, err := data_manage.GetChartListByCondition(condition, pars, 0, 1000)
-//		if err != nil {
-//			fmt.Println("err:", err)
-//			return
-//		}
-//		for _, chartInfo := range list {
-//			multipleGraphConfigChartMapping, e := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfo.ChartInfoId)
-//			if e != nil {
-//				fmt.Println(chartInfo.ChartInfoId, ";获取滚动相关性图表的配置信息失败, Err:"+e.Error())
-//				continue
-//			}
-//			multipleGraphConfig, e := data_manage.GetMultipleGraphConfigById(multipleGraphConfigChartMapping.MultipleGraphConfigId)
-//			if e != nil {
-//				fmt.Println(chartInfo.ChartInfoId, ";获取相关性图表的配置信息失败, Err:"+e.Error())
-//				continue
-//			}
-//			var curveConf data_manage.CurveConfig
-//			e = json.Unmarshal([]byte(multipleGraphConfig.Curve), &curveConf)
-//			if e != nil {
-//				fmt.Println(chartInfo.ChartInfoId, ";格式化曲线图数据失败, Err:"+e.Error())
-//				continue
-//			}
-//
-//			// 自己的配置
-//			selfChartCorrelationChart := new(data_manage.ChartInfoCorrelation)
-//			if e := selfChartCorrelationChart.GetItemById(chartInfo.ChartInfoId); e != nil {
-//				fmt.Println(chartInfo.ChartInfoId, ";获取自己的相关性图表信息失败, Err:"+e.Error())
-//				continue
-//			}
-//
-//			selfChartCorrelationChart.DateType = curveConf.DateType
-//
-//			startDate, endDate := utils.GetDateByDateType(curveConf.DateType, curveConf.StartDate, curveConf.EndDate)
-//			if startDate != `` {
-//				startDateTime, e := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
-//				if e != nil {
-//					fmt.Println(chartInfo.ChartInfoId, ";开始日期格式化失败,开始日期:", startDate, ", Err:"+e.Error())
-//					continue
-//				}
-//				selfChartCorrelationChart.StartDate = startDateTime
-//			}
-//			if endDate != `` {
-//				endDateTime, e := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
-//				if e != nil {
-//					fmt.Println(chartInfo.ChartInfoId, ";开始日期格式化失败,开始日期:", startDate, ", Err:"+e.Error())
-//					continue
-//				}
-//				selfChartCorrelationChart.EndDate = endDateTime
-//			}
-//			err = selfChartCorrelationChart.Update([]string{"DateType", "StartDate", "EndDate"})
-//			if err != nil {
-//				fmt.Println(chartInfo.ChartInfoId, ";更新相关性图表信息失败, Err:"+err.Error())
-//				continue
-//			}
-//		}
-//
-//		fmt.Println("图表更新完成")
-//	}
-//
-//	{
-//		// 更新指标
-//		condition := ` AND source =  ? `
-//		pars := []interface{}{utils.DATA_SOURCE_CALCULATE_CORRELATION}
-//		list, err := data_manage.GetEdbInfoListV2ByCondition(condition, pars, 0, 10000)
-//		if err != nil {
-//			fmt.Println("err:", err)
-//			return
-//		}
-//		for _, edbInfo := range list {
-//			multipleGraphConfigEdbMappingInfo, e := data_manage.GetMultipleGraphConfigEdbMappingByEdbInfoId(edbInfo.EdbInfoId)
-//			if e != nil {
-//				fmt.Println(edbInfo.EdbInfoId, ";获取滚动相关性指标的配置信息失败, Err:"+e.Error())
-//				continue
-//			}
-//			multipleGraphConfig, e := data_manage.GetMultipleGraphConfigById(multipleGraphConfigEdbMappingInfo.MultipleGraphConfigId)
-//			if e != nil {
-//				fmt.Println(edbInfo.EdbInfoId, ";获取相关性图表的配置信息失败, Err:"+e.Error())
-//				continue
-//			}
-//
-//			// 曲线图配置
-//			var curveConf data_manage.CurveConfig
-//			e = json.Unmarshal([]byte(multipleGraphConfig.Curve), &curveConf)
-//			if e != nil {
-//				fmt.Println(edbInfo.EdbInfoId, ";格式化曲线图数据失败, Err:"+e.Error())
-//				continue
-//			}
-//
-//			var formulaConf request.EdbCalculateFormula
-//			e = json.Unmarshal([]byte(edbInfo.CalculateFormula), &formulaConf)
-//			if e != nil {
-//				fmt.Println(edbInfo.EdbInfoId, ";格式化指标计算配置数据失败, Err:"+e.Error())
-//				continue
-//			}
-//			formulaConf.DateType = curveConf.DateType
-//			formulaConf.StartDate = curveConf.StartDate
-//			formulaConf.EndDate = curveConf.EndDate
-//			calculateFormulaByte, err := json.Marshal(formulaConf)
-//			edbInfo.CalculateFormula = string(calculateFormulaByte)
-//			err = edbInfo.Update([]string{"CalculateFormula"})
-//			if err != nil {
-//				fmt.Println(edbInfo.EdbInfoId, ";更新指标信息失败, Err:"+err.Error())
-//				continue
-//			}
-//		}
-//
-//		fmt.Println("指标更新完成")
-//	}
-//}

+ 2 - 11
controllers/data_manage/my_chart.go

@@ -27,7 +27,6 @@ type MyChartController struct {
 // @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 /chart/list [get]
 func (this *MyChartController) ChartList() {
@@ -83,12 +82,8 @@ func (this *MyChartController) ChartList() {
 		condition += ` AND  ( chart_name LIKE '%` + keyWord + `%' OR chart_name_en LIKE '%` + keyWord + `%' )`
 	}
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		condition += ` AND sys_user_id = ? `
-		pars = append(pars, sysUser.AdminId)
-	}
+	condition += ` AND sys_user_id = ? `
+	pars = append(pars, sysUser.AdminId)
 
 	// 获取当前账号的不可见指标
 	noPermissionChartIdList := make([]int, 0)
@@ -2250,10 +2245,6 @@ func (this *MyChartController) CompanyPublicClassifyList() {
 	br.Data = resp
 }
 
-//func init() {
-//	data.AddAllMyChartInfo()
-//}
-
 // ClassifyFrameworkNodeList
 // @Title 我的图表分类-关联的框架节点列表
 // @Description 我的图表分类-关联的框架节点列表

+ 4 - 4
controllers/data_manage/predict_edb_classify.go

@@ -138,7 +138,7 @@ func (this *PredictEdbClassifyController) Items() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, 1)
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, utils.EdbClassifyTypePredict, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -211,7 +211,7 @@ func (this *PredictEdbClassifyController) Add() {
 	}
 
 	// 添加指标分类
-	_, err, errMsg := data.AddEdbClassify(req.ClassifyName, req.ParentId, req.Level, 1, this.SysUser.AdminId, this.SysUser.AdminName, this.Lang)
+	_, err, errMsg := data.AddEdbClassify(req.ClassifyName, req.ParentId, req.Level, 1, this.SysUser.AdminId, this.SysUser.RealName, this.Lang)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -701,7 +701,7 @@ func (this *PredictEdbClassifyController) SimpleList() {
 		sysUserId = this.SysUser.AdminId
 	}
 
-	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, 1)
+	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, utils.EdbClassifyTypePredict, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -832,7 +832,7 @@ func (this *PredictEdbClassifyController) ClassifyTree() {
 		this.ServeJSON()
 	}()
 
-	allList, err := data_manage.GetPredictEdbClassifyAll()
+	allList, err := data_manage.GetAllEdbClassifyByType(utils.EdbClassifyTypePredict, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()

+ 23 - 11
controllers/data_manage/predict_edb_info.go

@@ -56,7 +56,6 @@ func (this *PredictEdbInfoController) EdbChartList() {
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
 	adminId, _ := this.GetInt("AdminId")
-	isOnlyMe, _ := this.GetBool("IsOnlyMe")
 
 	var total int
 	page := paging.GetPaging(currentIndex, pageSize, total)
@@ -96,10 +95,8 @@ func (this *PredictEdbInfoController) EdbChartList() {
 		condition += " AND sys_user_id = ? "
 		pars = append(pars, adminId)
 	}
-	if isOnlyMe {
-		condition += " AND sys_user_id = ? "
-		pars = append(pars, sysUser.AdminId)
-	}
+	condition += " AND sys_user_id = ? "
+	pars = append(pars, sysUser.AdminId)
 
 	// 获取当前账号的不可见指标
 	obj := data_manage.EdbInfoNoPermissionAdmin{}
@@ -159,6 +156,12 @@ func (this *PredictEdbInfoController) EdbChartList() {
 				br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
 				return
 			}
+			editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+				return
+			}
 
 			for _, v := range list {
 				if currClassify, ok := classifyMap[v.ClassifyId]; ok {
@@ -169,7 +172,7 @@ func (this *PredictEdbInfoController) EdbChartList() {
 						continue
 					}
 
-					v.Button = data.GetEdbOpButton(sysUser, v.SysUserId, v.EdbType, v.EdbInfoType, v.HaveOperaAuth)
+					v.Button = data.GetEdbOpButton(sysUser, v.SysUserId, v.EdbInfoId, v.EdbType, v.EdbInfoType, v.HaveOperaAuth, editShareEdbInfoIdMap)
 
 					respList = append(respList, v)
 				}
@@ -1082,6 +1085,7 @@ func (this *PredictEdbInfoController) FilterByEs() {
 
 	frequency := this.GetString("Frequency") //频度
 	isOnlyMe, _ := this.GetBool("IsOnlyMe")
+	isOnlyMe = true
 
 	var edbInfoList []*data_manage.EdbInfoList
 	var err error
@@ -1102,11 +1106,13 @@ func (this *PredictEdbInfoController) FilterByEs() {
 
 		newKeyWord := strings.Split(keyWord, " ")
 		keyWordArr = append(keyWordArr, newKeyWord...)
-		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, noPermissionEdbClassifyIdList, 0)
+
+		frequencyList := make([]string, 0)
+		if frequency != `` {
+			frequencyList = []string{frequency}
 		}
+		total, edbInfoList, err = elastic.SearchEdbInfoData(keyWord, startSize, pageSize, filterSource, source, frequencyList, []string{}, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, []int{}, []int{}, []int{}, []int{1, 2}, 1, 0, this.SysUser.AdminId, map[string]string{})
+
 		isEs = true
 	} else {
 		var condition string
@@ -1937,6 +1943,12 @@ func (this *PredictEdbInfoController) ClassifyEdbInfoItems() {
 			br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
 			return
 		}
+		editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+			return
+		}
 
 		for _, v := range allEdbInfo {
 			// 数据权限
@@ -1944,7 +1956,7 @@ func (this *PredictEdbInfoController) ClassifyEdbInfoItems() {
 				v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
 			}
 
-			button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+			button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbInfoId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth, editShareEdbInfoIdMap)
 			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 			v.Button = button
 

+ 587 - 0
controllers/data_manage/public_chart.go

@@ -0,0 +1,587 @@
+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/models/data_manage/request"
+	"eta_gn/eta_api/services/data"
+	dataApproveSerice "eta_gn/eta_api/services/data/data_approve"
+	"eta_gn/eta_api/services/elastic"
+	"eta_gn/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strconv"
+	"strings"
+)
+
+// ChartPublicController 公共图表
+type ChartPublicController struct {
+	controllers.BaseAuthController
+}
+
+// Save
+// @Title 单个图表设置公开
+// @Description 单个图表设置公开
+// @Param	request	body request.SetChartInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.ChartInfo
+// @router /chart_info/public/save [post]
+func (c *ChartPublicController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.SetChartPublicReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if len(req.ChartInfoList) <= 0 {
+		br.Msg = `请选择图表`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 待处理的资产
+	dataPublicItemList := make([]dataApproveSerice.SetDataPublicItem, 0)
+
+	// 校验是否重复存在已公开、已提交的图表
+	{
+		chartInfoIdList := make([]int, 0)
+		for _, item := range req.ChartInfoList {
+			chartInfoIdList = append(chartInfoIdList, item.ChartInfoId)
+
+			dataPublicItemList = append(dataPublicItemList, dataApproveSerice.SetDataPublicItem{
+				DataId:     item.ChartInfoId,
+				ClassifyId: item.ClassifyId,
+			})
+		}
+
+		list, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
+		if err != nil {
+			br.Msg = "保存失败!"
+			br.ErrMsg = "获取图表数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range list {
+			if v.PublicStatus != utils.DataPublicDefault {
+				br.Msg = `选择图表中存在已经公开/提交审批的图表,请仅选择未公开图表!`
+				br.IsSendEmail = false
+				return
+			}
+		}
+	}
+
+	// 校验是否开启了审批流
+	opening, e := dataApproveSerice.CheckOpenApprove(utils.DataApproveTypeChart)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验图表公开是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+	// 是否忽略审批
+	var isIgnoreApprove bool
+	{
+		businessConf, e := models.GetBusinessConfByKey(models.IgnoreChartApproveUserId)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取商家配置失败, Err: " + e.Error()
+			return
+		}
+		ignoreChartApproveUserIdList := strings.Split(businessConf.ConfVal, `,`)
+		if utils.InArrayByStr(ignoreChartApproveUserIdList, strconv.Itoa(c.SysUser.AdminId)) {
+			isIgnoreApprove = true
+		}
+	}
+
+	chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoList[0].ChartInfoId)
+	if err != nil {
+		br.Msg = "获取图表失败"
+		br.ErrMsg = "获取图表失败:" + err.Error()
+		return
+	}
+	title := chartInfo.ChartName
+	if len(req.ChartInfoList) > 1 {
+		title += `等图表`
+	}
+	title += `公开审批`
+
+	// 没开启审批流、或者无需审批
+	if !opening || isIgnoreApprove {
+		err = dataApproveSerice.UpdatePublicByDataList(utils.DataApproveTypeChart, dataApproveSerice.DataApproveStatePass, dataPublicItemList)
+	} else {
+		_, err = dataApproveSerice.SubmitDataApprove(utils.DataApproveTypeChart, dataPublicItemList, title, strings.TrimSpace(req.Description), c.SysUser.AdminId, c.SysUser.RealName)
+		if err != nil {
+			br.Msg = "提交审批失败"
+			br.ErrMsg = "提交审批失败, Err: " + err.Error()
+			return
+		}
+
+		// 更新ES
+		for _, dataPublicItem := range dataPublicItemList {
+			data.AddOrEditChartInfoToEs(dataPublicItem.DataId)
+		}
+	}
+
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// Cancel
+// @Title 撤销图表公开
+// @Description 撤销图表公开
+// @Param   ChartInfoId   query   int  true       "图表id"
+// @Success 200 {object} data_manage.ChartInfo
+// @router /chart_info/public/cancel [post]
+func (c *ChartPublicController) Cancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	// TODO 单个图表撤销的时候,需要校验状态,然后撤销
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	chartInfoId, _ := c.GetInt("ChartInfoId")
+	if chartInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+
+	var req request.SetChartPublicReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if len(req.ChartInfoList) <= 0 {
+		br.Msg = `请选择图表`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 待处理的资产
+	dataPublicItemList := make([]dataApproveSerice.SetDataPublicItem, 0)
+
+	// 校验是否重复存在已公开、已提交的图表
+	{
+		chartInfoIdList := make([]int, 0)
+		for _, item := range req.ChartInfoList {
+			chartInfoIdList = append(chartInfoIdList, item.ChartInfoId)
+
+			dataPublicItemList = append(dataPublicItemList, dataApproveSerice.SetDataPublicItem{
+				DataId:     item.ChartInfoId,
+				ClassifyId: item.ClassifyId,
+			})
+		}
+
+		list, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
+		if err != nil {
+			br.Msg = "保存失败!"
+			br.ErrMsg = "获取图表数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range list {
+			if v.PublicStatus != utils.DataPublicDefault {
+				br.Msg = `选择图表中存在已经公开/提交审批的图表,请仅选择未公开图表!`
+				br.IsSendEmail = false
+				return
+			}
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// ListByEs
+// @Title 图表筛选接口
+// @Description 图表筛选接口
+// @Success 200 {object} data_manage.ChartInfoList
+// @Param	request	body request.SearchPublicChartReq true "type json string"
+// @Success 200 {object} data_manage.ChartInfoFilterDataResp
+// @router /chart_info/public/list/es [post]
+func (c *ChartPublicController) ListByEs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.SearchPublicChartReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	pageSize := req.PageSize
+	currentIndex := req.CurrentIndex
+
+	var total int64
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	// 获取查询参数
+	keyword, searchChartPublicList, sourceList, chartTypeList, chartClassifyIdList, publicClassifyIdList, chartAuth, sortMap := data.GetChartSearchPar(req)
+
+	total, chartInfoList, err := elastic.SearchChartInfoDataByPublic(keyword, startSize, pageSize, searchChartPublicList, sourceList, chartTypeList, chartClassifyIdList, publicClassifyIdList, chartAuth, c.SysUser.AdminId, sortMap)
+	if err != nil {
+		chartInfoList = make([]*data_manage.ChartInfoView, 0)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+
+	// 因为是ES查找的,所以需要重新查一下图表的信息,主要是为了把是否授权字段找出来
+	if len(chartInfoList) > 0 {
+		// 图表map信息
+		chartInfoMap := make(map[int]*data_manage.ChartInfo)
+		classifyMap := make(map[int]*data_manage.ChartClassify)
+		publicClassifyMap := make(map[int]*data_manage.ChartPublicClassify)
+
+		// 指标id,分类id,公共分类id
+		chartInfoIdList := make([]int, 0)
+		tmpClassifyIdList := make([]int, 0)
+		tmpPublicClassifyIdList := make([]int, 0)
+
+		for _, v := range chartInfoList {
+			v.ConvertToResp()
+			v.HaveOperaAuth = true
+			chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
+			tmpClassifyIdList = append(tmpClassifyIdList, v.ChartClassifyId)
+			tmpPublicClassifyIdList = append(tmpPublicClassifyIdList, v.ChartPublicClassifyId)
+		}
+
+		// 获取所有有权限的图表
+		{
+			tmpChartList, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range tmpChartList {
+				chartInfoMap[v.ChartInfoId] = v
+			}
+		}
+
+		// 图表分类
+		{
+			tmpList, err := data_manage.GetChartClassifyByIdList(tmpClassifyIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的图表分类失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range tmpList {
+				classifyMap[v.ChartClassifyId] = v
+			}
+		}
+
+		// 公共分类
+		{
+			obj := data_manage.ChartPublicClassify{}
+			tmpList, err := obj.GetChartClassifyByIdList(tmpPublicClassifyIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的公共分类失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range tmpList {
+				publicClassifyMap[v.ChartPublicClassifyId] = v
+			}
+		}
+
+		// 数据重新赋值
+		for _, v := range chartInfoList {
+			if tmpChartInfo, ok := chartInfoMap[v.ChartInfoId]; ok {
+				v.IsJoinPermission = tmpChartInfo.IsJoinPermission
+			}
+
+			// 普通分类
+			if classifyItem, ok := classifyMap[v.ChartClassifyId]; ok {
+				v.ClassifyNamePath = classifyItem.ChartClassifyNamePath
+			}
+
+			// 公共分类
+			if classifyItem, ok := publicClassifyMap[v.ChartPublicClassifyId]; ok {
+				v.PublicClassifyNamePath = classifyItem.ChartPublicClassifyNamePath
+			}
+
+		}
+	}
+
+	resp := data_manage.ChartInfoFilterDataResp{
+		Paging: page,
+		List:   chartInfoList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// AllListByEs
+// @Title 图表筛选接口
+// @Description 图表筛选接口
+// @Success 200 {object} data_manage.ChartInfoList
+// @Param	request	body request.SearchChartInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.ChartInfoFilterDataResp
+// @router /chart_info/public/list/es/all [post]
+func (c *ChartPublicController) AllListByEs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.AllSearchPublicChartReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	// 选择所有图表,所以需要通过es获取数据
+
+	// 选中的图表id列表
+	chartInfoList := make([]*data_manage.ChartInfoView, 0)
+
+	// 选择所有图表,所以需要通过es获取数据
+	if req.IsSelectAll {
+		tmpChartInfoList, err := data.GetAllChartInfoListBySearchPublicChartReq(req.SearchPublicChartReq, c.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取图表列表失败!"
+			br.ErrMsg = "获取图表列表失败,Err:" + err.Error()
+			return
+		}
+
+		// 如果有过滤图表,那么就过滤吧
+		if len(req.NoChartIdList) > 0 {
+			noChartIdMap := make(map[int]bool)
+			for _, v := range req.NoChartIdList {
+				noChartIdMap[v] = true
+			}
+
+			for _, v := range tmpChartInfoList {
+				if _, ok := noChartIdMap[v.ChartInfoId]; !ok {
+					// 如果不在未选中的图表id列表中,那么就加入到选中的图表id列表
+					chartInfoList = append(chartInfoList, v)
+				}
+			}
+		} else {
+			chartInfoList = tmpChartInfoList
+		}
+
+		// 因为是ES查找的,所以需要重新查一下图表的信息,主要是为了把是否授权字段找出来
+		if len(chartInfoList) > 0 {
+
+			chartInfoIdList := make([]int, 0)
+			for _, v := range chartInfoList {
+				v.ConvertToResp()
+				v.HaveOperaAuth = true
+				chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
+			}
+
+			tmpChartList, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
+				return
+			}
+			chartInfoMap := make(map[int]*data_manage.ChartInfo)
+			for _, v := range tmpChartList {
+				chartInfoMap[v.ChartInfoId] = v
+			}
+
+			for _, v := range chartInfoList {
+				tmpChartInfo, ok := chartInfoMap[v.ChartInfoId]
+				if !ok {
+					continue
+				}
+				v.IsJoinPermission = tmpChartInfo.IsJoinPermission
+			}
+		}
+	} else {
+		// 因为是ES查找的,所以需要重新查一下图表的信息,主要是为了把是否授权字段找出来
+		if len(req.ChartIdList) > 0 {
+			chartInfoList, err = data_manage.GetChartInfoViewByIdList(req.ChartIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
+				return
+			}
+		}
+	}
+
+	resp := data_manage.ChartInfoFilterDataResp{
+		List: chartInfoList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// BatchMove
+// @Title 图表批量移动接口
+// @Description 图表批量移动接口
+// @Param	request	body request.MoveChartClassifyReq true "type json string"
+// @Success Ret=200 移动成功
+// @router /chart_info/public/batch_move [post]
+func (c *ChartPublicController) BatchMove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.MoveChartClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.NewClassifyId <= 0 {
+		br.Msg = `请选择要转移的新分类`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 校验分类
+	obj := data_manage.ChartPublicClassify{}
+	publicClassifyItem, err := obj.GetChartClassifyById(req.NewClassifyId)
+	if err != nil {
+		br.Msg = "获取公共分类失败!"
+		br.ErrMsg = "获取公共分类失败!" + err.Error()
+		return
+	}
+	if publicClassifyItem.ChartPublicClassifyId <= 0 {
+		br.Msg = "公共分类不存在!"
+		br.ErrMsg = "公共分类不存在!"
+		return
+	}
+
+	// 只是取公开
+	req.SearchPublicChartReq.ChartPublicList = []int{3}
+
+	chartInfoIdList := make([]int, 0)
+	if req.IsSelectAll {
+		// 获取图表
+		chartInfoList, err := data.GetAllChartInfoListBySearchPublicChartReq(req.SearchPublicChartReq, c.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取图表列表失败!"
+			br.ErrMsg = "获取图表列表失败,Err:" + err.Error()
+			return
+		}
+		// 如果有过滤图表,那么就过滤吧
+		if len(req.NoChartIdList) > 0 {
+			noChartIdMap := make(map[int]bool)
+			for _, v := range req.NoChartIdList {
+				noChartIdMap[v] = true
+			}
+
+			for _, chartInfo := range chartInfoList {
+				if _, ok := noChartIdMap[chartInfo.ChartInfoId]; !ok {
+					if chartInfo.PublicStatus != utils.DataPublicSuccess {
+						br.Msg = `存在未公开的图表:` + chartInfo.ChartName
+						br.IsSendEmail = false
+						return
+					}
+
+					// 如果不在未选中的图表id列表中,那么就加入到选中的图表id列表
+					chartInfoIdList = append(chartInfoIdList, chartInfo.ChartInfoId)
+				}
+			}
+		} else {
+			for _, chartInfo := range chartInfoList {
+				if chartInfo.PublicStatus != utils.DataPublicSuccess {
+					br.Msg = `存在未公开的图表:` + chartInfo.ChartName
+					br.IsSendEmail = false
+					return
+				}
+				chartInfoIdList = append(chartInfoIdList, chartInfo.ChartInfoId)
+			}
+		}
+	} else {
+		chartInfoList, err := data_manage.GetChartInfoViewByIdList(req.ChartIdList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的图表失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range chartInfoList {
+			if v.PublicStatus != utils.DataPublicSuccess {
+				br.Msg = `存在未公开的图表:` + v.ChartName
+				br.IsSendEmail = false
+				return
+			}
+		}
+		chartInfoIdList = req.ChartIdList
+	}
+
+	num := len(chartInfoIdList)
+	if num <= 0 {
+		br.Msg = `请选择要移动的图表!`
+		br.IsSendEmail = false
+		return
+	}
+	if num > 100 {
+		br.Msg = `最多只能选择100条图表!`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 开始批量修改图表分类
+	if len(chartInfoIdList) > 0 {
+		err = data_manage.UpdatePublicClassifyIdByChartInfoIdList(chartInfoIdList, req.NewClassifyId)
+		if err != nil {
+			br.Msg = `图表移动失败!`
+			br.ErrMsg = `图表移动失败,ERR:` + err.Error()
+			return
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 625 - 0
controllers/data_manage/public_chart_classify.go

@@ -0,0 +1,625 @@
+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/models/data_manage/request"
+	"eta_gn/eta_api/models/system"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/utils"
+	"sort"
+)
+
+// ChartPublicClassifyController 数据管理-公共分类模块
+type ChartPublicClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// SimpleList
+// @Title 单层公共分类列表
+// @Description 单层公共分类列表
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /chart_public/classify/simple [get]
+func (c *ChartPublicClassifyController) SimpleList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	// 公共分类来源筛选
+	// 目前只有图库会涉及到公共分类
+	source := utils.CHART_TYPE_CURVE
+
+	// 默认查一级公共分类和一级公共分类下的指标信息,
+	// 如果是 子级公共分类,查询该子级公共分类的下一级公共分类和指标信息
+	// 增加标识判断是文件夹还是指标列表
+	parentId, _ := c.GetInt("ParentId")
+
+	chartPublicClassifyObj := data_manage.ChartPublicClassify{}
+	rootList, err := chartPublicClassifyObj.GetChartClassifyItemsByParentId(parentId, int8(source))
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
+
+	var sortList data_manage.ChartClassifyItemList
+	if parentId > 0 {
+		allChartInfo, err := data_manage.GetChartInfoByPublicClassifyId(parentId, source)
+		if err != nil {
+			br.Msg = "获取指标数据失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+
+		editShareChartInfoIdMap, err := data.GetAllEditSharedChartInfoIdMapByReceivedUserId(c.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有编辑权限的分享图表失败,Err:" + err.Error()
+			return
+		}
+
+		// 查询当前公共分类信息
+		for _, v := range allChartInfo {
+			v.HaveOperaAuth = true
+			button := data.GetChartOpButton(c.SysUser, v.SysUserId, v.ChartInfoId, v.HaveOperaAuth, editShareChartInfoIdMap)
+			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
+			v.Button = button
+			v.Children = make([]*data_manage.ChartClassifyItems, 0)
+			v.ParentId = parentId
+			nodeAll = append(nodeAll, v)
+		}
+
+	}
+
+	for _, v := range rootList {
+		// 数据权限
+		v.HaveOperaAuth = true
+		// 按钮权限
+		button := data.GetChartClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+		v.Button = button
+		v.Children = make([]*data_manage.ChartClassifyItems, 0)
+		nodeAll = append(nodeAll, v)
+	}
+
+	if len(nodeAll) > 0 {
+		//根据sort值排序
+		sortList = nodeAll
+		sort.Sort(sortList)
+	}
+
+	language := `CN`
+	// 指标显示的语言
+	{
+		configDetail, _ := system.GetConfigDetailByCode(c.SysUser.AdminId, system.ChartLanguageVar)
+		if configDetail != nil {
+			language = configDetail.ConfigValue
+		} else {
+			configDetail, _ = system.GetDefaultConfigDetailByCode(system.ChartLanguageVar)
+			if configDetail != nil {
+				language = configDetail.ConfigValue
+			}
+		}
+	}
+
+	// 是否允许添加一级公共分类
+	canOpClassify := true
+	button := data.GetChartClassifyOpButton(c.SysUser, 0, true)
+	if !button.AddButton {
+		canOpClassify = false
+	}
+
+	resp := new(data_manage.ChartClassifyListResp)
+	resp.AllNodes = sortList
+	resp.Language = language
+	resp.CanOpClassify = canOpClassify
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ClassifyTree
+// @Title 多层公共分类列表树
+// @Description 多层公共分类列表树
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /chart_public/classify/tree [get]
+func (c *ChartPublicClassifyController) ClassifyTree() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	// 公共分类来源筛选
+	classifyType := utils.CHART_TYPE_CURVE
+
+	chartPublicClassifyObj := data_manage.ChartPublicClassify{}
+	allList, err := chartPublicClassifyObj.GetAllChartClassifyByType(int8(classifyType))
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	var sortList data_manage.ChartClassifyItemList
+	if len(allList) > 0 {
+		for k, v := range allList {
+			// 数据权限
+			v.HaveOperaAuth = true
+			// 按钮权限
+			button := data.GetChartClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+			allList[k].Button = button
+		}
+		allList = data.GetChartClassifyTreeRecursive(allList, 0)
+		//根据sort值排序
+		sortList = allList
+		sort.Sort(sortList)
+	}
+	language := `CN`
+
+	// 是否允许添加一级公共分类
+	canOpClassify := true
+	button := data.GetChartClassifyOpButton(c.SysUser, 0, true)
+	if !button.AddButton {
+		canOpClassify = false
+	}
+
+	resp := new(data_manage.ChartClassifyListResp)
+	resp.AllNodes = sortList
+	resp.Language = language
+	resp.CanOpClassify = canOpClassify
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// AddChartClassify
+// @Title 新增公共分类
+// @Description 新增公共分类接口
+// @Param	request	body data_manage.AddChartClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /chart_public/classify/add [post]
+func (c *ChartPublicClassifyController) AddClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req data_manage.AddChartClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartClassifyName == "" {
+		br.Msg = "请输入公共分类名称"
+		br.IsSendEmail = false
+		return
+	}
+	if req.ParentId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+	// 公共分类来源筛选
+	source := utils.CHART_TYPE_CURVE
+
+	//添加指标
+	_, err, errMsg := data.AddChartPublicClassify(req.ChartClassifyName, req.ParentId, source, c.SysUser.AdminId, c.SysUser.RealName)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = errMsg + ";Err:" + err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	//count, err := data_manage.GetChartClassifyCount(req.ClassifyName, req.ParentId)
+	//if err != nil {
+	//	br.Msg = "判断名称是否已存在失败"
+	//	br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
+	//	return
+	//}
+	//if count > 0 {
+	//	br.Msg = "公共分类名称已存在,请重新输入"
+	//	br.IsSendEmail = false
+	//	return
+	//}
+	////获取该层级下最大的排序数
+	//maxSort, err := data_manage.GetChartClassifyMaxSort(req.ParentId, req.ClassifyType)
+	//
+	//classify := new(data_manage.ChartClassify)
+	//classify.ClassifyType = req.ClassifyType
+	//classify.ParentId = req.ParentId
+	//classify.ClassifyName = req.ClassifyName
+	//classify.HasData = 0
+	//classify.CreateTime = time.Now()
+	//classify.ModifyTime = time.Now()
+	//classify.SysUserId = c.SysUser.AdminId
+	//classify.SysUserRealName = c.SysUser.RealName
+	//classify.Level = req.Level + 1
+	//timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	//classify.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
+	//classify.Sort = maxSort
+	//
+	//_, err = data_manage.AddChartClassify(classify)
+	//if err != nil {
+	//	br.Msg = "保存公共分类失败"
+	//	br.ErrMsg = "保存公共分类失败,Err:" + err.Error()
+	//	return
+	//}
+	br.Ret = 200
+	br.Msg = "新增成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// EditChartClassify
+// @Title 修改公共分类
+// @Description 修改公共分类接口
+// @Param	request	body data_manage.EditChartClassifyReq true "type json string"
+// @Success 200 Ret=200 修改成功
+// @router /chart_public/classify/edit [post]
+func (c *ChartPublicClassifyController) EditChartClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req data_manage.EditChartClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartClassifyName == "" {
+		br.Msg = "请输入公共分类名称"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.ChartClassifyId <= 0 {
+		br.Msg = "请选择指标"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.EditChartPublicClassify(req.ChartClassifyId, req.ChartClassifyName, c.SysUser)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = errMsg + ";Err:" + err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	br.Ret = 200
+	br.Msg = "修改成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// DeleteClassifyCheck
+// @Title 删除检测接口
+// @Description 删除检测接口
+// @Param	request	body request.PublicChartClassifyDeleteCheckReq true "type json string"
+// @Success 200 Ret=200 检测成功
+// @router /chart_public/classify/delete/check [post]
+func (c *ChartPublicClassifyController) DeleteClassifyCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.PublicChartClassifyDeleteCheckReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartClassifyId <= 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+	deleteStatus, tipsMsg, _, tableList, err, errMsg := data.DeleteChartPublicClassifyCheck(req.ChartClassifyId, c.SysUser)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	if c.Lang == "en" {
+		if utils.ViperConfig.InConfig(tipsMsg) {
+			tipsMsg = utils.ViperConfig.GetString(tipsMsg)
+		}
+	}
+
+	//var deleteStatus int
+	//var tipsMsg string
+	////删除公共分类
+	//if req.ClassifyId > 0 && req.ChartInfoId == 0 {
+	//	//判断公共分类下,是否含有指标
+	//	count, err := data_manage.GetChartInfoCountByClassifyId(req.ClassifyId)
+	//	if err != nil {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "公共分类下是否含有指标失败,Err:" + err.Error()
+	//		return
+	//	}
+	//
+	//	if count > 0 {
+	//		deleteStatus = 1
+	//		tipsMsg = "若目录关联指标不可删除"
+	//	}
+	//}
+	//
+	//if deleteStatus != 1 && req.ChartInfoId == 0 {
+	//	classifyCount, err := data_manage.GetClassifyCountByClassifyId(req.ClassifyId)
+	//	if err != nil && !utils.IsErrNoRow(err) {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "公共分类下是否含有指标失败,Err:" + err.Error()
+	//		return
+	//	}
+	//	if classifyCount > 0 {
+	//		deleteStatus = 2
+	//		tipsMsg = "确认删除当前目录及包含的子目录吗"
+	//	}
+	//}
+	//
+	////删除指标
+	//if req.ChartInfoId > 0 {
+	//	//判断指标是否用于作图,如果用于作图,则不可删除
+	//	chartCount, err := data_manage.GetChartChartMappingCount(req.ChartInfoId)
+	//	if err != nil && !utils.IsErrNoRow(err) {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "判断指标是否被用于作图失败,Err:" + err.Error()
+	//		return
+	//	}
+	//	if chartCount > 0 {
+	//		deleteStatus = 3
+	//		tipsMsg = "当前指标已用作画图,不可删除"
+	//	}
+	//	//判断指标是否用于计算
+	//	{
+	//		calculateCount, err := data_manage.GetChartInfoCalculateMappingCount(req.ChartInfoId)
+	//		if err != nil && !utils.IsErrNoRow(err) {
+	//			br.Msg = "删除失败"
+	//			br.ErrMsg = "判断指标是否被用于计算失败,GetChartInfoCalculateCount Err:" + err.Error()
+	//			return
+	//		}
+	//		if calculateCount > 0 {
+	//			deleteStatus = 4
+	//			tipsMsg = "当前指标已用作,指标运算,不可删除"
+	//		}
+	//	}
+	//}
+
+	resp := new(data_manage.ClassifyDeleteCheckResp)
+	resp.DeleteStatus = deleteStatus
+	resp.TipsMsg = tipsMsg
+	resp.TableList = tableList
+	br.Ret = 200
+	br.Msg = "检测成功"
+	br.Success = true
+	br.Data = resp
+}
+
+// DeleteClassify
+// @Title 删除公共分类/指标
+// @Description 删除公共分类/指标接口
+// @Param	request	body request.PublicChartClassifyDeleteCheckReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /chart_public/classify/delete [post]
+func (c *ChartPublicClassifyController) DeleteClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.PublicChartClassifyDeleteCheckReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartClassifyId <= 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	nextItem, _, err, errMsg := data.DeleteChartPublicClassify(req.ChartClassifyId, sysUser, string(c.Ctx.Input.RequestBody), c.Ctx.Input.URI())
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+
+	resp := data_manage.AddChartInfoResp{}
+	if nextItem != nil {
+		resp = data_manage.AddChartInfoResp{
+			ChartInfoId: nextItem.ChartInfoId,
+			UniqueCode:  nextItem.UniqueCode,
+		}
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+	br.Data = resp
+}
+
+// ChartClassifyMove
+// @Title 分类移动接口
+// @Description 分类移动接口
+// @Success 200 {object} data_manage.MoveChartClassifyReq
+// @router /chart_public/chart_classify/move [post]
+func (c *ChartPublicClassifyController) ChartClassifyMove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req data_manage.MoveChartClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId <= 0 && req.ChartInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "请选择拖动目标,分类目录或者指标"
+		return
+	}
+
+	//if chartClassifyInfo.Source != utils.CHART_SOURCE_DEFAULT {
+	//	br.Msg = "分类异常"
+	//	br.ErrMsg = "分类异常,不是ETA图库的分类"
+	//	return
+	//}
+
+	err, errMsg := data.MoveChartPublicClassify(req, sysUser)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	////判断分类是否存在
+	//edbClassifyInfo, err := data_manage.GetEdbClassifyById(req.ClassifyId)
+	//if err != nil {
+	//	br.Msg = "移动失败"
+	//	br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+	//	return
+	//}
+	//updateCol := make([]string, 0)
+	//
+	////判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	//if edbClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId != 0 {
+	//	parentEdbClassifyInfo, err := data_manage.GetEdbClassifyById(req.ParentClassifyId)
+	//	if err != nil {
+	//		br.Msg = "移动失败"
+	//		br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
+	//		return
+	//	}
+	//	edbClassifyInfo.ParentId = parentEdbClassifyInfo.ClassifyId
+	//	edbClassifyInfo.Level = parentEdbClassifyInfo.Level + 1
+	//	edbClassifyInfo.ModifyTime = time.Now()
+	//	updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
+	//}
+	//
+	////如果有传入 上一个兄弟节点分类id
+	//if req.PrevClassifyId > 0 {
+	//	prevClassify, err := data_manage.GetEdbClassifyById(req.PrevClassifyId)
+	//	if err != nil {
+	//		br.Msg = "移动失败"
+	//		br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
+	//		return
+	//	}
+	//
+	//	//如果是移动在两个兄弟节点之间
+	//	if req.NextClassifyId > 0 {
+	//		//下一个兄弟节点
+	//		nextClassify, err := data_manage.GetEdbClassifyById(req.NextClassifyId)
+	//		if err != nil {
+	//			br.Msg = "移动失败"
+	//			br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
+	//			return
+	//		}
+	//		//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+	//		if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == edbClassifyInfo.Sort {
+	//			//变更兄弟节点的排序
+	//			updateSortStr := `sort + 2`
+	//			_ = data_manage.UpdateEdbClassifySortByParentId(prevClassify.ParentId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr)
+	//		} else {
+	//			//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+	//			if nextClassify.Sort-prevClassify.Sort == 1 {
+	//				//变更兄弟节点的排序
+	//				updateSortStr := `sort + 1`
+	//				_ = data_manage.UpdateEdbClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
+	//			}
+	//		}
+	//	}
+	//
+	//	edbClassifyInfo.Sort = prevClassify.Sort + 1
+	//	edbClassifyInfo.ModifyTime = time.Now()
+	//	updateCol = append(updateCol, "Sort", "ModifyTime")
+	//} else {
+	//	firstClassify, err := data_manage.GetFirstEdbClassifyByParentId(edbClassifyInfo.ParentId)
+	//	if err != nil && !utils.IsErrNoRow(err) {
+	//		br.Msg = "移动失败"
+	//		br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
+	//		return
+	//	}
+	//
+	//	//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+	//	if firstClassify != nil && firstClassify.ChartClassifyId > 0 && firstClassify.Sort == 0 {
+	//		updateSortStr := ` sort + 1 `
+	//		_ = data_manage.UpdateEdbClassifySortByParentId(firstClassify.ParentId, firstClassify.ClassifyId-1, 0, updateSortStr)
+	//	}
+	//
+	//	edbClassifyInfo.Sort = 0 //那就是排在第一位
+	//	edbClassifyInfo.ModifyTime = time.Now()
+	//	updateCol = append(updateCol, "Sort", "ModifyTime")
+	//}
+	//
+	////更新
+	//if len(updateCol) > 0 {
+	//	err = edbClassifyInfo.Update(updateCol)
+	//	if err != nil {
+	//		br.Msg = "移动失败"
+	//		br.ErrMsg = "修改失败,Err:" + err.Error()
+	//		return
+	//	}
+	//}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "移动成功"
+}

+ 667 - 0
controllers/data_manage/public_edb.go

@@ -0,0 +1,667 @@
+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/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/request"
+	"eta_gn/eta_api/models/system"
+	"eta_gn/eta_api/services/data"
+	dataApproveSerice "eta_gn/eta_api/services/data/data_approve"
+	"eta_gn/eta_api/services/elastic"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strconv"
+	"strings"
+)
+
+// EdbPublicController 公共指标
+type EdbPublicController struct {
+	controllers.BaseAuthController
+}
+
+// Save
+// @Title 单个指标设置公开
+// @Description 单个指标设置公开
+// @Param	request	body request.SetEdbInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfo
+// @router /edb_info/public/save [post]
+func (c *EdbPublicController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.SetEdbPublicReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if len(req.EdbInfoList) <= 0 {
+		br.Msg = `请选择指标`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 待处理的资产
+	dataPublicItemList := make([]dataApproveSerice.SetDataPublicItem, 0)
+
+	// 校验是否重复存在已公开、已提交的指标
+	{
+		edbInfoIdList := make([]int, 0)
+		for _, item := range req.EdbInfoList {
+			edbInfoIdList = append(edbInfoIdList, item.EdbInfoId)
+
+			dataPublicItemList = append(dataPublicItemList, dataApproveSerice.SetDataPublicItem{
+				DataId:     item.EdbInfoId,
+				ClassifyId: item.ClassifyId,
+			})
+		}
+
+		list, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
+		if err != nil {
+			br.Msg = "保存失败!"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range list {
+			if v.PublicStatus != utils.DataPublicDefault {
+				br.Msg = `选择指标中存在已经公开/提交审批的指标,请仅选择未公开指标!`
+				br.IsSendEmail = false
+				return
+			}
+		}
+	}
+
+	// 校验是否开启了审批流
+	opening, e := dataApproveSerice.CheckOpenApprove(utils.DataApproveTypeEdb)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验指标公开是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+	// 是否忽略审批
+	var isIgnoreApprove bool
+	{
+		businessConf, e := models.GetBusinessConfByKey(models.IgnoreEdbApproveUserId)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取商家配置失败, Err: " + e.Error()
+			return
+		}
+		ignoreEdbApproveUserIdList := strings.Split(businessConf.ConfVal, `,`)
+		if utils.InArrayByStr(ignoreEdbApproveUserIdList, strconv.Itoa(c.SysUser.AdminId)) {
+			isIgnoreApprove = true
+		}
+	}
+
+	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoList[0].EdbInfoId)
+	if err != nil {
+		br.Msg = "获取指标失败"
+		br.ErrMsg = "获取指标失败:" + err.Error()
+		return
+	}
+	title := edbInfo.EdbName
+	if len(req.EdbInfoList) > 1 {
+		title += `等指标`
+	}
+	title += `公开审批`
+
+	// 没开启审批流、或者无需审批
+	if !opening || isIgnoreApprove {
+		err = dataApproveSerice.UpdatePublicByDataList(utils.DataApproveTypeEdb, dataApproveSerice.DataApproveStatePass, dataPublicItemList)
+	} else {
+		_, err = dataApproveSerice.SubmitDataApprove(utils.DataApproveTypeEdb, dataPublicItemList, title, strings.TrimSpace(req.Description), c.SysUser.AdminId, c.SysUser.RealName)
+		if err != nil {
+			br.Msg = "提交审批失败"
+			br.ErrMsg = "提交审批失败, Err: " + err.Error()
+			return
+		}
+
+		// 更新ES
+		for _, dataPublicItem := range dataPublicItemList {
+			data.AddOrEditEdbInfoToEs(dataPublicItem.DataId)
+		}
+	}
+
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// Cancel
+// @Title 撤销指标公开
+// @Description 撤销指标公开
+// @Param   EdbInfoId   query   int  true       "指标id"
+// @Success 200 {object} data_manage.EdbInfo
+// @router /edb_info/public/cancel [post]
+func (c *EdbPublicController) Cancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	edbInfoId, _ := c.GetInt("EdbInfoId")
+	if edbInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+
+	edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
+	if err != nil {
+		br.Msg = "保存失败!"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	// 判断指标公共状态
+	if !utils.InArrayByInt([]int{utils.DataPublicSuccess, utils.DataPublicReject, utils.DataPublicCommit}, edbInfo.PublicStatus) {
+		br.Msg = "保存失败,指标公开状态异常!"
+		br.ErrMsg = "保存失败,指标公开状态异常,public_status:" + fmt.Sprint(edbInfo.PublicStatus)
+		return
+	}
+
+	// 如果公开状态是:已驳回、已提交,那么直接去撤销审批单
+	if utils.InArrayByInt([]int{utils.DataPublicReject, utils.DataPublicCommit}, edbInfo.PublicStatus) {
+		obj := data_approve.DataApproveRelation{}
+		dataApproveId, err := obj.GetDataApproveIdByDataId(edbInfoId, utils.DataApproveTypeEdb)
+		if err != nil {
+			br.Msg = "保存失败!"
+			br.ErrMsg = "获取审批单失败,Err:" + err.Error()
+			return
+		}
+		// 撤销审批
+		msg, e := dataApproveSerice.DataApproveCancel(dataApproveId, sysUser.AdminId, sysUser.RealName)
+		if e != nil {
+			if msg != "" {
+				br.Msg = msg
+			} else {
+				br.Msg = "操作失败"
+			}
+			br.ErrMsg = "撤销审批失败, Err: " + e.Error()
+			return
+		}
+	}
+
+	checkUserIdList := []int{sysUser.AdminId}
+	noReferenced, otherUserIdList, err, tips := data.CheckEdbReferencedByOthers(edbInfo.EdbInfoType, []int{edbInfo.EdbInfoId}, checkUserIdList)
+	if err != nil {
+		br.Msg = "保存失败"
+		if tips != "" {
+			br.Msg = tips
+		}
+		br.ErrMsg = "撤销指标公开失败,查找指标的关联用户失败,Err:" + err.Error()
+		return
+	}
+
+	if !noReferenced {
+		userNameStr := ``
+		if len(otherUserIdList) > 0 {
+			userNameList := make([]string, 0)
+			userList, err := system.GetAdminListByIdList(otherUserIdList)
+			if err != nil {
+				br.Msg = "保存失败"
+				if tips != "" {
+					br.Msg = tips
+				}
+				br.ErrMsg = "撤销指标公开失败,查找用户信息失败,Err:" + err.Error()
+				return
+			}
+			for _, userInfo := range userList {
+				userNameList = append(userNameList, userInfo.RealName)
+			}
+			userNameStr = strings.Join(userNameList, ",")
+		}
+		msg := `指标被其他用户使用,无法撤销公开`
+		if userNameStr != "" {
+			msg = fmt.Sprintf(`指标被用户%s使用,无法撤销公开`, userNameStr)
+		}
+		if tips != "" {
+			msg = fmt.Sprintf(`%s,用户为:%s,无法撤销公开`, tips, userNameStr)
+		}
+		br.Msg = msg
+		br.ErrMsg = "指标被其他用户共享,无法撤销公开,EdbInfoId:" + strconv.Itoa(edbInfo.EdbInfoId)
+		br.IsSendEmail = false
+		return
+	}
+
+	edbInfo.PublicStatus = utils.DataPublicDefault
+	edbInfo.EdbPublicClassifyId = 0
+	err = edbInfo.Update([]string{"PublicStatus", "EdbPublicClassifyId"})
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "取消指标公共失败,Err:" + err.Error()
+		return
+	}
+
+	// 修改ES数据
+	data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+
+	// TODO 取消公共的时候,需要清除对应用户的收藏状态
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// ListByEs
+// @Title 指标筛选接口
+// @Description 指标筛选接口
+// @Success 200 {object} data_manage.EdbInfoList
+// @Param	request	body request.SearchPublicEdbReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfoFilterDataResp
+// @router /edb_info/public/list/es [post]
+func (c *EdbPublicController) ListByEs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.SearchPublicEdbReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	pageSize := req.PageSize
+	currentIndex := req.CurrentIndex
+
+	var total int64
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	// 获取查询参数
+	keyword, searchEdbPublicList, sourceList, edbClassifyIdList, publicClassifyIdList, edbTypeList, edbInfoType, edbAuth, sortMap := data.GetSearchPar(req)
+
+	total, edbInfoList, err := elastic.SearchEdbInfoDataByPublic(keyword, startSize, pageSize, searchEdbPublicList, sourceList, edbClassifyIdList, publicClassifyIdList, edbTypeList, edbInfoType, edbAuth, c.SysUser.AdminId, sortMap)
+	if err != nil {
+		edbInfoList = make([]*data_manage.EdbInfoList, 0)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+
+	edbInfoListLen := len(edbInfoList)
+
+	// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+	if len(edbInfoList) > 0 {
+		// 图表map
+		edbInfoMap := make(map[int]*data_manage.EdbInfo)
+		classifyMap := make(map[int]*data_manage.EdbClassify)
+		publicClassifyMap := make(map[int]*data_manage.EdbPublicClassify)
+
+		// 指标id,分类id,公共分类id
+		edbInfoIdList := make([]int, 0)
+		tmpClassifyIdList := make([]int, 0)
+		tmpPublicClassifyIdList := make([]int, 0)
+
+		for _, v := range edbInfoList {
+			v.ConvertToResp()
+			v.EdbNameAlias = v.EdbName
+			v.HaveOperaAuth = true
+			edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+		}
+
+		// 查找指标
+		{
+			tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range tmpEdbList {
+				edbInfoMap[v.EdbInfoId] = v
+				tmpClassifyIdList = append(tmpClassifyIdList, v.ClassifyId)
+				tmpPublicClassifyIdList = append(tmpPublicClassifyIdList, v.EdbPublicClassifyId)
+			}
+		}
+
+		// 指标分类
+		{
+			tmpList, err := data_manage.GetEdbClassifyByIdList(tmpClassifyIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的图表分类失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range tmpList {
+				classifyMap[v.ClassifyId] = v
+			}
+		}
+
+		// 公共分类
+		{
+			obj := data_manage.EdbPublicClassify{}
+			tmpList, err := obj.GetEdbClassifyByIdList(tmpPublicClassifyIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的公共分类失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range tmpList {
+				publicClassifyMap[v.EdbPublicClassifyId] = v
+			}
+		}
+
+		// 数据重新赋值
+		for _, v := range edbInfoList {
+			if tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]; ok {
+				v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
+			}
+
+			// 普通分类
+			if classifyItem, ok := classifyMap[v.ClassifyId]; ok {
+				v.ClassifyNamePath = classifyItem.ClassifyNamePath
+			}
+
+			// 公共分类
+			if classifyItem, ok := publicClassifyMap[v.EdbPublicClassifyId]; ok {
+				v.PublicClassifyNamePath = classifyItem.EdbPublicClassifyNamePath
+			}
+		}
+	}
+
+	for i := 0; i < edbInfoListLen; i++ {
+		for j := 0; j < edbInfoListLen; j++ {
+			if (edbInfoList[i].EdbNameAlias == edbInfoList[j].EdbNameAlias) &&
+				(edbInfoList[i].EdbInfoId != edbInfoList[j].EdbInfoId) &&
+				!(strings.Contains(edbInfoList[i].EdbName, edbInfoList[i].SourceName)) {
+				edbInfoList[i].EdbName = edbInfoList[i].EdbName + "(" + edbInfoList[i].SourceName + ")"
+			}
+		}
+	}
+
+	resp := data_manage.EdbInfoFilterDataResp{
+		Paging: page,
+		List:   edbInfoList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// AllListByEs
+// @Title 指标筛选接口
+// @Description 指标筛选接口
+// @Success 200 {object} data_manage.EdbInfoList
+// @Param	request	body request.SearchEdbInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfoFilterDataResp
+// @router /edb_info/public/list/es/all [post]
+func (c *EdbPublicController) AllListByEs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.AllSearchPublicEdbReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	// 选择所有指标,所以需要通过es获取数据
+
+	// 选中的指标id列表
+	edbInfoList := make([]*data_manage.EdbInfoList, 0)
+
+	// 选择所有指标,所以需要通过es获取数据
+	if req.IsSelectAll {
+		tmpEdbInfoList, err := data.GetAllEdbInfoListBySearchPublicEdbReq(req.SearchPublicEdbReq, c.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取指标列表失败!"
+			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
+			return
+		}
+
+		// 如果有过滤指标,那么就过滤吧
+		if len(req.NoEdbIdList) > 0 {
+			noEdbIdMap := make(map[int]bool)
+			for _, v := range req.NoEdbIdList {
+				noEdbIdMap[v] = true
+			}
+
+			for _, v := range tmpEdbInfoList {
+				if _, ok := noEdbIdMap[v.EdbInfoId]; !ok {
+					// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
+					edbInfoList = append(edbInfoList, v)
+				}
+			}
+		} else {
+			edbInfoList = tmpEdbInfoList
+		}
+
+		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+		if len(edbInfoList) > 0 {
+
+			edbInfoIdList := make([]int, 0)
+			for _, v := range edbInfoList {
+				v.ConvertToResp()
+				v.EdbNameAlias = v.EdbName
+				v.HaveOperaAuth = true
+				edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+			}
+
+			tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+				return
+			}
+			edbInfoMap := make(map[int]*data_manage.EdbInfo)
+			for _, v := range tmpEdbList {
+				edbInfoMap[v.EdbInfoId] = v
+			}
+
+			for _, v := range edbInfoList {
+				tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]
+				if !ok {
+					continue
+				}
+				v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
+			}
+		}
+	} else {
+		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+		if len(req.EdbIdList) > 0 {
+			edbInfoList, err = data_manage.GetEdbInfoListByCond(` AND edb_info_id in (?) `, []interface{}{req.EdbIdList})
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+				return
+			}
+		}
+	}
+
+	edbInfoListLen := len(edbInfoList)
+
+	for i := 0; i < edbInfoListLen; i++ {
+		for j := 0; j < edbInfoListLen; j++ {
+			if (edbInfoList[i].EdbNameAlias == edbInfoList[j].EdbNameAlias) &&
+				(edbInfoList[i].EdbInfoId != edbInfoList[j].EdbInfoId) &&
+				!(strings.Contains(edbInfoList[i].EdbName, edbInfoList[i].SourceName)) {
+				edbInfoList[i].EdbName = edbInfoList[i].EdbName + "(" + edbInfoList[i].SourceName + ")"
+			}
+		}
+	}
+
+	resp := data_manage.EdbInfoFilterDataResp{
+		List: edbInfoList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// BatchMoveEdb
+// @Title 指标批量移动接口
+// @Description 指标批量移动接口
+// @Param	request	body request.MoveEdbClassifyReq true "type json string"
+// @Success Ret=200 移动成功
+// @router /edb_info/public/batch_move [post]
+func (c *EdbPublicController) BatchMoveEdb() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.MoveEdbClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.NewClassifyId <= 0 {
+		br.Msg = `请选择要转移的新分类`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 校验分类
+	obj := data_manage.EdbPublicClassify{}
+	publicClassifyItem, err := obj.GetEdbClassifyById(req.NewClassifyId)
+	if err != nil {
+		br.Msg = "获取公共分类失败!"
+		br.ErrMsg = "获取公共分类失败!" + err.Error()
+		return
+	}
+	if publicClassifyItem.EdbPublicClassifyId <= 0 {
+		br.Msg = "公共分类不存在!"
+		br.ErrMsg = "公共分类不存在!"
+		return
+	}
+
+	// 只是取公开
+	req.SearchPublicEdbReq.EdbPublicList = []int{3}
+
+	edbInfoIdList := make([]int, 0)
+	if req.IsSelectAll {
+		// 获取指标
+		edbInfoList, err := data.GetAllEdbInfoListBySearchPublicEdbReq(req.SearchPublicEdbReq, c.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取指标列表失败!"
+			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
+			return
+		}
+		// 如果有过滤指标,那么就过滤吧
+		if len(req.NoEdbIdList) > 0 {
+			noEdbIdMap := make(map[int]bool)
+			for _, v := range req.NoEdbIdList {
+				noEdbIdMap[v] = true
+			}
+
+			for _, edbInfo := range edbInfoList {
+				if _, ok := noEdbIdMap[edbInfo.EdbInfoId]; !ok {
+					if edbInfo.PublicStatus != utils.DataPublicSuccess {
+						br.Msg = `存在未公开的指标:` + edbInfo.EdbName
+						br.IsSendEmail = false
+						return
+					}
+
+					// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
+					edbInfoIdList = append(edbInfoIdList, edbInfo.EdbInfoId)
+				}
+			}
+		} else {
+			for _, edbInfo := range edbInfoList {
+				if edbInfo.PublicStatus != utils.DataPublicSuccess {
+					br.Msg = `存在未公开的指标:` + edbInfo.EdbName
+					br.IsSendEmail = false
+					return
+				}
+				edbInfoIdList = append(edbInfoIdList, edbInfo.EdbInfoId)
+			}
+		}
+	} else {
+		edbInfoList, err := data_manage.GetEdbInfoListByCond(` AND edb_info_id in (?) `, []interface{}{req.EdbIdList})
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range edbInfoList {
+			if v.PublicStatus != utils.DataPublicSuccess {
+				br.Msg = `存在未公开的指标:` + v.EdbName
+				br.IsSendEmail = false
+				return
+			}
+		}
+		edbInfoIdList = req.EdbIdList
+	}
+
+	num := len(edbInfoIdList)
+	if num <= 0 {
+		br.Msg = `请选择要移动的指标!`
+		br.IsSendEmail = false
+		return
+	}
+	if num > 100 {
+		br.Msg = `最多只能选择100条指标!`
+		br.IsSendEmail = false
+		return
+	}
+
+	// 开始批量修改指标分类
+	if len(edbInfoIdList) > 0 {
+		err = data_manage.UpdatePublicClassifyIdByEdbInfoIdList(edbInfoIdList, req.NewClassifyId)
+		if err != nil {
+			br.Msg = `指标移动失败!`
+			br.ErrMsg = `指标移动失败,ERR:` + err.Error()
+			return
+		}
+		// 还得修改ES呢
+		for _, v := range edbInfoIdList {
+			data.AddOrEditEdbInfoToEs(v)
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 794 - 0
controllers/data_manage/public_edb_classify.go

@@ -0,0 +1,794 @@
+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/models/data_manage/request"
+	"eta_gn/eta_api/models/system"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/services/data/data_manage_permission"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"sort"
+)
+
+// EdbPublicClassifyController 数据管理-公共分类模块
+type EdbPublicClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// SimpleList
+// @Title 单层公共分类列表
+// @Description 单层公共分类列表
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/simple [get]
+func (c *EdbPublicClassifyController) SimpleList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	// 公共分类来源筛选
+	// 目前只有数据加工会涉及到公共分类
+	classifyType := utils.EdbClassifyTypeCalculate
+
+	// 默认查一级公共分类和一级公共分类下的指标信息,
+	// 如果是 子级公共分类,查询该子级公共分类的下一级公共分类和指标信息
+	// 增加标识判断是文件夹还是指标列表
+	parentId, _ := c.GetInt("ParentId")
+
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	rootList, err := edbPublicClassifyObj.GetEdbClassifyItemsByParentId(parentId, int8(classifyType))
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	nodeAll := make([]*data_manage.EdbClassifyItems, 0)
+
+	var sortList data_manage.EdbClassifyItemList
+	if parentId > 0 {
+		// 指标类型(基础指标,预测指标)
+		edbType := 0
+		switch classifyType {
+		case utils.EdbClassifyTypeBase:
+			edbType = 1
+		case utils.EdbClassifyTypeCalculate:
+			edbType = 2
+		}
+
+		allEdbInfo, err := data_manage.GetEdbInfoByPublicClassifyId(parentId, 0, edbType)
+		if err != nil {
+			br.Msg = "获取指标数据失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+
+		if len(allEdbInfo) > 0 {
+			editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(c.SysUser.AdminId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+				return
+			}
+			// 查询当前公共分类信息
+			for _, v := range allEdbInfo {
+				v.HaveOperaAuth = true
+				button := data.GetEdbOpButton(c.SysUser, v.SysUserId, v.EdbInfoId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth, editShareEdbInfoIdMap)
+				button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
+				v.Button = button
+				v.Children = make([]*data_manage.EdbClassifyItems, 0)
+				v.ParentId = parentId
+				nodeAll = append(nodeAll, v)
+			}
+		}
+
+	}
+	if len(rootList) > 0 {
+		// 已授权公共分类id
+		permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(c.SysUser.AdminId, 0)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
+			return
+		}
+
+		for _, v := range rootList {
+			// 公共分类设定了权限且无权限, 那么忽略掉该节点
+			if v.IsJoinPermission == 1 && !utils.InArrayByInt(permissionClassifyIdList, v.ClassifyId) {
+				continue
+			}
+
+			// 数据权限
+			v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+			// 按钮权限
+			button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+			v.Button = button
+			v.Children = make([]*data_manage.EdbClassifyItems, 0)
+			nodeAll = append(nodeAll, v)
+		}
+	}
+	if len(nodeAll) > 0 {
+		//根据sort值排序
+		sortList = nodeAll
+		sort.Sort(sortList)
+	}
+
+	language := `CN`
+	// 指标显示的语言
+	{
+		configDetail, _ := system.GetConfigDetailByCode(c.SysUser.AdminId, system.EdbLanguageVar)
+		if configDetail != nil {
+			language = configDetail.ConfigValue
+		} else {
+			configDetail, _ = system.GetDefaultConfigDetailByCode(system.EdbLanguageVar)
+			if configDetail != nil {
+				language = configDetail.ConfigValue
+			}
+		}
+	}
+
+	// 是否允许添加一级公共分类
+	canOpClassify := true
+	button := data.GetEdbClassifyOpButton(c.SysUser, 0, true)
+	if !button.AddButton {
+		canOpClassify = false
+	}
+
+	resp := new(data_manage.EdbClassifyListResp)
+	resp.AllNodes = sortList
+	resp.Language = language
+	resp.CanOpClassify = canOpClassify
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ClassifyTree
+// @Title 多层公共分类列表树
+// @Description 多层公共分类列表树
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/tree [get]
+func (c *EdbPublicClassifyController) ClassifyTree() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	// 公共分类来源筛选
+	classifyType := utils.EdbClassifyTypeCalculate
+
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	allList, err := edbPublicClassifyObj.GetAllEdbClassifyByType(int8(classifyType))
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	var sortList data_manage.EdbClassifyItemList
+	if len(allList) > 0 {
+		for k, v := range allList {
+			// 数据权限
+			v.HaveOperaAuth = true
+			// 按钮权限
+			button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+			allList[k].Button = button
+		}
+		allList = data.GetClassifyTreeRecursive(allList, 0)
+		//根据sort值排序
+		sortList = allList
+		sort.Sort(sortList)
+	}
+	language := `CN`
+
+	// 是否允许添加一级公共分类
+	canOpClassify := true
+	button := data.GetEdbClassifyOpButton(c.SysUser, 0, true)
+	if !button.AddButton {
+		canOpClassify = false
+	}
+
+	resp := new(data_manage.EdbClassifyListResp)
+	resp.AllNodes = sortList
+	resp.Language = language
+	resp.CanOpClassify = canOpClassify
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// AddEdbClassify
+// @Title 新增公共分类
+// @Description 新增公共分类接口
+// @Param	request	body data_manage.AddEdbClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /edb_public/classify/add [post]
+func (c *EdbPublicClassifyController) AddClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req data_manage.AddEdbClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "请输入公共分类名称"
+		br.IsSendEmail = false
+		return
+	}
+	if req.ParentId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+	// 公共分类来源筛选
+	classifyType := utils.EdbClassifyTypeCalculate
+
+	//添加指标
+	_, err, errMsg := data.AddEdbPublicClassify(req.ClassifyName, req.ParentId, uint8(classifyType), c.SysUser.AdminId, c.SysUser.RealName)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = errMsg + ";Err:" + err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	//count, err := data_manage.GetEdbClassifyCount(req.ClassifyName, req.ParentId)
+	//if err != nil {
+	//	br.Msg = "判断名称是否已存在失败"
+	//	br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
+	//	return
+	//}
+	//if count > 0 {
+	//	br.Msg = "公共分类名称已存在,请重新输入"
+	//	br.IsSendEmail = false
+	//	return
+	//}
+	////获取该层级下最大的排序数
+	//maxSort, err := data_manage.GetEdbClassifyMaxSort(req.ParentId, req.ClassifyType)
+	//
+	//classify := new(data_manage.EdbClassify)
+	//classify.ClassifyType = req.ClassifyType
+	//classify.ParentId = req.ParentId
+	//classify.ClassifyName = req.ClassifyName
+	//classify.HasData = 0
+	//classify.CreateTime = time.Now()
+	//classify.ModifyTime = time.Now()
+	//classify.SysUserId = c.SysUser.AdminId
+	//classify.SysUserRealName = c.SysUser.RealName
+	//classify.Level = req.Level + 1
+	//timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	//classify.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
+	//classify.Sort = maxSort
+	//
+	//_, err = data_manage.AddEdbClassify(classify)
+	//if err != nil {
+	//	br.Msg = "保存公共分类失败"
+	//	br.ErrMsg = "保存公共分类失败,Err:" + err.Error()
+	//	return
+	//}
+	br.Ret = 200
+	br.Msg = "新增成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// EditEdbClassify
+// @Title 修改公共分类
+// @Description 修改公共分类接口
+// @Param	request	body data_manage.EditEdbClassifyReq true "type json string"
+// @Success 200 Ret=200 修改成功
+// @router /edb_public/classify/edit [post]
+func (c *EdbPublicClassifyController) EditEdbClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req data_manage.EditEdbClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "请输入公共分类名称"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.ClassifyId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.EditEdbPublicClassify(req.ClassifyId, req.ClassifyName, c.SysUser)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = errMsg + ";Err:" + err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	br.Ret = 200
+	br.Msg = "修改成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// DeleteEdbClassifyCheck
+// @Title 删除检测接口
+// @Description 删除检测接口
+// @Param	request	body request.PublicClassifyDeleteCheckReq true "type json string"
+// @Success 200 Ret=200 检测成功
+// @router /edb_public/classify/delete/check [post]
+func (c *EdbPublicClassifyController) DeleteClassifyCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.PublicClassifyDeleteCheckReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId <= 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+	deleteStatus, tipsMsg, _, tableList, err, errMsg := data.DeleteEdbPublicClassifyCheck(req.ClassifyId, c.SysUser)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	if c.Lang == "en" {
+		if utils.ViperConfig.InConfig(tipsMsg) {
+			tipsMsg = utils.ViperConfig.GetString(tipsMsg)
+		}
+	}
+
+	//var deleteStatus int
+	//var tipsMsg string
+	////删除公共分类
+	//if req.ClassifyId > 0 && req.EdbInfoId == 0 {
+	//	//判断公共分类下,是否含有指标
+	//	count, err := data_manage.GetEdbInfoCountByClassifyId(req.ClassifyId)
+	//	if err != nil {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "公共分类下是否含有指标失败,Err:" + err.Error()
+	//		return
+	//	}
+	//
+	//	if count > 0 {
+	//		deleteStatus = 1
+	//		tipsMsg = "若目录关联指标不可删除"
+	//	}
+	//}
+	//
+	//if deleteStatus != 1 && req.EdbInfoId == 0 {
+	//	classifyCount, err := data_manage.GetClassifyCountByClassifyId(req.ClassifyId)
+	//	if err != nil && !utils.IsErrNoRow(err) {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "公共分类下是否含有指标失败,Err:" + err.Error()
+	//		return
+	//	}
+	//	if classifyCount > 0 {
+	//		deleteStatus = 2
+	//		tipsMsg = "确认删除当前目录及包含的子目录吗"
+	//	}
+	//}
+	//
+	////删除指标
+	//if req.EdbInfoId > 0 {
+	//	//判断指标是否用于作图,如果用于作图,则不可删除
+	//	chartCount, err := data_manage.GetChartEdbMappingCount(req.EdbInfoId)
+	//	if err != nil && !utils.IsErrNoRow(err) {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "判断指标是否被用于作图失败,Err:" + err.Error()
+	//		return
+	//	}
+	//	if chartCount > 0 {
+	//		deleteStatus = 3
+	//		tipsMsg = "当前指标已用作画图,不可删除"
+	//	}
+	//	//判断指标是否用于计算
+	//	{
+	//		calculateCount, err := data_manage.GetEdbInfoCalculateMappingCount(req.EdbInfoId)
+	//		if err != nil && !utils.IsErrNoRow(err) {
+	//			br.Msg = "删除失败"
+	//			br.ErrMsg = "判断指标是否被用于计算失败,GetEdbInfoCalculateCount Err:" + err.Error()
+	//			return
+	//		}
+	//		if calculateCount > 0 {
+	//			deleteStatus = 4
+	//			tipsMsg = "当前指标已用作,指标运算,不可删除"
+	//		}
+	//	}
+	//}
+
+	resp := new(data_manage.ClassifyDeleteCheckResp)
+	resp.DeleteStatus = deleteStatus
+	resp.TipsMsg = tipsMsg
+	resp.TableList = tableList
+	br.Ret = 200
+	br.Msg = "检测成功"
+	br.Success = true
+	br.Data = resp
+}
+
+// DeleteEdbClassify
+// @Title 删除公共分类/指标
+// @Description 删除公共分类/指标接口
+// @Param	request	body request.PublicClassifyDeleteCheckReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /edb_public/classify/delete [post]
+func (c *EdbPublicClassifyController) DeleteClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.PublicClassifyDeleteCheckReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId <= 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	nextItem, _, err, errMsg := data.DeleteEdbPublicClassify(req.ClassifyId, sysUser, string(c.Ctx.Input.RequestBody), c.Ctx.Input.URI())
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+
+	resp := data_manage.AddEdbInfoResp{}
+	if nextItem != nil {
+		resp = data_manage.AddEdbInfoResp{
+			EdbInfoId:  nextItem.EdbInfoId,
+			UniqueCode: nextItem.UniqueCode,
+		}
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+	br.Data = resp
+}
+
+// ListV2
+// @Title 公共分类列表
+// @Description 公共分类列表接口
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/list [get]
+func (c *EdbPublicClassifyController) ListV2() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	// 公共分类来源筛选
+	classifyType, _ := c.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), c.SysUser.AdminId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	//classifyAll, err := data_manage.GetEdbClassifyAll()
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, c.SysUser.AdminId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	// 公共分类map
+	classifyMap := make(map[int]*data_manage.EdbClassifyItems)
+	for _, v := range classifyAll {
+		classifyMap[v.ClassifyId] = v
+	}
+
+	// 已授权公共分类id
+	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(c.SysUser.AdminId, 0)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
+		return
+	}
+
+	// 获取当前账号的不可见指标
+	obj := data_manage.EdbInfoNoPermissionAdmin{}
+	confList, err := obj.GetAllListByAdminId(c.SysUser.AdminId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+		return
+	}
+	noPermissionEdbInfoIdMap := make(map[int]bool)
+	for _, v := range confList {
+		noPermissionEdbInfoIdMap[v.EdbInfoId] = true
+	}
+	//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()
+		return
+	}
+	edbInfoMap := make(map[int][]*data_manage.EdbClassifyItems)
+	if len(allEdbInfo) > 0 {
+		// 获取所有有权限的指标和公共分类
+		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(c.SysUser.AdminId, 0, 0)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的指标和公共分类失败,Err:" + err.Error()
+			return
+		}
+		editShareEdbInfoIdMap, err := data.GetAllEditSharedEdbInfoIdMapByReceivedUserId(c.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有编辑权限的分享指标失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range allEdbInfo {
+			// 如果指标不可见,那么就不返回该指标
+			if _, ok := noPermissionEdbInfoIdMap[v.EdbInfoId]; ok {
+				continue
+			}
+			// 数据权限
+			if classifyInfo, ok := classifyMap[v.ClassifyId]; ok {
+				v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
+			}
+
+			button := data.GetEdbOpButton(c.SysUser, v.SysUserId, v.EdbInfoId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth, editShareEdbInfoIdMap)
+			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
+			v.Button = button
+			edbInfoMap[v.ClassifyId] = append(edbInfoMap[v.ClassifyId], v)
+		}
+	}
+	rootChildMap := make(map[int][]*data_manage.EdbClassifyItems)
+	for _, v := range classifyAll {
+		// 数据权限
+		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+		// 按钮权限
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+		button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
+		v.Button = button
+
+		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
+		if existItems, ok := edbInfoMap[v.ClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.EdbClassifyItems, 0)
+			v.Children = items
+		}
+	}
+	nodeAll := make([]*data_manage.EdbClassifyItems, 0)
+	for _, v := range rootList {
+		// 数据权限
+		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+		// 按钮权限
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+		v.Button = button
+
+		if existItems, ok := rootChildMap[v.ClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.EdbClassifyItems, 0)
+			v.Children = items
+		}
+		nodeAll = append(nodeAll, v)
+	}
+	resp := new(data_manage.EdbClassifyListResp)
+	resp.AllNodes = nodeAll
+	resp.CanOpClassify = true
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// EdbClassifyMove
+// @Title 分类移动接口
+// @Description 分类移动接口
+// @Success 200 {object} data_manage.MoveEdbClassifyReq
+// @router /edb_public/edb_classify/move [post]
+func (c *EdbPublicClassifyController) EdbClassifyMove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req data_manage.MoveEdbClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId <= 0 && req.EdbInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "请选择拖动目标,分类目录或者指标"
+		return
+	}
+
+	// 分类来源筛选
+	classifyType := req.ClassifyType // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+
+	err, errMsg := data.MoveEdbPublicClassify(req, sysUser, uint8(classifyType))
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	////判断分类是否存在
+	//edbClassifyInfo, err := data_manage.GetEdbClassifyById(req.ClassifyId)
+	//if err != nil {
+	//	br.Msg = "移动失败"
+	//	br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+	//	return
+	//}
+	//updateCol := make([]string, 0)
+	//
+	////判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	//if edbClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId != 0 {
+	//	parentEdbClassifyInfo, err := data_manage.GetEdbClassifyById(req.ParentClassifyId)
+	//	if err != nil {
+	//		br.Msg = "移动失败"
+	//		br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
+	//		return
+	//	}
+	//	edbClassifyInfo.ParentId = parentEdbClassifyInfo.ClassifyId
+	//	edbClassifyInfo.Level = parentEdbClassifyInfo.Level + 1
+	//	edbClassifyInfo.ModifyTime = time.Now()
+	//	updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
+	//}
+	//
+	////如果有传入 上一个兄弟节点分类id
+	//if req.PrevClassifyId > 0 {
+	//	prevClassify, err := data_manage.GetEdbClassifyById(req.PrevClassifyId)
+	//	if err != nil {
+	//		br.Msg = "移动失败"
+	//		br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
+	//		return
+	//	}
+	//
+	//	//如果是移动在两个兄弟节点之间
+	//	if req.NextClassifyId > 0 {
+	//		//下一个兄弟节点
+	//		nextClassify, err := data_manage.GetEdbClassifyById(req.NextClassifyId)
+	//		if err != nil {
+	//			br.Msg = "移动失败"
+	//			br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
+	//			return
+	//		}
+	//		//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+	//		if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == edbClassifyInfo.Sort {
+	//			//变更兄弟节点的排序
+	//			updateSortStr := `sort + 2`
+	//			_ = data_manage.UpdateEdbClassifySortByParentId(prevClassify.ParentId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr)
+	//		} else {
+	//			//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+	//			if nextClassify.Sort-prevClassify.Sort == 1 {
+	//				//变更兄弟节点的排序
+	//				updateSortStr := `sort + 1`
+	//				_ = data_manage.UpdateEdbClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
+	//			}
+	//		}
+	//	}
+	//
+	//	edbClassifyInfo.Sort = prevClassify.Sort + 1
+	//	edbClassifyInfo.ModifyTime = time.Now()
+	//	updateCol = append(updateCol, "Sort", "ModifyTime")
+	//} else {
+	//	firstClassify, err := data_manage.GetFirstEdbClassifyByParentId(edbClassifyInfo.ParentId)
+	//	if err != nil && !utils.IsErrNoRow(err) {
+	//		br.Msg = "移动失败"
+	//		br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
+	//		return
+	//	}
+	//
+	//	//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+	//	if firstClassify != nil && firstClassify.ChartClassifyId > 0 && firstClassify.Sort == 0 {
+	//		updateSortStr := ` sort + 1 `
+	//		_ = data_manage.UpdateEdbClassifySortByParentId(firstClassify.ParentId, firstClassify.ClassifyId-1, 0, updateSortStr)
+	//	}
+	//
+	//	edbClassifyInfo.Sort = 0 //那就是排在第一位
+	//	edbClassifyInfo.ModifyTime = time.Now()
+	//	updateCol = append(updateCol, "Sort", "ModifyTime")
+	//}
+	//
+	////更新
+	//if len(updateCol) > 0 {
+	//	err = edbClassifyInfo.Update(updateCol)
+	//	if err != nil {
+	//		br.Msg = "移动失败"
+	//		br.ErrMsg = "修改失败,Err:" + err.Error()
+	//		return
+	//	}
+	//}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "移动成功"
+}

+ 13 - 10
controllers/data_manage/range_analysis/chart_classify.go

@@ -22,7 +22,6 @@ type RangeChartClassifyController struct {
 // ChartClassifyList
 // @Title 区间分析图表分类列表
 // @Description 区间分析图表分类列表接口
-// @Param   IsShowMe   query   bool  false       "是否只看我的,true、false"
 // @Param   ParentId   query   bool  false       "父级ID"
 // @Param   Source   query   int  false       "图表类型,3:相关性,4:滚动相关性"
 // @Success 200 {object} data_manage.ChartClassifyListResp
@@ -53,13 +52,12 @@ func (this *RangeChartClassifyController) ChartClassifyList() {
 	//	}
 	//}
 
-	isShowMe, _ := this.GetBool("IsShowMe")
 	parentId, _ := this.GetInt("ParentId")
 	source, _ := this.GetInt("Source", utils.CHART_SOURCE_RANGE_ANALYSIS)
 
 	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
 	// 查询分类节点
-	rootList, err := data_manage.GetChartClassifyByParentId(parentId, utils.CHART_SOURCE_RANGE_ANALYSIS)
+	rootList, err := data_manage.GetChartClassifyByParentId(parentId, utils.CHART_SOURCE_RANGE_ANALYSIS, this.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -104,10 +102,7 @@ func (this *RangeChartClassifyController) ChartClassifyList() {
 			return
 		}
 
-		var adminId int
-		if isShowMe {
-			adminId = this.SysUser.AdminId
-		}
+		adminId := this.SysUser.AdminId
 
 		charts, e := data_manage.GetChartInfoBySourceAndParentId(source, parentId, adminId)
 		if e != nil {
@@ -115,10 +110,18 @@ func (this *RangeChartClassifyController) ChartClassifyList() {
 			br.ErrMsg = fmt.Sprintf("获取图表信息失败, Err: %v", e)
 			return
 		}
+
+		editShareChartInfoIdMap, err := data.GetAllEditSharedChartInfoIdMapByReceivedUserId(this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有编辑权限的分享图表失败,Err:" + err.Error()
+			return
+		}
+
 		for _, v := range charts {
 			// 操作按钮权限
 			v.HaveOperaAuth = data_manage_permission.CheckChartPermissionByPermissionIdList(v.IsJoinPermission, currClassify.IsJoinPermission, v.ChartInfoId, v.ChartClassifyId, permissionEdbIdList, permissionClassifyIdList)
-			button := data.GetChartOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+			button := data.GetChartOpButton(this.SysUser, v.SysUserId, v.ChartInfoId, v.HaveOperaAuth, editShareChartInfoIdMap)
 			button.AddButton = false //不管有没有权限,图表都是没有添加按钮的
 			v.Button = button
 			v.ParentId = parentId
@@ -153,7 +156,7 @@ func (this *RangeChartClassifyController) ChartClassifyItems() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_RANGE_ANALYSIS)
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_RANGE_ANALYSIS, this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -519,7 +522,7 @@ func (this *RangeChartClassifyController) DeleteChartClassify() {
 		}
 		//删除ES
 		{
-			go data.EsDeleteChartInfo(chartInfo.ChartInfoId)
+			go data.DeleteChartInfoToEs(chartInfo.ChartInfoId)
 			// 删除MY ETA 图表 es数据
 			//go data.EsDeleteMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)

+ 5 - 16
controllers/data_manage/range_analysis/chart_info.go

@@ -897,7 +897,6 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
 // @Param   ChartClassifyId   query   int  true       "分类id"
 // @Param   Keyword   query   string  true       "搜索关键词"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "图表类型,3:区间计算,4:滚动区间计算"
 // @Success 200 {object} data_manage.ChartListResp
 // @router /chart_info/list [get]
@@ -964,12 +963,8 @@ func (this *RangeChartChartInfoController) List() {
 		condition += ` )`
 	}
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	if isShowMe {
-		condition += ` AND sys_user_id = ? `
-		pars = append(pars, sysUser.AdminId)
-	}
+	condition += ` AND sys_user_id = ? `
+	pars = append(pars, sysUser.AdminId)
 
 	// 获取当前账号的不可见指标
 	noPermissionChartIdList := make([]int, 0)
@@ -1780,7 +1775,6 @@ func (this *RangeChartChartInfoController) MultipleGraphConfigEdbList() {
 // @Title 图表模糊搜索(从es获取)
 // @Description  图表模糊搜索(从es获取)
 // @Param   Keyword   query   string  true       "图表名称"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Param   Source   query   int  true       "来源,3:相关性,4:滚动相关性,默认0:全部"
 // @Success 200 {object} data_manage.ChartInfo
 // @router /chart_info/search_by_es [get]
@@ -1812,12 +1806,7 @@ func (this *RangeChartChartInfoController) SearchByEs() {
 
 	keyword := this.GetString("Keyword")
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	showSysId := 0
-	if isShowMe {
-		showSysId = sysUser.AdminId
-	}
+	showSysId := sysUser.AdminId
 
 	sourceList := make([]int, 0)
 	sourceList = append(sourceList, utils.CHART_SOURCE_RANGE_ANALYSIS)
@@ -1996,7 +1985,7 @@ func (this *RangeChartChartInfoController) BaseInfoEdit() {
 	}
 
 	//添加es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 
@@ -2094,7 +2083,7 @@ func (this *RangeChartChartInfoController) ChartInfoSave() {
 	}
 
 	//修改es数据
-	go data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go data.AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 

+ 1 - 1
controllers/data_manage/wind_data.go

@@ -28,7 +28,7 @@ func (this *EdbInfoController) WindClassify() {
 	// 增加标识判断是文件夹还是指标列表
 	parentId, _ := this.GetInt("ParentId")
 	// 特殊处理顶级分类
-	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, 0)
+	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, 0, 0)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()

+ 704 - 0
controllers/fix.go

@@ -0,0 +1,704 @@
+package controllers
+
+import (
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// init
+// @Description: 数据修复
+// @author: Roc
+// @datetime 2024-12-02 09:29:56
+func init() {
+	// ### 1、先修复指标分类完整路径
+	//initFixEdbClassifyPath()
+
+	// ### 2、再修复个人分类、删除不存在指标的分类
+	// ### 2.1 数据加工
+	//initFixSelfEdbClassify(utils.EdbClassifyTypeCalculate)
+	//
+	//// ### 2.2 衍生指标
+	//initFixSelfEdbClassify(utils.EdbClassifyTypePredict)
+	//
+
+	// 开始图表数据了
+
+	// ### 3、修复图表分类完整路径
+	//initFixChartClassifyPath()
+
+	// ### 4、修复图表分类完整路径
+	//initFixSelfChartClassify()
+
+	// ### 5、修复ES数据
+	//initEs()
+
+	//fmt.Println("修复完成")
+}
+
+// initFixEdbClassifyPath
+// @Description: 修复分类完整路径
+// @author: Roc
+// @datetime 2024-11-26 15:40:57
+func initFixEdbClassifyPath() {
+	allList := make([]*data_manage.EdbClassifyItems, 0)
+	allList, e := data_manage.GetEdbClassifyByClassifyTypes([]int{utils.EdbClassifyTypeBase, utils.EdbClassifyTypePredict, utils.EdbClassifyTypeCalculate}, 0)
+	if e != nil {
+		fmt.Println("获取分类失败", e)
+		return
+	}
+
+	var sortList data_manage.EdbClassifyItemList
+
+	allList = data.GetClassifyTreeRecursive(allList, 0)
+	//根据sort值排序
+	sortList = allList
+	sort.Sort(sortList)
+
+	for _, v := range sortList {
+		updateEdbPath(v, "", "")
+	}
+	fmt.Println("修复分类路径完成")
+}
+
+func updateEdbPath(item *data_manage.EdbClassifyItems, classifyNamePath, classifyIdPath string) {
+	if classifyNamePath == `` {
+		classifyNamePath = item.ClassifyName
+		classifyIdPath = fmt.Sprint(item.ClassifyId)
+	} else {
+		classifyNamePath = fmt.Sprint(classifyNamePath, "|", item.ClassifyName)
+		classifyIdPath = fmt.Sprint(classifyIdPath, ",", item.ClassifyId)
+	}
+	err := data_manage.UpdateEdbClassify(item.ClassifyId, classifyNamePath, classifyIdPath)
+	if err != nil {
+		fmt.Println(item.ClassifyId, ";更新失败", err)
+	}
+	if item.Children != nil {
+		for _, v := range item.Children {
+			updateEdbPath(v, classifyNamePath, classifyIdPath)
+		}
+	}
+}
+
+// initFixSelfEdbClassify
+// @Description: initFixUserClassify
+// @author: Roc
+// @datetime 2024-11-29 16:57:54
+func initFixSelfEdbClassify(classifyType int) {
+	// 指标数据明细
+	condition := ` AND edb_info_type = 0 and edb_type = 2 `
+	if classifyType == utils.EdbClassifyTypePredict {
+		condition = ` AND edb_info_type = 1 `
+	}
+
+	pars := make([]interface{}, 0)
+	edbList, err := data_manage.GetEdbInfoListByCond(condition, pars)
+	if err != nil {
+		fmt.Println("查找指标加工数据失败", err.Error())
+		return
+	}
+
+	edbClassifyIdMap := make(map[int]bool)
+	classifyIdList := make([]int, 0)
+
+	edbUserMap := make(map[int]string)
+
+	for _, v := range edbList {
+		if _, ok := edbClassifyIdMap[v.ClassifyId]; !ok {
+			classifyIdList = append(classifyIdList, v.ClassifyId)
+			edbClassifyIdMap[v.ClassifyId] = true
+		}
+
+		edbUserMap[v.SysUserId] = v.SysUserRealName
+	}
+
+	// 获取所有数据加工的分类
+	classifyList, err := data_manage.GetAllEdbClassifyByType(classifyType, 0)
+	if err != nil {
+		fmt.Println("获取数据加工分类失败", err.Error())
+		return
+	}
+
+	hasClassifyIdStrList := make([]string, 0)
+	for _, v := range classifyList {
+		// 判断当前分类id是否加到指标中,如果加进去了,那么才处理
+		_, ok := edbClassifyIdMap[v.ClassifyId]
+		if !ok {
+			continue
+		}
+		hasClassifyIdStrList = append(hasClassifyIdStrList, v.ClassifyIdPath)
+	}
+
+	classifyIdStrList := make([]string, 0)
+	if len(hasClassifyIdStrList) > 0 {
+		classifyIdStrList = strings.Split(strings.Join(hasClassifyIdStrList, ","), ",")
+	}
+	classifyIdMap := make(map[string]bool)
+	for _, v := range classifyIdStrList {
+		classifyIdMap[v] = true
+	}
+	newClassifyList := make([]*data_manage.EdbClassifyItems, 0)
+	newClassifyMap := make(map[string]bool)
+	for _, v := range classifyList {
+		classifyIdStr := fmt.Sprint(v.ClassifyId)
+
+		// 是否在关联指标的map里面,如果不在的话,那么就过滤
+		_, ok := classifyIdMap[classifyIdStr]
+		if !ok {
+			continue
+		}
+
+		// 是否已经加到需要关联指标分类的map里面,如果已经在了,那么也过滤
+		_, ok = newClassifyMap[classifyIdStr]
+		if ok {
+			continue
+		}
+
+		newClassifyMap[classifyIdStr] = true
+		newClassifyList = append(newClassifyList, v)
+	}
+
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), 0)
+	nodeAll := make([]*data_manage.EdbClassifyItems, 0)
+	for k := range rootList {
+		rootNode := rootList[k]
+		data.EdbClassifyItemsMakeTree(newClassifyList, rootNode)
+		nodeAll = append(nodeAll, rootNode)
+	}
+
+	// 创建新的分类
+	// [用户id][原分类id][新分类id]
+	userClassifyIdMap := make(map[int]map[int]int)
+	for userId, sysUserName := range edbUserMap {
+		classifyRelationMap := make(map[int]int)
+		for _, v := range nodeAll {
+			createNewEdbClassify(userId, 0, 0, 0, sysUserName, ``, ``, v, classifyRelationMap)
+		}
+		userClassifyIdMap[userId] = classifyRelationMap
+	}
+
+	// ##### 第二步,指标数据迁移
+
+	// 指标数据迁移
+	for _, v := range edbList {
+		userClassifyMap, ok := userClassifyIdMap[v.SysUserId]
+		if !ok {
+			fmt.Println("找不到该用户所属的分类,userId:", v.SysUserId)
+			continue
+		}
+
+		newClassifyId, ok := userClassifyMap[v.ClassifyId]
+		if !ok {
+			fmt.Println("找不到该用户所属的分类,classifyId:", v.ClassifyId)
+			continue
+		}
+		// 开始迁移指标数据
+		err = data_manage.UpdateClassifyIdByEdbInfoId(v.EdbInfoId, newClassifyId)
+		if err != nil {
+			fmt.Println("指标数据迁移失败", err.Error())
+		}
+	}
+
+	// ##### 3、开始删除没有指标的分类
+	deleteNullEdbClassify(classifyType)
+	return
+}
+
+func deleteNullEdbClassify(classifyType int) {
+	// 指标列表数据
+	condition := ` AND edb_info_type = 0 and edb_type = 2 `
+	if classifyType == utils.EdbClassifyTypePredict {
+		condition = ` AND edb_info_type = 1 `
+	}
+
+	pars := make([]interface{}, 0)
+	edbList, err := data_manage.GetEdbInfoListByCond(condition, pars)
+	if err != nil {
+		fmt.Println("查找指标加工数据失败", err.Error())
+		return
+	}
+
+	edbClassifyIdMap := make(map[int]bool)
+	classifyIdList := make([]int, 0)
+
+	for _, v := range edbList {
+		if _, ok := edbClassifyIdMap[v.ClassifyId]; !ok {
+			classifyIdList = append(classifyIdList, v.ClassifyId)
+			edbClassifyIdMap[v.ClassifyId] = true
+		}
+	}
+
+	// 获取所有数据加工的分类
+	classifyList, err := data_manage.GetAllEdbClassifyByType(classifyType, 0)
+	if err != nil {
+		fmt.Println("获取数据加工分类失败", err.Error())
+		return
+	}
+
+	// 存在指标的分类
+	hasEdbClassifyList := make([]*data_manage.EdbClassifyItems, 0)
+	for _, v := range classifyList {
+		if _, ok := edbClassifyIdMap[v.ClassifyId]; ok {
+			hasEdbClassifyList = append(hasEdbClassifyList, v)
+		}
+	}
+
+	// 待删除的分类id集合
+	deleteClassifyIdMap := make(map[int]int)
+	// 全部的分类id集合
+	for _, v := range classifyList {
+		deleteClassifyIdMap[v.ClassifyId] = v.ClassifyId
+	}
+
+	// 存在指标的的分类id集合
+	hasClassifyIdStrList := make([]string, 0)
+	for _, v := range hasEdbClassifyList {
+		hasClassifyIdStrList = append(hasClassifyIdStrList, v.ClassifyIdPath)
+	}
+	classifyIdStrList := make([]string, 0)
+	if len(hasClassifyIdStrList) > 0 {
+		classifyIdStrList = strings.Split(strings.Join(hasClassifyIdStrList, ","), ",")
+	}
+	for _, v := range classifyIdStrList {
+		classifyId, err := strconv.Atoi(v)
+		if err != nil {
+			fmt.Println("分类字符串转int失败,", err.Error())
+			return
+		}
+		delete(deleteClassifyIdMap, classifyId)
+	}
+
+	// 删除空分类
+	if len(deleteClassifyIdMap) > 0 {
+		deleteClassifyIdList := make([]int, 0)
+		for _, v := range deleteClassifyIdMap {
+			deleteClassifyIdList = append(deleteClassifyIdList, v)
+		}
+
+		err = data_manage.DelEdbClassifyByIdList(deleteClassifyIdList)
+		if err != nil {
+			fmt.Println("删除空分类失败", err.Error())
+			return
+		}
+	}
+}
+
+// createNewEdbClassify
+// @Description: 创建分类
+// @author: Roc
+// @datetime 2024-11-29 17:57:47
+// @param userId int
+// @param parentId int
+// @param rootId int
+// @param level int
+// @param sysUserName string
+// @param parentClassifyNamePath string
+// @param parentClassifyIdPath string
+// @param node *data_manage.EdbClassifyItems
+// @param classifyRelationMap map[int]int
+func createNewEdbClassify(userId, parentId, rootId, level int, sysUserName, parentClassifyNamePath, parentClassifyIdPath string, node *data_manage.EdbClassifyItems, classifyRelationMap map[int]int) {
+	var classifyNamePath, classifyIdPath string
+
+	if parentId > 0 {
+		classifyNamePath = fmt.Sprint(parentClassifyNamePath, "|", node.ClassifyName)
+		classifyIdPath = fmt.Sprint(parentClassifyIdPath, ",")
+	} else {
+		classifyNamePath = node.ClassifyName
+	}
+
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	classifyInfo := &data_manage.EdbClassify{
+		//ClassifyId:      0,
+		ClassifyType:     node.ClassifyType,
+		ClassifyName:     node.ClassifyName,
+		ClassifyNameEn:   node.ClassifyNameEn,
+		ParentId:         parentId,
+		RootId:           rootId,
+		HasData:          1,
+		CreateTime:       time.Now(),
+		ModifyTime:       time.Now(),
+		SysUserId:        userId,
+		SysUserRealName:  sysUserName,
+		Level:            level + 1,
+		UniqueCode:       utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
+		Sort:             node.Sort,
+		ClassifyNamePath: classifyNamePath,
+	}
+	err := data_manage.AddEdbClassify(classifyInfo)
+	if err != nil {
+		fmt.Println("创建分类失败:", err.Error())
+		return
+	}
+
+	updateCols := []string{"ClassifyIdPath"}
+	// 更改分类id完整路径path
+	classifyInfo.ClassifyIdPath = fmt.Sprint(classifyIdPath, classifyInfo.ClassifyId)
+
+	if rootId <= 0 {
+		rootId = classifyInfo.ClassifyId
+		classifyInfo.RootId = classifyInfo.ClassifyId
+		updateCols = append(updateCols, "RootId")
+	}
+
+	_ = classifyInfo.Update(updateCols)
+
+	classifyRelationMap[node.ClassifyId] = classifyInfo.ClassifyId
+
+	level = classifyInfo.Level
+
+	if node.Children == nil {
+		return
+	}
+	if len(node.Children) <= 0 {
+		return
+	}
+	for _, child := range node.Children {
+		createNewEdbClassify(userId, classifyInfo.ClassifyId, rootId, level, sysUserName, classifyNamePath, classifyInfo.ClassifyIdPath, child, classifyRelationMap)
+	}
+
+	return
+}
+
+// initFixChartClassifyPath
+// @Description: 修复图表分类完整路径
+// @author: Roc
+// @datetime 2024-11-26 15:40:57
+func initFixChartClassifyPath() {
+	fmt.Println("开始修复图表分类路径,请稍等...")
+	allList := make([]*data_manage.ChartClassifyItems, 0)
+	allList, e := data_manage.GetAllChartClassify()
+	if e != nil {
+		fmt.Println("获取分类失败", e)
+		return
+	}
+
+	allList = data.GetChartClassifyTreeRecursive(allList, 0)
+	//根据sort值排序
+
+	for _, v := range allList {
+		updateChartPath(v, "", "")
+	}
+	fmt.Println("修复图表分类路径完成")
+}
+
+// initFixSelfChartClassify
+// @Description: 修复用户图表分类信息
+// @author: Roc
+// @datetime 2024-11-29 16:57:54
+func initFixSelfChartClassify() {
+	fmt.Println("修复用户图表分类信息开始,请稍后...")
+	// 图表数据明细
+	condition := ``
+
+	pars := make([]interface{}, 0)
+	chartList, err := data_manage.GetChartListByCondition(condition, pars, 0, 1000000)
+	if err != nil {
+		fmt.Println("查找用户图表列表数据失败", err.Error())
+		return
+	}
+
+	chartClassifyIdMap := make(map[int]bool)
+	classifyIdList := make([]int, 0)
+
+	edbUserMap := make(map[int]string)
+
+	for _, v := range chartList {
+		if _, ok := chartClassifyIdMap[v.ChartClassifyId]; !ok {
+			classifyIdList = append(classifyIdList, v.ChartClassifyId)
+			chartClassifyIdMap[v.ChartClassifyId] = true
+		}
+
+		edbUserMap[v.SysUserId] = v.SysUserRealName
+	}
+
+	// 获取所有图表的分类
+	classifyList, err := data_manage.GetAllChartClassify()
+	if err != nil {
+		fmt.Println("获取图表分类失败", err.Error())
+		return
+	}
+
+	hasClassifyIdStrList := make([]string, 0)
+	for _, v := range classifyList {
+		// 判断当前分类id是否加到指标中,如果加进去了,那么才处理
+		_, ok := chartClassifyIdMap[v.ChartClassifyId]
+		if !ok {
+			continue
+		}
+		hasClassifyIdStrList = append(hasClassifyIdStrList, v.ChartClassifyIdPath)
+	}
+	classifyIdStrList := make([]string, 0)
+	if len(hasClassifyIdStrList) > 0 {
+		classifyIdStrList = strings.Split(strings.Join(hasClassifyIdStrList, ","), ",")
+	}
+	classifyIdMap := make(map[string]bool)
+	for _, v := range classifyIdStrList {
+		classifyIdMap[v] = true
+	}
+	newClassifyList := make([]*data_manage.ChartClassifyItems, 0)
+	newClassifyMap := make(map[string]bool)
+	for _, v := range classifyList {
+		classifyIdStr := fmt.Sprint(v.ChartClassifyId)
+
+		// 是否在关联指标的map里面,如果不在的话,那么就过滤
+		_, ok := classifyIdMap[classifyIdStr]
+		if !ok {
+			continue
+		}
+
+		// 是否已经加到需要关联指标分类的map里面,如果已经在了,那么也过滤
+		_, ok = newClassifyMap[classifyIdStr]
+		if ok {
+			continue
+		}
+
+		newClassifyMap[classifyIdStr] = true
+		newClassifyList = append(newClassifyList, v)
+	}
+
+	rootList, err := data_manage.GetAllChartClassifyByParentId(0)
+	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
+	for k := range rootList {
+		rootNode := rootList[k]
+		data.ChartClassifyItemsMakeTreeV2(newClassifyList, rootNode)
+		nodeAll = append(nodeAll, rootNode)
+	}
+
+	// 创建新的分类
+	// [用户id][原分类id][新分类id]
+	userClassifyIdMap := make(map[int]map[int]int)
+	for userId, sysUserName := range edbUserMap {
+		classifyRelationMap := make(map[int]int)
+		for _, v := range nodeAll {
+			createNewChartClassify(userId, 0, 0, 0, sysUserName, ``, ``, v, classifyRelationMap)
+		}
+		userClassifyIdMap[userId] = classifyRelationMap
+	}
+
+	// ##### 第二步,图表数据迁移
+
+	// 指标数据迁移
+	for _, v := range chartList {
+		userClassifyMap, ok := userClassifyIdMap[v.SysUserId]
+		if !ok {
+			fmt.Println("找不到该用户所属的分类,userId:", v.SysUserId)
+			continue
+		}
+
+		newClassifyId, ok := userClassifyMap[v.ChartClassifyId]
+		if !ok {
+			fmt.Println("找不到该用户所属的图表分类,classifyId:", v.ChartClassifyId)
+			continue
+		}
+		// 开始迁移指标数据
+		err = data_manage.UpdateClassifyIdByChartInfoId(v.ChartInfoId, newClassifyId)
+		if err != nil {
+			fmt.Println("图表数据迁移失败", err.Error())
+		}
+	}
+
+	// ##### 3、开始删除没有图表的分类
+	deleteNullChartClassify()
+
+	fmt.Println("修复用户图表分类信息完成")
+	return
+}
+
+func deleteNullChartClassify() {
+	// 图表数据明细
+	condition := ``
+
+	pars := make([]interface{}, 0)
+	chartList, err := data_manage.GetChartListByCondition(condition, pars, 0, 1000000)
+	if err != nil {
+		fmt.Println("查找指标加工数据失败", err.Error())
+		return
+	}
+
+	chartClassifyIdMap := make(map[int]bool)
+	classifyIdList := make([]int, 0)
+
+	for _, v := range chartList {
+		if _, ok := chartClassifyIdMap[v.ChartClassifyId]; !ok {
+			classifyIdList = append(classifyIdList, v.ChartClassifyId)
+			chartClassifyIdMap[v.ChartClassifyId] = true
+		}
+	}
+
+	// 获取所有数据加工的分类
+	classifyList, err := data_manage.GetAllChartClassify()
+	if err != nil {
+		fmt.Println("获取数据加工分类失败", err.Error())
+		return
+	}
+
+	// 存在图表的分类
+	hasEdbClassifyList := make([]*data_manage.ChartClassifyItems, 0)
+	for _, v := range classifyList {
+		if _, ok := chartClassifyIdMap[v.ChartClassifyId]; ok {
+			hasEdbClassifyList = append(hasEdbClassifyList, v)
+		}
+	}
+
+	// 待删除的分类id集合
+	deleteClassifyIdMap := make(map[int]int)
+	// 全部的分类id集合
+	for _, v := range classifyList {
+		deleteClassifyIdMap[v.ChartClassifyId] = v.ChartClassifyId
+	}
+
+	// 存在指标的的分类id集合
+	hasClassifyIdStrList := make([]string, 0)
+	for _, v := range hasEdbClassifyList {
+		hasClassifyIdStrList = append(hasClassifyIdStrList, v.ChartClassifyIdPath)
+	}
+
+	classifyIdStrList := make([]string, 0)
+	if len(hasClassifyIdStrList) > 0 {
+		classifyIdStrList = strings.Split(strings.Join(hasClassifyIdStrList, ","), ",")
+	}
+	for _, v := range classifyIdStrList {
+		classifyId, err := strconv.Atoi(v)
+		if err != nil {
+			fmt.Println("分类字符串转int失败,", err.Error())
+			return
+		}
+		delete(deleteClassifyIdMap, classifyId)
+	}
+
+	// 删除空分类
+	if len(deleteClassifyIdMap) > 0 {
+		deleteClassifyIdList := make([]int, 0)
+		for _, v := range deleteClassifyIdMap {
+			deleteClassifyIdList = append(deleteClassifyIdList, v)
+		}
+
+		err = data_manage.DelChartClassifyByIdList(deleteClassifyIdList)
+		if err != nil {
+			fmt.Println("删除空分类失败", err.Error())
+			return
+		}
+	}
+}
+
+// createNewChartClassify
+// @Description: 创建图表分类
+// @author: Roc
+// @datetime 2024-11-29 17:57:47
+// @param userId int
+// @param parentId int
+// @param rootId int
+// @param level int
+// @param sysUserName string
+// @param parentClassifyNamePath string
+// @param parentClassifyIdPath string
+// @param node *data_manage.EdbClassifyItems
+// @param classifyRelationMap map[int]int
+func createNewChartClassify(userId, parentId, rootId, level int, sysUserName, parentClassifyNamePath, parentClassifyIdPath string, node *data_manage.ChartClassifyItems, classifyRelationMap map[int]int) {
+	var classifyNamePath, classifyIdPath string
+
+	if parentId > 0 {
+		classifyNamePath = fmt.Sprint(parentClassifyNamePath, "|", node.ChartClassifyName)
+		classifyIdPath = fmt.Sprint(parentClassifyIdPath, ",")
+	} else {
+		classifyNamePath = node.ChartClassifyName
+	}
+
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	classifyInfo := &data_manage.ChartClassify{
+		ChartClassifyId:   0,
+		ChartClassifyName: node.ChartClassifyName,
+		ParentId:          parentId,
+		HasData:           1,
+		CreateTime:        time.Now(),
+		ModifyTime:        time.Now(),
+		SysUserId:         userId,
+		SysUserRealName:   sysUserName,
+		Level:             level + 1,
+		UniqueCode:        utils.MD5(utils.CHART_PREFIX + "_" + timestamp),
+		Sort:              node.Sort,
+		Source:            node.Source,
+		//IsJoinPermission:      0,
+		ChartClassifyNameEn:   node.ChartClassifyNameEn,
+		RootId:                rootId,
+		ChartClassifyNamePath: classifyNamePath,
+		ChartClassifyIdPath:   "",
+	}
+	err := data_manage.AddChartClassify(classifyInfo)
+	if err != nil {
+		fmt.Println("创建分类失败:", err.Error())
+		return
+	}
+
+	updateCols := []string{"ChartClassifyIdPath"}
+	// 更改分类id完整路径path
+	classifyInfo.ChartClassifyIdPath = fmt.Sprint(classifyIdPath, classifyInfo.ChartClassifyId)
+
+	if rootId <= 0 {
+		rootId = classifyInfo.ChartClassifyId
+		classifyInfo.RootId = classifyInfo.ChartClassifyId
+		updateCols = append(updateCols, "RootId")
+	}
+
+	_ = classifyInfo.Update(updateCols)
+
+	classifyRelationMap[node.ChartClassifyId] = classifyInfo.ChartClassifyId
+
+	level = classifyInfo.Level
+
+	if node.Children == nil {
+		return
+	}
+	if len(node.Children) <= 0 {
+		return
+	}
+	for _, child := range node.Children {
+		createNewChartClassify(userId, classifyInfo.ChartClassifyId, rootId, level, sysUserName, classifyNamePath, classifyInfo.ChartClassifyIdPath, child, classifyRelationMap)
+	}
+
+	return
+}
+
+// updateChartPath
+// @Description: 更新图表分类的完整路径
+// @author: Roc
+// @datetime 2024-12-09 10:30:16
+// @param item *data_manage.ChartClassifyItems
+// @param classifyNamePath string
+// @param classifyIdPath string
+func updateChartPath(item *data_manage.ChartClassifyItems, classifyNamePath, classifyIdPath string) {
+	if classifyNamePath == `` {
+		classifyNamePath = item.ChartClassifyName
+		classifyIdPath = fmt.Sprint(item.ChartClassifyId)
+	} else {
+		classifyNamePath = fmt.Sprint(classifyNamePath, "|", item.ChartClassifyName)
+		classifyIdPath = fmt.Sprint(classifyIdPath, ",", item.ChartClassifyId)
+	}
+	err := data_manage.UpdateChartClassify(item.ChartClassifyId, classifyNamePath, classifyIdPath)
+	if err != nil {
+		fmt.Println(item.ChartClassifyId, ";更新失败", err)
+	}
+	if item.Children != nil {
+		for _, v := range item.Children {
+			updateChartPath(v, classifyNamePath, classifyIdPath)
+		}
+	}
+}
+
+// initEs
+// @Description: 修复ES中的指标和图表数据
+// @author: Roc
+// @datetime 2024-11-29 16:18:02
+func initEs() {
+	// 更新ES中的指标数据
+	//data.AddOrEditAllEdbInfoToEs()
+	// 更新es中的图表数据
+	data.AddAllChartInfo()
+
+	fmt.Println("全部es数据修复完成")
+}

+ 37 - 35
controllers/knowledge/resource.go

@@ -550,57 +550,59 @@ func (this *ResourceController) Add() {
 		br.Ret = 408
 		return
 	}
-	var req knowledge.AddReq
-	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	var reqList []knowledge.AddReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &reqList)
 	if err != nil {
 		br.Msg = "参数解析异常!"
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
 		return
 	}
 
-	if req.Title == `` {
-		br.Msg = "标题不能为空"
-		br.ErrMsg = "标题不能为空"
-		br.IsSendEmail = false
-		return
-	}
-	// 判断标题长度,如果超过600个字符则报错
-	//fmt.Println(len(req.Title))
-	if len(req.Title) > 600 {
-		br.Msg = "标题过长"
-		return
-	}
+	for _, req := range reqList {
+		if req.Title == `` {
+			br.Msg = "标题不能为空"
+			br.ErrMsg = "标题不能为空"
+			br.IsSendEmail = false
+			return
+		}
+		// 判断标题长度,如果超过600个字符则报错
+		//fmt.Println(len(req.Title))
+		if len(req.Title) > 600 {
+			br.Msg = "标题过长"
+			return
+		}
 
-	if req.ClassifyId <= 0 {
-		br.Msg = "分类必填"
-		br.ErrMsg = "分类必填"
-		br.IsSendEmail = false
-		return
-	}
-	if req.ResourceType == knowledge.KnowledgeResourceTypeEvent || req.ResourceType == knowledge.KnowledgeResourceTypePolicy || req.ResourceType == knowledge.KnowledgeResourceTypeOpinion {
-		if req.StartTime == "" {
-			br.Msg = "开始时间必填"
-			br.ErrMsg = "开始时间必填"
+		if req.ClassifyId <= 0 {
+			br.Msg = "分类必填"
+			br.ErrMsg = "分类必填"
+			br.IsSendEmail = false
 			return
 		}
-	}
-	item, err, errMsg := knowledgeSrv.AddResource(&req, sysUser)
-	if err != nil {
-		br.Msg = "保存失败"
-		if errMsg != "" {
-			br.Msg = errMsg
+		if req.ResourceType == knowledge.KnowledgeResourceTypeEvent || req.ResourceType == knowledge.KnowledgeResourceTypePolicy || req.ResourceType == knowledge.KnowledgeResourceTypeOpinion {
+			if req.StartTime == "" {
+				br.Msg = "开始时间必填"
+				br.ErrMsg = "开始时间必填"
+				return
+			}
+		}
+		_, err, errMsg := knowledgeServ.AddResource(&req, sysUser)
+		if err != nil {
+			br.Msg = "保存失败"
+			if errMsg != "" {
+				br.Msg = errMsg
+			}
+			br.ErrMsg = "保存失败,Err:" + err.Error()
+			return
 		}
-		br.ErrMsg = "保存失败,Err:" + err.Error()
-		return
 	}
 
-	resp := new(knowledge.AddResp)
+	/*resp := new(knowledge.AddResp)
 	resp.KnowledgeResourceId = item.KnowledgeResourceId
-	resp.ResourceCode = item.ResourceCode
+	resp.ResourceCode = item.ResourceCode*/
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "保存成功"
-	br.Data = resp
+	//br.Data = resp
 }
 
 // Edit

+ 28 - 13
controllers/message.go

@@ -5,7 +5,6 @@ import (
 	biapprove "eta_gn/eta_api/models/bi_approve"
 	"eta_gn/eta_api/models/data_manage/data_manage_permission"
 	"eta_gn/eta_api/models/knowledge_approve"
-	"eta_gn/eta_api/models/report_approve"
 	"fmt"
 )
 
@@ -39,24 +38,40 @@ func (c *MessageController) UnReadMessageNum() {
 
 	var unReadReportNum, unReadDataPermissionNum, unReadBiNum, unReadKnowledgeNum int
 
-	// 获取报告审批消息
-	{
-		cond := fmt.Sprintf(` AND %s = ?`, report_approve.ReportApproveMessageCols.ReceiveUserId)
-		pars := make([]interface{}, 0)
-		pars = append(pars, sysUser.AdminId)
-
-		messageOb := new(report_approve.ReportApproveMessage)
+	// 获取报告审批消息(废弃)
+	//{
+	//	cond := fmt.Sprintf(` AND %s = ?`, report_approve.ReportApproveMessageCols.ReceiveUserId)
+	//	pars := make([]interface{}, 0)
+	//	pars = append(pars, sysUser.AdminId)
+	//
+	//	messageOb := new(report_approve.ReportApproveMessage)
+	//
+	//	// 未读消息数
+	//	cond += fmt.Sprintf(` AND %s = ?`, report_approve.ReportApproveMessageCols.IsRead)
+	//	pars = append(pars, 0)
+	//	unreadTotal, e := messageOb.GetCountByCondition(cond, pars)
+	//	if e != nil {
+	//		br.Msg = "获取失败"
+	//		br.ErrMsg = "获取审批消息列表总数失败, Err: " + e.Error()
+	//		return
+	//	}
+	//	unReadReportNum = unreadTotal
+	//}
 
+	// 报告通知消息
+	{
 		// 未读消息数
-		cond += fmt.Sprintf(` AND %s = ?`, report_approve.ReportApproveMessageCols.IsRead)
-		pars = append(pars, 0)
-		unreadTotal, e := messageOb.GetCountByCondition(cond, pars)
+		messageOb := new(models.ReportMessage)
+		cond := fmt.Sprintf(` AND %s = ? AND %s = ?`, models.ReportMessageCols.ReceiveUserId, models.ReportMessageCols.IsRead)
+		pars := make([]interface{}, 0)
+		pars = append(pars, sysUser.AdminId, 0)
+		total, e := messageOb.GetCountByCondition(cond, pars)
 		if e != nil {
 			br.Msg = "获取失败"
-			br.ErrMsg = "获取审批消息列表总数失败, Err: " + e.Error()
+			br.ErrMsg = "获取报告通知列表总数失败, Err: " + e.Error()
 			return
 		}
-		unReadReportNum = unreadTotal
+		unReadReportNum = total
 	}
 
 	// 获取资产消息

+ 7 - 0
controllers/report_v2.go

@@ -888,6 +888,7 @@ func (this *ReportController) AuthorizedListReport() {
 	classifyIdFirst, _ := this.GetInt("ClassifyIdFirst", 0)
 	classifyIdSecond, _ := this.GetInt("ClassifyIdSecond", 0)
 	classifyIdThird, _ := this.GetInt("ClassifyIdThird", 0)
+	stateStr := this.GetString("State")
 
 	var startSize int
 	if pageSize <= 0 {
@@ -948,6 +949,12 @@ func (this *ReportController) AuthorizedListReport() {
 		pars = utils.GetLikeKeywordPars(pars, keyword, 1)
 	}
 
+	if stateStr != `` {
+		stateStrList := strings.Split(stateStr, ",")
+		condition += ` AND a.state in (` + utils.GetOrmInReplace(len(stateStrList)) + `) `
+		pars = append(pars, stateStrList)
+	}
+
 	var err error
 	var total int
 	noVisibleClassifyIds, err := models.GetNoVisibleClassifyIdByAdminId(this.SysUser.AdminId)

文件差异内容过多而无法显示
+ 0 - 4
controllers/resource.go


+ 0 - 14
controllers/sys_admin.go

@@ -890,20 +890,6 @@ func (this *SysAdminController) Delete() {
 	br.Msg = "删除成功"
 }
 
-/*
-func init() {
-	fmt.Println("start")
-	pwdStr:=`11111`
-	//compile := `(\d+.*[^a-zA-Z]+){6,12}|([^a-zA-Z]+.*\d+){6,12}`
-	compile := `([0-9a-z]+){6,12}|(a-z0-9]+){6,12}`
-	///^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,12}$/
-	///^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,12}$/
-	reg := regexp.MustCompile(compile)
-	flag := reg.MatchString(pwdStr)
-	fmt.Println(flag)
-	fmt.Println("end")
-}*/
-
 // SetConfig
 // @Title 用户信息配置接口
 // @Description 用户信息配置接口

+ 3 - 0
models/business_conf.go

@@ -56,6 +56,9 @@ const (
 
 	BusinessConfEdbStopRefreshRule = "EdbStopRefreshRule" // 是否停止指标刷新规则
 	BusinessConfOuterReportApiUrl  = "OuterReportApiUrl"  // 智力共享-报告API地址
+
+	IgnoreEdbApproveUserId   = `IgnoreEdbApproveUserId`   // 忽略指标审批用户id集合
+	IgnoreChartApproveUserId = `IgnoreChartApproveUserId` //忽略图表审批用户id集合
 )
 
 const (

+ 262 - 23
models/data_manage/chart_classify.go

@@ -8,29 +8,30 @@ import (
 )
 
 type ChartClassify struct {
-	ChartClassifyId     int       `orm:"column(chart_classify_id);pk" gorm:"primaryKey" `
-	ChartClassifyName   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:"层级"`
-	UniqueCode          string    `description:"唯一编码"`
-	Sort                int       `description:"排序字段,越小越靠前,默认值:10"`
-	Source              int       `description:"1:ETA图库;2:商品价格曲线"`
-	IsJoinPermission    int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
-	ChartClassifyNameEn string    `description:"英文分类名称"`
-	RootId              int       `description:"顶级ID"`
-}
-
-func AddChartClassify(item *ChartClassify) (lastId int64, err error) {
+	ChartClassifyId       int       `orm:"column(chart_classify_id);pk" gorm:"primaryKey" `
+	ChartClassifyName     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:"层级"`
+	UniqueCode            string    `description:"唯一编码"`
+	Sort                  int       `description:"排序字段,越小越靠前,默认值:10"`
+	Source                int       `description:"1:ETA图库;2:商品价格曲线"`
+	IsJoinPermission      int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	ChartClassifyNameEn   string    `description:"英文分类名称"`
+	RootId                int       `description:"顶级ID"`
+	ChartClassifyNamePath string    `description:"分类名称的完整路径,格式为:父级分类名称|当前分类名称"`
+	ChartClassifyIdPath   string    `description:"分类的完整路径,格式为:父级ID,当前ID"`
+}
+
+func AddChartClassify(item *ChartClassify) (err error) {
 	err = global.DmSQL["data"].Create(item).Error
 	if err != nil {
 		return
 	}
-	lastId = int64(item.ChartClassifyId)
 
 	return
 }
@@ -102,9 +103,13 @@ type DeleteChartClassifyReq struct {
 
 // GetChartClassifyByParentId
 // @param source int 1:ETA图库;2:商品价格曲线;3:相关性图表
-func GetChartClassifyByParentId(parentId, source int) (items []*ChartClassifyItems, err error) {
+func GetChartClassifyByParentId(parentId, source, sysUserId int) (items []*ChartClassifyItems, err error) {
 	o := global.DmSQL["data"]
-	sql := ` SELECT * FROM chart_classify WHERE parent_id=? AND source = ? order by sort asc,chart_classify_id asc`
+	sql := ` SELECT * FROM chart_classify WHERE parent_id=? AND source = ? `
+	if sysUserId > 0 {
+		sql += fmt.Sprintf(` AND sys_user_id = %d `, sysUserId)
+	}
+	sql += `  order by sort asc,chart_classify_id asc `
 	err = o.Raw(sql, parentId, source).Scan(&items).Error
 
 	return
@@ -112,14 +117,42 @@ func GetChartClassifyByParentId(parentId, source int) (items []*ChartClassifyIte
 
 // GetChartClassifyAll
 // @param source int 1:ETA图库;2:商品价格曲线;3:相关性图表
-func GetChartClassifyAll(source int) (items []*ChartClassifyItems, err error) {
+func GetChartClassifyAll(source, sysUserId int) (items []*ChartClassifyItems, err error) {
 	o := global.DmSQL["data"]
-	sql := ` SELECT * FROM chart_classify WHERE parent_id<>0 AND source = ? order by sort asc,chart_classify_id asc`
+	sql := ` SELECT * FROM chart_classify WHERE parent_id<>0 AND source = ?`
+	if sysUserId > 0 {
+		sql += fmt.Sprintf(` AND sys_user_id = %d `, sysUserId)
+	}
+	sql += ` order by sort asc,chart_classify_id asc `
 	err = o.Raw(sql, source).Scan(&items).Error
 
 	return
 }
 
+// GetAllChartClassify
+// @Description: 获取所有类型的图表分类
+// @author: Roc
+// @datetime 2024-12-09 10:11:46
+// @return items []*ChartClassifyItems
+// @return err error
+func GetAllChartClassify() (items []*ChartClassifyItems, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM chart_classify order by sort asc,chart_classify_id asc`
+	err = o.Raw(sql).Scan(&items).Error
+
+	return
+}
+
+// GetChartClassifyByParentId
+// @param source int 1:ETA图库;2:商品价格曲线;3:相关性图表
+func GetAllChartClassifyByParentId(parentId int) (items []*ChartClassifyItems, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM chart_classify WHERE parent_id=?  order by sort asc,chart_classify_id asc`
+	err = o.Raw(sql, parentId).Scan(&items).Error
+
+	return
+}
+
 type ChartClassifyItems struct {
 	ChartClassifyId     int `description:"分类id"`
 	ChartInfoId         int `description:"指标id"`
@@ -144,6 +177,7 @@ type ChartClassifyItems struct {
 	Button              ChartClassifyItemsButton `gorm:"-" description:"按钮权限"`
 	IsJoinPermission    int                      `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
 	HaveOperaAuth       bool                     `description:"是否有数据权限,默认:false"`
+	ChartClassifyIdPath string                   `description:"分类的完整路径,格式为:父级ID,当前ID"`
 }
 
 // ChartClassifyItemsButton 操作按钮
@@ -319,6 +353,25 @@ func GetChartClassifyByIdList(classifyIdList []int) (items []*ChartClassify, err
 	return
 }
 
+// GetChartClassifyItemsByIdList
+// @Description:  根据分类ID列表获取分类
+// @author: Roc
+// @datetime 2024-04-01 13:21:48
+// @param classifyId []int
+// @return items []*ChartClassify
+// @return err error
+func GetChartClassifyItemsByIdList(classifyIdList []int) (items []*ChartClassifyItems, err error) {
+	num := len(classifyIdList)
+	if num <= 0 {
+		return
+	}
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM chart_classify WHERE chart_classify_id in (` + utils.GetOrmInReplace(num) + `) `
+	err = o.Raw(sql, classifyIdList).Scan(&items).Error
+
+	return
+}
+
 // GetChartClassifyBySourceAndIsJoinPermission
 // @Description: 根据分类类型和是否涉密获取分类列表
 // @author: Roc
@@ -388,3 +441,189 @@ func DeleteChartClassifyByIds(ids []int) (err error) {
 	err = o.Exec(sql, ids).Error
 	return
 }
+
+// UpdateChartClassify
+// @Description: 更新图表分类的基础信息
+// @author: Roc
+// @datetime 2024-12-09 10:29:51
+// @param classifyId int
+// @param classifyNamePath string
+// @param classifyIdPath string
+// @return err error
+func UpdateChartClassify(classifyId int, classifyNamePath, classifyIdPath string) (err error) {
+	sql := `UPDATE chart_classify SET chart_classify_name_path = ?,chart_classify_id_path = ? WHERE chart_classify_id = ?`
+
+	err = global.DmSQL["data"].Exec(sql, classifyNamePath, classifyIdPath, classifyId).Error
+
+	return
+}
+
+// UpdateClassifyIdByChartInfoId
+// @Description: 根据图表id更新所属分类id
+// @author: Roc
+// @datetime 2024-11-29 17:54:44
+// @param edbInfoId int
+// @param edbClassifyId int
+// @return err error
+func UpdateClassifyIdByChartInfoId(chartInfoId, chartClassifyId int) (err error) {
+	sql := ` UPDATE chart_info SET chart_classify_id = ? WHERE  chart_info_id=? `
+	err = global.DmSQL["data"].Exec(sql, chartClassifyId, chartInfoId).Error
+	return
+}
+
+// DelChartClassifyByIdList
+// @Description: 根据id删除图表分类
+// @author: Roc
+// @datetime 2024-12-02 09:27:26
+// @param idList []int
+// @return err error
+func DelChartClassifyByIdList(idList []int) (err error) {
+	num := len(idList)
+	if num <= 0 {
+		return
+	}
+	sql := `DELETE  FROM chart_classify  WHERE chart_classify_id IN (?) `
+	err = global.DmSQL["data"].Exec(sql, idList).Error
+
+	return
+}
+
+// UpdateClassifyNameAndNamePath
+// @Description: 更新分类名称和完整名称路径
+// @author: Roc
+// @receiver chartClassify
+// @datetime 2024-12-09 14:13:05
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func (chartClassify *ChartClassify) UpdateClassifyNameAndNamePath(cols []string, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	tx := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	// 变更分类信息
+	err = tx.Select(cols).Updates(chartClassify).Error
+	if err != nil {
+		return
+	}
+
+	// 更改子分类的完整的路径
+	if oldClassifyNamePath != `` && newClassifyNamePath != `` {
+		sql := `UPDATE chart_classify SET chart_classify_name_path = REPLACE(chart_classify_name_path,?,?) WHERE chart_classify_id_path LIKE ?`
+		err = tx.Exec(sql, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(chartClassify.ChartClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// UpdateChartClassifyNameAndNamePathByOldClassifyIdPath
+// @Description: 根据源分类id全路径更新分类名称和子分类的全路径
+// @author: Roc
+// @receiver edbClassify
+// @datetime 2024-11-26 14:39:09
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func UpdateChartClassifyNameAndNamePathByOldClassifyIdPath(oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	// 更改子分类的完整的路径
+	if oldClassifyIdPath != `` && newClassifyNamePath != `` && newClassifyIdPath != `` {
+		sql := `UPDATE chart_classify SET chart_classify_id_path = REPLACE(chart_classify_id_path,?,?) ,chart_classify_name_path = REPLACE(chart_classify_name_path,?,?)  WHERE chart_classify_id_path LIKE ?`
+		err = global.DmSQL["data"].Exec(sql, oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(oldClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+func GetChildChartClassifyListByParentId(classifyIdPath, orderStr string) (items []*ChartClassifyItems, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM chart_classify WHERE chart_classify_id_path like ? `
+	if orderStr != "" {
+		sql += orderStr
+	} else {
+		sql += ` order by level desc, sort asc, chart_classify_id asc`
+	}
+
+	err = o.Raw(sql, classifyIdPath).Scan(&items).Error
+
+	return
+}
+
+// GetChartInfoMaxPublicSortByClassifyId
+// @Description: 获取分类下公共图库的最大的排序数
+// @param classifyId
+// @return sort
+// @return err
+func GetChartInfoMaxPublicSortByClassifyId(classifyId int) (sort int, err error) {
+	sql := `SELECT COALESCE(Max(public_sort), 0) AS sort FROM chart_info WHERE public_status = 3 AND chart_public_classify_id = ? `
+	err = global.DmSQL["data"].Raw(sql, classifyId).Scan(&sort).Error
+
+	return
+}
+
+type ChartClassifyItemList []*ChartClassifyItems
+
+func (m ChartClassifyItemList) Len() int {
+	return len(m)
+}
+
+func (m ChartClassifyItemList) Less(i, j int) bool {
+	return m[i].Sort < m[j].Sort
+}
+
+func (m ChartClassifyItemList) Swap(i, j int) {
+	m[i], m[j] = m[j], m[i]
+}
+
+func (m *ChartClassifyItems) ToUserShareChartClassifyItem() (item *UserShareChartClassifyItem) {
+	return &UserShareChartClassifyItem{
+		ChartClassifyId:     m.ChartClassifyId,
+		ChartInfoId:         m.ChartInfoId,
+		ChartClassifyName:   m.ChartClassifyName,
+		ChartClassifyNameEn: m.ChartClassifyNameEn,
+		ParentId:            m.ParentId,
+		Level:               m.Level,
+		Sort:                m.Sort,
+		UniqueCode:          m.UniqueCode,
+		Source:              m.Source,
+		SourceName:          m.SourceName,
+		SysUserId:           m.SysUserId,
+		SysUserRealName:     m.SysUserRealName,
+		DateType:            m.DateType,
+		StartDate:           m.StartDate,
+		EndDate:             m.EndDate,
+		ChartType:           m.ChartType,
+		Calendar:            m.Calendar,
+		SeasonStartDate:     m.SeasonStartDate,
+		SeasonEndDate:       m.SeasonEndDate,
+		Children:            m.ToUserShareChartClassifyItemByList(m.Children),
+		Button:              ChartClassifyItemsButton{},
+		IsJoinPermission:    m.IsJoinPermission,
+		HaveOperaAuth:       true,
+		ChartClassifyIdPath: m.ChartClassifyIdPath,
+	}
+}
+
+func (m *ChartClassifyItems) ToUserShareChartClassifyItemByList(list []*ChartClassifyItems) (items []*UserShareChartClassifyItem) {
+	items = make([]*UserShareChartClassifyItem, 0)
+	if list == nil {
+		return
+	}
+
+	for _, v := range list {
+		items = append(items, v.ToUserShareChartClassifyItem())
+	}
+	return
+}

+ 71 - 0
models/data_manage/chart_edb_mapping.go

@@ -1,6 +1,7 @@
 package data_manage
 
 import (
+	sql2 "database/sql"
 	"eta_gn/eta_api/global"
 	"eta_gn/eta_api/utils"
 	"fmt"
@@ -97,6 +98,29 @@ func GetChartEdbMappingListByChartInfoIds(chartInfoIds string) (list []*ChartEdb
 	return
 }
 
+func GetChartEdbMappingListByChartInfoIdList(chartInfoIdList []int) (list []*ChartEdbInfoMapping, err error) {
+	if len(chartInfoIdList) <= 0 {
+		return
+	}
+	o := global.DmSQL["data"]
+	sql := ` SELECT a.*,b.source_name,b.source,b.sub_source,b.edb_code,b.edb_name,b.edb_name_en,b.frequency,b.unit,b.unit_en,b.start_date,b.end_date,b.modify_time,b.latest_date,b.latest_value,b.unique_code,b.edb_info_type AS edb_info_category_type,b.edb_type,b.classify_id,b.is_join_permission
+             FROM chart_edb_mapping AS a
+			 INNER JOIN edb_info AS b ON a.edb_info_id=b.edb_info_id
+			 WHERE chart_info_id in (?) 
+             ORDER BY chart_edb_mapping_id ASC `
+	err = o.Raw(sql, chartInfoIdList).Scan(&list).Error
+	if err != nil {
+		return
+	}
+
+	// 日期格式转换
+	for _, v := range list {
+		v.ConvertToResp()
+	}
+
+	return
+}
+
 func GetChartEdbMappingListByEdbInfoId(edbInfoStr string) (list []*ChartEdbInfoMapping, err error) {
 	o := global.DmSQL["data"]
 	sql := ` SELECT edb_info_id,source_name,source,sub_source,edb_code,edb_name,edb_name_en,frequency,unit,unit_en,start_date,end_date,modify_time,latest_date,latest_value,unique_code,edb_info_type AS edb_info_category_type,max_value,min_value,edb_type,classify_id,is_join_permission
@@ -460,3 +484,50 @@ func GetRelationEdbInfoListMappingByCondition(condition string, pars []interface
 
 	return
 }
+
+// GetCountRelationChartEdbInfoListMappingByCondition
+// @Description: 根据条件获取关联图数量
+// @author: Roc
+// @datetime 2024-12-26 10:13:47
+// @param condition string
+// @param pars []interface{}
+// @return total int
+// @return err error
+func GetCountRelationChartEdbInfoListMappingByCondition(condition string, pars []interface{}) (total int, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT COUNT(1) total FROM chart_edb_mapping AS a 
+	JOIN chart_info AS b on a.chart_info_id = b.chart_info_id WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	var totalNull sql2.NullInt64
+	err = o.Raw(sql, pars...).Scan(&totalNull).Error
+	if err != nil {
+		return
+	}
+	total = int(totalNull.Int64)
+
+	return
+}
+
+// GetUserIdListRelationChartEdbInfoListMappingByCondition
+// @Description: 根据条件获取关联图的用户id列表
+// @author: Roc
+// @datetime 2024-12-26 10:13:47
+// @param condition string
+// @param pars []interface{}
+// @return total int
+// @return err error
+func GetUserIdListRelationChartEdbInfoListMappingByCondition(condition string, pars []interface{}) (userIdList []int, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT b.sys_user_id FROM chart_edb_mapping AS a 
+	JOIN chart_info AS b on a.chart_info_id = b.chart_info_id WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY b.sys_user_id `
+
+	err = o.Raw(sql, pars...).Scan(&userIdList).Error
+
+	return
+}

+ 201 - 65
models/data_manage/chart_info.go

@@ -16,51 +16,55 @@ import (
 )
 
 type ChartInfo struct {
-	ChartInfoId       int    `orm:"column(chart_info_id);pk" gorm:"primaryKey" `
-	ChartName         string `description:"图表名称"`
-	ChartNameEn       string `description:"英文图表名称"`
-	ChartClassifyId   int    `description:"图表分类id"`
-	SysUserId         int
-	SysUserRealName   string
-	UniqueCode        string `description:"图表唯一编码"`
-	CreateTime        time.Time
-	ModifyTime        time.Time
-	DateType          int    `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
-	StartDate         string `description:"自定义开始日期"`
-	EndDate           string `description:"自定义结束日期"`
-	IsSetName         int    `description:"设置名称"`
-	EdbInfoIds        string `description:"指标id"`
-	ChartType         int    `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图,10:截面散点图, 11:雷达图"`
-	Calendar          string `description:"公历/农历"`
-	SeasonStartDate   string `description:"季节性图开始日期"`
-	SeasonEndDate     string `description:"季节性图开始日期"`
-	ChartImage        string `description:"图表图片"`
-	Sort              int    `description:"排序字段,数字越小越排前面"`
-	XMin              string `description:"图表X轴最小值"`
-	XMax              string `description:"图表X轴最大值"`
-	LeftMin           string `description:"图表左侧最小值"`
-	LeftMax           string `description:"图表左侧最大值"`
-	RightMin          string `description:"图表右侧最小值"`
-	RightMax          string `description:"图表右侧最大值"`
-	Right2Min         string `description:"图表右侧2最小值"`
-	Right2Max         string `description:"图表右侧2最大值"`
-	MinMaxSave        int    `description:"是否手动保存过上下限:0-否;1-是"`
-	Disabled          int    `description:"是否禁用,0:启用,1:禁用,默认:0"`
-	BarConfig         string `description:"柱方图的配置,json数据"`
-	Source            int    `description:"1:ETA图库;2:商品价格曲线"`
-	ExtraConfig       string `description:"图表额外配置,json数据"`
-	SeasonExtraConfig string `description:"季节性图表中的配置,json数据"`
-	StartYear         int    `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
-	ChartThemeId      int    `description:"图表应用主题ID"`
-	SourcesFrom       string `description:"图表来源"`
-	Instructions      string `description:"图表说明"`
-	MarkersLines      string `description:"标识线"`
-	MarkersAreas      string `description:"标识区"`
-	Unit              string `description:"中文单位名称"`
-	UnitEn            string `description:"英文单位名称"`
-	IsJoinPermission  int    `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
-	ForumChartInfoId  int    `description:"社区的图表ID"`
-	ChartAlias        string `description:"图表别名"`
+	ChartInfoId           int    `orm:"column(chart_info_id);pk" gorm:"primaryKey" `
+	ChartName             string `description:"图表名称"`
+	ChartNameEn           string `description:"英文图表名称"`
+	ChartClassifyId       int    `description:"图表分类id"`
+	SysUserId             int
+	SysUserRealName       string
+	UniqueCode            string `description:"图表唯一编码"`
+	CreateTime            time.Time
+	ModifyTime            time.Time
+	DateType              int       `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate             string    `description:"自定义开始日期"`
+	EndDate               string    `description:"自定义结束日期"`
+	IsSetName             int       `description:"设置名称"`
+	EdbInfoIds            string    `description:"指标id"`
+	ChartType             int       `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图,10:截面散点图, 11:雷达图"`
+	Calendar              string    `description:"公历/农历"`
+	SeasonStartDate       string    `description:"季节性图开始日期"`
+	SeasonEndDate         string    `description:"季节性图开始日期"`
+	ChartImage            string    `description:"图表图片"`
+	Sort                  int       `description:"排序字段,数字越小越排前面"`
+	XMin                  string    `description:"图表X轴最小值"`
+	XMax                  string    `description:"图表X轴最大值"`
+	LeftMin               string    `description:"图表左侧最小值"`
+	LeftMax               string    `description:"图表左侧最大值"`
+	RightMin              string    `description:"图表右侧最小值"`
+	RightMax              string    `description:"图表右侧最大值"`
+	Right2Min             string    `description:"图表右侧2最小值"`
+	Right2Max             string    `description:"图表右侧2最大值"`
+	MinMaxSave            int       `description:"是否手动保存过上下限:0-否;1-是"`
+	Disabled              int       `description:"是否禁用,0:启用,1:禁用,默认:0"`
+	BarConfig             string    `description:"柱方图的配置,json数据"`
+	Source                int       `description:"1:ETA图库;2:商品价格曲线"`
+	ExtraConfig           string    `description:"图表额外配置,json数据"`
+	SeasonExtraConfig     string    `description:"季节性图表中的配置,json数据"`
+	StartYear             int       `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+	ChartThemeId          int       `description:"图表应用主题ID"`
+	SourcesFrom           string    `description:"图表来源"`
+	Instructions          string    `description:"图表说明"`
+	MarkersLines          string    `description:"标识线"`
+	MarkersAreas          string    `description:"标识区"`
+	Unit                  string    `description:"中文单位名称"`
+	UnitEn                string    `description:"英文单位名称"`
+	IsJoinPermission      int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	ForumChartInfoId      int       `description:"社区的图表ID"`
+	ChartAlias            string    `description:"图表别名"`
+	PublicStatus          int       `description:"公开状态;0:未公开;1:审批中;2:已驳回;3:已公开"`
+	ChartPublicClassifyId int       `description:"图表公开分类id"`
+	PublicTime            time.Time `description:"设置公开的时间"`
+	PublicSort            int       `description:"公开分类下的排序字段"`
 }
 
 type ChartInfoMore struct {
@@ -87,7 +91,7 @@ type ChartInfoItem struct {
 
 // GetChartInfoAll 用于分类展示
 // @param source int 1:ETA图库;2:商品价格曲线
-func GetChartInfoAll(sourceList []int) (items []*ChartClassifyItems, err error) {
+func GetChartInfoAll(sourceList []int, sysUserId int) (items []*ChartClassifyItems, err error) {
 	num := len(sourceList)
 	if num <= 0 {
 		return
@@ -96,7 +100,13 @@ func GetChartInfoAll(sourceList []int) (items []*ChartClassifyItems, err error)
 	o := global.DmSQL["data"]
 	sql := ` SELECT chart_info_id,chart_classify_id,chart_name AS chart_classify_name,chart_name_en AS chart_classify_name_en,
              unique_code,sys_user_id,sys_user_real_name,date_type,start_date,end_date,chart_type,calendar,season_start_date,season_end_date,source
-            FROM chart_info WHERE source in (` + utils.GetOrmInReplace(num) + `)  ORDER BY sort asc,chart_info_id ASC `
+            FROM chart_info WHERE source in (` + utils.GetOrmInReplace(num) + `)  `
+
+	if sysUserId > 0 {
+		sql += fmt.Sprintf(` AND sys_user_id = %d `, sysUserId)
+	}
+
+	sql += ` ORDER BY sort asc,chart_info_id ASC `
 	err = o.Raw(sql, sourceList).Scan(&items).Error
 
 	return
@@ -146,6 +156,68 @@ type ChartInfoSearchResp struct {
 	Status     int            `description:"1:数据已存在于国能数据库,2:新数据"`
 }
 
+// ChartEsInfo
+// @Description: Es中的数据
+type ChartEsInfo struct {
+	ChartInfoId           int    `orm:"column(chart_info_id);pk" gorm:"primaryKey" `
+	ChartName             string `description:"图表名称"`
+	ChartNameEn           string `description:"英文图表名称"`
+	ChartClassifyId       int    `description:"图表分类id"`
+	SysUserId             int
+	SysUserRealName       string
+	UniqueCode            string `description:"图表唯一编码"`
+	CreateTime            time.Time
+	ModifyTime            time.Time
+	DateType              int       `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate             string    `description:"自定义开始日期"`
+	EndDate               string    `description:"自定义结束日期"`
+	IsSetName             int       `description:"设置名称"`
+	EdbInfoIds            string    `description:"指标id"`
+	ChartType             int       `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图,10:截面散点图, 11:雷达图"`
+	Calendar              string    `description:"公历/农历"`
+	SeasonStartDate       string    `description:"季节性图开始日期"`
+	SeasonEndDate         string    `description:"季节性图开始日期"`
+	ChartImage            string    `description:"图表图片"`
+	Sort                  int       `description:"排序字段,数字越小越排前面"`
+	XMin                  string    `description:"图表X轴最小值"`
+	XMax                  string    `description:"图表X轴最大值"`
+	LeftMin               string    `description:"图表左侧最小值"`
+	LeftMax               string    `description:"图表左侧最大值"`
+	RightMin              string    `description:"图表右侧最小值"`
+	RightMax              string    `description:"图表右侧最大值"`
+	Right2Min             string    `description:"图表右侧2最小值"`
+	Right2Max             string    `description:"图表右侧2最大值"`
+	MinMaxSave            int       `description:"是否手动保存过上下限:0-否;1-是"`
+	Disabled              int       `description:"是否禁用,0:启用,1:禁用,默认:0"`
+	BarConfig             string    `description:"柱方图的配置,json数据"`
+	Source                int       `description:"1:ETA图库;2:商品价格曲线"`
+	ExtraConfig           string    `description:"图表额外配置,json数据"`
+	SeasonExtraConfig     string    `description:"季节性图表中的配置,json数据"`
+	StartYear             int       `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+	ChartThemeId          int       `description:"图表应用主题ID"`
+	SourcesFrom           string    `description:"图表来源"`
+	Instructions          string    `description:"图表说明"`
+	MarkersLines          string    `description:"标识线"`
+	MarkersAreas          string    `description:"标识区"`
+	Unit                  string    `description:"中文单位名称"`
+	UnitEn                string    `description:"英文单位名称"`
+	IsJoinPermission      int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	ForumChartInfoId      int       `description:"社区的图表ID"`
+	ChartAlias            string    `description:"图表别名"`
+	SharedUserIdList      []int     `description:"共享用户id列表" gorm:"-"`
+	PublicStatus          int       `description:"公开状态;0:未公开;1:审批中;2:已驳回;3:已公开"`
+	ChartPublicClassifyId int       `description:"图表公开分类id"`
+	PublicTime            time.Time `description:"设置公开的时间"`
+}
+
+func GetChartEsInfoById(chartInfoId int) (item *ChartEsInfo, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM chart_info WHERE chart_info_id=? `
+	err = o.Raw(sql, chartInfoId).First(&item).Error
+
+	return
+}
+
 func GetChartInfoById(chartInfoId int) (item *ChartInfo, err error) {
 	o := global.DmSQL["data"]
 	sql := ` SELECT * FROM chart_info WHERE chart_info_id=? `
@@ -373,8 +445,8 @@ type ChartInfoList struct {
 	UniqueCode           string `description:"图表唯一编码"`
 	CreateTime           time.Time
 	ModifyTime           time.Time
-	EdbInfoList          []*EdbInfoList
-	ChartAlias           string `description:"图表别名"`
+	EdbInfoList          []*EdbInfoList `gorm:"-" description:"实际指标数据"`
+	ChartAlias           string         `description:"图表别名"`
 }
 
 type ChartInfoListResp struct {
@@ -1927,22 +1999,31 @@ type ChartInfoView struct {
 	BarConfig         string               `description:"柱方图的配置,json数据" json:"-"`
 	Source            int                  `description:"1:ETA图库;2:商品价格曲线;3:相关性图表"`
 	//CorrelationLeadUnit string `description:"相关性图表-领先单位"`
-	ExtraConfig       string          `description:"图表额外配置,json数据"`
-	ChartSource       string          `description:"图表来源str"`
-	ChartSourceEn     string          `description:"图表来源(英文)"`
-	Button            ChartViewButton `gorm:"-" description:"操作按钮"`
-	SeasonExtraConfig string          `description:"季节性图表中的配置,json数据"`
-	StartYear         int             `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
-	ChartThemeId      int             `description:"图表应用主题ID"`
-	ChartThemeStyle   string          `description:"图表应用主题样式"`
-	SourcesFrom       string          `description:"图表来源"`
-	Instructions      string          `description:"图表说明"`
-	MarkersLines      string          `description:"标识线"`
-	MarkersAreas      string          `description:"标识区"`
-	IsJoinPermission  int             `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
-	HaveOperaAuth     bool            `description:"是否有数据权限,默认:false"`
-	ForumChartInfoId  int             `description:"社区的图表ID"`
-	ChartAlias        string          `description:"图表别名"`
+	ExtraConfig             string          `description:"图表额外配置,json数据"`
+	ChartSource             string          `description:"图表来源str"`
+	ChartSourceEn           string          `description:"图表来源(英文)"`
+	Button                  ChartViewButton `gorm:"-" description:"操作按钮"`
+	SeasonExtraConfig       string          `description:"季节性图表中的配置,json数据"`
+	StartYear               int             `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+	ChartThemeId            int             `description:"图表应用主题ID"`
+	ChartThemeStyle         string          `description:"图表应用主题样式"`
+	SourcesFrom             string          `description:"图表来源"`
+	Instructions            string          `description:"图表说明"`
+	MarkersLines            string          `description:"标识线"`
+	MarkersAreas            string          `description:"标识区"`
+	IsJoinPermission        int             `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth           bool            `description:"是否有数据权限,默认:false"`
+	ForumChartInfoId        int             `description:"社区的图表ID"`
+	ChartAlias              string          `description:"图表别名"`
+	SharedUserIdList        []int           `description:"共享用户id列表" gorm:"-"`
+	SharedUserName          string          `description:"共享用户姓名,多个用英文,隔开" gorm:"-"`
+	PublicStatus            int             `description:"公开状态;0:未公开;1:审批中;2:已驳回;3:已公开"`
+	ChartPublicClassifyId   int             `description:"图表公开分类id"`
+	PublicTime              time.Time       `description:"设置公开的时间"`
+	ClassifyNamePath        string          `description:"分类完整路径"`
+	PublicClassifyNamePath  string          `description:"公共分类完整路径"`
+	CollectClassifyIdList   []int           `description:"所属收藏分类id列表" gorm:"-"`
+	CollectClassifyNameList []string        `description:"所属收藏分类名称列表" gorm:"-"`
 }
 
 type ChartViewButton struct {
@@ -2044,6 +2125,12 @@ type ChartInfoListByEsResp struct {
 	List   []*ChartInfoMore
 }
 
+// ChartInfoListByEsRespV2 图表数据Es搜索返回
+type ChartInfoListByEsRespV2 struct {
+	Paging *paging.PagingItem
+	List   []*ChartInfoView
+}
+
 // GetChartInfoListByCondition 根据条件获取图表数据了列表
 func GetChartInfoListByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*ChartInfo, err error) {
 	o := global.DmSQL["data"]
@@ -2866,3 +2953,52 @@ func getThsHfEdbDataListMinAndMaxByMongo(source, subSource, edbInfoId int, start
 	maxData = result.MaxValue
 	return
 }
+
+// UpdateClassifyIdByChartInfoIdList
+// @Description: 根据图表id列表更新所属分类id
+// @author: Roc
+// @datetime 2024-12-10 13:18:52
+// @param chartInfoIdList int
+// @param chartClassifyId int
+// @return err error
+func UpdateClassifyIdByChartInfoIdList(chartInfoIdList []int, chartClassifyId int) (err error) {
+	if len(chartInfoIdList) <= 0 {
+		return
+	}
+	sql := ` UPDATE chart_info SET chart_classify_id = ? WHERE  chart_info_id in (?) `
+	err = global.DmSQL["data"].Exec(sql, chartClassifyId, chartInfoIdList).Error
+
+	return
+}
+
+// UpdateChartInfoPublicSortByClassifyId
+// @Description: 根据公共分类id更新图表公共排序
+// @param classifyId
+// @param nowSort
+// @param prevChartInfoId
+// @param updateSort
+// @param source
+// @return err
+func UpdateChartInfoPublicSortByClassifyId(classifyId, nowSort int, prevChartInfoId int, updateSort string, source int) (err error) {
+	sql := ` update chart_info set sort = ` + updateSort + ` WHERE chart_public_classify_id=? AND public_status = 3 AND source = ? `
+	if prevChartInfoId > 0 {
+		sql += ` AND ( public_sort > ? or ( chart_info_id > ` + fmt.Sprint(prevChartInfoId) + ` and public_sort=` + fmt.Sprint(nowSort) + ` )) `
+	} else {
+		sql += ` AND ( public_sort > ? )`
+	}
+	err = global.DmSQL["data"].Exec(sql, classifyId, nowSort, source).Error
+
+	return
+}
+
+// GetFirstChartInfoByPublicClassifyId
+// @Description: 获取当前公共分类下,且排序数相同 的排序第一条的图表数据
+// @param classifyId
+// @return item
+// @return err
+func GetFirstChartInfoByPublicClassifyId(classifyId int) (item *ChartInfo, err error) {
+	sql := ` SELECT * FROM chart_info WHERE chart_public_classify_id=? AND public_status = 3 order by public_sort asc,chart_info_id asc limit 1`
+	err = global.DmSQL["data"].Raw(sql, classifyId).First(&item).Error
+
+	return
+}

+ 10 - 1
models/data_manage/chart_info_resp.go

@@ -1,6 +1,9 @@
 package data_manage
 
-import "eta_gn/eta_api/utils"
+import (
+	"eta_gn/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
 
 // ConvertToResp
 // @Description: 转成需要输出的格式
@@ -29,3 +32,9 @@ func (m *ChartInfoView) ConvertToResp() {
 
 	return
 }
+
+// ChartInfoFilterDataResp 搜索指标列表数据返回
+type ChartInfoFilterDataResp struct {
+	Paging *paging.PagingItem
+	List   []*ChartInfoView
+}

+ 291 - 0
models/data_manage/chart_info_share.go

@@ -0,0 +1,291 @@
+package data_manage
+
+import (
+	sql2 "database/sql"
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+// ChartInfoShare
+// @Description: 指标分享表
+type ChartInfoShare struct {
+	ChartInfoShareId int       `gorm:"primaryKey" `
+	ChartInfoId      int       `description:"图表id"`
+	SysUserId        int       `description:"sys_user_id"`
+	ShareType        int8      `description:"分享类型,1:仅查看;2:可编辑"`
+	CreateTime       time.Time `description:"创建时间"`
+}
+
+// TableName
+// @Description: 表名
+// @author: Roc
+// @receiver m
+// @datetime 2024-11-27 14:04:14
+// @return string
+func (m ChartInfoShare) TableName() string {
+	return `chart_info_share`
+}
+
+// GetListByChartInfoId
+// @Description: 根据指标id获取分享用户列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-11-27 15:39:17
+// @param chartInfoId int
+// @return items []*ChartInfoShare
+// @return err error
+func (m ChartInfoShare) GetListByChartInfoId(chartInfoId int) (items []*ChartInfoShare, err error) {
+	sql := ` SELECT * FROM chart_info_share WHERE chart_info_id = ? ORDER BY chart_info_share_id ASC `
+	err = global.DmSQL["data"].Raw(sql, chartInfoId).Find(&items).Error
+
+	return
+}
+
+// SaveChartInfoShare
+// @Description: 保存配置
+// @author: Roc
+// @receiver m
+// @datetime 2024-11-27 15:54:07
+// @param chartInfoIdList []int
+// @param userIdList []int
+// @param shareType int8
+// @return err error
+func (m ChartInfoShare) SaveChartInfoShare(chartInfoIdList, userIdList []int, shareType int8) (err error) {
+	// TODO 保存之前,得先做关联校验
+	addList := make([]*ChartInfoShare, 0)
+	for _, chartInfoId := range chartInfoIdList {
+		for _, userId := range userIdList {
+			addList = append(addList, &ChartInfoShare{
+				ChartInfoShareId: 0,
+				ChartInfoId:      chartInfoId,
+				SysUserId:        userId,
+				ShareType:        shareType,
+				CreateTime:       time.Now(),
+			})
+		}
+	}
+
+	tx := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	// 先删除原来的配置,新增最新的配置
+	sql := fmt.Sprintf("DELETE FROM %s WHERE chart_info_id IN (?) AND share_type = ? ", m.TableName())
+	err = tx.Exec(sql, chartInfoIdList, shareType).Error
+	if err != nil {
+		return
+	}
+
+	// 批量添加新的配置
+	if len(addList) > 0 {
+		err = tx.CreateInBatches(addList, utils.MultiAddNum).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// ShareChartInfoQuery
+// @Description: 共享指标
+type ShareChartInfoQuery struct {
+	ChartInfo
+	ShareType string    `gorm:"column:share_type" description:"共享类型"`
+	ShareTime time.Time `gorm:"column:share_time" description:"设置共享时间"`
+}
+
+// GetAllSharedChartInfoListByFromUserId
+// @Description: 获取所有我共享出去的指标列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 09:56:41
+// @param sysUserId int
+// @return list []*ShareChartInfoQuery
+// @return err error
+func (m ChartInfoShare) GetAllSharedChartInfoListByFromUserId(sysUserId int) (list []*ShareChartInfoQuery, err error) {
+	sql := `SELECT b."chart_info_id",
+       MAX(a.share_type) AS share_type,
+MAX(a.create_time) as share_time,
+MAX(b."chart_name") "chart_name",
+MAX(b."source") "source",
+MAX(b."chart_type") "chart_type",
+MAX(b."chart_classify_id") "chart_classify_id",
+MAX(b."chart_public_classify_id") "chart_public_classify_id",
+MAX(b."unique_code") "unique_code",
+MAX(b."chart_image") "chart_image",
+MAX(b."sys_user_id") "sys_user_id",
+MAX(b."sys_user_real_name") "sys_user_real_name",
+MAX(b."create_time") "create_time",
+MAX(b."modify_time") "modify_time",
+MAX(b."sort") AS "sort"
+ FROM chart_info_share AS a 
+     JOIN chart_info AS b ON a.chart_info_id = b.chart_info_id
+	  WHERE 1=1 AND b.sys_user_id = ?
+	  GROUP BY b.chart_info_id
+ORDER BY share_time DESC`
+	err = global.DmSQL["data"].Raw(sql, sysUserId).Scan(&list).Error
+	return
+}
+
+// GetAllSharedChartInfoListByReceivedUserId
+// @Description: 获取所有我收到的共享的指标列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 09:56:41
+// @param sysUserId int
+// @return list []*ShareChartInfoQuery
+// @return err error
+func (m ChartInfoShare) GetAllSharedChartInfoListByReceivedUserId(sysUserId int) (list []*ShareChartInfoQuery, err error) {
+	sql := `SELECT b."chart_info_id",
+       MAX(a.share_type) AS share_type,
+MAX(a.create_time) as share_time,
+MAX(b."chart_name") "chart_name",
+MAX(b."source") "source",
+MAX(b."chart_type") "chart_type",
+MAX(b."chart_classify_id") "chart_classify_id",
+MAX(b."chart_public_classify_id") "chart_public_classify_id",
+MAX(b."unique_code") "unique_code",
+MAX(b."chart_image") "chart_image",
+MAX(b."sys_user_id") "sys_user_id",
+MAX(b."sys_user_real_name") "sys_user_real_name",
+MAX(b."create_time") "create_time",
+MAX(b."modify_time") "modify_time",
+MAX(b."sort") AS "sort"
+ FROM chart_info_share AS a 
+     JOIN chart_info AS b ON a.chart_info_id = b.chart_info_id
+	  WHERE 1=1 AND a.sys_user_id = ? AND b.sys_user_id != ?
+	  GROUP BY b.chart_info_id
+ORDER BY share_time DESC`
+	err = global.DmSQL["data"].Raw(sql, sysUserId, sysUserId).Scan(&list).Error
+	return
+}
+
+// GetAllEditSharedChartInfoIdListByReceivedUserId
+// @Description: 获取所有我收到的共享的、可以编辑的图表id列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 09:56:41
+// @param sysUserId int
+// @return list []*ShareChartInfoQuery
+// @return err error
+func (m ChartInfoShare) GetAllEditSharedChartInfoIdListByReceivedUserId(sysUserId int, chartInfoIdList []int) (list []int, err error) {
+	sql := `SELECT a."chart_info_id" FROM chart_info_share AS a 
+            WHERE 1=1 AND a.sys_user_id = ? AND share_type = ? `
+	pars := []interface{}{sysUserId, utils.ShareTypeEdit}
+
+	if len(chartInfoIdList) > 0 {
+		sql += ` AND a.chart_info_id in (?) `
+		pars = append(pars, chartInfoIdList)
+	}
+	sql += ` GROUP BY a.chart_info_id `
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error
+	return
+}
+
+// GetShareChartInfoListPageList
+// @Description: 获取分享的指标列表(分页)
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 14:42:12
+// @param condition string
+// @param pars []interface{}
+// @param startSize int
+// @param pageSize int
+// @return total int32
+// @return list []*ChartInfoList
+// @return err error
+func (m ChartInfoShare) GetShareChartInfoListPageList(condition string, pars []interface{}, startSize, pageSize int) (total int32, list []*ChartInfoView, err error) {
+	baseSql := `SELECT b."chart_info_id",
+       MAX(a.share_type) AS share_type,
+MAX(a.create_time) as share_time,
+MAX(b."chart_name") "chart_name",
+MAX(b."source") "source",
+MAX(b."chart_type") "chart_type",
+MAX(b."chart_classify_id") "chart_classify_id",
+MAX(b."chart_public_classify_id") "chart_public_classify_id",
+MAX(b."unique_code") "unique_code",
+MAX(b."chart_image") "chart_image",
+MAX(b."sys_user_id") "sys_user_id",
+MAX(b."sys_user_real_name") "sys_user_real_name",
+MAX(b."create_time") "create_time",
+MAX(b."modify_time") "modify_time",
+MAX(b."sort") AS "sort"
+  FROM chart_info_share AS a 
+     JOIN chart_info AS b ON a.chart_info_id = b.chart_info_id
+	  WHERE 1=1 `
+
+	baseSql += condition
+	baseSql += ` GROUP BY b.chart_info_id `
+
+	totalSql := `SELECT COUNT(1) AS total FROM (` + baseSql + `) AS d`
+	var totalNull sql2.NullInt32
+	err = global.DmSQL["data"].Raw(totalSql, pars...).Scan(&totalNull).Error
+	if err != nil {
+		return
+	}
+	total = totalNull.Int32
+
+	sql := baseSql + ` ORDER BY share_time DESC LIMIT ?,? `
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error
+	if err != nil {
+		return
+	}
+
+	for _, v := range list {
+		v.ConvertToResp()
+	}
+
+	return
+}
+
+type UserShareChartClassifyItem struct {
+	UserId              int    `description:"用户id"`
+	UserName            string `description:"用户名称"`
+	ChartClassifyId     int    `description:"分类id"`
+	ChartInfoId         int    `description:"指标id"`
+	ChartClassifyName   string
+	ChartClassifyNameEn string
+	ParentId            int
+	Level               int                           `description:"层级"`
+	Sort                int                           `description:"排序字段,越小越靠前,默认值:10"`
+	UniqueCode          string                        `description:"唯一编码"`
+	Source              int                           `description:"来源id"`
+	SourceName          string                        `description:"来源名称"`
+	SysUserId           int                           `description:"创建人id"`
+	SysUserRealName     string                        `description:"创建人姓名"`
+	DateType            int                           `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate           string                        `description:"自定义开始日期"`
+	EndDate             string                        `description:"自定义结束日期"`
+	ChartType           int                           `description:"生成样式:1:曲线图,2:季节性图"`
+	Calendar            string                        `description:"公历/农历"`
+	SeasonStartDate     string                        `description:"季节性图开始日期"`
+	SeasonEndDate       string                        `description:"季节性图开始日期"`
+	Children            []*UserShareChartClassifyItem `gorm:"-"`
+	Button              ChartClassifyItemsButton      `gorm:"-" description:"按钮权限"`
+	IsJoinPermission    int                           `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth       bool                          `description:"是否有数据权限,默认:false"`
+	ChartClassifyIdPath string                        `description:"分类的完整路径,格式为:父级ID,当前ID"`
+}
+
+type UserShareChartClassifyItemList []*UserShareChartClassifyItem
+
+func (m UserShareChartClassifyItemList) Len() int {
+	return len(m)
+}
+
+func (m UserShareChartClassifyItemList) Less(i, j int) bool {
+	return m[i].Sort < m[j].Sort
+}
+
+func (m UserShareChartClassifyItemList) Swap(i, j int) {
+	m[i], m[j] = m[j], m[i]
+}

+ 365 - 0
models/data_manage/collect_chart.go

@@ -0,0 +1,365 @@
+package data_manage
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// ChartCollect 图表收藏
+type ChartCollect struct {
+	ChartCollectId         int       `gorm:"primaryKey;autoIncrement;column:chart_collect_id;type:int(10) unsigned;not null"`
+	ChartCollectClassifyId int       `gorm:"index:idx_classify_id;column:chart_collect_classify_id;type:int(10) unsigned;not null;default:0"` // 图表收藏分类ID
+	ChartInfoId            int       `gorm:"column:chart_info_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
+	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 *ChartCollect) TableName() string {
+	return "chart_collect"
+}
+
+type ChartCollectCols struct {
+	PrimaryId              string
+	ChartCollectClassifyId string
+	ChartInfoId            string
+	SysUserId              string
+	SysRealName            string
+	Sort                   string
+	CreateTime             string
+	ModifyTime             string
+}
+
+func (m *ChartCollect) Cols() ChartCollectCols {
+	return ChartCollectCols{
+		PrimaryId:              "chart_collect_id",
+		ChartCollectClassifyId: "chart_collect_classify_id",
+		ChartInfoId:            "chart_info_id",
+		SysUserId:              "sys_user_id",
+		SysRealName:            "sys_real_name",
+		Sort:                   "sort",
+		CreateTime:             "create_time",
+		ModifyTime:             "modify_time",
+	}
+}
+
+func (m *ChartCollect) Create() (err error) {
+	err = global.DmSQL["data"].Create(m).Error
+	return
+}
+
+func (m *ChartCollect) CreateMulti(items []*ChartCollect) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	err = global.DmSQL["data"].CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (m *ChartCollect) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Select(cols).Updates(m).Error
+	return
+}
+
+func (m *ChartCollect) 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.ChartCollectId).Error
+	return
+}
+
+func (m *ChartCollect) 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 *ChartCollect) 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
+}
+
+// RemoveAndCreateMulti
+// @Description: 清除原有配置并新增收藏
+// @receiver m
+// @param delCondition
+// @param delPars
+// @param items
+// @return err
+func (m *ChartCollect) RemoveAndCreateMulti(delCondition string, delPars []interface{}, items []*ChartCollect) (err error) {
+	to := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	// 先删除
+	{
+		if delCondition == "" {
+			return
+		}
+		sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), delCondition)
+		err = to.Exec(sql, delPars...).Error
+		if err != nil {
+			return
+		}
+	}
+
+	if len(items) == 0 {
+		return
+	}
+	err = to.CreateInBatches(items, utils.MultiAddNum).Error
+
+	return
+}
+
+func (m *ChartCollect) GetItemById(id int) (item *ChartCollect, 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 *ChartCollect) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *ChartCollect, 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 *ChartCollect) 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 *ChartCollect) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*ChartCollect, 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 *ChartCollect) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*ChartCollect, 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
+}
+
+// GetCollectChartInfoByClassifyId 获取分类下收藏的图表信息
+func GetCollectChartInfoByClassifyId(classifyId int) (items []*ChartInfo, err error) {
+	sql := `SELECT b.* FROM chart_collect AS a JOIN chart_info AS b ON a.chart_info_id = b.chart_info_id WHERE a.chart_collect_classify_id = ? ORDER BY a.sort ASC`
+	err = global.DmSQL["data"].Raw(sql, classifyId).Find(&items).Error
+	return
+}
+
+// ChartCollectReq 加入/取消收藏
+type ChartCollectReq struct {
+	ClassifyId     int   `description:"分类ID"`
+	ClassifyIdList []int `description:"分类ID列表"`
+	ChartInfoId    int   `description:"图表ID"`
+}
+
+// GetCollectChartInfoCount 获取收藏的图表信息总数
+func GetCollectChartInfoCount(condition string, pars []interface{}) (total int64, err error) {
+	sql := fmt.Sprintf(`SELECT COUNT(1) AS ct FROM (
+	  SELECT b.chart_info_id FROM chart_collect AS a JOIN chart_info AS b ON a.chart_info_id = b.chart_info_id
+	  WHERE 1=1 %s
+	  GROUP BY b.chart_info_id
+	) AS sub`, condition)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&total).Error
+	return
+}
+
+// GetCollectChartInfoPageList 获取收藏的图表信息列表-分页
+func GetCollectChartInfoPageList(condition string, pars []interface{}, startSize, pageSize int) (list []*CollectChartInfoQuery, err error) {
+	sql := fmt.Sprintf(`SELECT b."chart_info_id",
+       WM_CONCAT(DISTINCT a."chart_collect_classify_id") AS "collect_classify_id",
+MAX(a.create_time) as collect_time,
+MAX(b."chart_name") "chart_name",
+MAX(b."chart_type") "chart_type",
+MAX(b."source") "source",
+MAX(b."chart_classify_id") "chart_classify_id",
+MAX(b."create_time") "create_time",
+MAX(b."unique_code") "unique_code",
+MAX(b."chart_image") "chart_image",
+MAX(b."modify_time") "modify_time",
+MAX(a."sort") AS "sort"
+ FROM chart_collect AS a JOIN chart_info AS b ON a.chart_info_id = b.chart_info_id
+	  WHERE 1=1 %s
+	  GROUP BY b.chart_info_id
+ORDER BY collect_time DESC LIMIT ?,?`, condition)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error
+	return
+}
+
+// GetUserAllCollectChartInfoIdList
+// @Description: 获取用户所有收藏的图表id列表
+// @author: Roc
+// @datetime 2024-11-28 15:27:52
+// @param userId int
+// @return list []int
+// @return err error
+func GetUserAllCollectChartInfoIdList(userId int) (list []int, err error) {
+	sql := `SELECT chart_info_id FROM chart_collect WHERE 1=1 AND sys_user_id = ? GROUP BY chart_info_id`
+	err = global.DmSQL["data"].Raw(sql, userId).Scan(&list).Error
+	return
+}
+
+type CollectChartInfoQuery struct {
+	ChartInfo
+	CollectClassifyIdStr string    `gorm:"column:collect_classify_id" description:"收藏分类ID"`
+	CollectTime          time.Time `gorm:"column:collect_time" description:"收藏时间"`
+}
+
+// CollectChartInfoItem 收藏列表图表信息
+type CollectChartInfoItem struct {
+	ChartInfoId           int    `description:"图表ID"`
+	ChartInfoType         int    `description:"图表类型:0-普通图表; 1-预测图表"`
+	ChartType             int    `description:"图表类型:1-基础图表; 2-计算图表"`
+	Source                int    `description:"来源ID"`
+	SourceName            string `description:"来源名称"`
+	ChartName             string `description:"图表名称"`
+	Frequency             string `description:"频率"`
+	Unit                  string `description:"单位"`
+	UniqueCode            string `description:"唯一编码"`
+	ChartImage            string `description:"图表图片"`
+	ClassifyId            int    `description:"图表分类ID"`
+	CollectClassifyIdList []int  `description:"收藏分类ID列表"`
+	CollectTime           string `description:"收藏时间"`
+	CreateTime            string `description:"创建时间"`
+	Sort                  int    `description:"排序"`
+}
+
+func FormatChartInfo2CollectItem(origin *CollectChartInfoQuery) (item *CollectChartInfoItem) {
+	item = new(CollectChartInfoItem)
+	item.ChartInfoId = origin.ChartInfoId
+	item.ChartType = origin.ChartType
+	item.Source = origin.Source
+	item.ChartName = origin.ChartName
+	item.Unit = origin.Unit
+	item.UniqueCode = origin.UniqueCode
+	item.ChartImage = origin.ChartImage
+	item.ClassifyId = origin.ChartClassifyId
+	collectClassifyIdList := make([]int, 0)
+	if origin.CollectClassifyIdStr != `` {
+		collectClassifyIdStrList := strings.Split(origin.CollectClassifyIdStr, ",")
+		for _, v := range collectClassifyIdStrList {
+			collectClassifyId, tmpErr := strconv.Atoi(v)
+			if tmpErr == nil {
+				collectClassifyIdList = append(collectClassifyIdList, collectClassifyId)
+			}
+		}
+	}
+	item.CollectClassifyIdList = collectClassifyIdList
+	item.CollectTime = origin.CollectTime.Format(utils.FormatDateTime)
+	item.CreateTime = origin.CreateTime.Format(utils.FormatDateTime)
+	item.Sort = origin.Sort
+	return
+}
+
+// CollectChartInfoListResp 收藏图表分页列表相应
+type CollectChartInfoListResp struct {
+	Paging *paging.PagingItem
+	List   []*CollectChartInfoItem
+}
+
+// ChartCollectMoveReq 移动收藏
+type ChartCollectMoveReq struct {
+	ChartInfoId     int `description:"收藏的图表ID(分类下图表ID唯一)"`
+	PrevChartInfoId int `description:"前一个收藏的图表ID"`
+	NextChartInfoId int `description:"后一个收藏的图表ID"`
+	ClassifyId      int `description:"当前分类ID"`
+}
+
+func GetChartCollectSort(adminId, classifyId, sort int) (item *ChartCollect, err error) {
+	sql := ` SELECT * FROM chart_collect WHERE 1=1 AND sys_user_id = ? AND chart_collect_classify_id = ? `
+	if sort == 1 {
+		sql += ` ORDER BY sort DESC, chart_collect_id ASC LIMIT 1 `
+	} else {
+		sql += ` ORDER BY sort ASC, chart_collect_id DESC LIMIT 1 `
+	}
+	err = global.DmSQL["data"].Raw(sql, adminId, classifyId).First(&item).Error
+	return
+}
+
+func GetChartCollectByChartInfoId(adminId, chartInfoId, classifyId int) (item *ChartCollect, err error) {
+	sql := `SELECT * FROM chart_collect WHERE sys_user_id = ? AND chart_info_id = ? AND chart_collect_classify_id=? `
+	err = global.DmSQL["data"].Raw(sql, adminId, chartInfoId, classifyId).First(&item).Error
+	return
+}
+
+func UpdateChartCollectSortByClassifyId(classifyId, nowSort int, prevMyChartClassifyMappingId int, updateSort string) (err error) {
+	sql := ` update chart_collect set sort = ` + updateSort + ` WHERE chart_collect_classify_id = ?  `
+	if prevMyChartClassifyMappingId > 0 {
+		sql += ` AND ( sort > ? or ( chart_collect_id < ? and sort=? )) `
+	}
+	err = global.DmSQL["data"].Exec(sql, classifyId, nowSort, prevMyChartClassifyMappingId, nowSort).Error
+	return
+}
+
+func UpdateChartCollectMove(sort, adminId, chartInfoId, myChartClassifyId int) (err error) {
+	sql := ` UPDATE chart_collect SET sort = ?,modify_time=NOW() WHERE sys_user_id=? AND chart_info_id=? AND chart_collect_classify_id=? `
+	err = global.DmSQL["data"].Exec(sql, sort, adminId, chartInfoId, myChartClassifyId).Error
+	return
+}
+
+// ChartCollectItem 图表收藏信息
+type ChartCollectItem struct {
+	ChartCollectId         int       `gorm:"primaryKey;autoIncrement;column:chart_collect_id;type:int(10) unsigned;not null"`
+	ChartCollectClassifyId int       `gorm:"index:idx_classify_id;column:chart_collect_classify_id;type:int(10) unsigned;not null;default:0"` // 图表收藏分类ID
+	ChartInfoId            int       `gorm:"column:chart_info_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
+	SysRealName            string    `gorm:"column:sys_real_name;type:int(10) unsigned;not null;default:0"`                                   // 创建人姓名
+	ClassifyName           string    `gorm:"column:classify_name;type:varchar(255);not null;default:''"`                                      // 分类名称
+	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 *ChartCollect) GetItemsByUserIdAndChartInfoIdList(userId int, chartInfoIdList []int) (items []*ChartCollectItem, err error) {
+	if len(chartInfoIdList) <= 0 {
+		return
+	}
+	sql := `SELECT a.*,b.classify_name FROM chart_collect  AS a
+    JOIN chart_collect_classify b on a.chart_collect_classify_id = b.chart_collect_classify_id
+    WHERE a.sys_user_id = ? AND a.chart_info_id in (?)  ORDER BY a.chart_collect_id DESC `
+	err = global.DmSQL["data"].Raw(sql, userId, chartInfoIdList).Find(&items).Error
+
+	return
+}

+ 280 - 0
models/data_manage/collect_chart_classify.go

@@ -0,0 +1,280 @@
+package data_manage
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// ChartCollectClassify 图表收藏分类
+type ChartCollectClassify struct {
+	ChartCollectClassifyId int       `gorm:"primaryKey;autoIncrement;column:chart_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 *ChartCollectClassify) TableName() string {
+	return "chart_collect_classify"
+}
+
+type ChartCollectClassifyCols 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 *ChartCollectClassify) Cols() ChartCollectClassifyCols {
+	return ChartCollectClassifyCols{
+		PrimaryId:       "chart_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 *ChartCollectClassify) Create() (err error) {
+	err = global.DmSQL["data"].Create(m).Error
+	return
+}
+
+func (m *ChartCollectClassify) CreateMulti(items []*ChartCollectClassify) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	err = global.DmSQL["data"].CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (m *ChartCollectClassify) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Select(cols).Updates(m).Error
+	return
+}
+
+func (m *ChartCollectClassify) 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.ChartCollectClassifyId).Error
+	return
+}
+
+func (m *ChartCollectClassify) 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 *ChartCollectClassify) 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 *ChartCollectClassify) GetItemById(id int) (item *ChartCollectClassify, 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 *ChartCollectClassify) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *ChartCollectClassify, 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 *ChartCollectClassify) 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 *ChartCollectClassify) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*ChartCollectClassify, 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 *ChartCollectClassify) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*ChartCollectClassify, 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 *ChartCollectClassify) 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
+}
+
+// ChartCollectClassifyItem 图表收藏分类
+type ChartCollectClassifyItem 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     []*ChartCollectClassifyItem `description:"子分类"`
+}
+
+func (m *ChartCollectClassify) Format2Item() (item *ChartCollectClassifyItem) {
+	item = new(ChartCollectClassifyItem)
+	item.ClassifyId = m.ChartCollectClassifyId
+	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([]*ChartCollectClassifyItem, 0)
+	return
+}
+
+// ChartCollectClassifyListItem 图表收藏分类列表
+type ChartCollectClassifyListItem struct {
+	NodeType     int                             `description:"类型: 1-分类; 2-图表"`
+	ClassifyId   int                             `description:"分类ID"`
+	ClassifyName string                          `description:"分类名称"`
+	ChartInfoId  int                             `description:"图表ID"`
+	ChartCode    string                          `description:"图表编码"`
+	ChartName    string                          `description:"图表名称"`
+	ParentId     int                             `description:"父级ID"`
+	Level        int                             `description:"层级"`
+	Sort         int                             `description:"排序"`
+	UniqueCode   string                          `description:"唯一编码, 图表的话用indexCode"`
+	Children     []*ChartCollectClassifyListItem `description:"子分类"`
+}
+
+// ChartCollectClassifyAddReq 新增分类
+type ChartCollectClassifyAddReq struct {
+	ClassifyName string `description:"分类名称"`
+	ParentId     int    `description:"父级ID"`
+	Level        int    `description:"层级"`
+}
+
+// ChartCollectClassifyEditReq 编辑分类
+type ChartCollectClassifyEditReq struct {
+	ClassifyId   int    `description:"分类ID"`
+	ClassifyName string `description:"分类名称"`
+}
+
+// ChartCollectClassifyRemoveReq 删除分类
+type ChartCollectClassifyRemoveReq struct {
+	ClassifyId int `description:"分类ID"`
+}
+
+// RemoveClassifyAndCollect 移除分类及收藏
+func (m *ChartCollectClassify) 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(ChartCollect)
+	sql = fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, collectOb.TableName(), collectOb.Cols().ChartCollectClassifyId, utils.GetOrmInReplace(len(classifyIds)))
+	e = tx.Exec(sql, classifyIds).Error
+	if e != nil {
+		err = fmt.Errorf("remove collect err: %v", e)
+		return
+	}
+	return
+}
+
+// ChartCollectClassifyMoveReq 移动分类
+type ChartCollectClassifyMoveReq struct {
+	ClassifyId     int `description:"分类ID"`
+	PrevClassifyId int `description:"上一个兄弟节点分类ID"`
+	NextClassifyId int `description:"下一个兄弟节点分类ID"`
+}
+
+// GetChartCollectClassifyById 获取分类
+func GetChartCollectClassifyById(adminId, classifyId int) (item *ChartCollectClassify, err error) {
+	sql := `SELECT * FROM chart_collect_classify WHERE sys_user_id = ? AND chart_collect_classify_id = ? `
+	err = global.DmSQL["data"].Raw(sql, adminId, classifyId).First(&item).Error
+	return
+}
+
+// GetFirstChartCollectClassifyByAdminId 获取当前账号下,排序第一条的分类数据
+func GetFirstChartCollectClassifyByAdminId(adminId int) (item *ChartCollectClassify, err error) {
+	sql := `SELECT * FROM chart_collect_classify WHERE sys_user_id = ? ORDER BY sort ASC, chart_collect_classify_id ASC LIMIT 1`
+	err = global.DmSQL["data"].Raw(sql, adminId).First(&item).Error
+	return
+}
+
+// UpdateChartCollectClassifySortByClassifyId 更新排序
+func UpdateChartCollectClassifySortByClassifyId(adminId, classifyId, nowSort int, updateSort string) (err error) {
+	sql := fmt.Sprintf(`UPDATE chart_collect_classify SET sort = %d WHERE sys_user_id = ? and sort > ? `, updateSort)
+	if classifyId > 0 {
+		sql += ` OR ( chart_collect_classify_id > ` + fmt.Sprint(classifyId) + ` AND sort = ` + fmt.Sprint(nowSort) + `)`
+	}
+	err = global.DmSQL["data"].Exec(sql, adminId, nowSort).Error
+	return
+}

+ 73 - 16
models/data_manage/edb_collect.go → models/data_manage/collect_edb.go

@@ -221,6 +221,12 @@ MAX(b."source") "source",
 MAX(b."source_name") "source_name",
 MAX(b."frequency") "frequency",
 MAX(b."unit") "unit",
+MAX(b."end_date") "end_date",
+MAX(b."end_value") "end_value",
+MAX(b."latest_date") "latest_date",
+MAX(b."latest_value") "latest_value",
+MAX(b."sys_user_id") "sys_user_id",
+MAX(b."sys_user_real_name") "sys_user_real_name",
 MAX(b."classify_id") "classify_id",
 MAX(b."create_time") "create_time",
 MAX(b."unique_code") "unique_code",
@@ -236,6 +242,19 @@ ORDER BY collect_time DESC LIMIT ?,?`, condition)
 	return
 }
 
+// GetUserAllCollectEdbInfoIdList
+// @Description: 获取用户所有收藏的指标id列表
+// @author: Roc
+// @datetime 2024-11-28 15:27:52
+// @param userId int
+// @return list []int
+// @return err error
+func GetUserAllCollectEdbInfoIdList(userId int) (list []int, err error) {
+	sql := `SELECT edb_info_id FROM edb_collect WHERE 1=1 AND sys_user_id = ? GROUP BY edb_info_id`
+	err = global.DmSQL["data"].Raw(sql, userId).Scan(&list).Error
+	return
+}
+
 type CollectEdbInfoQuery struct {
 	EdbInfo
 	CollectClassifyIdStr string    `gorm:"column:collect_classify_id" description:"收藏分类ID"`
@@ -244,22 +263,28 @@ type CollectEdbInfoQuery struct {
 
 // 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"`
-	CollectClassifyIdList []int  `description:"收藏分类ID列表"`
-	CollectTime           string `description:"收藏时间"`
-	CreateTime            string `description:"创建时间"`
-	Sort                  int    `description:"排序"`
+	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"`
+	CollectClassifyIdList []int     `description:"收藏分类ID列表"`
+	CollectTime           string    `description:"收藏时间"`
+	CreateTime            string    `description:"创建时间"`
+	Sort                  int       `description:"排序"`
+	LatestDate            string    `description:"数据最新日期(实际日期)"`
+	LatestValue           float64   `description:"数据最新值(实际值)"`
+	EndValue              float64   `description:"数据的最新值(预测日期的最新值)"`
+	EndDate               time.Time `description:"终止日期"`
+	SysUserId             int
+	SysUserRealName       string
 }
 
 func FormatEdbInfo2CollectItem(origin *CollectEdbInfoQuery) (item *CollectEdbInfoItem) {
@@ -276,6 +301,12 @@ func FormatEdbInfo2CollectItem(origin *CollectEdbInfoQuery) (item *CollectEdbInf
 	item.UniqueCode = origin.UniqueCode
 	item.ChartImage = origin.ChartImage
 	item.ClassifyId = origin.ClassifyId
+	item.EndDate = origin.EndDate
+	item.EndValue = origin.EndValue
+	item.LatestDate = origin.LatestDate
+	item.LatestValue = origin.LatestValue
+	item.SysUserId = origin.SysUserId
+	item.SysUserRealName = origin.SysUserRealName
 	collectClassifyIdList := make([]int, 0)
 	if origin.CollectClassifyIdStr != `` {
 		collectClassifyIdStrList := strings.Split(origin.CollectClassifyIdStr, ",")
@@ -338,3 +369,29 @@ func UpdateEdbCollectMove(sort, adminId, edbInfoId, myChartClassifyId int) (err
 	err = global.DmSQL["data"].Exec(sql, sort, adminId, edbInfoId, myChartClassifyId).Error
 	return
 }
+
+// EdbCollectItem 指标收藏信息
+type EdbCollectItem 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"`                                 // 创建人姓名
+	ClassifyName         string    `gorm:"column:classify_name;type:varchar(255);not null;default:''"`                                    // 分类名称
+	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) GetItemsByUserIdAndEdbInfoIdList(userId int, edbInfoIdList []int) (items []*EdbCollectItem, err error) {
+	if len(edbInfoIdList) <= 0 {
+		return
+	}
+	sql := `SELECT a.*,b.classify_name FROM edb_collect  AS a
+    JOIN edb_collect_classify b on a.edb_collect_classify_id = b.edb_collect_classify_id
+    WHERE a.sys_user_id = ? AND a.edb_info_id in (?)  ORDER BY a.edb_collect_id DESC `
+	err = global.DmSQL["data"].Raw(sql, userId, edbInfoIdList).Find(&items).Error
+
+	return
+}

+ 0 - 0
models/data_manage/edb_collect_classify.go → models/data_manage/collect_edb_classify.go


+ 252 - 0
models/data_manage/data_approve/data_approve.go

@@ -0,0 +1,252 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+type DataApprove struct {
+	DataApproveId int       `gorm:"column:data_approve_id;primary_key"`
+	Title         string    `gorm:"column:title"`
+	DataType      int       `gorm:"column:data_type"`
+	State         int       `gorm:"column:state"` //  '审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回'
+	FlowId        int       `gorm:"column:flow_id"`
+	FlowVersion   int       `gorm:"column:flow_version"`
+	StartNodeId   int       `gorm:"column:start_node_id"`
+	CurrNodeId    int       `gorm:"column:curr_node_id"`
+	ApplyUserId   int       `gorm:"column:apply_user_id"`
+	ApplyUserName string    `gorm:"column:apply_user_name"`
+	ApproveRemark string    `gorm:"column:approve_remark"`
+	ApproveTime   time.Time `gorm:"column:approve_time"`
+	CreateTime    time.Time `gorm:"column:create_time"`
+	ModifyTime    time.Time `gorm:"column:update_time"`
+}
+
+var DataApproveCols = struct {
+	DataApproveId string
+	Title         string
+	DataType      string // 资产类型:1:指标、2:图表
+	State         string //  '审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回'
+	FlowId        string
+	FlowVersion   string
+	StartNodeId   string
+	CurrNodeId    string
+	ApplyUserId   string
+	ApplyUserName string
+	ApproveRemark string
+	ApproveTime   string
+	CreateTime    string
+	ModifyTime    string
+}{
+	DataApproveId: "data_approve_id",
+	Title:         "title",
+	DataType:      "data_type",
+	State:         "state",
+	FlowId:        "flow_id",
+	FlowVersion:   "flow_version",
+	StartNodeId:   "start_node_id",
+	CurrNodeId:    "curr_node_id",
+	ApplyUserId:   "apply_user_id",
+	ApplyUserName: "apply_user_name",
+	ApproveRemark: "approve_remark",
+	ApproveTime:   "approve_time",
+	CreateTime:    "create_time",
+	ModifyTime:    "modify_time",
+}
+
+type DataApproveItemOrm struct {
+	DataApproveId       int       `description:"审批ID"`
+	DataApproveRecordId int       `description:"审批记录ID"`
+	Title               string    `description:"审批标题"`
+	DataType            int       `description:"资产类型"`
+	State               int       `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	RecordState         int       `description:"审批记录状态:1-待审批;2-已通过;3-已驳回"`
+	FlowId              int       `description:"审批流ID"`
+	FlowVersion         int       `description:"审批流版本"`
+	StartNodeId         int       `description:"开始节点ID"`
+	CurrNodeId          int       `description:"当前节点ID"`
+	ApplyUserId         int       `description:"申请人ID"`
+	ApplyUserName       string    `description:"申请人姓名"`
+	ApproveRemark       string    `description:"审批备注"`
+	ApproveTime         time.Time `description:"审批时间"`
+	HandleTime          time.Time `description:"处理时间"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"修改时间"`
+	NodeState           int       `description:"当前节点审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回" json:"-"`
+	NodeApproveTime     time.Time `description:"当前节点审批时间" json:"-"`
+}
+
+func (b *DataApprove) TableName() string {
+	return "data_approve"
+}
+
+func (b *DataApprove) Update(cols []string) (err error) {
+	db := global.DmSQL["data"]
+	err = db.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func (b *DataApprove) Create() (err error) {
+	db := global.DmSQL["data"]
+	err = db.Create(b).Error
+	return
+}
+
+// AddDataApprove
+// @Description: 添加审批单
+// @author: Roc
+// @datetime 2024-12-06 09:46:04
+// @param dataApprove *DataApprove
+// @param relationList []*DataApproveRelation
+// @return err error
+func AddDataApprove(dataApprove *DataApprove, relationList []*DataApproveRelation) (err error) {
+	db := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			db.Rollback()
+		} else {
+			db.Commit()
+		}
+	}()
+
+	err = db.Create(dataApprove).Error
+	if err != nil {
+		return
+	}
+
+	relationIdList := make([]int, 0)
+	// 关联指标
+	if len(relationList) > 0 {
+		for _, v := range relationList {
+			v.DataApproveId = dataApprove.DataApproveId
+
+			relationIdList = append(relationIdList, v.DataId)
+		}
+		err = db.CreateInBatches(relationList, utils.MultiAddNum).Error
+		if err != nil {
+			return
+		}
+	}
+
+	// 更新资产公开状态
+	switch dataApprove.DataType {
+	case utils.DataApproveTypeEdb:
+		sql := `UPDATE edb_info set public_status = ?,modify_time=now()  WHERE edb_info_id in (?) `
+		err = global.DmSQL["data"].Exec(sql, utils.DataPublicCommit, relationIdList).Error
+
+	case utils.DataApproveTypeChart:
+		sql := `UPDATE chart_info set public_status = ?,modify_time=now()  WHERE chart_info_id in (?) `
+		err = global.DmSQL["data"].Exec(sql, utils.DataPublicCommit, relationIdList).Error
+
+	}
+
+	return
+}
+
+func GetDataApproveByFlowIdAndVersionId(dataFlowId int, flowVersion int) (item []*DataApprove, err error) {
+	db := global.DmSQL["data"]
+	err = db.Where("flow_id = ? AND flow_version = ?", dataFlowId, flowVersion).Find(&item).Error
+	return
+}
+
+func GetDataApproveById(DataApproveId int) (item *DataApprove, err error) {
+	db := global.DmSQL["data"]
+	err = db.Where("data_approve_id = ?", DataApproveId).First(&item).Error
+	return
+}
+
+// GetApprovingDataApproveCount 获取待处理的审批分页列表总数
+func GetApprovingDataApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.data_approve_record_id
+		FROM data_approve_record AS a
+		JOIN data_approve AS b ON a.data_approve_id = b.data_approve_id AND a.node_id = b.curr_node_id
+		WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApprovingDataApprovePageList 获取待处理的审批列表-分页
+func GetApprovingDataApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*DataApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.data_approve_record_id, a.state AS record_state, b.*
+		FROM data_approve_record AS a
+		JOIN data_approve AS b ON a.data_approve_id = b.data_approve_id AND a.node_id = b.curr_node_id
+		WHERE 1 = 1 %s %s
+		LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetApprovedDataApproveCount 获取已处理的审批分页列表总数
+func GetApprovedDataApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.data_approve_record_id
+		FROM data_approve_record AS a
+		JOIN data_approve AS b ON a.data_approve_id = b.data_approve_id
+		WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApprovedDataApprovePageList 获取已处理的审批列表-分页
+func GetApprovedDataApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*DataApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.data_approve_record_id, a.node_state AS record_state,a.node_state,a.node_approve_time, a.node_approve_time AS handle_time, b.*
+		FROM data_approve_record AS a
+		JOIN data_approve AS b ON a.data_approve_id = b.data_approve_id
+		WHERE 1 = 1 %s %s
+		LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetApplyDataApproveCount 获取我发起的审批分页列表总数
+func GetApplyDataApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.* FROM data_approve AS a WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApplyDataApprovePageList 获取我发起的审批列表-分页
+func GetApplyDataApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*DataApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.*,a.approve_time as handle_time,a.state as record_state FROM data_approve AS a WHERE 1 = 1 %s %s LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func GetDataApproveCountByState(state int) (count int, err error) {
+	db := global.DmSQL["data"]
+	sql := `SELECT COUNT(*) FROM data_approve WHERE state = ?`
+	err = db.Raw(sql, state).Scan(&count).Error
+	return
+}
+
+// GetListByDataApproveId
+// @Description: 根据审批id获取关联的资产(指标、图表)
+// @author: Roc
+// @datetime 2024-12-05 17:23:39
+// @param dataApproveId int
+// @return dataIdList []int
+// @return err error
+func (b *DataApprove) GetByDataApproveId(dataApproveId int) (dataIdList []*DataApproveRelation, err error) {
+	sql := `SELECT * FROM data_approve_relation AS a WHERE data_approve_id = ? `
+	err = global.DmSQL["data"].Raw(sql, dataApproveId).Scan(&dataIdList).Error
+	return
+}

+ 198 - 0
models/data_manage/data_approve/data_approve_flow.go

@@ -0,0 +1,198 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"time"
+)
+
+type DataApproveFlow struct {
+	DataApproveFlowId int       `gorm:"column:data_approve_flow_id;primaryKey"`
+	FlowName          string    `gorm:"column:flow_name"`
+	DataType          int       `gorm:"column:data_type"`
+	Remark            string    `gorm:"column:remark"`
+	CurrVersion       int       `gorm:"column:curr_version"`
+	CreateTime        time.Time `gorm:"column:create_time"`
+	ModifyTime        time.Time `gorm:"column:modify_time"`
+}
+
+var DataApproveFlowCols = struct {
+	DataApproveFlowId string
+	FlowName          string
+	DataType          string // 资产类型:1:指标、2:图表
+	CurrVersion       string
+	CreateTime        string
+	ModifyTime        string
+}{
+	DataApproveFlowId: "data_approve_flow_id",
+	FlowName:          "flow_name",
+	DataType:          "data_type",
+	CurrVersion:       "curr_version",
+	CreateTime:        "create_time",
+	ModifyTime:        "modify_time",
+}
+
+func (b *DataApproveFlow) TableName() string {
+	return "data_approve_flow"
+}
+
+func (b *DataApproveFlow) Add(node []*DataApproveNode) (err error) {
+	prevNodes := make([]*DataApproveNode, 0)
+	o := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			o.Rollback()
+		} else {
+			o.Commit()
+		}
+
+		// 更新每个节点的下一个节点信息, 放在事务中会更新失败
+		if e := UpdateNextNodes(prevNodes); e != nil {
+			err = fmt.Errorf("UpdatePrevNodes err: %s", e.Error())
+			return
+		}
+	}()
+
+	err = o.Create(b).Error
+	if err != nil {
+		err = fmt.Errorf("insert approve err: %v", err)
+		return
+	}
+
+	nodesLen := len(node)
+	if nodesLen == 0 {
+		return
+	}
+	prevId := 0
+	prevNode := new(DataApproveNode)
+	for k, v := range node {
+		v.DataApproveFlowId = b.DataApproveFlowId
+		v.PrevNodeId = prevId
+		err = o.Create(v).Error
+		if err != nil {
+			err = fmt.Errorf("insert node err: %v", err)
+			return
+		}
+		prevId = v.DataApproveNodeId
+
+		// 下一个节点
+		if prevNode != nil && k > 0 && k < nodesLen {
+			prevNode.NextNodeId = v.DataApproveNodeId
+			prevNodes = append(prevNodes, prevNode)
+		}
+		prevNode = v
+	}
+	return
+}
+
+func (b *DataApproveFlow) Update(cols []string, node []*DataApproveNode) (err error) {
+	prevNodes := make([]*DataApproveNode, 0)
+	o := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			o.Rollback()
+		} else {
+			o.Commit()
+		}
+
+		// 更新每个节点的下一个节点信息, 放在事务中会更新失败
+		if e := UpdateNextNodes(prevNodes); e != nil {
+			err = fmt.Errorf("UpdatePrevNodes err: %s", e.Error())
+			return
+		}
+	}()
+	err = o.Model(b).Select(cols).Updates(b).Error
+	if err != nil {
+		return
+	}
+
+	nodesLen := len(node)
+	if nodesLen == 0 {
+		return
+	}
+	prevId := 0
+	prevNode := new(DataApproveNode)
+	for k, v := range node {
+		v.DataApproveFlowId = b.DataApproveFlowId
+		v.PrevNodeId = prevId
+		err = o.Create(v).Error
+		if err != nil {
+			err = fmt.Errorf("insert node err: %v", err)
+			return
+		}
+		prevId = v.DataApproveNodeId
+
+		// 下一个节点
+		if prevNode != nil && k > 0 && k < nodesLen {
+			prevNode.NextNodeId = v.DataApproveNodeId
+			prevNodes = append(prevNodes, prevNode)
+		}
+		prevNode = v
+	}
+	
+	return
+}
+
+func (b *DataApproveFlow) Delete() error {
+	return global.DmSQL["data"].Delete(b).Error
+}
+
+func (m *DataApproveFlow) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *DataApproveFlow, err error) {
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s `, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).First(&item).Error
+	return
+}
+
+func GetDataApproveFlowById(DataApproveFlowId int) (item *DataApproveFlow, err error) {
+	err = global.DmSQL["data"].Where("data_approve_flow_id = ?", DataApproveFlowId).First(&item).Error
+	return
+}
+
+// GetDataApproveFlowByDataType
+// @Description: 根据数据类型获取审核流
+// @author: Roc
+// @datetime 2024-12-05 16:06:52
+// @param dataType int
+// @return item *DataApproveFlow
+// @return err error
+func GetDataApproveFlowByDataType(dataType int) (item *DataApproveFlow, err error) {
+	err = global.DmSQL["data"].Where("data_type = ?", dataType).First(&item).Error
+	return
+}
+
+func GetDataApproveFlowByClassifyId(classifyId int) (item *DataApproveFlow, err error) {
+	err = global.DmSQL["data"].Where("classify_id = ?", classifyId).First(&item).Error
+	return
+}
+
+func GetDataApproveFlowByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*DataApproveFlow, err error) {
+	o := global.DmSQL["data"]
+	sql := "SELECT * FROM data_approve_flow WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	sql += " LIMIT ?,?"
+	pars = append(pars, startSize, pageSize)
+	err = o.Raw(sql, pars...).Scan(&items).Error
+	return
+}
+
+func GetDataApproveFlowCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := global.DmSQL["data"]
+	sql := "SELECT COUNT(*) AS count FROM data_approve_flow WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+func UpdateFlowClassifyName(classifyId int, classifyName string) (err error) {
+	o := global.DmSQL["data"]
+	err = o.Model(&DataApproveFlow{}).Where("classify_id = ?", classifyId).Update("classify_name", classifyName).Error
+	return
+}

+ 118 - 0
models/data_manage/data_approve/data_approve_message.go

@@ -0,0 +1,118 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type DataApproveMessage struct {
+	Id            int       `gorm:"primaryKey;column:id"`
+	SendUserId    int       `gorm:"column:send_user_id"`    // 发送人Id
+	ReceiveUserId int       `gorm:"column:receive_user_id"` // 接收者Id
+	DataType      int       `gorm:"column:data_type"`       // 资产类型
+	Content       string    `gorm:"column:content"`         // 消息内容
+	Remark        string    `gorm:"column:remark"`          // 备注信息
+	DataApproveId int       `gorm:"column:data_approve_id"` // 审批Id
+	ApproveState  int       `gorm:"column:approve_state"`   // 审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回
+	IsRead        int       `gorm:"column:is_read"`         // 是否已读:0-未读;1-已读
+	CreateTime    time.Time `gorm:"column:create_time"`     // 创建时间
+	ModifyTime    time.Time `gorm:"column:modify_time"`     // 修改时间
+}
+
+var DataApproveMessageCols = struct {
+	Id            string
+	SendUserId    string
+	ReceiveUserId string
+	DataType      string
+	Content       string
+	Remark        string
+	DataApproveId string
+	ApproveState  string
+	IsRead        string
+	CreateTime    string
+	ModifyTime    string
+}{
+	Id:            "id",
+	SendUserId:    "send_user_id",
+	ReceiveUserId: "receive_user_id",
+	DataType:      "data_type",
+	Content:       "content",
+	Remark:        "remark",
+	DataApproveId: "data_approve_id",
+	ApproveState:  "approve_state",
+	IsRead:        "is_read",
+	CreateTime:    "create_time",
+	ModifyTime:    "modify_time",
+}
+
+func (r *DataApproveMessage) TableName() string {
+	return "data_approve_message"
+}
+
+func (r *DataApproveMessage) Create() (err error) {
+	o := global.DmSQL["data"]
+	err = o.Create(r).Error
+	return err
+}
+
+func (m *DataApproveMessage) PrimaryId() string {
+	return DataApproveMessageCols.Id
+}
+
+func (r *DataApproveMessage) CreateMulti(items []*DataApproveMessage) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := global.DmSQL["data"]
+	err = o.CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (m *DataApproveMessage) 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 *DataApproveMessage) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*DataApproveMessage, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	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 *DataApproveMessage) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*DataApproveMessage, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	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 *DataApproveMessage) GetItemById(id int) (item *DataApproveMessage, err error) {
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? `, m.TableName(), m.PrimaryId())
+	err = global.DmSQL["data"].Raw(sql, id).First(&item).Error
+	return
+}
+
+func (m *DataApproveMessage) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Model(m).Select(cols).Updates(m).Error
+	return
+}

+ 90 - 0
models/data_manage/data_approve/data_approve_node.go

@@ -0,0 +1,90 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type DataApproveNode struct {
+	DataApproveNodeId int       `gorm:"column:data_approve_node_id;primaryKey"`
+	DataApproveFlowId int       `gorm:"column:data_approve_flow_id"`
+	PrevNodeId        int       `gorm:"column:prev_node_id"`
+	NextNodeId        int       `gorm:"column:next_node_id"`
+	NodeType          int       `gorm:"column:node_type"`
+	ApproveType       int       `gorm:"column:approve_type"`
+	Users             string    `gorm:"column:users"`
+	CurrVersion       int       `gorm:"column:curr_version"`
+	CreatedTime       time.Time `gorm:"column:created_time"`
+}
+
+var DataApproveNodeCols = struct {
+	DataApproveNodeId string
+	DataApproveFlowId string
+	PrevNodeId        string
+	NextNodeId        string
+	NodeType          string
+	ApproveType       string
+	Users             string
+	CurrVersion       string
+	CreatedTime       string
+}{
+	DataApproveNodeId: "data_approve_node_id",
+	DataApproveFlowId: "data_approve_flow_id",
+	PrevNodeId:        "prev_node_id",
+	NextNodeId:        "next_node_id",
+	NodeType:          "node_type",
+	ApproveType:       "approve_type",
+	Users:             "users",
+	CurrVersion:       "curr_version",
+	CreatedTime:       "created_time",
+}
+
+func (b *DataApproveNode) TableName() string {
+	return "data_approve_node"
+}
+
+func (m *DataApproveNode) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*DataApproveNode, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY created_time DESC, data_approve_node_id ASC`
+	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 UpdateNextNodes(nodes []*DataApproveNode) (err error) {
+	if len(nodes) == 0 {
+		return
+	}
+	updateCols := []string{"NextNodeId"}
+	for _, v := range nodes {
+		e := global.DmSQL["data"].Select(updateCols).Updates(v).Error
+		if e != nil {
+			err = fmt.Errorf("prev node update err: %v", e)
+			return
+		}
+	}
+	return
+}
+
+func GetDataApproveNodeByCondition(condition string, pars []interface{}) (node []*DataApproveNode, err error) {
+	o := global.DmSQL["data"]
+	sql := "SELECT * FROM data_approve_node WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).Find(&node).Error
+	return
+}
+
+func GetDataApproveNodeByFlowIdAndVersionId(flowId int, versionId int) (node []*DataApproveNode, err error) {
+	err = global.DmSQL["data"].Model(&DataApproveNode{}).Where("data_approve_flow_id =? AND curr_version =?", flowId, versionId).Scan(&node).Error
+	return
+}

+ 152 - 0
models/data_manage/data_approve/data_approve_record.go

@@ -0,0 +1,152 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type DataApproveRecord struct {
+	DataApproveRecordId int       `gorm:"column:data_approve_record_id;primary_key"`
+	DataApproveId       int       `gorm:"column:data_approve_id"`
+	State               int       `gorm:"column:state"`
+	NodeId              int       `gorm:"column:node_id"`
+	NodeType            int       `gorm:"column:node_type"`
+	PrevNodeId          int       `gorm:"column:prev_node_id"`
+	NextNodeId          int       `gorm:"column:next_node_id"`
+	ApproveType         int       `gorm:"column:approve_type"`
+	ApproveUserId       int       `gorm:"column:approve_user_id"`
+	ApproveUserName     string    `gorm:"column:approve_user_name"`
+	ApproveUserSort     int       `gorm:"column:approve_user_sort"`
+	ApproveRemark       string    `gorm:"column:approve_remark"`
+	ApproveTime         time.Time `gorm:"column:approve_time"`
+	CreateTime          time.Time `gorm:"column:create_time"`
+	ModifyTime          time.Time `gorm:"column:modify_time"`
+	NodeState           int       `gorm:"column:node_state"`
+	NodeApproveUserId   int       `gorm:"column:node_approve_user_id"`
+	NodeApproveUserName string    `gorm:"column:node_approve_user_name"`
+	NodeApproveTime     time.Time `gorm:"column:node_approve_time"`
+}
+
+var DataApproveRecordCols = struct {
+	DataApproveRecordId string
+	DataApproveId       string
+	State               string
+	NodeId              string
+	NodeType            string
+	PrevNodeId          string
+	NextNodeId          string
+	ApproveType         string
+	ApproveUserId       string
+	ApproveUserName     string
+	ApproveUserSort     string
+	ApproveRemark       string
+	ApproveTime         string
+	CreateTime          string
+	ModifyTime          string
+	NodeState           string
+	NodeApproveUserId   string
+	NodeApproveUserName string
+	NodeApproveTime     string
+}{
+	DataApproveRecordId: "data_approve_record_id",
+	DataApproveId:       "data_approve_id",
+	State:               "state",
+	NodeId:              "node_id",
+	NodeType:            "node_type",
+	PrevNodeId:          "prev_node_id",
+	NextNodeId:          "next_node_id",
+	ApproveType:         "approve_type",
+	ApproveUserId:       "approve_user_id",
+	ApproveUserName:     "approve_user_name",
+	ApproveUserSort:     "approve_user_sort",
+	ApproveRemark:       "approve_remark",
+	ApproveTime:         "approve_time",
+	CreateTime:          "create_time",
+	ModifyTime:          "modify_time",
+	NodeState:           "node_state",
+	NodeApproveUserId:   "node_approve_user_id",
+	NodeApproveUserName: "node_approve_user_name",
+	NodeApproveTime:     "node_approve_time",
+}
+
+func (b *DataApproveRecord) TableName() string {
+	return "data_approve_record"
+}
+
+func (b *DataApproveRecord) Create() (err error) {
+	o := global.DmSQL["data"]
+	err = o.Create(b).Error
+	return
+}
+
+func (b *DataApproveRecord) CreateMulti(items []*DataApproveRecord) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := global.DmSQL["data"]
+	err = o.CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (b *DataApproveRecord) Update(cols []string) (err error) {
+	o := global.DmSQL["data"]
+	err = o.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func GetDataApproveRecordByCondition(condition string, pars []interface{}) (record *DataApproveRecord, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM data_approve_record WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).First(&record).Error
+	return
+}
+
+func GetDataApproveRecordItemsByCondition(condition string, pars []interface{}) (items []*DataApproveRecord, err error) {
+	order := `ORDER BY create_time DESC`
+	sql := fmt.Sprintf(`SELECT * FROM data_approve_record WHERE 1=1 %s %s`, condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (b *DataApproveRecord) UpdateNodeState(DataApproveId, nodeId, nodeState, nodeApproveUserId int, nodeApproveUserName string, nodeApproveTime time.Time) (err error) {
+	pars := make([]interface{}, 0)
+	pars = append(pars, nodeState, nodeApproveUserId, nodeApproveUserName, nodeApproveTime)
+
+	// 更新条件
+	whereParas := []interface{}{DataApproveId, nodeId}
+	pars = append(pars, whereParas...)
+
+	sql := fmt.Sprintf(`UPDATE %s SET node_state=?,node_approve_user_id=?,node_approve_user_name=?,node_approve_time=? WHERE data_approve_id = ? AND node_id = ?`, b.TableName())
+	err = global.DmSQL["data"].Exec(sql, pars...).Error
+	return
+}
+
+func (m *DataApproveRecord) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*DataApproveRecord, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	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 *DataApproveRecord) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *DataApproveRecord, 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
+}

+ 83 - 0
models/data_manage/data_approve/data_approve_relation.go

@@ -0,0 +1,83 @@
+package data_approve
+
+import (
+	sql2 "database/sql"
+	"eta_gn/eta_api/global"
+	"time"
+)
+
+type DataApproveRelation struct {
+	DataApproveRelationId int       `gorm:"column:data_approve_relation_id;primary_key"`
+	DataApproveId         int       `gorm:"column:data_approve_id"`
+	DataId                int       `gorm:"column:data_id"`
+	ClassifyId            int       `gorm:"column:classify_id"`
+	CreateTime            time.Time `gorm:"column:create_time"`
+}
+
+var DataApproveRelationCols = struct {
+	DataApproveRelationId string
+	DataApproveId         string
+	DataId                string // 资产类型:1:指标、2:图表
+	ClassifyId            string //
+	CreateTime            string
+}{
+	DataApproveRelationId: "data_approve_relation_id",
+	DataApproveId:         "data_approve_id",
+	DataId:                "data_id",
+	ClassifyId:            "classify_id",
+	CreateTime:            "create_time",
+}
+
+func (b *DataApproveRelation) TableName() string {
+	return "data_approve_relation"
+}
+
+func (b *DataApproveRelation) Update(cols []string) (err error) {
+	db := global.DmSQL["data"]
+	err = db.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func (b *DataApproveRelation) Create() (err error) {
+	db := global.DmSQL["data"]
+	err = db.Create(b).Error
+	return
+}
+
+// GetListByDataApproveId
+// @Description: 根据审批id获取关联的资产(指标、图表)
+// @author: Roc
+// @datetime 2024-12-05 17:23:39
+// @param dataApproveId int
+// @return dataIdList []int
+// @return err error
+func (b *DataApproveRelation) GetListByDataApproveId(dataApproveId int) (dataIdList []*DataApproveRelation, err error) {
+	sql := `SELECT * FROM data_approve_relation AS a WHERE data_approve_id = ? `
+	err = global.DmSQL["data"].Raw(sql, dataApproveId).Scan(&dataIdList).Error
+	return
+}
+
+// GetDataApproveIdByDataId
+// @Description: 根据审批类型和资产id获取最大的审批单
+// @author: Roc
+// @receiver b
+// @datetime 2024-12-26 15:56:03
+// @param dataId int
+// @param dataType int
+// @return dataApproveId int
+// @return err error
+func (b *DataApproveRelation) GetDataApproveIdByDataId(dataId, dataType int) (dataApproveId int, err error) {
+	sql := `SELECT max(a.data_approve_id) data_approve_id FROM data_approve_relation AS a 
+         JOIN data_approve ON a.data_approve_id = b.data_approve_id
+         WHERE a.data_id = ? AND b.data_type = ? `
+
+	var maxIdNull sql2.NullInt64
+	err = global.DmSQL["data"].Raw(sql, dataId, dataType).Scan(&maxIdNull).Error
+	if err != nil {
+		return
+	}
+
+	dataApproveId = int(maxIdNull.Int64)
+
+	return
+}

+ 21 - 0
models/data_manage/data_approve/request/approve.go

@@ -0,0 +1,21 @@
+package request
+
+type DataApprovePassReq struct {
+	DataApproveId int `description:"审批ID"`
+}
+
+// DataApproveRefuseReq 审批驳回请求体
+type DataApproveRefuseReq struct {
+	DataApproveId int    `description:"审批ID"`
+	ApproveRemark string `description:"驳回理由"`
+}
+
+// DataApproveCancelReq 撤销审批请求体
+type DataApproveCancelReq struct {
+	DataApproveId int `description:"审批ID"`
+}
+
+// DataApproveCheckApproveOpenReq 校验当前资产是否打开审批请求体
+type DataApproveCheckApproveOpenReq struct {
+	DataType int `description:"资产类型"`
+}

+ 23 - 0
models/data_manage/data_approve/request/approve_flow.go

@@ -0,0 +1,23 @@
+package request
+
+type DataApproveFlowSaveReq struct {
+	DataType                int
+	FlowName                string
+	Nodes                   []Node
+	IgnoreApproveUserIdList []int `description:"忽略审批人id"`
+}
+
+type Node struct {
+	ApproveType int `description:"审批类型: 1-依次审批, 2-会签, 3-或签"`
+	Users       []User
+}
+
+type User struct {
+	UserId   int    `description:"用户ID"`
+	UserName string `description:"用户名"`
+	UserType string `description:"用户类型: user-用户 role-角色"`
+}
+
+type DataApproveFlowRemoveResp struct {
+	DataApproveFlowId int
+}

+ 5 - 0
models/data_manage/data_approve/request/approve_message.go

@@ -0,0 +1,5 @@
+package request
+
+type DataApproveMessageReadReq struct {
+	MessageId int `description:"审批消息ID"`
+}

+ 90 - 0
models/data_manage/data_approve/response/approve.go

@@ -0,0 +1,90 @@
+package response
+
+// DataApproveDetail 审批详情信息
+type DataApproveDetail struct {
+	Approve          *DataApproveDetailItem    `description:"审批信息"`
+	ApproveFlowNodes []*DataApproveDetailNodes `description:"审批节点信息"`
+	DataList         []DataApproveDetailData   `description:"指标/图表列表"`
+}
+
+// DataApproveDetailData 审批详情-报告信息
+type DataApproveDetailData struct {
+	DataId           int    `description:"数据ID"`
+	DataName         string `description:"数据名称"`
+	DataCode         string `description:"数据code"`
+	DataClassifyId   int    `description:"数据所属分类id"`
+	DataClassifyName string `description:"数据所属分类名称"`
+}
+
+// DataApproveDetailItem 审批详情-审批信息
+type DataApproveDetailItem struct {
+	DataApproveId int    `description:"审批ID"`
+	State         int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	FlowId        int    `description:"审批流ID"`
+	FlowVersion   int    `description:"审批流版本"`
+	StartNodeId   int    `description:"开始节点ID"`
+	CurrNodeId    int    `description:"当前节点ID"`
+	ApplyUserId   int    `description:"申请人ID"`
+	ApplyUserName string `description:"申请人姓名"`
+	ApproveRemark string `description:"申请理由"`
+	ApproveTime   string `description:"审批时间"`
+	CreateTime    string `description:"创建时间"`
+	ModifyTime    string `description:"修改时间"`
+}
+
+// DataApproveDetailNodes 审批详情-节点信息
+type DataApproveDetailNodes struct {
+	DataApproveNodeId int                          `description:"看板审批节点ID"`
+	DataApproveFlowId int                          `description:"看板审批流ID"`
+	PrevNodeId        int                          `description:"上一个节点ID(0为开始节点)"`
+	NextNodeId        int                          `description:"下一个节点ID(0为结束节点)"`
+	NodeType          int                          `description:"节点类型:0-审批;1-抄送"`
+	ApproveType       int                          `description:"审批类型:1-依次审批;2-会签;3-或签"`
+	Users             []*DataApproveDetailNodeUser `description:"审批人信息"`
+}
+
+// DataApproveDetailNodeUser 审批详情-节点用户信息
+type DataApproveDetailNodeUser struct {
+	DataApproveNodeUserReq
+	ApproveRecord *DataApproveDetailNodeUserRecord `description:"用户审批记录"`
+}
+
+// DataApproveNodeUserReq 报告审批节点用户请求体
+type DataApproveNodeUserReq struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+
+// DataApproveDetailNodeUserRecord 审批详情-节点用户审批记录
+type DataApproveDetailNodeUserRecord struct {
+	DataApproveRecordId int    `description:"审批记录ID"`
+	State               int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	ApproveUserId       int    `description:"审批人ID"`
+	ApproveUserName     string `description:"审批人姓名"`
+	ApproveRemark       string `description:"审批备注"`
+	ApproveTime         string `description:"审批时间"`
+}
+
+type DataApproveItemOrmResp struct {
+	DataApproveId       int    `description:"审批ID"`
+	DataApproveRecordId int    `description:"审批记录ID"`
+	Title               string `description:"审批标题"`
+	DataType            int    `description:"自查类型"`
+	State               int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	RecordState         int    `description:"审批记录状态:1-待审批;2-已通过;3-已驳回"`
+	FlowId              int    `description:"审批流ID"`
+	FlowVersion         int    `description:"审批流版本"`
+	StartNodeId         int    `description:"开始节点ID"`
+	CurrNodeId          int    `description:"当前节点ID"`
+	ApplyUserId         int    `description:"申请人ID"`
+	ApplyUserName       string `description:"申请人姓名"`
+	ApproveRemark       string `description:"审批备注"`
+	ApproveTime         string `description:"审批时间"`
+	HandleTime          string `description:"处理时间"`
+	CreateTime          string `description:"创建时间"`
+	ModifyTime          string `description:"修改时间"`
+	NodeState           int    `description:"当前节点审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回" json:"-"`
+	NodeApproveTime     string `description:"当前节点审批时间" json:"-"`
+}

+ 47 - 0
models/data_manage/data_approve/response/approve_flow.go

@@ -0,0 +1,47 @@
+package response
+
+import (
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type DataApproveFlowItem struct {
+	DataApproveFlowId int    `description:"主键"`
+	FlowName          string `description:"bi审批流程名称"`
+	DataType          int    `description:"资产类型"`
+	ClassifyName      string `description:"分类名称"`
+	CurrVersion       int    `description:"当前版本"`
+	CreateTime        string `description:"创建时间"`
+	ModifyTime        string `description:"修改时间"`
+}
+
+type DataApproveFlowListResp struct {
+	List   []*DataApproveFlowItem
+	Paging *paging.PagingItem
+}
+
+type DataApproveFlowDetailResp struct {
+	DataApproveFlowItem     `description:"审批流信息"`
+	Nodes                   []*DataApproveNodeItem `description:"节点信息"`
+	IgnoreApproveUserIdList []int                  `description:"忽略审批人ID列表"`
+}
+
+type DataApproveNodeUser struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+type DataApproveNodeItem struct {
+	DataApproveNodeId int                    `description:"BI审批节点ID"`
+	DataApproveFlowId int                    `description:"BI审批流ID"`
+	PrevNodeId        int                    `description:"上一个节点ID(0为开始节点)"`
+	NextNodeId        int                    `description:"下一个节点ID(0为结束节点)"`
+	NodeType          int                    `description:"节点类型:0-审批;1-抄送"`
+	ApproveType       int                    `description:"审批类型:1-依次审批;2-会签;3-或签"`
+	Users             []*DataApproveNodeUser `description:"审批人信息"`
+}
+
+type DataApproveListResp struct {
+	List   []*DataApproveItemOrmResp
+	Paging *paging.PagingItem
+}

+ 25 - 0
models/data_manage/data_approve/response/approve_message.go

@@ -0,0 +1,25 @@
+package response
+
+import "github.com/rdlucklib/rdluck_tools/paging"
+
+// DataApproveMessageListResp 审批消息列表响应体
+type DataApproveMessageListResp struct {
+	List        []*DataApproveMessageItem
+	Paging      *paging.PagingItem `description:"分页数据"`
+	UnreadTotal int                `description:"消息未读数"`
+}
+
+// DataApproveMessageItem 报告审批消息信息
+type DataApproveMessageItem struct {
+	Id            int
+	SendUserId    int    `description:"发送人ID"`
+	ReceiveUserId int    `description:"接收者ID"`
+	DataType      int    `description:"资产类型"`
+	Content       string `description:"消息内容"`
+	Remark        string `description:"备注信息"`
+	DataApproveId int    `description:"审批ID"`
+	ApproveState  int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	IsRead        int    `description:"是否已读:0-未读;1-已读"`
+	CreateTime    string `description:"创建时间"`
+	ModifyTime    string `description:"修改时间"`
+}

+ 224 - 20
models/data_manage/edb_classify.go

@@ -25,14 +25,12 @@ type EdbClassify struct {
 	LastModifyUserRealName string    `description:"最后修改人姓名"`
 	IsJoinPermission       int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
 	ClassifyNameEn         string    `description:"英文分类名称"`
+	ClassifyNamePath       string    `description:"分类名称的完整路径,格式为:父级分类名称|当前分类名称"`
+	ClassifyIdPath         string    `description:"分类的完整路径,格式为:父级ID,当前ID"`
 }
 
-func AddEdbClassify(item *EdbClassify) (lastId int64, err error) {
+func AddEdbClassify(item *EdbClassify) (err error) {
 	err = global.DmSQL["data"].Create(item).Error
-	if err != nil {
-		return
-	}
-	lastId = int64(item.ClassifyId)
 
 	return
 }
@@ -49,13 +47,26 @@ type AddEdbClassifyReq struct {
 // @author: Roc
 // @datetime 2024-04-17 14:12:22
 // @param classifyName string
+// @param notClassifyId int 忽略的分类id
 // @param parentId int
 // @param classifyType uint8
 // @return count int
 // @return err error
-func GetEdbClassifyCount(classifyName string, parentId int, classifyType uint8) (count int, err error) {
+func GetEdbClassifyCount(classifyName string, notClassifyId, parentId, sysUserId int, classifyType uint8) (count int, err error) {
 	sql := `SELECT COUNT(1) AS count FROM edb_classify WHERE parent_id=? AND classify_name=? AND classify_type = ? `
-	err = global.DmSQL["data"].Raw(sql, parentId, classifyName, classifyType).Scan(&count).Error
+	pars := make([]interface{}, 0)
+	pars = append(pars, parentId, classifyName, classifyType)
+	if classifyType != utils.EdbClassifyTypeBase {
+		sql += " AND sys_user_id = ?"
+		pars = append(pars, sysUserId)
+	}
+
+	if notClassifyId > 0 {
+		sql += " AND classify_id != ?"
+		pars = append(pars, notClassifyId)
+	}
+
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
 
 	return
 }
@@ -69,9 +80,15 @@ func GetEdbClassifyCount(classifyName string, parentId int, classifyType uint8)
 // @param classifyType uint8
 // @return count int
 // @return err error
-func GetEdbClassifyEnCount(classifyNameEn string, parentId int, classifyType uint8) (count int, err error) {
+func GetEdbClassifyEnCount(classifyNameEn string, parentId, sysUserId int, classifyType uint8) (count int, err error) {
 	sql := `SELECT COUNT(1) AS count FROM edb_classify WHERE parent_id=? AND classify_name_en = ? AND classify_type = ? `
-	err = global.DmSQL["data"].Raw(sql, parentId, classifyNameEn, classifyType).Scan(&count).Error
+	pars := make([]interface{}, 0)
+	pars = append(pars, parentId, classifyNameEn, classifyType)
+	if classifyType != utils.EdbClassifyTypeBase {
+		sql += " AND sys_user_id = ?"
+		pars = append(pars, sysUserId)
+	}
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
 
 	return
 }
@@ -161,9 +178,14 @@ DELETE
 	return
 }
 
-func GetEdbClassifyByParentId(parentId int, classifyType int8) (items []*EdbClassifyItems, err error) {
+func GetEdbClassifyByParentId(parentId int, classifyType int8, sysUserId int) (items []*EdbClassifyItems, err error) {
 	o := global.DmSQL["data"]
-	sql := ` SELECT * FROM edb_classify WHERE parent_id=? AND classify_type = ?  order by sort asc,classify_id asc`
+	sql := ` SELECT * FROM edb_classify WHERE parent_id=? AND classify_type = ? `
+
+	if sysUserId > 0 {
+		sql += fmt.Sprintf(` AND sys_user_id = %d `, sysUserId)
+	}
+	sql += ` order by sort asc,classify_id asc `
 	err = o.Raw(sql, parentId, classifyType).Scan(&items).Error
 
 	return
@@ -193,7 +215,7 @@ func GetAllEdbClassify() (items []*EdbClassifyItems, err error) {
 }
 
 // GetPredictEdbClassifyAll 获取预测指标的分类列表
-func GetPredictEdbClassifyAll() (items []*EdbClassifyItems, err error) {
+func GetPredictEdbClassifyAll(sysUserId int) (items []*EdbClassifyItems, err error) {
 	o := global.DmSQL["data"]
 	sql := ` SELECT * FROM edb_classify WHERE classify_type = 1  order by sort asc,classify_id asc`
 	err = o.Raw(sql).Scan(&items).Error
@@ -202,17 +224,22 @@ func GetPredictEdbClassifyAll() (items []*EdbClassifyItems, err error) {
 }
 
 // GetAllEdbClassifyByType 根据类型获取分类列表
-func GetAllEdbClassifyByType(classifyType int) (items []*EdbClassifyItems, err error) {
+func GetAllEdbClassifyByType(classifyType, sysUserId int) (items []*EdbClassifyItems, err error) {
 	o := global.DmSQL["data"]
-	sql := ` SELECT * FROM edb_classify WHERE classify_type = ? order by sort ASC,classify_id ASC`
+	sql := ` SELECT * FROM edb_classify WHERE classify_type = ?`
+	if sysUserId > 0 {
+		sql += fmt.Sprintf(` AND sys_user_id = %d `, sysUserId)
+	}
+	sql += ` order by sort ASC,classify_id ASC `
 	err = o.Raw(sql, classifyType).Scan(&items).Error
 
 	return
 }
 
 type EdbClassifyItems struct {
-	ClassifyId       int `description:"分类id"`
-	EdbInfoId        int `description:"指标id"`
+	ClassifyId       int   `description:"分类id"`
+	EdbInfoId        int   `description:"指标id"`
+	ClassifyType     uint8 `description:"分类类型,0:普通指标分类,1:预测指标分类"`
 	ClassifyName     string
 	ClassifyNameEn   string
 	ParentId         int
@@ -231,6 +258,7 @@ type EdbClassifyItems struct {
 	Button           EdbClassifyItemsButton `gorm:"-" description:"操作权限"`
 	IsJoinPermission int                    `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
 	HaveOperaAuth    bool                   `description:"是否有数据权限"`
+	ClassifyIdPath   string                 `description:"分类的完整路径,格式为:父级ID,当前ID"`
 }
 
 type EdbClassifyIdItems struct {
@@ -291,6 +319,7 @@ type ExcelBaseInfo struct {
 	//SysUserId       int    `description:"操作人id"`
 	//SysUserRealName string `description:"操作人真实姓名"`
 }
+
 type ClassifyDeleteCheckReq struct {
 	ClassifyId int `description:"分类id"`
 	EdbInfoId  int `description:"指标id"`
@@ -398,6 +427,14 @@ func GetEdbInfoMaxSortByClassifyId(classifyId int) (sort int, err error) {
 	return
 }
 
+// GetEdbInfoMaxPublicSortByClassifyId 获取分类下公共指标的最大的排序数
+func GetEdbInfoMaxPublicSortByClassifyId(classifyId int) (sort int, err error) {
+	sql := `SELECT COALESCE(Max(public_sort), 0) AS sort FROM edb_info WHERE public_status = 3 AND edb_public_classify_id=? `
+	err = global.DmSQL["data"].Raw(sql, classifyId).Scan(&sort).Error
+
+	return
+}
+
 type ClassifyEdbInfoListResp struct {
 	EdbInfoList []*EdbClassifyItems
 }
@@ -520,9 +557,16 @@ func GetEdbClassifyRootIdsByClassifyIds(classifyIds []int) (items []int, err err
 }
 
 // GetChildEdbClassifyByClassifyType 根据类型获取非顶级分类
-func GetChildEdbClassifyByClassifyType(classifyType int) (items []*EdbClassifyItems, err error) {
+func GetChildEdbClassifyByClassifyType(classifyType, sysUserId 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`
+	sql := `SELECT * FROM edb_classify WHERE parent_id <> 0 AND classify_type = ?`
+
+	if sysUserId > 0 {
+		sql += fmt.Sprintf(` AND sys_user_id = %d `, sysUserId)
+	}
+
+	sql += ` ORDER BY sort ASC,classify_id ASC `
+
 	err = o.Raw(sql, classifyType).Find(&items).Error
 	return
 }
@@ -545,12 +589,172 @@ func GetIsJoinPermissionEdbClassifyIdList(classifyType int) (list []int, err err
 }
 
 // GetEdbClassifyByClassifyTypes 根据类型IDs获取分类
-func GetEdbClassifyByClassifyTypes(classifyTypes []int) (items []*EdbClassifyItems, err error) {
+func GetEdbClassifyByClassifyTypes(classifyTypes []int, sysUserId int) (items []*EdbClassifyItems, err error) {
 	if len(classifyTypes) == 0 {
 		return
 	}
 	o := global.DmSQL["data"]
-	sql := `SELECT * FROM edb_classify WHERE classify_type IN (?) ORDER BY classify_type ASC, sort ASC, classify_id ASC`
+	sql := `SELECT * FROM edb_classify WHERE classify_type IN (?) `
+
+	// 指定人
+	if sysUserId > 0 {
+		sql += ` AND sys_user_id = ? `
+	}
+	sql += ` ORDER BY classify_type ASC, sort ASC, classify_id ASC `
 	err = o.Raw(sql, classifyTypes).Scan(&items).Error
 	return
 }
+
+// UpdateEdbClassifyNameAndNamePath
+// @Description: 更新分类名称和子分类的全路径
+// @author: Roc
+// @receiver edbClassify
+// @datetime 2024-11-26 14:39:09
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func (edbClassify *EdbClassify) UpdateEdbClassifyNameAndNamePath(cols []string, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	tx := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	// 变更分类信息
+	err = tx.Select(cols).Updates(edbClassify).Error
+	if err != nil {
+		return
+	}
+
+	// 更改子分类的完整的路径
+	if oldClassifyNamePath != `` && newClassifyNamePath != `` {
+		sql := `UPDATE edb_classify SET classify_name_path = REPLACE(classify_name_path,?,?) WHERE classify_id_path LIKE ?`
+		err = tx.Exec(sql, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(edbClassify.ClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// UpdateEdbClassifyNameAndNamePathByOldClassifyIdPath
+// @Description: 根据源分类id全路径更新分类名称和子分类的全路径
+// @author: Roc
+// @receiver edbClassify
+// @datetime 2024-11-26 14:39:09
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func UpdateEdbClassifyNameAndNamePathByOldClassifyIdPath(oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	// 更改子分类的完整的路径
+	if oldClassifyIdPath != `` && newClassifyNamePath != `` && newClassifyIdPath != `` {
+		sql := `UPDATE edb_classify SET classify_id_path = REPLACE(classify_id_path,?,?) ,classify_name_path = REPLACE(classify_name_path,?,?)  WHERE classify_id_path LIKE ?`
+		err = global.DmSQL["data"].Exec(sql, oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(oldClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// UpdateEdbClassify 更新分类基础信息
+func UpdateEdbClassify(classifyId int, classifyNamePath, classifyIdPath string) (err error) {
+	sql := `UPDATE edb_classify SET classify_name_path = ?,classify_id_path = ? WHERE classify_id = ?`
+
+	err = global.DmSQL["data"].Exec(sql, classifyNamePath, classifyIdPath, classifyId).Error
+
+	return
+}
+
+// DelEdbClassifyByIdList
+// @Description: 根据id删除分类
+// @author: Roc
+// @datetime 2024-12-02 09:27:26
+// @param idList []int
+// @return err error
+func DelEdbClassifyByIdList(idList []int) (err error) {
+	num := len(idList)
+	if num <= 0 {
+		return
+	}
+	sql := `DELETE  FROM edb_classify  WHERE classify_id IN (?) `
+	err = global.DmSQL["data"].Exec(sql, idList).Error
+
+	return
+}
+
+func GetChildEdbClassifyListByParentId(classifyIdPath, orderStr string) (items []*EdbClassifyItems, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM edb_classify WHERE classify_id_path like ? `
+	if orderStr != "" {
+		sql += orderStr
+	} else {
+		sql += ` order by level desc, sort asc, classify_id asc`
+	}
+
+	err = o.Raw(sql, classifyIdPath).Scan(&items).Error
+
+	return
+}
+
+// GetEdbClassifyItemsByIdList
+// @Description: 根据分类id列表获取分类列表
+// @author: Roc
+// @datetime 2024-03-29 10:30:21
+// @param classifyId int
+// @return item *EdbClassify
+// @return err error
+func GetEdbClassifyItemsByIdList(classifyIdList []int) (item []*EdbClassifyItems, err error) {
+	num := len(classifyIdList)
+	if num <= 0 {
+		return
+	}
+	sql := `SELECT * FROM edb_classify WHERE classify_id in (` + utils.GetOrmInReplace(num) + `) `
+	err = global.DmSQL["data"].Raw(sql, classifyIdList).Scan(&item).Error
+
+	return
+}
+
+func (m *EdbClassifyItems) ToUserShareEdbClassifyItem() (item *UserShareEdbClassifyItem) {
+	return &UserShareEdbClassifyItem{
+		ClassifyId:       m.ClassifyId,
+		EdbInfoId:        m.EdbInfoId,
+		ParentId:         m.ClassifyId,
+		ClassifyType:     m.ClassifyType,
+		ClassifyName:     m.ClassifyName,
+		ClassifyNameEn:   m.ClassifyNameEn,
+		Sort:             m.Sort,
+		UniqueCode:       m.UniqueCode,
+		Source:           m.Source,
+		SourceName:       m.SourceName,
+		SysUserId:        m.SysUserId,
+		SysUserRealName:  m.SysUserRealName,
+		StartDate:        m.StartDate,
+		EdbCode:          m.EdbCode,
+		EdbType:          m.EdbType,
+		Children:         m.ToUserShareEdbClassifyItemByList(m.Children),
+		Button:           EdbClassifyItemsButton{},
+		IsJoinPermission: m.IsJoinPermission,
+		HaveOperaAuth:    m.HaveOperaAuth,
+		ClassifyIdPath:   "",
+	}
+}
+
+func (m *EdbClassifyItems) ToUserShareEdbClassifyItemByList(list []*EdbClassifyItems) (items []*UserShareEdbClassifyItem) {
+	items = make([]*UserShareEdbClassifyItem, 0)
+	if list == nil {
+		return
+	}
+
+	for _, v := range list {
+		items = append(items, v.ToUserShareEdbClassifyItem())
+	}
+	return
+}

+ 256 - 108
models/data_manage/edb_info.go

@@ -20,54 +20,57 @@ import (
 )
 
 type EdbInfo struct {
-	EdbInfoId        int       `gorm:"primaryKey" `
-	EdbInfoType      int       `description:"指标类型,0:普通指标,1:预测指标"`
-	SourceName       string    `description:"来源名称"`
-	Source           int       `description:"来源id"`
-	EdbCode          string    `description:"指标编码"`
-	EdbName          string    `description:"指标名称"`
-	EdbNameEn        string    `description:"英文指标名称"`
-	EdbNameSource    string    `description:"指标名称来源"`
-	Frequency        string    `description:"频率"`
-	Unit             string    `description:"单位"`
-	UnitEn           string    `description:"英文单位"`
-	StartDate        time.Time `description:"起始日期"`
-	EndDate          time.Time `description:"终止日期"`
-	ClassifyId       int       `description:"分类id"`
-	SysUserId        int
-	SysUserRealName  string
-	UniqueCode       string `description:"指标唯一编码"`
-	CreateTime       time.Time
-	ModifyTime       time.Time
-	BaseModifyTime   time.Time
-	MinValue         float64 `description:"指标最小值"`
-	MaxValue         float64 `description:"指标最大值"`
-	CalculateFormula string  `description:"计算公式"`
-	EdbType          int     `description:"指标类型:1:基础指标,2:计算指标"`
-	Sort             int     `description:"排序字段"`
-	LatestDate       string  `description:"数据最新日期(实际日期)"`
-	LatestValue      float64 `description:"数据最新值(实际值)"`
-	EndValue         float64 `description:"数据的最新值(预测日期的最新值)"`
-	MoveType         int     `description:"移动方式:1:领先(默认),2:滞后"`
-	MoveFrequency    string  `description:"移动频度"`
-	NoUpdate         int8    `description:"是否停止更新,0:继续更新;1:停止更新"`
-	ServerUrl        string  `description:"服务器地址"`
-	ChartImage       string  `description:"图表图片"`
-	Calendar         string  `description:"公历/农历" orm:"default(公历);"`
-	DataDateType     string  `orm:"column(data_date_type);size(255);null;default(交易日)"`
-	ManualSave       int     `description:"是否有手动保存过上下限: 0-否; 1-是"`
-	EmptyType        int     `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
-	MaxEmptyType     int     `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
-	TerminalCode     string  `description:"终端编码,用于配置在机器上"`
-	DataUpdateTime   string  `description:"最近一次数据发生变化的时间"`
-	ErDataUpdateDate string  `description:"本次更新,数据发生变化的最早日期"`
-	SourceIndexName  string  `description:"数据源中的指标名称"`
-	SubSource        int     `description:"子数据来源:0:经济数据库,1:日期序列"`
-	SubSourceName    string  `description:"子数据来源名称"`
-	IndicatorCode    string  `description:"指标代码"`
-	StockCode        string  `description:"证券代码"`
-	Extra            string  `description:"指标额外配置"`
-	IsJoinPermission int     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	EdbInfoId           int       `gorm:"primaryKey" `
+	EdbInfoType         int       `description:"指标类型,0:普通指标,1:预测指标"`
+	SourceName          string    `description:"来源名称"`
+	Source              int       `description:"来源id"`
+	EdbCode             string    `description:"指标编码"`
+	EdbName             string    `description:"指标名称"`
+	EdbNameEn           string    `description:"英文指标名称"`
+	EdbNameSource       string    `description:"指标名称来源"`
+	Frequency           string    `description:"频率"`
+	Unit                string    `description:"单位"`
+	UnitEn              string    `description:"英文单位"`
+	StartDate           time.Time `description:"起始日期"`
+	EndDate             time.Time `description:"终止日期"`
+	ClassifyId          int       `description:"分类id"`
+	SysUserId           int
+	SysUserRealName     string
+	UniqueCode          string `description:"指标唯一编码"`
+	CreateTime          time.Time
+	ModifyTime          time.Time
+	BaseModifyTime      time.Time
+	MinValue            float64 `description:"指标最小值"`
+	MaxValue            float64 `description:"指标最大值"`
+	CalculateFormula    string  `description:"计算公式"`
+	EdbType             int     `description:"指标类型:1:基础指标,2:计算指标"`
+	Sort                int     `description:"排序字段"`
+	LatestDate          string  `description:"数据最新日期(实际日期)"`
+	LatestValue         float64 `description:"数据最新值(实际值)"`
+	EndValue            float64 `description:"数据的最新值(预测日期的最新值)"`
+	MoveType            int     `description:"移动方式:1:领先(默认),2:滞后"`
+	MoveFrequency       string  `description:"移动频度"`
+	NoUpdate            int8    `description:"是否停止更新,0:继续更新;1:停止更新"`
+	ServerUrl           string  `description:"服务器地址"`
+	ChartImage          string  `description:"图表图片"`
+	Calendar            string  `description:"公历/农历" orm:"default(公历);"`
+	DataDateType        string  `orm:"column(data_date_type);size(255);null;default(交易日)"`
+	ManualSave          int     `description:"是否有手动保存过上下限: 0-否; 1-是"`
+	EmptyType           int     `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
+	MaxEmptyType        int     `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
+	TerminalCode        string  `description:"终端编码,用于配置在机器上"`
+	DataUpdateTime      string  `description:"最近一次数据发生变化的时间"`
+	ErDataUpdateDate    string  `description:"本次更新,数据发生变化的最早日期"`
+	SourceIndexName     string  `description:"数据源中的指标名称"`
+	SubSource           int     `description:"子数据来源:0:经济数据库,1:日期序列"`
+	SubSourceName       string  `description:"子数据来源名称"`
+	IndicatorCode       string  `description:"指标代码"`
+	StockCode           string  `description:"证券代码"`
+	Extra               string  `description:"指标额外配置"`
+	IsJoinPermission    int     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	PublicStatus        int     `description:"公开状态;0:未公开;1:审批中;2:已驳回;3:已公开"`
+	EdbPublicClassifyId int     `description:"指标公开分类id"`
+	PublicSort          int     `description:"公开分类下的排序字段"`
 }
 
 type EdbInfoFullClassify struct {
@@ -365,50 +368,58 @@ func ModifyEdbEnInfo(item *EditEdbEnInfoReq) (err error) {
 }
 
 type EdbInfoList struct {
-	EdbInfoId             int                     `orm:"column(edb_info_id);pk" gorm:"primaryKey" `
-	EdbInfoType           int                     `description:"指标类型,0:普通指标,1:预测指标"`
-	SourceName            string                  `description:"来源名称"`
-	Source                int                     `description:"来源id"`
-	EdbCode               string                  `description:"指标编码"`
-	EdbNameEn             string                  `description:"英文指标名称"`
-	EdbName               string                  `description:"指标名称"`
-	Frequency             string                  `description:"频率"`
-	FrequencyEn           string                  `description:"英文频率"`
-	Unit                  string                  `description:"单位"`
-	UnitEn                string                  `description:"英文单位"`
-	StartDate             string                  `description:"起始日期"`
-	EndDate               string                  `description:"终止日期"`
-	LatestDate            string                  `description:"数据最新日期(实际日期)"`
-	LatestValue           float64                 `description:"数据最新值(实际值)"`
-	EndValue              float64                 `description:"数据的最新值(预测日期的最新值)"`
-	ClassifyId            int                     `description:"分类id"`
-	UniqueCode            string                  `description:"指标唯一编码"`
-	SysUserId             int                     `description:"创建人id"`
-	SysUserRealName       string                  `description:"创建人姓名"`
-	ModifyTime            string                  `description:"最新修改时间"`
-	CreateTime            string                  `description:"创建时间"`
-	EdbNameAlias          string                  `json:"-" description:"指标名称,别名"`
-	EdbType               int                     `description:"指标类型:1:基础指标,2:计算指标"`
-	ChartImage            string                  `description:"图表图片"`
-	RuleType              int                     `description:"预测规则,1:最新,2:固定值"`
-	FixedValue            float64                 `description:"固定值"`
-	DataList              []*EdbData              `gorm:"-" description:"实际指标数据"`
-	PredictDataList       []*EdbData              `gorm:"-" description:"预测指标数据"`
-	Button                EdbClassifyItemsButton  `gorm:"-" description:"操作权限"`
-	IsEnEdb               bool                    `description:"是否展示英文标识"`
-	DataInsertConfig      EdbDataInsertConfigItem `gorm:"-" description:"指标数据插入配置"`
-	DataDateType          string                  `description:"数据日期类型,枚举值:交易日、自然日"`
-	EmptyType             int                     `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
-	MaxEmptyType          int                     `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
-	SubSource             int                     `description:"子数据来源:0:经济数据库,1:日期序列"`
-	SubSourceName         string                  `description:"子数据来源名称"`
-	IndicatorCode         string                  `description:"指标代码"`
-	StockCode             string                  `description:"证券代码"`
-	NoUpdate              int8                    `description:"是否停止更新,0:继续更新;1:停止更新"`
-	IsJoinPermission      int                     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
-	HaveOperaAuth         bool                    `description:"是否有数据权限,默认:false"`
-	IsSupplierStop        int                     `description:"是否供应商停更:1:停更,0:未停更"`
-	CollectClassifyIdList []int                   `description:"所属收藏分类id列表" gorm:"-"`
+	EdbInfoId               int                     `orm:"column(edb_info_id);pk" gorm:"primaryKey" `
+	EdbInfoType             int                     `description:"指标类型,0:普通指标,1:预测指标"`
+	SourceName              string                  `description:"来源名称"`
+	Source                  int                     `description:"来源id"`
+	EdbCode                 string                  `description:"指标编码"`
+	EdbNameEn               string                  `description:"英文指标名称"`
+	EdbName                 string                  `description:"指标名称"`
+	Frequency               string                  `description:"频率"`
+	FrequencyEn             string                  `description:"英文频率"`
+	Unit                    string                  `description:"单位"`
+	UnitEn                  string                  `description:"英文单位"`
+	StartDate               string                  `description:"起始日期"`
+	EndDate                 string                  `description:"终止日期"`
+	LatestDate              string                  `description:"数据最新日期(实际日期)"`
+	LatestValue             float64                 `description:"数据最新值(实际值)"`
+	EndValue                float64                 `description:"数据的最新值(预测日期的最新值)"`
+	ClassifyId              int                     `description:"分类id"`
+	UniqueCode              string                  `description:"指标唯一编码"`
+	SysUserId               int                     `description:"创建人id"`
+	SysUserRealName         string                  `description:"创建人姓名"`
+	ModifyTime              string                  `description:"最新修改时间"`
+	CreateTime              string                  `description:"创建时间"`
+	EdbNameAlias            string                  `json:"-" description:"指标名称,别名"`
+	EdbType                 int                     `description:"指标类型:1:基础指标,2:计算指标"`
+	ChartImage              string                  `description:"图表图片"`
+	RuleType                int                     `description:"预测规则,1:最新,2:固定值"`
+	FixedValue              float64                 `description:"固定值"`
+	DataList                []*EdbData              `gorm:"-" description:"实际指标数据"`
+	PredictDataList         []*EdbData              `gorm:"-" description:"预测指标数据"`
+	Button                  EdbClassifyItemsButton  `gorm:"-" description:"操作权限"`
+	IsEnEdb                 bool                    `description:"是否展示英文标识"`
+	DataInsertConfig        EdbDataInsertConfigItem `gorm:"-" description:"指标数据插入配置"`
+	DataDateType            string                  `description:"数据日期类型,枚举值:交易日、自然日"`
+	EmptyType               int                     `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
+	MaxEmptyType            int                     `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
+	SubSource               int                     `description:"子数据来源:0:经济数据库,1:日期序列"`
+	SubSourceName           string                  `description:"子数据来源名称"`
+	IndicatorCode           string                  `description:"指标代码"`
+	StockCode               string                  `description:"证券代码"`
+	NoUpdate                int8                    `description:"是否停止更新,0:继续更新;1:停止更新"`
+	IsJoinPermission        int                     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth           bool                    `description:"是否有数据权限,默认:false"`
+	IsSupplierStop          int                     `description:"是否供应商停更:1:停更,0:未停更"`
+	CollectClassifyIdList   []int                   `description:"所属收藏分类id列表" gorm:"-"`
+	CollectClassifyNameList []string                `description:"所属收藏分类名称列表" gorm:"-"`
+	SharedUserIdList        []int                   `description:"共享用户id列表" gorm:"-"`
+	SharedUserName          string                  `description:"共享用户姓名,多个用英文,隔开" gorm:"-"`
+	PublicStatus            int                     `description:"公开状态;0:未公开;1:审批中;2:已驳回;3:已公开"`
+	EdbPublicClassifyId     int                     `description:"指标公开分类id"`
+	PublicTime              time.Time               `description:"设置公开的时间"`
+	ClassifyNamePath        string                  `description:"分类完整路径"`
+	PublicClassifyNamePath  string                  `description:"公共分类完整路径"`
 }
 
 type EdbDataInsertConfigItem struct {
@@ -495,6 +506,17 @@ func GetEdbInfoByCondition(condition string, pars []interface{}) (item *EdbInfoL
 	return
 }
 
+func GetEdbInfoEsByCondition(condition string, pars []interface{}) (item *EdbInfoEs, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM edb_info WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).First(&item).Error
+
+	return
+}
+
 func GetEdbDataCountByCondition(condition string, pars []interface{}, source, subSource int) (count int, err error) {
 	o := global.DmSQL["data"]
 	tableName := GetEdbDataTableName(source, subSource)
@@ -826,6 +848,18 @@ func GetFirstEdbInfoByClassifyId(classifyId int) (item *EdbInfo, err error) {
 	return
 }
 
+// GetFirstEdbInfoByPublicClassifyId
+// @Description: 获取当前公共分类下,且排序数相同 的排序第一条的数据
+// @param classifyId
+// @return item
+// @return err
+func GetFirstEdbInfoByPublicClassifyId(classifyId int) (item *EdbInfo, err error) {
+	sql := ` SELECT * FROM edb_info WHERE edb_public_classify_id=? AND public_status = 3 order by public_sort asc,edb_info_id asc limit 1`
+	err = global.DmSQL["data"].Raw(sql, classifyId).First(&item).Error
+
+	return
+}
+
 // UpdateEdbInfoSortByClassifyId 根据分类id更新排序
 func UpdateEdbInfoSortByClassifyId(classifyId, nowSort int, prevEdbInfoId int, updateSort string) (err error) {
 	sql := ` update edb_info set sort = ` + updateSort + ` WHERE classify_id=?`
@@ -839,6 +873,19 @@ func UpdateEdbInfoSortByClassifyId(classifyId, nowSort int, prevEdbInfoId int, u
 	return
 }
 
+// UpdateEdbInfoPublicSortByClassifyId 根据公共分类id更新公共排序
+func UpdateEdbInfoPublicSortByClassifyId(classifyId, nowSort int, prevEdbInfoId int, updateSort string) (err error) {
+	sql := ` update edb_info set sort = ` + updateSort + ` WHERE edb_public_classify_id=? AND public_status = 3 `
+	if prevEdbInfoId > 0 {
+		sql += ` AND ( public_sort > ? or ( edb_info_id > ` + fmt.Sprint(prevEdbInfoId) + ` and public_sort=` + fmt.Sprint(nowSort) + ` )) `
+	} else {
+		sql += ` AND ( public_sort > ? )`
+	}
+	err = global.DmSQL["data"].Exec(sql, classifyId, nowSort).Error
+
+	return
+}
+
 // Update 更新指标基础信息
 func (edbInfo *EdbInfo) Update(cols []string) (err error) {
 	err = global.DmSQL["data"].Select(cols).Updates(edbInfo).Error
@@ -869,7 +916,7 @@ type EdbInfoReplaceReq struct {
 }
 
 // ReplaceChartEdb 替换图表中的指标
-func ReplaceChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (relationEdbInfoIdList []int, replaceChartTotal, replaceCalculateTotal int, err error) {
+func ReplaceChartEdb(oldEdbInfo, newEdbInfo *EdbInfo, userId int) (relationEdbInfoIdList []int, replaceChartTotal, replaceCalculateTotal int, err error) {
 	var errmsg string
 	relationEdbInfoIdList = make([]int, 0) // 关联的指标id
 	logMsg := ``                           // 记录替换的日志
@@ -892,11 +939,13 @@ func ReplaceChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (relationEdbInfoIdList []i
 			//go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"替换指标失败提醒", "errmsg:"+errmsg, utils.EmailSendToUsers)
 		}
 	}()
-	//替换图表
+	//替换自己创建的图表
 	{
 		chartEdbMappingList := make([]*ChartEdbInfoMapping, 0)
-		csql := `SELECT * FROM chart_edb_mapping WHERE edb_info_id=?`
-		err = to.Raw(csql, oldEdbInfo.EdbInfoId).Scan(&chartEdbMappingList).Error
+		csql := `SELECT a.* FROM chart_edb_mapping AS a 
+         JOIN chart_info AS b on a.chart_info_id=b.chart_info_id
+         WHERE b.sys_user_id = ? AND  a.edb_info_id=? `
+		err = to.Raw(csql, userId, oldEdbInfo.EdbInfoId).Scan(&chartEdbMappingList).Error
 		if err != nil {
 			errmsg = "获取指标关联图表信息失败:Err:" + err.Error()
 			return
@@ -1099,7 +1148,8 @@ func ReplaceChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (relationEdbInfoIdList []i
 				}
 			}
 		}
-		// 查询所有的图表信息
+
+		// 查询我的所有图表信息
 		if len(chartEdbMappingList) > 0 {
 			chartInfoIdList := make([]string, 0)
 			for _, mv := range chartEdbMappingList {
@@ -1153,8 +1203,10 @@ func ReplaceChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (relationEdbInfoIdList []i
 		//获取所有包含的计算指标
 		mappingList := make([]*EdbInfoCalculateMapping, 0)
 		queryList := make([]*EdbInfoCalculateMapping, 0)
-		msql := ` SELECT * FROM edb_info_calculate_mapping WHERE from_edb_info_id = ?`
-		err = to.Raw(msql, oldEdbInfo.EdbInfoId).Find(&queryList).Error
+		msql := ` SELECT a.* FROM edb_info_calculate_mapping AS a 
+          JOIN edb_info AS b ON a.edb_info_id=b.edb_info_id
+          WHERE b.sys_user_id = ? AND a.from_edb_info_id = ?`
+		err = to.Raw(msql, userId, oldEdbInfo.EdbInfoId).Find(&queryList).Error
 		if err != nil {
 			errmsg = "获取计算指标关联基础指标信息失败:Err:" + err.Error()
 			return
@@ -1195,7 +1247,9 @@ func ReplaceChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (relationEdbInfoIdList []i
 		//获取所有包含的计算指标
 		predictEdbConfList := make([]*PredictEdbConf, 0)
 		queryList := make([]*PredictEdbConf, 0)
-		msql := ` SELECT * FROM predict_edb_conf WHERE source_edb_info_id = ?`
+		msql := ` SELECT a.* FROM predict_edb_conf AS a
+          JOIN edb_info AS b on a.predict_edb_info_id = b.edb_info_id
+          WHERE source_edb_info_id = ?`
 		err = to.Raw(msql, oldEdbInfo.EdbInfoId).Scan(&predictEdbConfList).Error
 		if err != nil {
 			errmsg = "获取关联的预测指标信息失败:Err:" + err.Error()
@@ -1208,15 +1262,15 @@ func ReplaceChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (relationEdbInfoIdList []i
 			}
 			exists[v.PredictEdbInfoId] = true
 			predictEdbConfList = append(predictEdbConfList, v)
-		}
-		replaceCalculateTotal += len(predictEdbConfList)
 
-		//替换预测指标的来源指标
-		msql = `UPDATE predict_edb_conf SET source_edb_info_id=? WHERE source_edb_info_id=? `
-		err = to.Exec(msql, newEdbInfo.EdbInfoId, oldEdbInfo.EdbInfoId).Error
-		if err != nil {
-			return
+			//替换预测指标的来源指标
+			msql = `UPDATE predict_edb_conf SET source_edb_info_id=? WHERE config_id=? `
+			err = to.Exec(msql, newEdbInfo.EdbInfoId, v.ConfigId).Error
+			if err != nil {
+				return
+			}
 		}
+		replaceCalculateTotal += len(predictEdbConfList)
 
 		if len(predictEdbConfList) > 0 {
 			edbInfoIdList := make([]string, 0)
@@ -1287,6 +1341,69 @@ func GetEdbInfoFilterList(condition string, pars []interface{}, startSize, pageS
 	return
 }
 
+// EdbInfoEs 写入es的指标数据结构
+type EdbInfoEs struct {
+	EdbInfoId             int        `orm:"column(edb_info_id);pk" gorm:"primaryKey" `
+	EdbInfoType           int        `description:"指标类型,0:普通指标,1:预测指标"`
+	SourceName            string     `description:"来源名称"`
+	Source                int        `description:"来源id"`
+	EdbCode               string     `description:"指标编码"`
+	EdbNameEn             string     `description:"英文指标名称"`
+	EdbName               string     `description:"指标名称"`
+	Frequency             string     `description:"频率"`
+	FrequencyEn           string     `description:"英文频率"`
+	Unit                  string     `description:"单位"`
+	UnitEn                string     `description:"英文单位"`
+	StartDate             string     `description:"起始日期"`
+	EndDate               string     `description:"终止日期"`
+	LatestDate            string     `description:"数据最新日期(实际日期)"`
+	LatestValue           float64    `description:"数据最新值(实际值)"`
+	EndValue              float64    `description:"数据的最新值(预测日期的最新值)"`
+	ClassifyId            int        `description:"分类id"`
+	UniqueCode            string     `description:"指标唯一编码"`
+	SysUserId             int        `description:"创建人id"`
+	SysUserRealName       string     `description:"创建人姓名"`
+	ModifyTime            string     `description:"最新修改时间"`
+	CreateTime            string     `description:"创建时间"`
+	EdbNameAlias          string     `json:"-" description:"指标名称,别名"`
+	EdbType               int        `description:"指标类型:1:基础指标,2:计算指标"`
+	ChartImage            string     `description:"图表图片"`
+	RuleType              int        `description:"预测规则,1:最新,2:固定值"`
+	FixedValue            float64    `description:"固定值"`
+	IsEnEdb               bool       `description:"是否展示英文标识"`
+	DataDateType          string     `description:"数据日期类型,枚举值:交易日、自然日"`
+	SubSource             int        `description:"子数据来源:0:经济数据库,1:日期序列"`
+	SubSourceName         string     `description:"子数据来源名称"`
+	IndicatorCode         string     `description:"指标代码"`
+	StockCode             string     `description:"证券代码"`
+	NoUpdate              int8       `description:"是否停止更新,0:继续更新;1:停止更新"`
+	IsJoinPermission      int        `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth         bool       `description:"是否有数据权限,默认:false"`
+	IsSupplierStop        int        `description:"是否供应商停更:1:停更,0:未停更"`
+	CollectClassifyIdList []int      `description:"所属收藏分类id列表" gorm:"-"`
+	SharedUserIdList      []int      `description:"共享用户id列表" gorm:"-"`
+	PublicStatus          int        `description:"公开状态;0:未公开;1:审批中;2:已驳回;3:已公开"`
+	EdbPublicClassifyId   int        `description:"指标公开分类id"`
+	PublicTime            *time.Time `description:"设置公开的时间"`
+}
+
+// GetEsEdbInfo 获取指指标列表数据接口
+func GetEsEdbInfo(condition string, pars []interface{}, startSize, pageSize int) (total int64, list []*EdbInfoEs, err error) {
+	o := global.DmSQL["data"]
+
+	sql := ` SELECT count(1) total FROM edb_info where 1=1 ` + condition + ` ORDER BY edb_info_id DESC `
+	err = o.Raw(sql, pars...).Scan(&total).Error
+	if err != nil {
+		return
+	}
+
+	sql = ` SELECT * FROM edb_info where 1=1 ` + condition + ` ORDER BY edb_info_id DESC  LIMIT ?,? `
+	pars = append(pars, startSize, pageSize)
+	err = o.Raw(sql, pars...).Scan(&list).Error
+
+	return
+}
+
 // SetEdbInfoImageReq 设置指标图片
 type SetEdbInfoImageReq struct {
 	EdbInfoId int    `description:"指标ID"`
@@ -1373,7 +1490,7 @@ func GetEdbInfoListByCondition(condition string, pars []interface{}, startSize,
 // @param edbIdList
 // @return items
 // @return err
-func GetEdbInfoListByEdbInfoId(edbIdList []string) (items []*EdbInfo, err error) {
+func GetEdbInfoListByEdbInfoId(edbIdList []int) (items []*EdbInfo, err error) {
 	num := len(edbIdList)
 	if num <= 0 {
 		return
@@ -1892,6 +2009,7 @@ func GetEdbInfoByClassifyIdAndSource(classifyId, edbInfoType, source int) (items
 type ReplaceEdbInfoItem struct {
 	OldEdbInfo *EdbInfo
 	NewEdbInfo *EdbInfo
+	UserId     int
 }
 
 type EdbInfoEditRecord struct {
@@ -2050,3 +2168,33 @@ func GetIsJoinPermissionEdbInfoIdList(edbInfoType, edbType int) (list []int, err
 
 	return
 }
+
+// UpdateClassifyIdByEdbInfoId
+// @Description: 根据指标id更新所属分类id
+// @author: Roc
+// @datetime 2024-11-29 17:54:44
+// @param edbInfoId int
+// @param edbClassifyId int
+// @return err error
+func UpdateClassifyIdByEdbInfoId(edbInfoId, edbClassifyId int) (err error) {
+	sql := ` UPDATE edb_info SET classify_id = ? WHERE  edb_info_id=? `
+	err = global.DmSQL["data"].Exec(sql, edbClassifyId, edbInfoId).Error
+	return
+}
+
+// UpdateClassifyIdByEdbInfoIdList
+// @Description: 根据指标id列表更新所属分类id
+// @author: Roc
+// @datetime 2024-12-10 13:18:52
+// @param edbInfoId int
+// @param edbClassifyId int
+// @return err error
+func UpdateClassifyIdByEdbInfoIdList(edbInfoIdList []int, edbClassifyId int) (err error) {
+	if len(edbInfoIdList) <= 0 {
+		return
+	}
+	sql := ` UPDATE edb_info SET classify_id = ? WHERE  edb_info_id in (?) `
+	err = global.DmSQL["data"].Exec(sql, edbClassifyId, edbInfoIdList).Error
+
+	return
+}

+ 48 - 0
models/data_manage/edb_info_calculate_mapping.go

@@ -1,6 +1,7 @@
 package data_manage
 
 import (
+	sql2 "database/sql"
 	"eta_gn/eta_api/global"
 	"eta_gn/eta_api/utils"
 	"time"
@@ -110,3 +111,50 @@ func GetEdbInfoCalculateMappingListByEdbInfoIds(edbInfoIds []int) (items []*EdbI
 
 	return
 }
+
+// GetCountRelationEdbInfoListMappingByCondition
+// @Description: 根据条件获取关联指标数量
+// @author: Roc
+// @datetime 2024-12-26 10:37:48
+// @param condition string
+// @param pars []interface{}
+// @return total int
+// @return err error
+func GetCountRelationEdbInfoListMappingByCondition(condition string, pars []interface{}) (total int, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT COUNT(1) total FROM edb_info_calculate_mapping AS a 
+	JOIN edb_info AS b on a.edb_info_id = b.edb_info_id WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	var totalNull sql2.NullInt64
+	err = o.Raw(sql, pars...).Scan(&totalNull).Error
+	if err != nil {
+		return
+	}
+	total = int(totalNull.Int64)
+
+	return
+}
+
+// GetCountRelationEdbInfoListMappingByCondition
+// @Description: 根据条件获取关联指标的用户id列表
+// @author: Roc
+// @datetime 2024-12-26 10:37:48
+// @param condition string
+// @param pars []interface{}
+// @return total int
+// @return err error
+func GetUserIdListRelationEdbInfoListMappingByCondition(condition string, pars []interface{}) (userIdList []int, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT b.sys_user_id FROM edb_info_calculate_mapping AS a 
+	JOIN edb_info AS b on a.edb_info_id = b.edb_info_id WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY b.sys_user_id `
+
+	err = o.Raw(sql, pars...).Scan(&userIdList).Error
+
+	return
+}

+ 311 - 0
models/data_manage/edb_info_share.go

@@ -0,0 +1,311 @@
+package data_manage
+
+import (
+	sql2 "database/sql"
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+// EdbInfoShare
+// @Description: 指标分享表
+type EdbInfoShare struct {
+	EdbInfoShareId int       `gorm:"primaryKey" `
+	EdbInfoId      int       `description:"指标id"`
+	SysUserId      int       `description:"sys_user_id"`
+	ShareType      int8      `description:"分享类型,1:仅查看;2:可编辑"`
+	CreateTime     time.Time `description:"创建时间"`
+}
+
+// TableName
+// @Description: 表名
+// @author: Roc
+// @receiver m
+// @datetime 2024-11-27 14:04:14
+// @return string
+func (m EdbInfoShare) TableName() string {
+	return `edb_info_share`
+}
+
+// GetListByEdbInfoId
+// @Description: 根据指标id获取分享用户列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-11-27 15:39:17
+// @param edbInfoId int
+// @return items []*EdbInfoShare
+// @return err error
+func (m EdbInfoShare) GetListByEdbInfoId(edbInfoId int) (items []*EdbInfoShare, err error) {
+	sql := ` SELECT * FROM edb_info_share WHERE edb_info_id = ? ORDER BY edb_info_share_id ASC `
+	err = global.DmSQL["data"].Raw(sql, edbInfoId).Find(&items).Error
+
+	return
+}
+
+// SaveEdbInfoShare
+// @Description: 保存配置
+// @author: Roc
+// @receiver m
+// @datetime 2024-11-27 15:54:07
+// @param edbInfoIdList []int
+// @param userIdList []int
+// @param shareType int8
+// @return err error
+func (m EdbInfoShare) SaveEdbInfoShare(edbInfoIdList, userIdList []int, shareType int8) (err error) {
+	// TODO 保存之前,得先做关联校验
+	addList := make([]*EdbInfoShare, 0)
+	for _, edbInfoId := range edbInfoIdList {
+		for _, userId := range userIdList {
+			addList = append(addList, &EdbInfoShare{
+				EdbInfoShareId: 0,
+				EdbInfoId:      edbInfoId,
+				SysUserId:      userId,
+				ShareType:      shareType,
+				CreateTime:     time.Now(),
+			})
+		}
+	}
+
+	tx := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	// 先删除原来的配置,新增最新的配置
+	sql := fmt.Sprintf("DELETE FROM %s WHERE edb_info_id IN (?) AND share_type = ? ", m.TableName())
+	err = tx.Exec(sql, edbInfoIdList, shareType).Error
+	if err != nil {
+		return
+	}
+
+	// 批量添加新的配置
+	if len(addList) > 0 {
+		err = tx.CreateInBatches(addList, utils.MultiAddNum).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// ShareEdbInfoQuery
+// @Description: 共享指标
+type ShareEdbInfoQuery struct {
+	EdbInfo
+	ShareType string    `gorm:"column:share_type" description:"共享类型"`
+	ShareTime time.Time `gorm:"column:share_time" description:"设置共享时间"`
+}
+
+// GetAllSharedEdbInfoListByFromUserId
+// @Description: 获取所有我共享出去的指标列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 09:56:41
+// @param sysUserId int
+// @return list []*ShareEdbInfoQuery
+// @return err error
+func (m EdbInfoShare) GetAllSharedEdbInfoListByFromUserId(sysUserId int) (list []*ShareEdbInfoQuery, err error) {
+	sql := `SELECT b."edb_info_id",
+       MAX(a.share_type) AS share_type,
+MAX(a.create_time) as share_time,
+MAX(b."edb_code") AS "edb_code",
+MAX(b."edb_name") "edb_name",
+MAX(b."edb_info_type") "edb_info_type",
+MAX(b."edb_type") "edb_type",
+MAX(b."source") "source",
+MAX(b."source_name") "source_name",
+MAX(b."frequency") "frequency",
+MAX(b."unit") "unit",
+MAX(b."classify_id") "classify_id",
+MAX(b."create_time") "create_time",
+MAX(b."unique_code") "unique_code",
+MAX(b."chart_image") "chart_image",
+MAX(b."modify_time") "modify_time",
+MAX(b."start_date") "start_date",
+MAX(b."sort") AS "sort"
+ FROM edb_info_share AS a 
+     JOIN edb_info AS b ON a.edb_info_id = b.edb_info_id
+	  WHERE 1=1 AND b.sys_user_id = ?
+	  GROUP BY b.edb_info_id
+ORDER BY share_time DESC`
+	err = global.DmSQL["data"].Raw(sql, sysUserId).Scan(&list).Error
+	return
+}
+
+// GetAllSharedEdbInfoListByReceivedUserId
+// @Description: 获取所有我收到的共享的指标列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 09:56:41
+// @param sysUserId int
+// @return list []*ShareEdbInfoQuery
+// @return err error
+func (m EdbInfoShare) GetAllSharedEdbInfoListByReceivedUserId(sysUserId int) (list []*ShareEdbInfoQuery, err error) {
+	sql := `SELECT b."edb_info_id",
+       MAX(a.share_type) AS share_type,
+MAX(a.create_time) as share_time,
+MAX(b."edb_code") AS "edb_code",
+MAX(b."edb_name") "edb_name",
+MAX(b."edb_info_type") "edb_info_type",
+MAX(b."edb_type") "edb_type",
+MAX(b."source") "source",
+MAX(b."source_name") "source_name",
+MAX(b."latest_date") "latest_date",
+MAX(b."latest_value") "latest_value",
+MAX(b."sys_user_id") "sys_user_id",
+MAX(b."sys_user_real_name") "sys_user_real_name",
+MAX(b."frequency") "frequency",
+MAX(b."unit") "unit",
+MAX(b."classify_id") "classify_id",
+MAX(b."create_time") "create_time",
+MAX(b."unique_code") "unique_code",
+MAX(b."chart_image") "chart_image",
+MAX(b."modify_time") "modify_time",
+MAX(b."start_date") "start_date",
+MAX(b."sort") AS "sort"
+ FROM edb_info_share AS a 
+     JOIN edb_info AS b ON a.edb_info_id = b.edb_info_id
+	  WHERE 1=1 AND a.sys_user_id = ? AND b.sys_user_id != ?
+	  GROUP BY b.edb_info_id
+ORDER BY share_time DESC`
+	err = global.DmSQL["data"].Raw(sql, sysUserId, sysUserId).Scan(&list).Error
+	return
+}
+
+// GetAllEditSharedEdbInfoIdListByReceivedUserId
+// @Description: 获取所有我收到的共享的、可以编辑的指标id列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 09:56:41
+// @param sysUserId int
+// @return list []*ShareEdbInfoQuery
+// @return err error
+func (m EdbInfoShare) GetAllEditSharedEdbInfoIdListByReceivedUserId(sysUserId int, edbInfoIdList []int) (list []int, err error) {
+	sql := `SELECT a."edb_info_id" FROM edb_info_share AS a 
+            WHERE 1=1 AND a.sys_user_id = ? AND share_type = ? `
+	pars := []interface{}{sysUserId, utils.ShareTypeEdit}
+
+	if len(edbInfoIdList) > 0 {
+		sql += ` AND a.edb_info_id in (?) `
+		pars = append(pars, edbInfoIdList)
+	}
+	sql += ` GROUP BY a.edb_info_id `
+
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error
+	return
+}
+
+// GetShareEdbInfoListPageList
+// @Description: 获取分享的指标列表(分页)
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 14:42:12
+// @param condition string
+// @param pars []interface{}
+// @param startSize int
+// @param pageSize int
+// @return total int32
+// @return list []*EdbInfoList
+// @return err error
+func (m EdbInfoShare) GetShareEdbInfoListPageList(condition string, pars []interface{}, startSize, pageSize int) (total int32, list []*EdbInfoList, err error) {
+	baseSql := `SELECT b."edb_info_id",
+       MAX(a.share_type) AS share_type,
+MAX(a.create_time) as share_time,
+MAX(b."edb_code") AS "edb_code",
+MAX(b."edb_name") "edb_name",
+MAX(b."edb_info_type") "edb_info_type",
+MAX(b."edb_type") "edb_type",
+MAX(b."source") "source",
+MAX(b."source_name") "source_name",
+MAX(b."end_date") "end_date",
+MAX(b."end_value") "end_value",
+MAX(b."latest_date") "latest_date",
+MAX(b."latest_value") "latest_value",
+MAX(b."sys_user_id") "sys_user_id",
+MAX(b."sys_user_real_name") "sys_user_real_name",
+MAX(b."frequency") "frequency",
+MAX(b."unit") "unit",
+MAX(b."classify_id") "classify_id",
+MAX(b."create_time") "create_time",
+MAX(b."unique_code") "unique_code",
+MAX(b."chart_image") "chart_image",
+MAX(b."modify_time") "modify_time",
+MAX(b."start_date") "start_date",
+MAX(b."sort") AS "sort"
+  FROM edb_info_share AS a 
+     JOIN edb_info AS b ON a.edb_info_id = b.edb_info_id
+	  WHERE 1=1 `
+
+	baseSql += condition
+	baseSql += ` GROUP BY b.edb_info_id `
+
+	totalSql := `SELECT COUNT(1) AS total FROM (` + baseSql + `) AS d`
+	var totalNull sql2.NullInt32
+	err = global.DmSQL["data"].Raw(totalSql, pars...).Scan(&totalNull).Error
+	if err != nil {
+		return
+	}
+	total = totalNull.Int32
+
+	sql := baseSql + ` ORDER BY share_time DESC LIMIT ?,? `
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error
+
+	if err != nil {
+		return
+	}
+	for _, v := range list {
+		v.ConvertToResp()
+	}
+
+	return
+}
+
+// UserShareEdbClassifyItem
+// @Description: 用户分享的指标分类列表
+type UserShareEdbClassifyItem struct {
+	UserId           int    `description:"用户id"`
+	UserName         string `description:"用户名称"`
+	ClassifyId       int    `description:"分类id"`
+	EdbInfoId        int    `description:"指标id"`
+	ClassifyType     uint8  `description:"分类类型,0:普通指标分类,1:预测指标分类"`
+	ClassifyName     string
+	ClassifyNameEn   string
+	ParentId         int
+	RootId           int    `description:"顶级id"`
+	Level            int    `description:"层级"`
+	Sort             int    `description:"排序字段,越小越靠前,默认值:10"`
+	UniqueCode       string `description:"唯一编码"`
+	Source           int    `description:"来源id"`
+	SourceName       string `description:"来源名称"`
+	SysUserId        int    `description:"创建人id"`
+	SysUserRealName  string `description:"创建人姓名"`
+	StartDate        string
+	EdbCode          string
+	EdbType          int                         `description:"指标类型:1:基础指标,2:计算指标"`
+	Children         []*UserShareEdbClassifyItem `gorm:"-"`
+	Button           EdbClassifyItemsButton      `gorm:"-" description:"操作权限"`
+	IsJoinPermission int                         `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth    bool                        `description:"是否有数据权限"`
+	ClassifyIdPath   string                      `description:"分类的完整路径,格式为:父级ID,当前ID"`
+}
+
+type UserShareEdbClassifyItemList []*UserShareEdbClassifyItem
+
+func (m UserShareEdbClassifyItemList) Len() int {
+	return len(m)
+}
+
+func (m UserShareEdbClassifyItemList) Less(i, j int) bool {
+	return m[i].Sort < m[j].Sort
+}
+
+func (m UserShareEdbClassifyItemList) Swap(i, j int) {
+	m[i], m[j] = m[j], m[i]
+}

+ 1 - 0
models/data_manage/edb_source.go

@@ -25,6 +25,7 @@ type EdbSource struct {
 	SourceExtend     string `description:"扩展字段做查询用"`
 	EdbCodeRequired  int    `description:"指标编码是否必填: 0-否; 1-是"`
 	IndexTableName   string `description:"数据源指标表名"`
+	EdbInfoTType     int    `description:"指标类型,0:指标库;1:预测指标"`
 }
 
 // GetEdbSourceItemsByCondition 获取指标来源列表

+ 58 - 0
models/data_manage/excel/excel_edb_mapping.go

@@ -1,6 +1,7 @@
 package excel
 
 import (
+	sql2 "database/sql"
 	"eta_gn/eta_api/global"
 	"eta_gn/eta_api/utils"
 	"fmt"
@@ -104,6 +105,15 @@ func GetExcelEdbMappingByEdbInfoIdAndSource(edbInfoId int, sources []int) (items
 	return
 }
 
+// GetUserExcelEdbMappingByEdbInfoIdAndSource 根据指标id获取所属用户的配置关系
+func GetUserExcelEdbMappingByEdbInfoIdAndSource(userId, edbInfoId int, sources []int) (items []*ExcelEdbMapping, err error) {
+	sql := ` SELECT a.*  FROM excel_edb_mapping AS a 
+           JOIN excel_info AS b on a.excel_info_id = b.excel_info_id
+           WHERE 1=1 AND a.sys_user_id = ? AND b.edb_info_id = ? AND b.source in (` + utils.GetOrmInReplace(len(sources)) + `) `
+	err = global.DmSQL["data"].Raw(sql, userId, edbInfoId, sources).Find(&items).Error
+	return
+}
+
 // DeleteCustomAnalysisExcelEdbMappingByEdbInfoId
 // @Description: 根据指标id删除与自定义分析表格的关系
 // @author: Roc
@@ -143,3 +153,51 @@ func GetExcelEdbMappingItemByExcelInfoIdOrKeyword(excelInfoId int, keyword strin
 	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
 	return
 }
+
+// GetCountRelationExcelEdbInfoListMappingByCondition
+// @Description: 根据条件获取表格关联指标的数量
+// @author: Roc
+// @datetime 2024-12-26 10:37:48
+// @param condition string
+// @param pars []interface{}
+// @return total int
+// @return err error
+func GetCountRelationExcelEdbInfoListMappingByCondition(condition string, pars []interface{}) (total int, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT COUNT(1) total FROM excel_edb_mapping AS a 
+	JOIN excel_info AS b on a.excel_info_id = b.excel_info_id WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	var totalNull sql2.NullInt64
+	err = o.Raw(sql, pars...).Scan(&totalNull).Error
+	if err != nil {
+		return
+	}
+
+	total = int(totalNull.Int64)
+
+	return
+}
+
+// GetUserIdListRelationExcelEdbInfoListMappingByCondition
+// @Description: 根据条件获取表格关联指标的用户id列表
+// @author: Roc
+// @datetime 2024-12-26 10:37:48
+// @param condition string
+// @param pars []interface{}
+// @return total int
+// @return err error
+func GetUserIdListRelationExcelEdbInfoListMappingByCondition(condition string, pars []interface{}) (userIdList []int, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT b.sys_user_id FROM excel_edb_mapping AS a 
+	JOIN excel_info AS b on a.excel_info_id = b.excel_info_id WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY b.sys_user_id `
+
+	err = o.Raw(sql, pars...).Scan(&userIdList).Error
+
+	return
+}

+ 3 - 3
models/data_manage/multiple_graph_config.go

@@ -81,7 +81,7 @@ type RollingCorrelationConfig struct {
 }
 
 // ReplaceEdbInfoInLineEquationMultipleGraphConfig 获取拟合方程配置
-func ReplaceEdbInfoInLineEquationMultipleGraphConfig(oldEdbInfo, newEdbInfo *EdbInfo) (replaceConfigTotal int, err error) {
+func ReplaceEdbInfoInLineEquationMultipleGraphConfig(oldEdbInfo, newEdbInfo *EdbInfo, userId int) (replaceConfigTotal int, err error) {
 	var errmsg string
 	logMsg := `` // 记录替换的日志
 	to := global.DmSQL["data"].Begin()
@@ -106,8 +106,8 @@ func ReplaceEdbInfoInLineEquationMultipleGraphConfig(oldEdbInfo, newEdbInfo *Edb
 	//替换multiple_graph_config中的指标
 	{
 		multipleGraphConfigList := make([]*MultipleGraphConfig, 0)
-		csql := `SELECT * FROM multiple_graph_config WHERE edb_info_id_a=0 AND edb_info_id_b=0 AND curve !=''`
-		err = to.Raw(csql).Find(&multipleGraphConfigList).Error
+		csql := `SELECT * FROM multiple_graph_config WHERE sys_user_id = ? AND  edb_info_id_a=0 AND edb_info_id_b=0 AND curve !=''`
+		err = to.Raw(csql, userId).Find(&multipleGraphConfigList).Error
 		if err != nil {
 			errmsg = "获取指标关联图表配置信息失败:Err:" + err.Error()
 			return

+ 38 - 15
models/data_manage/multiple_graph_config_chart_mapping.go

@@ -54,7 +54,7 @@ func GetMultipleGraphConfigChartMappingListById(configId int) (items []*Multiple
 }
 
 // ReplaceMultipleGraphConfigChartEdb 替换相关性分析配置中的指标
-func ReplaceMultipleGraphConfigChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (replaceConfigTotal int, err error) {
+func ReplaceMultipleGraphConfigChartEdb(oldEdbInfo, newEdbInfo *EdbInfo, userId int) (replaceConfigTotal int, err error) {
 	var errmsg string
 	logMsg := `` // 记录替换的日志
 	to := global.DmSQL["data"].Begin()
@@ -78,8 +78,8 @@ func ReplaceMultipleGraphConfigChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (replac
 
 	//替换multiple_graph_config中的指标
 	multipleGraphConfigList := make([]*MultipleGraphConfig, 0)
-	csql := `SELECT * FROM multiple_graph_config WHERE (edb_info_id_a=? or edb_info_id_b=?)`
-	err = to.Raw(csql, oldEdbInfo.EdbInfoId, oldEdbInfo.EdbInfoId).Find(&multipleGraphConfigList).Error
+	csql := `SELECT * FROM multiple_graph_config WHERE sys_user_id = ? AND (edb_info_id_a=? or edb_info_id_b=?)`
+	err = to.Raw(csql, userId, oldEdbInfo.EdbInfoId, oldEdbInfo.EdbInfoId).Find(&multipleGraphConfigList).Error
 	if err != nil {
 		errmsg = "获取指标关联图表配置信息失败:Err:" + err.Error()
 		return
@@ -160,22 +160,45 @@ func ReplaceMultipleGraphConfigChartEdb(oldEdbInfo, newEdbInfo *EdbInfo) (replac
 	}
 
 	// 更新相关性图表中的
-	sql := `UPDATE chart_info_correlation SET edb_info_id_first=?, modify_time=? WHERE edb_info_id_first=?`
-	err = to.Exec(sql, newEdbInfo.EdbInfoId, time.Now(), oldEdbInfo.EdbInfoId).Error
-	if err != nil {
-		errmsg = "更新相关性图表中的指标id关联失败:Err:" + err.Error()
-		return
-	}
+	{
+		// 查询我的相关性图表
+
+		tmpChartInfoCorrelationList := make([]*ChartInfoCorrelation, 0)
+		tmpSql := `SELECT a.* FROM chart_info_correlation AS a 
+         JOIN chart_info AS b on a.correlation_chart_info_id = b.chart_info_id
+         WHERE b.sys_user_id = ? AND (edb_info_id_a=? or edb_info_id_b=?) `
+		err = to.Raw(tmpSql, userId, oldEdbInfo.EdbInfoId, oldEdbInfo.EdbInfoId).Find(&tmpChartInfoCorrelationList).Error
+		if err != nil {
+			errmsg = "获取指标关联图表配置信息失败:Err:" + err.Error()
+			return
+		}
+		chartInfoIdList := make([]int, 0)
+		for _, v := range tmpChartInfoCorrelationList {
+			chartInfoIdList = append(chartInfoIdList, v.CorrelationChartInfoId)
+		}
+
+		num := len(chartInfoIdList)
+		// 更新相关性图表中的
+		if num > 0 {
+			sql := `UPDATE chart_info_correlation SET edb_info_id_first=?, modify_time=? WHERE edb_info_id_first=? AND correlation_chart_info_id IN (?) `
+			err = to.Exec(sql, newEdbInfo.EdbInfoId, time.Now(), oldEdbInfo.EdbInfoId, chartInfoIdList).Error
+			if err != nil {
+				errmsg = "更新相关性图表中的指标id关联失败:Err:" + err.Error()
+				return
+			}
+
+			sql = `UPDATE chart_info_correlation SET edb_info_id_second=?, modify_time=? WHERE edb_info_id_second=? AND correlation_chart_info_id IN (?) `
+			err = to.Exec(sql, newEdbInfo.EdbInfoId, time.Now(), oldEdbInfo.EdbInfoId, chartInfoIdList).Error
+			if err != nil {
+				errmsg = "更新相关性图表中的指标id关联失败:Err:" + err.Error()
+				return
+			}
+		}
 
-	sql = `UPDATE chart_info_correlation SET edb_info_id_second=?, modify_time=? WHERE edb_info_id_second=?`
-	err = to.Exec(sql, newEdbInfo.EdbInfoId, time.Now(), oldEdbInfo.EdbInfoId).Error
-	if err != nil {
-		errmsg = "更新相关性图表中的指标id关联失败:Err:" + err.Error()
-		return
 	}
 
 	// 替换拟合方程曲线替换指标
-	sql = `UPDATE chart_tag_variety SET edb_info_id=?, modify_time=? WHERE edb_info_id=?`
+	sql := `UPDATE chart_tag_variety SET edb_info_id=?, modify_time=? WHERE edb_info_id=?`
 	err = to.Exec(sql, newEdbInfo.EdbInfoId, time.Now(), oldEdbInfo.EdbInfoId).Error
 	if err != nil {
 		errmsg = "更新指标id关联跨品种分析标签失败:Err:" + err.Error()

+ 48 - 0
models/data_manage/predict_edb_conf.go

@@ -1,6 +1,7 @@
 package data_manage
 
 import (
+	sql2 "database/sql"
 	"eta_gn/eta_api/global"
 	"eta_gn/eta_api/utils"
 	"time"
@@ -169,3 +170,50 @@ func GetGroupPredictEdbInfoIdListBySourceEdbInfoId(sourceEdbInfoId int) (items [
 	err = global.DmSQL["data"].Raw(sql, sourceEdbInfoId).Scan(&items).Error
 	return
 }
+
+// GetCountRelationPredictEdbInfoListMappingByCondition
+// @Description: 根据条件获取关联预测指标数量
+// @author: Roc
+// @datetime 2024-12-26 10:13:47
+// @param condition string
+// @param pars []interface{}
+// @return total int
+// @return err error
+func GetCountRelationPredictEdbInfoListMappingByCondition(condition string, pars []interface{}) (total int, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT COUNT(1) total FROM predict_edb_conf AS a 
+	JOIN edb_info AS b on a.predict_edb_info_id = b.edb_info_id WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	var totalNull sql2.NullInt64
+	err = o.Raw(sql, pars...).Scan(&totalNull).Error
+	if err != nil {
+		return
+	}
+	total = int(totalNull.Int64)
+
+	return
+}
+
+// GetUserIdListRelationPredictEdbInfoListMappingByCondition
+// @Description: 根据条件获取关联预测指标的用户id列表
+// @author: Roc
+// @datetime 2024-12-26 10:13:47
+// @param condition string
+// @param pars []interface{}
+// @return total int
+// @return err error
+func GetUserIdListRelationPredictEdbInfoListMappingByCondition(condition string, pars []interface{}) (userIdList []int, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT b.sys_user_id FROM predict_edb_conf AS a 
+	JOIN edb_info AS b on a.predict_edb_info_id = b.edb_info_id WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY b.sys_user_id `
+
+	err = o.Raw(sql, pars...).Scan(&userIdList).Error
+
+	return
+}

+ 400 - 0
models/data_manage/public_chart_classify.go

@@ -0,0 +1,400 @@
+package data_manage
+
+import (
+	"errors"
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+// ChartPublicClassify
+// @Description: 公共分类
+type ChartPublicClassify struct {
+	ChartPublicClassifyId       int       `gorm:"primaryKey" `
+	Source                      int       `description:"分类来源: 1-图库; 2-商品价格曲线; 3-相关性图表; 6-拟合方程图表; 7-统计特征"`
+	ChartPublicClassifyName     string    `description:"分类名称"`
+	ParentId                    int       `description:"父级id"`
+	HasData                     int       `description:"是否含有指标数据"`
+	RootId                      int       `description:"顶级id"`
+	CreateTime                  time.Time `description:"创建时间"`
+	ModifyTime                  time.Time `description:"修改时间"`
+	SysUserId                   int       `description:"创建人id"`
+	SysUserRealName             string    `description:"创建人姓名"`
+	Level                       int       `description:"层级"`
+	UniqueCode                  string    `description:"唯一编码"`
+	Sort                        int       `description:"排序字段,越小越靠前,默认值:10"`
+	LastModifyUserId            int       `description:"最后修改人ID"`
+	LastModifyUserRealName      string    `description:"最后修改人姓名"`
+	ChartPublicClassifyNamePath string    `description:"分类名称的完整路径,格式为:父级分类名称|当前分类名称"`
+	ChartPublicClassifyIdPath   string    `description:"分类的完整路径,格式为:父级ID,当前ID"`
+}
+
+func (m ChartPublicClassify) ToChartClassifyItems() *ChartClassifyItems {
+	return &ChartClassifyItems{
+		ChartClassifyId: m.ChartPublicClassifyId,
+		//ChartInfoId:         0,
+		ChartClassifyName:   m.ChartPublicClassifyName,
+		ChartClassifyNameEn: m.ChartPublicClassifyName,
+		ParentId:            m.ParentId,
+		Level:               m.Level,
+		Sort:                m.Sort,
+		UniqueCode:          m.UniqueCode,
+		Source:              m.Source,
+		//SourceName:          "",
+		SysUserId:       m.SysUserId,
+		SysUserRealName: m.SysUserRealName,
+		//DateType:            0,
+		//StartDate:           "",
+		//EndDate:             "",
+		//ChartType:           0,
+		//Calendar:            "",
+		//SeasonStartDate:     "",
+		//SeasonEndDate:       "",
+		Children:            nil,
+		Button:              ChartClassifyItemsButton{},
+		IsJoinPermission:    0,
+		HaveOperaAuth:       false,
+		ChartClassifyIdPath: m.ChartPublicClassifyIdPath,
+	}
+}
+
+// Add
+// @Description: 添加分类
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 17:00:18
+// @return err error
+func (m *ChartPublicClassify) Add() (err error) {
+	err = global.DmSQL["data"].Create(m).Error
+
+	return
+}
+
+// Update
+// @Description: 更新分类基础信息
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 17:01:51
+// @param cols []string
+// @return err error
+func (m *ChartPublicClassify) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Select(cols).Updates(m).Error
+
+	return
+}
+
+// GetChartClassifyById
+// @Description: 根据id获取分类
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 16:56:15
+// @param classifyId int
+// @return item *ChartPublicClassify
+// @return err error
+func (m ChartPublicClassify) GetChartClassifyById(classifyId int) (item *ChartPublicClassify, err error) {
+	sql := `SELECT * FROM chart_public_classify WHERE chart_public_classify_id=? `
+	err = global.DmSQL["data"].Raw(sql, classifyId).First(&item).Error
+
+	return
+}
+
+// GetChartClassifyByIdList
+// @Description: 根据id列表获取分类列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 16:56:15
+// @param classifyIdList []int
+// @return items []*ChartPublicClassify
+// @return err error
+func (m ChartPublicClassify) GetChartClassifyByIdList(classifyIdList []int) (items []*ChartPublicClassify, err error) {
+	if len(classifyIdList) <= 0 {
+		return
+	}
+	sql := `SELECT * FROM chart_public_classify WHERE chart_public_classify_id in (?) `
+	err = global.DmSQL["data"].Raw(sql, classifyIdList).Find(&items).Error
+
+	return
+}
+
+// GetChartClassifyListByParentId
+// @Description: 根据父级id获取下级分类列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 13:57:48
+// @param parentId int
+// @param source int8
+// @return items []*ChartPublicClassify
+// @return err error
+func (m ChartPublicClassify) GetChartClassifyListByParentId(parentId int, source int8) (items []*ChartPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM chart_public_classify WHERE parent_id=? AND source = ? order by sort asc,chart_public_classify_id asc `
+	err = o.Raw(sql, parentId, source).Find(&items).Error
+
+	return
+}
+
+// GetChartClassifyItemsByParentId
+// @Description: 根据父级id获取下级分类列表(结构型的)
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 13:56:18
+// @param parentId int
+// @param source int8
+// @return items []*ChartClassifyItems
+// @return err error
+func (m ChartPublicClassify) GetChartClassifyItemsByParentId(parentId int, source int8) (items []*ChartClassifyItems, err error) {
+	list, err := m.GetChartClassifyListByParentId(parentId, source)
+	if err != nil {
+		return
+	}
+
+	for _, v := range list {
+		items = append(items, v.ToChartClassifyItems())
+	}
+
+	return
+}
+
+// GetChartClassifyListByParentId
+// @Description: 根据父级id获取下级分类列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 13:57:48
+// @param parentId int
+// @param source int8
+// @return items []*ChartPublicClassify
+// @return err error
+func (m ChartPublicClassify) GetChartClassifyListByType(source int8) (items []*ChartPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM chart_public_classify WHERE source = ? order by sort asc,chart_public_classify_id asc `
+	err = o.Raw(sql, source).Find(&items).Error
+
+	return
+}
+
+// GetAllChartClassifyByType 根据类型获取分类列表
+func (m ChartPublicClassify) GetAllChartClassifyByType(source int8) (items []*ChartClassifyItems, err error) {
+	list, err := m.GetChartClassifyListByType(int8(source))
+	if err != nil {
+		return
+	}
+
+	for _, v := range list {
+		items = append(items, v.ToChartClassifyItems())
+	}
+
+	return
+}
+
+func (m ChartPublicClassify) GetChartClassifyCount(classifyName string, parentId int, source int) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM chart_public_classify WHERE parent_id=? AND chart_public_classify_name=? AND source = ?  `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyName, source).Scan(&count).Error
+
+	return
+}
+
+// UpdateChartClassifyNameAndNamePath
+// @Description: 更新分类信息
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 09:27:33
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func (m *ChartPublicClassify) UpdateChartClassifyNameAndNamePath(cols []string, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	tx := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	// 变更分类信息
+	err = tx.Select(cols).Updates(m).Error
+	if err != nil {
+		return
+	}
+
+	// 更改子分类的完整的路径
+	if oldClassifyNamePath != `` && newClassifyNamePath != `` {
+		sql := `UPDATE chart_public_classify SET chart_public_classify_name_path = REPLACE(chart_public_classify_name_path,?,?) WHERE chart_public_classify_id_path LIKE ?`
+		err = tx.Exec(sql, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(m.ChartPublicClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// GetChartClassifyMaxSort 获取分类下最大的排序数
+func (m ChartPublicClassify) GetChartClassifyMaxSort(parentId int, source int) (sort int, err error) {
+	sql := `SELECT COALESCE(Max(sort), 0) AS sort FROM chart_public_classify WHERE parent_id=? AND source=? `
+	err = global.DmSQL["data"].Raw(sql, parentId, source).Scan(&sort).Error
+
+	return
+}
+
+// GetChartInfoCountByClassifyIdList
+// @Description: 根据公共分类id集合获取名下指标数量
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 09:59:56
+// @param classifyIdList []int
+// @return count int
+// @return err error
+func (m ChartPublicClassify) GetChartInfoCountByClassifyIdList(classifyIdList []int) (count int, err error) {
+	if len(classifyIdList) <= 0 {
+		return
+	}
+	sql := `SELECT COUNT(1) total FROM chart_info  WHERE chart_public_classify_id IN (?) `
+	err = global.DmSQL["data"].Raw(sql, classifyIdList).Scan(&count).Error
+
+	return
+}
+
+func (m *ChartPublicClassify) GetAllChildClassifyIdList() (items []int, err error) {
+	sql := ` SELECT chart_public_classify_id FROM chart_public_classify  WHERE chart_public_classify_id_path LIKE ?  ORDER BY create_time DESC `
+	err = global.DmSQL["data"].Raw(sql, fmt.Sprint(m.ChartPublicClassifyIdPath+`,%`)).Scan(&items).Error
+
+	return
+}
+
+// BatchesDel
+// @Description: 根据分类id批量删除
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 11:13:06
+// @param classifyIdList []int
+// @return err error
+func (m *ChartPublicClassify) BatchesDel(classifyIdList []int) (err error) {
+	sql := ` DELETE FROM chart_public_classify  WHERE chart_public_classify_id IN (?) `
+	err = global.DmSQL["data"].Exec(sql, classifyIdList).Error
+
+	return
+}
+
+func (m *ChartPublicClassify) GetChildClassifyListByParentId(classifyIdPath, orderStr string) (items []*ChartPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM chart_public_classify WHERE chart_public_classify_id_path like ? `
+	if orderStr != "" {
+		sql += orderStr
+	} else {
+		sql += ` order by level asc, sort asc, chart_public_classify_id_path asc`
+	}
+
+	err = o.Raw(sql, classifyIdPath).Scan(&items).Error
+
+	return
+}
+
+// GetAllChildClassifyByParentId
+// @Description: 根据上级id获取所有的下级id
+// @author: Roc
+// @datetime 2024-12-02 15:14:13
+// @param parentId int
+// @return targetList []*data_manage.ChartPublicClassify
+// @return err error
+// @return errMsg string
+func (m *ChartPublicClassify) GetAllChildClassifyByParentId(parentId int) (targetList []*ChartPublicClassify, err error, errMsg string) {
+	//判断是否是挂在顶级目录下
+	parentClassify, err := m.GetChartClassifyById(parentId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			errMsg = "当前分类不存在"
+			err = errors.New(errMsg)
+			return
+		}
+		errMsg = "获取失败"
+		err = errors.New("获取分类信息失败,Err:" + err.Error())
+		return
+	}
+	orderStr := ` order by level asc, sort asc, chart_public_classify_id_path asc`
+
+	targetList, err = m.GetChildClassifyListByParentId(fmt.Sprint(parentClassify.ChartPublicClassifyIdPath, ",%"), orderStr)
+
+	return
+}
+
+// GetChartPublicClassifyByParentIdAndName 根据父级ID和名称获取分类
+func (m *ChartPublicClassify) GetChartPublicClassifyByParentIdAndName(source, parentId int, classifyName string, classifyId int) (item *ChartPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM chart_public_classify WHERE source = ? AND parent_id = ? AND chart_public_classify_name = ? AND chart_public_classify_id <> ? LIMIT 1`
+	err = o.Raw(sql, source, parentId, classifyName, classifyId).First(&item).Error
+
+	return
+}
+
+// UpdateChartClassifySortByParentId 根据父类id更新排序
+func (m *ChartPublicClassify) UpdateChartClassifySortByParentId(parentId, classifyId, nowSort int, updateSort string, source int) (err error) {
+	sql := ` update chart_public_classify set sort = ` + updateSort + ` WHERE parent_id=? AND sort > ? AND source = ? `
+	if classifyId > 0 {
+		sql += ` or ( chart_public_classify_id > ` + fmt.Sprint(classifyId) + ` and sort = ` + fmt.Sprint(nowSort) + `)`
+	}
+	err = global.DmSQL["data"].Exec(sql, parentId, nowSort, source).Error
+
+	return
+}
+
+// GetFirstChartClassifyByParentId 获取当前父级分类下,且排序数相同 的排序第一条的数据
+func (m *ChartPublicClassify) GetFirstChartClassifyByParentId(parentId int) (item *ChartPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM chart_public_classify WHERE parent_id=? order by sort asc,chart_public_classify_id asc limit 1`
+	err = o.Raw(sql, parentId).First(&item).Error
+
+	return
+}
+func (m *ChartPublicClassify) GetChartClassifyByRootIdLevel(rootId int, source int, orderStr string) (items []*ChartPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM chart_public_classify WHERE root_id=? AND source = ? `
+	if orderStr != "" {
+		sql += orderStr
+	} else {
+		sql += ` order by level desc, sort asc, chart_public_classify_id asc`
+	}
+
+	err = o.Raw(sql, rootId, source).Scan(&items).Error
+
+	return
+}
+func (m *ChartPublicClassify) UpdateChartClassifyChildByParentClassifyId(classifyIds []int, rootId int, levelStep int) (err error) {
+	var pars []interface{}
+	pars = append(pars, rootId, levelStep)
+	pars = append(pars, classifyIds)
+	// 更新相关联的二级分类的parentId,和classify_name_second
+	sql := `update chart_public_classify 
+SET root_id = ?, level = level+?
+where chart_public_classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `)`
+	err = global.DmSQL["data"].Exec(sql, pars...).Error
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// UpdateChartClassifyNameAndNamePathByOldClassifyIdPath
+// @Description: 根据源分类id全路径更新分类名称和子分类的全路径
+// @author: Roc
+// @receiver chartClassify
+// @datetime 2024-11-26 14:39:09
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func (m *ChartPublicClassify) UpdateChartClassifyNameAndNamePathByOldClassifyIdPath(oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	// 更改子分类的完整的路径
+	if oldClassifyIdPath != `` && newClassifyNamePath != `` && newClassifyIdPath != `` {
+		sql := `UPDATE chart_public_classify SET chart_public_classify_id_path = REPLACE(chart_public_classify_id_path,?,?) ,chart_public_classify_name_path = REPLACE(chart_public_classify_name_path,?,?)  WHERE chart_public_classify_id_path LIKE ?`
+		err = global.DmSQL["data"].Exec(sql, oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(oldClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}

+ 77 - 0
models/data_manage/public_chart_info.go

@@ -0,0 +1,77 @@
+package data_manage
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+)
+
+// GetChartInfoByPublicClassifyId
+// @Description: 根据公共分类id获取指标列表
+// @author: Roc
+// @datetime 2024-12-03 14:09:32
+// @param classifyId int
+// @param chartInfoType int
+// @param source int
+// @return items []*ChartClassifyItems
+// @return err error
+func GetChartInfoByPublicClassifyId(classifyId, source int) (items []*ChartClassifyItems, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT chart_info_id,chart_classify_id,chart_public_classify_id,chart_name AS chart_classify_name,chart_name_en AS chart_classify_name_en,unique_code,source,sys_user_id,sys_user_real_name,start_date,chart_type, public_sort as sort,is_join_permission FROM chart_info WHERE chart_public_classify_id = ? AND source = ?`
+
+	sql += ` order by public_sort asc,chart_info_id asc `
+	err = o.Raw(sql, classifyId, source).Scan(&items).Error
+
+	return
+}
+
+// UpdatePublicChartSuccess
+// @Description: 更新指标的公开成功状态
+// @author: Roc
+// @datetime 2024-12-06 13:37:01
+// @param chartInfoId int
+// @param classifyId int
+// @return err error
+func UpdatePublicChartSuccess(chartInfoId, classifyId int) (err error) {
+	sql := `UPDATE chart_info set public_status = ?,chart_public_classify_id = ? ,modify_time=now(),public_time = now()  WHERE chart_info_id  = ?`
+	err = global.DmSQL["data"].Exec(sql, utils.DataPublicSuccess, classifyId, chartInfoId).Error
+
+	return
+}
+
+// UpdatePublicChart
+// @Description: 更新指标的公开状态
+// @author: Roc
+// @datetime 2024-12-06 11:10:53
+// @param chartInfoIdList []int
+// @param status int
+// @return err error
+func UpdatePublicChart(chartInfoIdList []int, status int) (err error) {
+	if len(chartInfoIdList) <= 0 {
+		return
+	}
+	sql := `UPDATE chart_info set public_status = ?,modify_time=now() `
+	if status == utils.DataPublicSuccess {
+		sql += `,public_time = now() `
+	}
+	sql += ` WHERE chart_info_id in (?) `
+	err = global.DmSQL["data"].Exec(sql, status, chartInfoIdList).Error
+
+	return
+}
+
+// UpdatePublicClassifyIdByChartInfoIdList
+// @Description: 根据指标id列表更新所属公共分类id
+// @author: Roc
+// @datetime 2024-12-10 13:18:52
+// @param chartInfoId int
+// @param chartClassifyId int
+// @return err error
+func UpdatePublicClassifyIdByChartInfoIdList(chartInfoIdList []int, chartClassifyId int) (err error) {
+	if len(chartInfoIdList) <= 0 {
+		return
+	}
+	sql := ` UPDATE chart_info SET chart_public_classify_id = ? WHERE  chart_info_id in (?) AND public_status = 3 `
+	err = global.DmSQL["data"].Exec(sql, chartClassifyId, chartInfoIdList).Error
+
+	return
+}

+ 397 - 0
models/data_manage/public_edb_classify.go

@@ -0,0 +1,397 @@
+package data_manage
+
+import (
+	"errors"
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+// EdbPublicClassify
+// @Description: 公共分类
+type EdbPublicClassify struct {
+	EdbPublicClassifyId       int       `gorm:"primaryKey" `
+	ClassifyType              uint8     `description:"分类类型,0:普通指标分类,1:预测指标分类,2:指标加工的分类(普通指标的计算指标)"`
+	EdbPublicClassifyName     string    `description:"分类名称"`
+	ParentId                  int       `description:"父级id"`
+	HasData                   int       `description:"是否含有指标数据"`
+	RootId                    int       `description:"顶级id"`
+	CreateTime                time.Time `description:"创建时间"`
+	ModifyTime                time.Time `description:"修改时间"`
+	SysUserId                 int       `description:"创建人id"`
+	SysUserRealName           string    `description:"创建人姓名"`
+	Level                     int       `description:"层级"`
+	UniqueCode                string    `description:"唯一编码"`
+	Sort                      int       `description:"排序字段,越小越靠前,默认值:10"`
+	LastModifyUserId          int       `description:"最后修改人ID"`
+	LastModifyUserRealName    string    `description:"最后修改人姓名"`
+	EdbPublicClassifyNamePath string    `description:"分类名称的完整路径,格式为:父级分类名称|当前分类名称"`
+	EdbPublicClassifyIdPath   string    `description:"分类的完整路径,格式为:父级ID,当前ID"`
+}
+
+func (m EdbPublicClassify) ToEdbClassifyItems() *EdbClassifyItems {
+	return &EdbClassifyItems{
+		ClassifyId: m.EdbPublicClassifyId,
+		//EdbInfoId:        0,
+		ClassifyType:   m.ClassifyType,
+		ClassifyName:   m.EdbPublicClassifyName,
+		ClassifyNameEn: m.EdbPublicClassifyName,
+		ParentId:       m.ParentId,
+		RootId:         m.RootId,
+		Level:          m.Level,
+		Sort:           m.Sort,
+		UniqueCode:     m.UniqueCode,
+		//Source:           0,
+		//SourceName:       "",
+		SysUserId:       m.SysUserId,
+		SysUserRealName: m.SysUserRealName,
+		//StartDate:        "",
+		//EdbCode:          "",
+		//EdbType:          0,
+		//Children:         nil,
+		//Button:           EdbClassifyItemsButton{},
+		//IsJoinPermission: 0,
+		//HaveOperaAuth:    false,
+		ClassifyIdPath: m.EdbPublicClassifyIdPath,
+	}
+}
+
+// Add
+// @Description: 添加分类
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 17:00:18
+// @return err error
+func (m *EdbPublicClassify) Add() (err error) {
+	err = global.DmSQL["data"].Create(m).Error
+
+	return
+}
+
+// Update
+// @Description: 更新分类基础信息
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 17:01:51
+// @param cols []string
+// @return err error
+func (m *EdbPublicClassify) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Select(cols).Updates(m).Error
+
+	return
+}
+
+// GetEdbClassifyById
+// @Description: 根据id获取分类
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 16:56:15
+// @param classifyId int
+// @return item *EdbPublicClassify
+// @return err error
+func (m EdbPublicClassify) GetEdbClassifyById(classifyId int) (item *EdbPublicClassify, err error) {
+	sql := `SELECT * FROM edb_public_classify WHERE edb_public_classify_id=? `
+	err = global.DmSQL["data"].Raw(sql, classifyId).First(&item).Error
+
+	return
+}
+
+// GetEdbClassifyByIdList
+// @Description: 根据id列表获取分类列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 16:56:15
+// @param classifyIdList []int
+// @return items []*EdbPublicClassify
+// @return err error
+func (m EdbPublicClassify) GetEdbClassifyByIdList(classifyIdList []int) (items []*EdbPublicClassify, err error) {
+	if len(classifyIdList) <= 0 {
+		return
+	}
+	sql := `SELECT * FROM edb_public_classify WHERE edb_public_classify_id in (?) `
+	err = global.DmSQL["data"].Raw(sql, classifyIdList).Find(&items).Error
+
+	return
+}
+
+// GetEdbClassifyListByParentId
+// @Description: 根据父级id获取下级分类列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 13:57:48
+// @param parentId int
+// @param classifyType int8
+// @return items []*EdbPublicClassify
+// @return err error
+func (m EdbPublicClassify) GetEdbClassifyListByParentId(parentId int, classifyType int8) (items []*EdbPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM edb_public_classify WHERE parent_id=? AND classify_type = ? order by sort asc,edb_public_classify_id asc `
+	err = o.Raw(sql, parentId, classifyType).Find(&items).Error
+
+	return
+}
+
+// GetEdbClassifyItemsByParentId
+// @Description: 根据父级id获取下级分类列表(结构型的)
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 13:56:18
+// @param parentId int
+// @param classifyType int8
+// @return items []*EdbClassifyItems
+// @return err error
+func (m EdbPublicClassify) GetEdbClassifyItemsByParentId(parentId int, classifyType int8) (items []*EdbClassifyItems, err error) {
+	list, err := m.GetEdbClassifyListByParentId(parentId, classifyType)
+	if err != nil {
+		return
+	}
+
+	for _, v := range list {
+		items = append(items, v.ToEdbClassifyItems())
+	}
+
+	return
+}
+
+// GetEdbClassifyListByParentId
+// @Description: 根据父级id获取下级分类列表
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-03 13:57:48
+// @param parentId int
+// @param classifyType int8
+// @return items []*EdbPublicClassify
+// @return err error
+func (m EdbPublicClassify) GetEdbClassifyListByType(classifyType int8) (items []*EdbPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM edb_public_classify WHERE classify_type = ? order by sort asc,edb_public_classify_id asc `
+	err = o.Raw(sql, classifyType).Find(&items).Error
+
+	return
+}
+
+// GetAllEdbClassifyByType 根据类型获取分类列表
+func (m EdbPublicClassify) GetAllEdbClassifyByType(classifyType int8) (items []*EdbClassifyItems, err error) {
+	list, err := m.GetEdbClassifyListByType(int8(classifyType))
+	if err != nil {
+		return
+	}
+
+	for _, v := range list {
+		items = append(items, v.ToEdbClassifyItems())
+	}
+
+	return
+}
+
+func (m EdbPublicClassify) GetEdbClassifyCount(classifyName string, parentId int, classifyType uint8) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM edb_public_classify WHERE parent_id=? AND edb_public_classify_name=? AND classify_type = ?  `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyName, classifyType).Scan(&count).Error
+
+	return
+}
+
+// UpdateEdbClassifyNameAndNamePath
+// @Description: 更新分类信息
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 09:27:33
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func (m *EdbPublicClassify) UpdateEdbClassifyNameAndNamePath(cols []string, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	tx := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	// 变更分类信息
+	err = tx.Select(cols).Updates(m).Error
+	if err != nil {
+		return
+	}
+
+	// 更改子分类的完整的路径
+	if oldClassifyNamePath != `` && newClassifyNamePath != `` {
+		sql := `UPDATE edb_public_classify SET edb_public_classify_name_path = REPLACE(edb_public_classify_name_path,?,?) WHERE edb_public_classify_id_path LIKE ?`
+		err = tx.Exec(sql, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(m.EdbPublicClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// GetEdbClassifyMaxSort 获取分类下最大的排序数
+func (m EdbPublicClassify) GetEdbClassifyMaxSort(parentId int, classifyType uint8) (sort int, err error) {
+	sql := `SELECT COALESCE(Max(sort), 0) AS sort FROM edb_public_classify WHERE parent_id=? AND classify_type=? `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyType).Scan(&sort).Error
+
+	return
+}
+
+// GetEdbInfoCountByClassifyIdList
+// @Description: 根据公共分类id集合获取名下指标数量
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 09:59:56
+// @param classifyIdList []int
+// @return count int
+// @return err error
+func (m EdbPublicClassify) GetEdbInfoCountByClassifyIdList(classifyIdList []int) (count int, err error) {
+	if len(classifyIdList) <= 0 {
+		return
+	}
+	sql := `SELECT COUNT(1) total FROM edb_info  WHERE edb_public_classify_id IN (?) `
+	err = global.DmSQL["data"].Raw(sql, classifyIdList).Scan(&count).Error
+
+	return
+}
+
+func (m *EdbPublicClassify) GetAllChildClassifyIdList() (items []int, err error) {
+	sql := ` SELECT edb_public_classify_id FROM edb_public_classify  WHERE edb_public_classify_id_path LIKE ?  ORDER BY create_time DESC `
+	err = global.DmSQL["data"].Raw(sql, fmt.Sprint(m.EdbPublicClassifyIdPath+`,%`)).Scan(&items).Error
+
+	return
+}
+
+// BatchesDel
+// @Description: 根据分类id批量删除
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 11:13:06
+// @param classifyIdList []int
+// @return err error
+func (m *EdbPublicClassify) BatchesDel(classifyIdList []int) (err error) {
+	sql := ` DELETE FROM edb_public_classify  WHERE edb_public_classify_id IN (?) `
+	err = global.DmSQL["data"].Exec(sql, classifyIdList).Error
+
+	return
+}
+
+func (m *EdbPublicClassify) GetChildEdbClassifyListByParentId(classifyIdPath, orderStr string) (items []*EdbPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM edb_public_classify WHERE edb_public_classify_id_path like ? `
+	if orderStr != "" {
+		sql += orderStr
+	} else {
+		sql += ` order by level asc, sort asc, edb_public_classify_id asc`
+	}
+
+	err = o.Raw(sql, classifyIdPath).Scan(&items).Error
+
+	return
+}
+
+// GetAllChildClassifyByParentId
+// @Description: 根据上级id获取所有的下级id
+// @author: Roc
+// @datetime 2024-12-02 15:14:13
+// @param parentId int
+// @return targetList []*data_manage.EdbClassifyItems
+// @return err error
+// @return errMsg string
+func (m *EdbPublicClassify) GetAllChildClassifyByParentId(parentId int) (targetList []*EdbPublicClassify, err error, errMsg string) {
+	//判断是否是挂在顶级目录下
+	parentClassify, err := m.GetEdbClassifyById(parentId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			errMsg = "当前分类不存在"
+			err = errors.New(errMsg)
+			return
+		}
+		errMsg = "获取失败"
+		err = errors.New("获取分类信息失败,Err:" + err.Error())
+		return
+	}
+	orderStr := ` order by level asc, sort asc, edb_public_classify_id asc`
+
+	targetList, err = m.GetChildEdbClassifyListByParentId(fmt.Sprint(parentClassify.EdbPublicClassifyIdPath, ",%"), orderStr)
+
+	return
+}
+
+// GetEdbPublicClassifyByParentIdAndName 根据父级ID和名称获取分类
+func (m *EdbPublicClassify) GetEdbPublicClassifyByParentIdAndName(parentId int, classifyName string, classifyId int, classifyType uint8) (item *EdbPublicClassify, err error) {
+	sql := `SELECT * FROM edb_public_classify WHERE parent_id = ? AND edb_public_classify_name = ? AND edb_public_classify_id <> ? and classify_type=? LIMIT 1`
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyName, classifyId, classifyType).First(&item).Error
+
+	return
+}
+
+// UpdateEdbClassifySortByParentId 根据父类id更新排序
+func (m *EdbPublicClassify) UpdateEdbClassifySortByParentId(parentId, classifyId, nowSort int, updateSort string, classifyType uint8) (err error) {
+	sql := ` update edb_public_classify set sort = ` + updateSort + ` WHERE parent_id=? AND sort > ? AND classify_type = ? `
+	if classifyId > 0 {
+		sql += ` or ( edb_public_classify_id > ` + fmt.Sprint(classifyId) + ` and sort = ` + fmt.Sprint(nowSort) + `)`
+	}
+	err = global.DmSQL["data"].Exec(sql, parentId, nowSort, classifyType).Error
+
+	return
+}
+
+// GetFirstEdbClassifyByParentId 获取当前父级分类下,且排序数相同 的排序第一条的数据
+func (m *EdbPublicClassify) GetFirstEdbClassifyByParentId(parentId int) (item *EdbPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM edb_public_classify WHERE parent_id=? order by sort asc,edb_public_classify_id asc limit 1`
+	err = o.Raw(sql, parentId).First(&item).Error
+
+	return
+}
+func (m *EdbPublicClassify) GetEdbClassifyByRootIdLevel(rootId int, classifyType uint8, orderStr string) (items []*EdbPublicClassify, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM edb_public_classify WHERE root_id=? AND classify_type = ? `
+	if orderStr != "" {
+		sql += orderStr
+	} else {
+		sql += ` order by level desc, sort asc, edb_public_classify_id asc`
+	}
+
+	err = o.Raw(sql, rootId, classifyType).Scan(&items).Error
+
+	return
+}
+func (m *EdbPublicClassify) UpdateEdbClassifyChildByParentClassifyId(classifyIds []int, rootId int, levelStep int) (err error) {
+	var pars []interface{}
+	pars = append(pars, rootId, levelStep)
+	pars = append(pars, classifyIds)
+	// 更新相关联的二级分类的parentId,和classify_name_second
+	sql := `update edb_public_classify 
+SET root_id = ?, level = level+?
+where edb_public_classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `)`
+	err = global.DmSQL["data"].Exec(sql, pars...).Error
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// UpdateEdbClassifyNameAndNamePathByOldClassifyIdPath
+// @Description: 根据源分类id全路径更新分类名称和子分类的全路径
+// @author: Roc
+// @receiver edbClassify
+// @datetime 2024-11-26 14:39:09
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func (m *EdbPublicClassify) UpdateEdbClassifyNameAndNamePathByOldClassifyIdPath(oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	// 更改子分类的完整的路径
+	if oldClassifyIdPath != `` && newClassifyNamePath != `` && newClassifyIdPath != `` {
+		sql := `UPDATE edb_public_classify SET edb_public_classify_id_path = REPLACE(edb_public_classify_id_path,?,?) ,edb_public_classify_name_path = REPLACE(edb_public_classify_name_path,?,?)  WHERE edb_public_classify_id_path LIKE ?`
+		err = global.DmSQL["data"].Exec(sql, oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(oldClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}

+ 85 - 0
models/data_manage/public_edb_info.go

@@ -0,0 +1,85 @@
+package data_manage
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+)
+
+// GetEdbInfoByPublicClassifyId
+// @Description: 根据公共分类id获取指标列表
+// @author: Roc
+// @datetime 2024-12-03 14:09:32
+// @param classifyId int
+// @param edbInfoType int
+// @param edbType int
+// @return items []*EdbClassifyItems
+// @return err error
+func GetEdbInfoByPublicClassifyId(classifyId, edbInfoType, edbType int) (items []*EdbClassifyItems, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT edb_info_id,classify_id,edb_public_classify_id,edb_name 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, public_sort sort,is_join_permission FROM edb_info WHERE edb_public_classify_id = ? AND edb_info_type = ?`
+
+	pars := []interface{}{classifyId, edbInfoType}
+
+	// 如果筛选了指标类型,那么就根据条件来
+	if edbType > 0 {
+		sql += ` AND edb_type = ? `
+		pars = append(pars, edbType)
+	}
+
+	sql += ` order by public_sort asc,edb_info_id asc `
+	err = o.Raw(sql, pars...).Scan(&items).Error
+
+	return
+}
+
+// UpdatePublicEdbSuccess
+// @Description: 更新指标的公开成功状态
+// @author: Roc
+// @datetime 2024-12-06 13:37:01
+// @param edbInfoId int
+// @param classifyId int
+// @return err error
+func UpdatePublicEdbSuccess(edbInfoId, classifyId int) (err error) {
+	sql := `UPDATE edb_info set public_status = ?,edb_public_classify_id = ? ,modify_time=now(),public_time = now()  WHERE edb_info_id  = ?`
+	err = global.DmSQL["data"].Exec(sql, utils.DataPublicSuccess, classifyId, edbInfoId).Error
+
+	return
+}
+
+// UpdatePublicEdb
+// @Description: 更新指标的公开状态
+// @author: Roc
+// @datetime 2024-12-06 11:10:53
+// @param edbInfoIdList []int
+// @param status int
+// @return err error
+func UpdatePublicEdb(edbInfoIdList []int, status int) (err error) {
+	if len(edbInfoIdList) <= 0 {
+		return
+	}
+	sql := `UPDATE edb_info set public_status = ?,modify_time=now() `
+	if status == utils.DataPublicSuccess {
+		sql += `,public_time = now() `
+	}
+	sql += ` WHERE edb_info_id in (?) `
+	err = global.DmSQL["data"].Exec(sql, status, edbInfoIdList).Error
+
+	return
+}
+
+// UpdatePublicClassifyIdByEdbInfoIdList
+// @Description: 根据指标id列表更新所属公共分类id
+// @author: Roc
+// @datetime 2024-12-10 13:18:52
+// @param edbInfoId int
+// @param edbClassifyId int
+// @return err error
+func UpdatePublicClassifyIdByEdbInfoIdList(edbInfoIdList []int, edbClassifyId int) (err error) {
+	if len(edbInfoIdList) <= 0 {
+		return
+	}
+	sql := ` UPDATE edb_info SET edb_public_classify_id = ? WHERE  edb_info_id in (?) AND public_status = 3 `
+	err = global.DmSQL["data"].Exec(sql, edbClassifyId, edbInfoIdList).Error
+
+	return
+}

+ 32 - 0
models/data_manage/request/chart_info_share.go

@@ -0,0 +1,32 @@
+package request
+
+// SetChartInfoShareReq
+// @Description: 设置指标分享人请求
+type SetChartInfoShareReq struct {
+	ChartInfoId int   `description:"指标id"`
+	UserIdList  []int `description:"分享用户id列表,如果为空,说明要给该指标移除分享人"`
+	ShareType   int8  `description:"分享类型,1:仅查看;2:可编辑"`
+}
+
+// SearchChartInfoShareReq
+// @Description: 获取指标列表(设置共享的时候)请求结构体
+type SearchChartInfoShareReq struct {
+	ChartShareList []int  `description:"指标分享状态:1-未共享;2-已共享。可多选,默认是未共享"`
+	ChartTypeList  []int  `description:"图表类型id列表"`
+	Keyword        string `description:"关键字"`
+	ClassifyIdList []int  `description:"分类选择,如果不指定分类,那么就是所有分类"`
+	CurrentIndex   int    `description:"当前页页码,从1开始"`
+	PageSize       int    `description:"每页数据条数"`
+}
+
+// SetChartSharePermissionReq
+// @Description: 设置数据权限请求
+type SetChartSharePermissionReq struct {
+	SearchChartInfoShareReq
+	ChartIdList   []int `description:"选中的指标id列表"`
+	NoChartIdList []int `description:"未选中的指标id列表"`
+	IsSelectAll   bool  `description:"是否选择所有指标"`
+
+	UserIdList []int `description:"分享用户id列表,如果为空,说明要给该指标移除分享人"`
+	ShareType  int8  `description:"分享类型,1:仅查看;2:可编辑"`
+}

+ 24 - 0
models/data_manage/request/collect_edb.go

@@ -0,0 +1,24 @@
+package request
+
+// BatchEdbCollectReq 批量加入收藏
+type BatchEdbCollectReq struct {
+	GeneralEdbEsSearchReq
+	EdbIdList             []int `description:"选中的指标id列表"`
+	NoEdbIdList           []int `description:"未选中的指标id列表"`
+	IsSelectAll           bool  `description:"是否选择所有指标"`
+	CollectClassifyIdList []int `description:"收藏分类ID列表"`
+}
+
+// GeneralEdbEsSearchReq 指标通用es搜索参数
+type GeneralEdbEsSearchReq struct {
+	FilterSource int    `description:"搜索来源:1:其他搜索,2:累计值转月值搜索,3:变频,4:基础指标,5:同比"`
+	ClassifyId   int    `description:"父级分类id"`
+	Source       int    `description:"来源"`
+	EdbAuth      int    `description:"指标权限范围,0-全部;1-我的;2-公共"`
+	EdbCollect   int    `description:"指标收藏状态:0-全部;1-已收藏"`
+	Frequency    string `description:"频度"`
+	NotFrequency string `description:"不需要的频度"`
+	EdbType      string `description:"指标类型:0-基础和计算;1-基础指标;2-计算指标;3-预测指标"`
+	Keyword      string `description:"关键字"`
+	KeyWord      string `description:"关键字"`
+}

+ 32 - 0
models/data_manage/request/edb_info_share.go

@@ -0,0 +1,32 @@
+package request
+
+// SetEdbInfoShareReq
+// @Description: 设置指标分享人请求
+type SetEdbInfoShareReq struct {
+	EdbInfoId  int   `description:"指标id"`
+	UserIdList []int `description:"分享用户id列表,如果为空,说明要给该指标移除分享人"`
+	ShareType  int8  `description:"分享类型,1:仅查看;2:可编辑"`
+}
+
+// SearchEdbInfoShareReq
+// @Description: 获取指标列表(设置共享的时候)请求结构体
+type SearchEdbInfoShareReq struct {
+	EdbShareList   []int  `description:"指标分享状态:1-未共享;2-已共享。可多选,默认是未共享"`
+	SourceList     []int  `description:"来源id"`
+	Keyword        string `description:"关键字"`
+	ClassifyIdList []int  `description:"分类选择,如果不指定分类,那么就是所有分类"`
+	CurrentIndex   int    `description:"当前页页码,从1开始"`
+	PageSize       int    `description:"每页数据条数"`
+}
+
+// SetEdbSharePermissionReq
+// @Description: 设置数据权限请求
+type SetEdbSharePermissionReq struct {
+	SearchEdbInfoShareReq
+	EdbIdList   []int `description:"选中的指标id列表"`
+	NoEdbIdList []int `description:"未选中的指标id列表"`
+	IsSelectAll bool  `description:"是否选择所有指标"`
+
+	UserIdList []int `description:"分享用户id列表,如果为空,说明要给该指标移除分享人"`
+	ShareType  int8  `description:"分享类型,1:仅查看;2:可编辑"`
+}

+ 57 - 0
models/data_manage/request/public_chart.go

@@ -0,0 +1,57 @@
+package request
+
+// PublicChartClassifyDeleteCheckReq
+// @Description: 公共图表分类删除请求
+type PublicChartClassifyDeleteCheckReq struct {
+	ChartClassifyId int `description:"分类id"`
+}
+
+// SetChartPublicReq
+// @Description: 设置图表公开的请求
+type SetChartPublicReq struct {
+	ChartInfoList []SetChartPublicChartReq `description:"待设置的图表"`
+	Description   string                   `description:"备注"`
+}
+
+// CancelChartPublicReq
+// @Description: 撤销图表公开的请求
+type CancelChartPublicReq struct {
+	ChartInfoId int    `description:"待设置的图表"`
+	Description string `description:"备注"`
+}
+
+type SetChartPublicChartReq struct {
+	ChartInfoId int `description:"图表id列表"`
+	ClassifyId  int `description:"公共分类id"`
+}
+
+// SearchPublicChartReq
+// @Description: 获取图表列表(设置公开的时候)请求结构体
+type SearchPublicChartReq struct {
+	ChartPublicList      []int  `description:"图表公开状态:1:未公开,2:已提交;3:已公开。可多选,默认是未公开"`
+	ChartTypeList        []int  `description:"图表类型id列表"`
+	Keyword              string `description:"关键字"`
+	ClassifyIdList       []int  `description:"图表分类选择,如果不指定分类,那么就是所有分类"`
+	PublicClassifyIdList []int  `description:"图表所属公共分类id,如果不指定分类,那么就是所有分类"`
+	CurrentIndex         int    `description:"当前页页码,从1开始"`
+	PageSize             int    `description:"每页数据条数"`
+}
+
+// AllSearchPublicChartReq
+// @Description: 获取所有图表列表(设置公开的时候)请求结构体
+type AllSearchPublicChartReq struct {
+	SearchPublicChartReq
+	ChartIdList   []int `description:"选中的图表id列表"`
+	NoChartIdList []int `description:"未选中的图表id列表"`
+	IsSelectAll   bool  `description:"是否选择所有图表"`
+}
+
+// MoveChartClassifyReq
+// @Description: 移动图表分类的请求结构体
+type MoveChartClassifyReq struct {
+	SearchPublicChartReq
+	ChartIdList   []int `description:"选中的图表id列表"`
+	NoChartIdList []int `description:"未选中的图表id列表"`
+	IsSelectAll   bool  `description:"是否选择所有图表"`
+	NewClassifyId int   `description:"新的分类id"`
+}

+ 57 - 0
models/data_manage/request/public_edb.go

@@ -0,0 +1,57 @@
+package request
+
+// PublicClassifyDeleteCheckReq
+// @Description: 公共分类删除请求
+type PublicClassifyDeleteCheckReq struct {
+	ClassifyId int `description:"分类id"`
+}
+
+// SetEdbPublicReq
+// @Description: 设置指标公开的请求
+type SetEdbPublicReq struct {
+	EdbInfoList []SetEdbPublicEdbReq `description:"待设置的指标"`
+	Description string               `description:"备注"`
+}
+
+// CancelEdbPublicReq
+// @Description: 撤销指标公开的请求
+type CancelEdbPublicReq struct {
+	EdbInfoId   int    `description:"待设置的指标"`
+	Description string `description:"备注"`
+}
+
+type SetEdbPublicEdbReq struct {
+	EdbInfoId  int `description:"指标id列表"`
+	ClassifyId int `description:"公共分类id"`
+}
+
+// SearchPublicEdbReq
+// @Description: 获取指标列表(设置公开的时候)请求结构体
+type SearchPublicEdbReq struct {
+	EdbPublicList        []int  `description:"指标公开状态:1:未公开,2:已提交;3:已公开。可多选,默认是未公开"`
+	SourceList           []int  `description:"来源id"`
+	Keyword              string `description:"关键字"`
+	ClassifyIdList       []int  `description:"指标分类选择,如果不指定分类,那么就是所有分类"`
+	PublicClassifyIdList []int  `description:"指标所属公共分类id,如果不指定分类,那么就是所有分类"`
+	CurrentIndex         int    `description:"当前页页码,从1开始"`
+	PageSize             int    `description:"每页数据条数"`
+}
+
+// AllSearchPublicEdbReq
+// @Description: 获取所有指标列表(设置公开的时候)请求结构体
+type AllSearchPublicEdbReq struct {
+	SearchPublicEdbReq
+	EdbIdList   []int `description:"选中的指标id列表"`
+	NoEdbIdList []int `description:"未选中的指标id列表"`
+	IsSelectAll bool  `description:"是否选择所有指标"`
+}
+
+// MoveEdbClassifyReq
+// @Description: 移动指标分类的请求结构体
+type MoveEdbClassifyReq struct {
+	SearchPublicEdbReq
+	EdbIdList     []int `description:"选中的指标id列表"`
+	NoEdbIdList   []int `description:"未选中的指标id列表"`
+	IsSelectAll   bool  `description:"是否选择所有指标"`
+	NewClassifyId int   `description:"新的分类id"`
+}

+ 11 - 0
models/data_manage/response/chart.go

@@ -1,7 +1,18 @@
 package response
 
+import (
+	"eta_gn/eta_api/models/data_manage"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
 // ChartRefreshResp
 // @Description: 图表更新结果
 type ChartRefreshResp struct {
 	RefreshResult bool `description:"刷新结果"`
 }
+
+// ChartInfoChartListResp ETA图库列表返回数据
+type ChartInfoChartListResp struct {
+	Paging *paging.PagingItem
+	List   []*data_manage.ChartInfoView
+}

+ 16 - 0
models/data_manage/response/chart_info_share.go

@@ -0,0 +1,16 @@
+package response
+
+import "eta_gn/eta_api/models/data_manage"
+
+// ChartInfoShareUserResp
+// @Description: 获取指标分享用户列表
+type ChartInfoShareUserResp struct {
+	List []*data_manage.ChartInfoShare `description:"分享用户列表"`
+}
+
+// ChartShareListResp
+// @Description: 共享列表
+type ChartShareListResp struct {
+	Send     data_manage.UserShareChartClassifyItemList
+	Received data_manage.UserShareChartClassifyItemList `description:"收到的共享"`
+}

+ 16 - 0
models/data_manage/response/edb_info_share.go

@@ -0,0 +1,16 @@
+package response
+
+import "eta_gn/eta_api/models/data_manage"
+
+// EdbInfoShareUserResp
+// @Description: 获取指标分享用户列表
+type EdbInfoShareUserResp struct {
+	List []*data_manage.EdbInfoShare `description:"分享用户列表"`
+}
+
+// EdbShareListResp
+// @Description: 共享列表
+type EdbShareListResp struct {
+	Send     data_manage.UserShareEdbClassifyItemList
+	Received data_manage.UserShareEdbClassifyItemList `description:"收到的共享"`
+}

+ 2 - 2
models/report_v2.go

@@ -351,12 +351,12 @@ func GetReportListCountByAuthorized(condition string, pars []interface{}) (count
 // @return items []*ReportList
 // @return err error
 func GetReportListByAuthorized(condition string, pars []interface{}, startSize, pageSize int) (items []*ReportList, err error) {
-	sql := `SELECT id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter,publish_time,report_create_time FROM report as a WHERE 1=1  `
+	sql := `SELECT id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter,publish_time,report_create_time,state FROM report as a WHERE 1=1  `
 	if condition != "" {
 		sql += condition
 	}
 	// 排序:1:未发布;2:已发布;3-待提交;4-待审批;5-已驳回;6-已通过
-	sql += ` GROUP BY id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter,publish_time,report_create_time
+	sql += ` GROUP BY id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter,publish_time,report_create_time,state
             ORDER BY  report_create_time DESC LIMIT ?,?`
 	pars = append(pars, startSize)
 	pars = append(pars, pageSize)

+ 540 - 0
routers/commentsRouter.go

@@ -862,6 +862,96 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "Approve",
+            Router: `/approve`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "CheckApproveOpen",
+            Router: `/check_open`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "MessageList",
+            Router: `/message/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "MessageRead",
+            Router: `/message/read`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "Refuse",
+            Router: `/refuse`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/flow/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/flow/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_manage_permission:DataMangePermissionController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_manage_permission:DataMangePermissionController"],
         beego.ControllerComments{
             Method: "MoveAllEdbChartUser",
@@ -2743,6 +2833,96 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/chart_collect/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/chart_collect/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/chart_collect/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Move",
+            Router: `/chart_collect/classify/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Remove",
+            Router: `/chart_collect/classify/remove`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectClassifyController"],
+        beego.ControllerComments{
+            Method: "Tree",
+            Router: `/chart_collect/classify/tree`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectController"],
+        beego.ControllerComments{
+            Method: "CancelCollect",
+            Router: `/chart_collect/cancel_collect`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectController"],
+        beego.ControllerComments{
+            Method: "Collect",
+            Router: `/chart_collect/collect`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/chart_collect/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartCollectController"],
+        beego.ControllerComments{
+            Method: "Move",
+            Router: `/chart_collect/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartFrameworkController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartFrameworkController"],
         beego.ControllerComments{
             Method: "Add",
@@ -2851,6 +3031,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoController"],
+        beego.ControllerComments{
+            Method: "BatchMove",
+            Router: `/chart_info/batch_move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoController"],
         beego.ControllerComments{
             Method: "CommonChartInfoDetailFromUniqueCode",
@@ -3337,6 +3526,168 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"],
+        beego.ControllerComments{
+            Method: "BatchSave",
+            Router: `/chart_info/share/batch_save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/chart_info/share/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"],
+        beego.ControllerComments{
+            Method: "ListByEs",
+            Router: `/chart_info/share/list/es`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/chart_info/share/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"],
+        beego.ControllerComments{
+            Method: "Tree",
+            Router: `/chart_info/share/tree`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartInfoShareController"],
+        beego.ControllerComments{
+            Method: "UserList",
+            Router: `/chart_info/share/user_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "ChartClassifyMove",
+            Router: `/chart_public/chart_classify/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "AddClassify",
+            Router: `/chart_public/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "DeleteClassify",
+            Router: `/chart_public/classify/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "DeleteClassifyCheck",
+            Router: `/chart_public/classify/delete/check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "EditChartClassify",
+            Router: `/chart_public/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "SimpleList",
+            Router: `/chart_public/classify/simple`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "ClassifyTree",
+            Router: `/chart_public/classify/tree`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"],
+        beego.ControllerComments{
+            Method: "BatchMove",
+            Router: `/chart_info/public/batch_move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/chart_info/public/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"],
+        beego.ControllerComments{
+            Method: "ListByEs",
+            Router: `/chart_info/public/list/es`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"],
+        beego.ControllerComments{
+            Method: "AllListByEs",
+            Router: `/chart_info/public/list/es/all`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartPublicController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/chart_info/public/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:ChartThemeController"],
         beego.ControllerComments{
             Method: "Add",
@@ -3634,6 +3985,15 @@ func init() {
             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: "BatchCollect",
+            Router: `/edb_collect/batch_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: "CancelCollect",
@@ -3742,6 +4102,15 @@ func init() {
             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: "BatchMoveEdb",
+            Router: `/edb_info/batch_move`,
+            AllowHTTPMethods: []string{"post"},
+            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: "EdbChartList",
@@ -4183,6 +4552,177 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"],
+        beego.ControllerComments{
+            Method: "BatchSave",
+            Router: `/edb_info/share/batch_save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/edb_info/share/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"],
+        beego.ControllerComments{
+            Method: "ListByEs",
+            Router: `/edb_info/share/list/es`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/edb_info/share/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"],
+        beego.ControllerComments{
+            Method: "Tree",
+            Router: `/edb_info/share/tree`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"],
+        beego.ControllerComments{
+            Method: "UserList",
+            Router: `/edb_info/share/user_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "AddClassify",
+            Router: `/edb_public/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "DeleteClassify",
+            Router: `/edb_public/classify/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "DeleteClassifyCheck",
+            Router: `/edb_public/classify/delete/check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "EditEdbClassify",
+            Router: `/edb_public/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "ListV2",
+            Router: `/edb_public/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "SimpleList",
+            Router: `/edb_public/classify/simple`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "ClassifyTree",
+            Router: `/edb_public/classify/tree`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
+        beego.ControllerComments{
+            Method: "EdbClassifyMove",
+            Router: `/edb_public/edb_classify/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "BatchMoveEdb",
+            Router: `/edb_info/public/batch_move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/edb_info/public/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "ListByEs",
+            Router: `/edb_info/public/list/es`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "AllListByEs",
+            Router: `/edb_info/public/list/es/all`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/edb_info/public/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:FactorEdbSeriesController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:FactorEdbSeriesController"],
         beego.ControllerComments{
             Method: "Add",

+ 15 - 0
routers/router.go

@@ -14,6 +14,7 @@ import (
 	"eta_gn/eta_api/controllers/data_manage"
 	"eta_gn/eta_api/controllers/data_manage/correlation"
 	"eta_gn/eta_api/controllers/data_manage/cross_variety"
+	"eta_gn/eta_api/controllers/data_manage/data_approve"
 	"eta_gn/eta_api/controllers/data_manage/data_manage_permission"
 	"eta_gn/eta_api/controllers/data_manage/excel"
 	future_good2 "eta_gn/eta_api/controllers/data_manage/future_good"
@@ -161,6 +162,20 @@ func init() {
 				&data_manage.FactorEdbSeriesController{},
 				&data_manage.EdbCollectController{},
 				&data_manage.EdbCollectClassifyController{},
+				&data_manage.EdbInfoShareController{},
+				&data_manage.EdbPublicController{},
+				&data_manage.EdbPublicClassifyController{},
+				&data_manage.ChartInfoShareController{},
+				&data_manage.ChartPublicController{},
+				&data_manage.ChartPublicClassifyController{},
+				&data_manage.ChartCollectController{},
+				&data_manage.ChartCollectClassifyController{},
+			),
+			web.NSNamespace("/data_approve",
+				web.NSInclude(
+					&data_approve.DataApproveController{},
+					&data_approve.DataApproveFlowController{},
+				),
 			),
 		),
 		web.NSNamespace("/my_chart",

+ 662 - 53
services/data/chart_classify.go

@@ -57,6 +57,40 @@ func ChartClassifyItemsMakeTree(sysUser *system.Admin, allNode []*data_manage.Ch
 	}
 }
 
+func ChartClassifyItemsMakeTreeV2(allNode []*data_manage.ChartClassifyItems, node *data_manage.ChartClassifyItems) {
+	//node.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(node.IsJoinPermission, node.ChartClassifyId, permissionClassifyIdList)
+	//button := GetChartClassifyOpButton(sysUser, node.SysUserId, node.HaveOperaAuth)
+	//node.Button = button
+
+	childs, _ := chartClassifyHaveChild(allNode, node) //判断节点是否有子节点并返回
+	if len(childs) > 0 {
+		//for _, child := range childs {
+		//child.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(child.IsJoinPermission, child.ChartClassifyId, permissionClassifyIdList)
+		//childButton := GetChartClassifyOpButton(sysUser, child.SysUserId, child.HaveOperaAuth)
+		//if child.Level == 3 {
+		//	childButton.AddButton = false //第三级的话,默认图表都是没有添加按钮的
+		//}
+		//child.Button = childButton
+		//node.Children = append(node.Children, child)
+		//}
+		node.Children = append(node.Children, childs[0:]...) //添加子节点
+		for _, v := range childs {
+			//v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ChartClassifyId, permissionClassifyIdList)
+			//查询子节点的子节点,并添加到子节点
+			_, has := chartClassifyHaveChild(allNode, v)
+			if has {
+				ChartClassifyItemsMakeTreeV2(allNode, v) //递归添加节点
+			} else {
+				childrenArr := make([]*data_manage.ChartClassifyItems, 0)
+				v.Children = childrenArr
+			}
+		}
+	} else {
+		childrenArr := make([]*data_manage.ChartClassifyItems, 0)
+		node.Children = childrenArr
+	}
+}
+
 // GetChartClassifyOpButton 获取ETA图库分类的操作权限
 func GetChartClassifyOpButton(sysUser *system.Admin, belongUserId int, haveOperaAuth bool) (button data_manage.ChartClassifyItemsButton) {
 	// 没有数据权限就直接返回
@@ -76,17 +110,22 @@ func GetChartClassifyOpButton(sysUser *system.Admin, belongUserId int, haveOpera
 }
 
 // GetChartOpButton 获取ETA图库的操作权限
-func GetChartOpButton(sysUser *system.Admin, belongUserId int, haveOperaAuth bool) (button data_manage.ChartClassifyItemsButton) {
+func GetChartOpButton(sysUser *system.Admin, belongUserId, chartInfoId int, haveOperaAuth bool, editShareChartMap map[int]bool) (button data_manage.ChartClassifyItemsButton) {
 	// 数据权限判断
 	if !haveOperaAuth {
 		return
 	}
-	//预测指标的添加人对该预测指标有全部操作权限,ficc管理员、超管对所有预测指标有全部操作权限;
-	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN || sysUser.AdminId == belongUserId || sysUser.PredictEdbPermission == 1 {
-		button.AddButton = true
+
+	if sysUser.AdminId == belongUserId {
+		//button.AddButton = true
 		button.OpButton = true
 		button.DeleteButton = true
 		button.MoveButton = true
+	} else {
+		// 拥有别人分享的操作权限
+		if _, ok := editShareChartMap[chartInfoId]; ok {
+			button.OpButton = true
+		}
 	}
 
 	return
@@ -175,26 +214,26 @@ func AddChartClassify(chartClassifyName string, parentId, level, source int, lan
 	isSendEmail = true
 	errMsg = "保存分类失败"
 
-	// 校验分类名称相同的数量
-	{
-		var count int
-		switch lang {
-		case utils.EnLangVersion:
-			count, err = data_manage.GetChartClassifyEnCount(chartClassifyName, parentId, source)
-		default:
-			count, err = data_manage.GetChartClassifyCount(chartClassifyName, parentId, source)
-		}
-		if err != nil {
-			errMsg = "判断名称是否已存在失败"
-			return
-		}
-		if count > 0 {
-			errMsg = "分类名称已存在,请重新输入"
-			err = errors.New(errMsg)
-			isSendEmail = false
-			return
-		}
-	}
+	// 校验分类名称相同的数量(eta2.3,图表名称允许重复)
+	//{
+	//	var count int
+	//	switch lang {
+	//	case utils.EnLangVersion:
+	//		count, err = data_manage.GetChartClassifyEnCount(chartClassifyName, parentId, source)
+	//	default:
+	//		count, err = data_manage.GetChartClassifyCount(chartClassifyName, parentId, source)
+	//	}
+	//	if err != nil {
+	//		errMsg = "判断名称是否已存在失败"
+	//		return
+	//	}
+	//	if count > 0 {
+	//		errMsg = "分类名称已存在,请重新输入"
+	//		err = errors.New(errMsg)
+	//		isSendEmail = false
+	//		return
+	//	}
+	//}
 
 	if level > 6 {
 		errMsg = `最高只支持添加6级分类`
@@ -210,6 +249,7 @@ func AddChartClassify(chartClassifyName string, parentId, level, source int, lan
 	}
 	//查询顶级rootId
 	rootId := 0
+	var classifyNamePath, classifyIdPath string
 	if parentId > 0 {
 		parentClassify, tErr := data_manage.GetChartClassifyById(parentId)
 		if tErr != nil {
@@ -223,6 +263,10 @@ func AddChartClassify(chartClassifyName string, parentId, level, source int, lan
 			return
 		}
 		rootId = parentClassify.RootId
+		classifyNamePath = fmt.Sprint(parentClassify.ChartClassifyNamePath, "|", chartClassifyName)
+		classifyIdPath = fmt.Sprint(parentClassify.ChartClassifyIdPath, ",")
+	} else {
+		classifyNamePath = chartClassifyName
 	}
 
 	classifyInfo = new(data_manage.ChartClassify)
@@ -236,29 +280,35 @@ func AddChartClassify(chartClassifyName string, parentId, level, source int, lan
 	classifyInfo.SysUserRealName = sysUser.RealName
 	classifyInfo.Level = level + 1
 	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-	classifyInfo.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
+	classifyInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
 	classifyInfo.Sort = maxSort + 1
 	classifyInfo.Source = source
 	classifyInfo.RootId = rootId
+	classifyInfo.ChartClassifyNamePath = classifyNamePath
 
-	newId, err := data_manage.AddChartClassify(classifyInfo)
+	err = data_manage.AddChartClassify(classifyInfo)
 	if err != nil {
 		return
 	}
+
+	// 更改分类id完整路径path
+	updateCols := []string{"ClassifyIdPath"}
+	classifyInfo.ChartClassifyIdPath = fmt.Sprint(classifyIdPath, classifyInfo.ChartClassifyId)
 	if parentId == 0 { //一级目录的rootId等于自己本身
-		classifyInfo.RootId = int(newId)
-		err = classifyInfo.Update([]string{"RootId"})
-		if err != nil {
-			errMsg = "更新分类失败"
-			return
-		}
+		classifyInfo.RootId = classifyInfo.ChartClassifyId
+		updateCols = append(updateCols, "RootId")
 	}
-
-	// 目前只有ETA图库需要继承分类权限
-	if classifyInfo.Source == utils.CHART_SOURCE_DEFAULT {
-		go data_manage_permission.InheritParentClassify(5, classifyInfo.Source, classifyInfo.ChartClassifyId, classifyInfo.ParentId, classifyInfo.ChartClassifyName)
+	err = classifyInfo.Update(updateCols)
+	if err != nil {
+		errMsg = "更新分类失败"
+		return
 	}
 
+	//// 目前只有ETA图库需要继承分类权限
+	//if classifyInfo.Source == utils.CHART_SOURCE_DEFAULT {
+	//	go data_manage_permission.InheritParentClassify(5, classifyInfo.Source, classifyInfo.ChartClassifyId, classifyInfo.ParentId, classifyInfo.ChartClassifyName)
+	//}
+
 	return
 }
 
@@ -295,6 +345,8 @@ func EditChartClassify(chartClassifyId, source int, chartClassifyName, lang stri
 
 	// 需要变更的字段
 	updateCols := make([]string, 0)
+	// 旧完整路径  , 新的完整路径
+	var oldClassifyNamePath, newClassifyNamePath string
 
 	// 语言版本校验
 	switch lang {
@@ -319,27 +371,41 @@ func EditChartClassify(chartClassifyId, source int, chartClassifyName, lang stri
 		}
 	default:
 		if classifyInfo.ChartClassifyName != chartClassifyName {
-			count, tmpErr := data_manage.GetChartClassifyCount(chartClassifyName, classifyInfo.ParentId, source)
-			if tmpErr != nil {
-				errMsg = "判断名称是否已存在失败"
-				err = errors.New("判断名称是否已存在失败,Err:" + tmpErr.Error())
-				return
-			}
-			if count > 0 {
-				errMsg = "分类名称已存在,请重新输入"
-				err = errors.New(errMsg)
-				isSendEmail = false
-				return
+			//count, tmpErr := data_manage.GetChartClassifyCount(chartClassifyName, classifyInfo.ParentId, source)
+			//if tmpErr != nil {
+			//	errMsg = "判断名称是否已存在失败"
+			//	err = errors.New("判断名称是否已存在失败,Err:" + tmpErr.Error())
+			//	return
+			//}
+			//if count > 0 {
+			//	errMsg = "分类名称已存在,请重新输入"
+			//	err = errors.New(errMsg)
+			//	isSendEmail = false
+			//	return
+			//}
+			// 旧完整路径
+			oldClassifyNamePath = classifyInfo.ChartClassifyNamePath
+
+			if classifyInfo.ParentId > 0 {
+				parentItem, tmpErr := data_manage.GetChartClassifyById(classifyInfo.ParentId)
+				if tmpErr != nil {
+					err = tmpErr
+					return
+				}
+				newClassifyNamePath = fmt.Sprint(parentItem.ChartClassifyNamePath, "|", chartClassifyName)
+			} else {
+				newClassifyNamePath = chartClassifyName
 			}
 
 			classifyInfo.ChartClassifyName = chartClassifyName
 			classifyInfo.ModifyTime = time.Now()
-			updateCols = append(updateCols, "ChartClassifyName", "ModifyTime")
+			classifyInfo.ChartClassifyNamePath = newClassifyNamePath
+			updateCols = append(updateCols, "ChartClassifyName", "ModifyTime", "ChartClassifyNamePath")
 		}
 	}
 
 	if len(updateCols) > 0 {
-		err = classifyInfo.Update(updateCols)
+		err = classifyInfo.UpdateClassifyNameAndNamePath(updateCols, oldClassifyNamePath, newClassifyNamePath)
 	}
 
 	return
@@ -465,8 +531,15 @@ func MoveChartClassify(req data_manage.MoveChartClassifyReq, sysUser *system.Adm
 			}
 		}
 
+		editShareChartInfoIdMap, tmpErr := GetAllEditSharedChartInfoIdMapByReceivedUserIdAndChartInfoIdList(sysUser.AdminId, []int{chartInfo.ChartInfoId})
+		if tmpErr != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取所有有编辑权限的分享图表失败,Err:" + tmpErr.Error())
+			return
+		}
+
 		// 移动权限校验
-		button := GetChartOpButton(sysUser, chartInfo.SysUserId, haveOperaAuth)
+		button := GetChartOpButton(sysUser, chartInfo.SysUserId, chartInfo.ChartInfoId, haveOperaAuth, editShareChartInfoIdMap)
 		if !button.MoveButton {
 			errMsg = "无操作权限"
 			err = errors.New(errMsg)
@@ -512,12 +585,11 @@ func MoveChartClassify(req data_manage.MoveChartClassifyReq, sysUser *system.Adm
 		nextSort = nextChartInfo.Sort
 	}
 
-	err, errMsg = moveChartClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify, nextClassify, chartInfo, prevChartInfo, nextChartInfo, parentClassifyId, prevSort, nextSort, source)
+	err, errMsg = moveChartOrClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify, nextClassify, chartInfo, prevChartInfo, nextChartInfo, parentClassifyId, prevSort, nextSort, source)
 	return
 }
 
-// moveChartClassify 移动图表分类
-func moveChartClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify, nextClassify *data_manage.ChartClassify, chartInfo, prevChartInfo, nextChartInfo *data_manage.ChartInfo, parentClassifyId, prevSort, nextSort, source int) (err error, errMsg string) {
+func moveChartOrClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify, nextClassify *data_manage.ChartClassify, chartInfo, prevChartInfo, nextChartInfo *data_manage.ChartInfo, parentClassifyId, prevSort, nextSort, source int) (err error, errMsg string) {
 	updateCol := make([]string, 0)
 
 	// 移动对象为分类, 判断分类是否存在
@@ -804,6 +876,472 @@ func moveChartClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify,
 	}
 	return
 }
+func moveChart(parentChartClassifyInfo, chartClassifyInfo, prevClassify, nextClassify *data_manage.ChartClassify, chartInfo, prevChartInfo, nextChartInfo *data_manage.ChartInfo, parentClassifyId, prevSort, nextSort, source int) (err error, errMsg string) {
+	updateCol := make([]string, 0)
+
+	// 移动对象为分类, 判断分类是否存在
+	if chartClassifyInfo != nil {
+		oldParentId := chartClassifyInfo.ParentId
+		oldLevel := chartClassifyInfo.Level
+		var classifyIds []int
+		if oldParentId != parentClassifyId {
+			//更新子分类对应的level
+			childList, e, m := GetChildChartClassifyByClassifyId(chartClassifyInfo.ChartClassifyId)
+			if e != nil {
+				errMsg = "移动失败"
+				err = errors.New("查询子分类失败,Err:" + e.Error() + m)
+				return
+			}
+
+			if len(childList) > 0 {
+				for _, v := range childList {
+					if v.ChartClassifyId == chartClassifyInfo.ChartClassifyId {
+						continue
+					}
+					classifyIds = append(classifyIds, v.ChartClassifyId)
+				}
+			}
+		}
+		//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+		if chartClassifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
+			if chartClassifyInfo.Level != parentChartClassifyInfo.Level+1 { //禁止层级调整
+				errMsg = "移动失败"
+				err = errors.New("不支持目录层级变更")
+				return
+			}
+			chartClassifyInfo.ParentId = parentChartClassifyInfo.ChartClassifyId
+			chartClassifyInfo.RootId = parentChartClassifyInfo.RootId
+			chartClassifyInfo.Level = parentChartClassifyInfo.Level + 1
+			chartClassifyInfo.ModifyTime = time.Now()
+			updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime")
+		} else if chartClassifyInfo.ParentId != parentClassifyId && parentClassifyId == 0 {
+			errMsg = "移动失败"
+			err = errors.New("不支持目录层级变更")
+			return
+		}
+
+		if prevSort > 0 {
+			//如果是移动在两个兄弟节点之间
+			if nextSort > 0 {
+				//下一个兄弟节点
+				//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+				if prevSort == nextSort || prevSort == chartClassifyInfo.Sort {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 2`
+
+					//变更分类
+					if prevClassify != nil {
+						_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevClassify.Sort, updateSortStr, source)
+					} else {
+						_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source)
+					}
+
+					//变更图表
+					if prevChartInfo != nil {
+						//变更兄弟节点的排序
+						_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr)
+					} else {
+						_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr)
+					}
+				} else {
+					//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+					if nextSort-prevSort == 1 {
+						//变更兄弟节点的排序
+						updateSortStr := `sort + 1`
+
+						//变更分类
+						if prevClassify != nil {
+							_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevSort, updateSortStr, source)
+						} else {
+							_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source)
+						}
+
+						//变更图表
+						if prevChartInfo != nil {
+							//变更兄弟节点的排序
+							_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr)
+						} else {
+							_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr)
+						}
+
+					}
+				}
+			}
+
+			chartClassifyInfo.Sort = prevSort + 1
+			chartClassifyInfo.ModifyTime = time.Now()
+			updateCol = append(updateCol, "Sort", "ModifyTime")
+		} else if prevClassify == nil && nextClassify == nil && prevChartInfo == nil && nextChartInfo == nil && parentClassifyId > 0 {
+			//处理只拖动到目录里,默认放到目录底部的情况
+			var maxSort int
+			maxSort, err = GetChartClassifyMaxSort(parentClassifyId, source)
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+				return
+			}
+			chartClassifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+			chartClassifyInfo.ModifyTime = time.Now()
+			updateCol = append(updateCol, "Sort", "ModifyTime")
+		} else {
+			// 拖动到父级分类的第一位
+			firstClassify, tmpErr := data_manage.GetFirstChartClassifyByParentId(parentClassifyId)
+			if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+				errMsg = "移动失败"
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+				return
+			}
+
+			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+			if firstClassify != nil && firstClassify.ChartClassifyId > 0 && firstClassify.Sort == 0 {
+				updateSortStr := ` sort + 1 `
+				_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, firstClassify.ChartClassifyId-1, 0, updateSortStr, source)
+				//该分类下的所有图表也需要+1
+				_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, 0, updateSortStr)
+			} else {
+				//如果该分类下存在图表,且第一个图表的排序等于0,那么需要调整排序
+				firstEdb, tErr := data_manage.GetFirstChartInfoByClassifyId(parentClassifyId)
+				if tErr != nil && !utils.IsErrNoRow(tErr) {
+					errMsg = "移动失败"
+					err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
+					return
+				}
+
+				//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+				if firstEdb != nil && firstEdb.ChartClassifyId > 0 && firstEdb.Sort == 0 {
+					updateSortStr := ` sort + 1 `
+					_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, firstEdb.ChartInfoId-1, updateSortStr)
+					_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, 0, updateSortStr, source)
+				}
+			}
+
+			chartClassifyInfo.Sort = 0 //那就是排在第一位
+			chartClassifyInfo.ModifyTime = time.Now()
+			updateCol = append(updateCol, "Sort", "ModifyTime")
+		}
+
+		//更新
+		if len(updateCol) > 0 {
+			err = chartClassifyInfo.Update(updateCol)
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("修改失败,Err:" + err.Error())
+				return
+			}
+			//更新对应分类的root_id和层级
+			if oldParentId != parentClassifyId {
+				if len(classifyIds) > 0 {
+					levelStep := chartClassifyInfo.Level - oldLevel
+					err = data_manage.UpdateEdbClassifyChildByParentClassifyId(classifyIds, chartClassifyInfo.RootId, levelStep)
+					if err != nil {
+						errMsg = "移动失败"
+						err = errors.New("更新子分类失败,Err:" + err.Error())
+						return
+					}
+				}
+			}
+		}
+	} else {
+		if chartInfo == nil {
+			errMsg = "当前图表不存在"
+			err = errors.New(errMsg)
+			return
+		}
+		//如果改变了分类,那么移动该图表数据
+		if chartInfo.ChartClassifyId != parentClassifyId {
+			chartInfo.ChartClassifyId = parentClassifyId
+			chartInfo.ModifyTime = time.Now()
+			updateCol = append(updateCol, "ChartClassifyId", "ModifyTime")
+		}
+		if prevSort > 0 {
+			//如果是移动在两个兄弟节点之间
+			if nextSort > 0 {
+				//下一个兄弟节点
+				//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+				if prevSort == nextSort || prevSort == chartInfo.Sort {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 2`
+
+					//变更分类
+					if prevClassify != nil {
+						_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevClassify.Sort, updateSortStr, source)
+					} else {
+						_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source)
+					}
+
+					//变更图表
+					if prevChartInfo != nil {
+						//变更兄弟节点的排序
+						_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr)
+					} else {
+						_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr)
+					}
+				} else {
+					//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+					if nextSort-prevSort == 1 {
+						//变更兄弟节点的排序
+						updateSortStr := `sort + 1`
+						//变更分类
+						if prevClassify != nil {
+							_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevSort, updateSortStr, source)
+						} else {
+							_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source)
+						}
+
+						//变更图表
+						if prevChartInfo != nil {
+							//变更兄弟节点的排序
+							_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr)
+						} else {
+							_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr)
+						}
+					}
+				}
+			}
+
+			chartInfo.Sort = prevSort + 1
+			chartInfo.ModifyTime = time.Now()
+			updateCol = append(updateCol, "Sort", "ModifyTime")
+		} else if prevClassify == nil && nextClassify == nil && prevChartInfo == nil && nextChartInfo == nil && parentClassifyId > 0 {
+			//处理只拖动到目录里,默认放到目录底部的情况
+			var maxSort int
+			maxSort, err = GetChartClassifyMaxSort(parentClassifyId, source)
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+				return
+			}
+			chartInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+			chartInfo.ModifyTime = time.Now()
+			updateCol = append(updateCol, "Sort", "ModifyTime")
+		} else {
+			// 拖动到父级分类的第一位
+			firstClassify, tmpErr := data_manage.GetFirstChartClassifyByParentId(parentClassifyId)
+			if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+				errMsg = "移动失败"
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+				return
+			}
+
+			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+			if firstClassify != nil && firstClassify.ChartClassifyId > 0 && firstClassify.Sort == 0 {
+				updateSortStr := ` sort + 1 `
+				_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, firstClassify.ChartClassifyId-1, 0, updateSortStr, source)
+				//该分类下的所有图表也需要+1
+				_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, 0, updateSortStr)
+			} else {
+				//如果该分类下存在图表,且第一个图表的排序等于0,那么需要调整排序
+				firstEdb, tErr := data_manage.GetFirstChartInfoByClassifyId(parentClassifyId)
+				if tErr != nil && !utils.IsErrNoRow(tErr) {
+					errMsg = "移动失败"
+					err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
+					return
+				}
+
+				//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+				if firstEdb != nil && firstEdb.ChartClassifyId > 0 && firstEdb.Sort == 0 {
+					updateSortStr := ` sort + 1 `
+					_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, firstEdb.ChartInfoId-1, updateSortStr)
+					_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, 0, updateSortStr, source)
+				}
+			}
+
+			chartInfo.Sort = 0 //那就是排在第一位
+			chartInfo.ModifyTime = time.Now()
+			updateCol = append(updateCol, "Sort", "ModifyTime")
+		}
+
+		//更新
+		if len(updateCol) > 0 {
+			err = chartInfo.Update(updateCol)
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("修改失败,Err:" + err.Error())
+				return
+			}
+		}
+	}
+	return
+}
+
+// moveChartClassify 移动图表分类
+func moveChartClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify, nextClassify *data_manage.ChartClassify, prevChartInfo, nextChartInfo *data_manage.ChartInfo, parentClassifyId, prevSort, nextSort, source int) (err error, errMsg string) {
+	updateCol := make([]string, 0)
+
+	oldParentId := chartClassifyInfo.ParentId
+	oldLevel := chartClassifyInfo.Level
+	var classifyIds []int
+	if oldParentId != parentClassifyId {
+		//更新子分类对应的level
+		childList, e, m := GetChildChartClassifyByClassifyId(chartClassifyInfo.ChartClassifyId)
+		if e != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询子分类失败,Err:" + e.Error() + m)
+			return
+		}
+
+		if len(childList) > 0 {
+			for _, v := range childList {
+				if v.ChartClassifyId == chartClassifyInfo.ChartClassifyId {
+					continue
+				}
+				classifyIds = append(classifyIds, v.ChartClassifyId)
+			}
+		}
+	}
+	//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	if chartClassifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
+		if chartClassifyInfo.Level != parentChartClassifyInfo.Level+1 { //禁止层级调整
+			errMsg = "移动失败"
+			err = errors.New("不支持目录层级变更")
+			return
+		}
+		chartClassifyInfo.ParentId = parentChartClassifyInfo.ChartClassifyId
+		chartClassifyInfo.RootId = parentChartClassifyInfo.RootId
+		chartClassifyInfo.Level = parentChartClassifyInfo.Level + 1
+		chartClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime")
+	} else if chartClassifyInfo.ParentId != parentClassifyId && parentClassifyId == 0 {
+		errMsg = "移动失败"
+		err = errors.New("不支持目录层级变更")
+		return
+	}
+
+	if prevSort > 0 {
+		//如果是移动在两个兄弟节点之间
+		if nextSort > 0 {
+			//下一个兄弟节点
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevSort == nextSort || prevSort == chartClassifyInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+
+				//变更分类
+				if prevClassify != nil {
+					_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevClassify.Sort, updateSortStr, source)
+				} else {
+					_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source)
+				}
+
+				//变更图表
+				if prevChartInfo != nil {
+					//变更兄弟节点的排序
+					_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr)
+				} else {
+					_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr)
+				}
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextSort-prevSort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+
+					//变更分类
+					if prevClassify != nil {
+						_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevSort, updateSortStr, source)
+					} else {
+						_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source)
+					}
+
+					//变更图表
+					if prevChartInfo != nil {
+						//变更兄弟节点的排序
+						_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr)
+					} else {
+						_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr)
+					}
+
+				}
+			}
+		}
+
+		chartClassifyInfo.Sort = prevSort + 1
+		chartClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else if prevClassify == nil && nextClassify == nil && prevChartInfo == nil && nextChartInfo == nil && parentClassifyId > 0 {
+		//处理只拖动到目录里,默认放到目录底部的情况
+		var maxSort int
+		maxSort, err = GetChartClassifyMaxSort(parentClassifyId, source)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+			return
+		}
+		chartClassifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+		chartClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, tmpErr := data_manage.GetFirstChartClassifyByParentId(parentClassifyId)
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.ChartClassifyId > 0 && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, firstClassify.ChartClassifyId-1, 0, updateSortStr, source)
+			//该分类下的所有图表也需要+1
+			_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, 0, updateSortStr)
+		} else {
+			//如果该分类下存在图表,且第一个图表的排序等于0,那么需要调整排序
+			firstEdb, tErr := data_manage.GetFirstChartInfoByClassifyId(parentClassifyId)
+			if tErr != nil && !utils.IsErrNoRow(tErr) {
+				errMsg = "移动失败"
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
+				return
+			}
+
+			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+			if firstEdb != nil && firstEdb.ChartClassifyId > 0 && firstEdb.Sort == 0 {
+				updateSortStr := ` sort + 1 `
+				_ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, firstEdb.ChartInfoId-1, updateSortStr)
+				_ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, 0, updateSortStr, source)
+			}
+		}
+
+		chartClassifyInfo.Sort = 0 //那就是排在第一位
+		chartClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	oldClassifyIdPath := chartClassifyInfo.ChartClassifyIdPath
+	oldClassifyNamePath := chartClassifyInfo.ChartClassifyNamePath
+	newClassifyNamePath := fmt.Sprint(chartClassifyInfo.ChartClassifyNamePath, `|`, chartClassifyInfo.ChartClassifyName)
+	newClassifyIdPath := fmt.Sprint(chartClassifyInfo.ChartClassifyIdPath, `,`, chartClassifyInfo.ChartClassifyId)
+
+	//更新
+	if len(updateCol) > 0 {
+		err = chartClassifyInfo.Update(updateCol)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("修改失败,Err:" + err.Error())
+			return
+		}
+		//更新对应分类的root_id和层级
+		if oldParentId != parentClassifyId {
+			if len(classifyIds) > 0 {
+				levelStep := chartClassifyInfo.Level - oldLevel
+				err = data_manage.UpdateEdbClassifyChildByParentClassifyId(classifyIds, chartClassifyInfo.RootId, levelStep)
+				if err != nil {
+					errMsg = "移动失败"
+					err = errors.New("更新子分类失败,Err:" + err.Error())
+					return
+				}
+			}
+
+			// 更改了上级分类,那么需要同步去更改自己的分类全路径
+			tmpErr := data_manage.UpdateChartClassifyNameAndNamePathByOldClassifyIdPath(oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath)
+			if tmpErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("更新图表分类全路径失败,分类id:%d;失败原因Err:%s", chartClassifyInfo.ChartClassifyId, tmpErr.Error()))
+			}
+		}
+	}
+
+	return
+}
 
 func GetChildChartClassifyByClassifyId(targetClassifyId int) (targetList []*data_manage.ChartClassifyIdItems, err error, errMsg string) {
 	//判断是否是挂在顶级目录下
@@ -884,6 +1422,49 @@ func GetChartClassifyTreeRecursive(list []*data_manage.ChartClassifyItems, paren
 	return res
 }
 
+// GetChartClassifyTreeRecursiveAndInsert
+// @Description: 递归获取分类树形结构,同时根据分类id插入对应的图表数据
+// @author: Roc
+// @datetime 2024-12-12 14:42:28
+// @param list []*data_manage.ChartClassifyItems
+// @param parentId int
+// @param chartClassifyItemListMap map[int][]*data_manage.ChartClassifyItems
+// @return []*data_manage.ChartClassifyItems
+func GetChartClassifyTreeRecursiveAndInsert(list []*data_manage.ChartClassifyItems, parentId int, chartClassifyItemListMap map[int][]*data_manage.ChartClassifyItems) []*data_manage.ChartClassifyItems {
+	// 先获取树形结构
+	list = GetChartClassifyTreeRecursive(list, parentId)
+
+	// 将图表数据插入到分类树中
+	InsertChartClassifyItemsToClassifyTree(list, chartClassifyItemListMap)
+
+	return list
+}
+
+// InsertChartClassifyItemsToClassifyTree
+// @Description: 递归将图表数据插入到分类树中
+// @author: Roc
+// @datetime 2024-12-12 14:42:00
+// @param list []*data_manage.ChartClassifyItems
+// @param chartClassifyItemListMap map[int][]*data_manage.ChartClassifyItems
+// @return []*data_manage.ChartClassifyItems
+func InsertChartClassifyItemsToClassifyTree(list []*data_manage.ChartClassifyItems, chartClassifyItemListMap map[int][]*data_manage.ChartClassifyItems) []*data_manage.ChartClassifyItems {
+	for k, v := range list {
+		children := v.Children
+		if children != nil {
+			children = InsertChartClassifyItemsToClassifyTree(children, chartClassifyItemListMap)
+		} else {
+			children = make([]*data_manage.ChartClassifyItems, 0)
+		}
+
+		if chartClassifyItemList, ok := chartClassifyItemListMap[v.ChartClassifyId]; ok {
+			children = append(children, chartClassifyItemList...)
+		}
+		list[k].Children = children
+	}
+
+	return list
+}
+
 // GetChartClassifyParentRecursive 根据子目录递归父级目录
 func GetChartClassifyParentRecursive(list []*data_manage.ChartClassifyItems, classifyId int) []*data_manage.ChartClassifyItems {
 	res := make([]*data_manage.ChartClassifyItems, 0)
@@ -906,3 +1487,31 @@ func GetChartClassifyChildIds(classifyId int, classifymap map[int]*data_manage.C
 		}
 	}
 }
+
+// GetAllChartChildClassifyByParentId
+// @Description: 根据上级id获取所有的下级id
+// @author: Roc
+// @datetime 2024-12-02 15:14:13
+// @param parentId int
+// @return targetList []*data_manage.EdbClassifyItems
+// @return err error
+// @return errMsg string
+func GetAllChartChildClassifyByParentId(parentId int) (targetList []*data_manage.ChartClassifyItems, err error, errMsg string) {
+	//判断是否是挂在顶级目录下
+	parentClassify, err := data_manage.GetChartClassifyById(parentId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			errMsg = "当前分类不存在"
+			err = errors.New(errMsg)
+			return
+		}
+		errMsg = "获取失败"
+		err = errors.New("获取分类信息失败,Err:" + err.Error())
+		return
+	}
+	orderStr := ` order by level asc, sort asc, chart_classify_id asc`
+
+	targetList, err = data_manage.GetChildChartClassifyListByParentId(fmt.Sprint(parentClassify.ChartClassifyIdPath, ",%"), orderStr)
+
+	return
+}

+ 2 - 2
services/data/chart_info.go

@@ -2382,7 +2382,7 @@ func AddChartInfo(req data_manage.AddChartInfoReq, sysUserId int, sysUserRealNam
 	_ = SaveChartEdbInfoRelation(edbInfoIdArr, chartInfo)
 
 	//添加es数据
-	go EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	go AddOrEditChartInfoToEs(chartInfo.ChartInfoId)
 
 	return
 }
@@ -2745,7 +2745,7 @@ func EditChartInfo(req data_manage.EditChartInfoReq, sysUser *system.Admin, lang
 	_ = SaveChartEdbInfoRelation(edbInfoIdArr, chartItem)
 
 	//添加es数据
-	go EsAddOrEditChartInfo(chartItem.ChartInfoId)
+	go AddOrEditChartInfoToEs(chartItem.ChartInfoId)
 	//修改my eta es数据
 	go EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
 

+ 29 - 8
services/data/chart_info_elastic.go

@@ -21,27 +21,41 @@ func AddAllChartInfo() {
 	}
 	total := len(allList)
 	for k, v := range allList {
-		EsAddOrEditChartInfo(v.ChartInfoId)
+		AddOrEditChartInfoToEs(v.ChartInfoId)
 		fmt.Println("剩余", total-k-1, "条图表数据,当前图表id:", v.ChartInfoId)
 	}
 }
 
-// EsAddOrEditChartInfo 新增和修改ES中的图表数据
-func EsAddOrEditChartInfo(chartInfoId int) {
+// AddOrEditChartInfoToEs 新增和修改ES中的图表数据
+func AddOrEditChartInfoToEs(chartInfoId int) {
 	var err error
 	defer func() {
 		if err != nil {
 			fmt.Println("新增和修改ES中的图表数据失败:", err.Error())
 		}
 	}()
-	itemInfo, _ := data_manage.GetChartInfoById(chartInfoId)
+	itemInfo, err := data_manage.GetChartEsInfoById(chartInfoId)
+	if err != nil {
+		return
+	}
+
+	// 获取分享人
+	obj := data_manage.ChartInfoShare{}
+	list, _ := obj.GetListByChartInfoId(itemInfo.ChartInfoId)
+	sharedList := make([]int, 0)
+	for _, v := range list {
+		sharedList = append(sharedList, v.SysUserId)
+	}
+	itemInfo.SharedUserIdList = sharedList
+
 	//添加es
-	err = elastic.EsAddOrEditChartInfoData(utils.CHART_INDEX_NAME, strconv.Itoa(itemInfo.ChartInfoId), itemInfo)
+	err = elastic.AddOrEditChartInfoToEsData(utils.CHART_INDEX_NAME, strconv.Itoa(itemInfo.ChartInfoId), itemInfo)
+
 	return
 }
 
-// EsDeleteChartInfo 删除ES中的图表数据
-func EsDeleteChartInfo(chartInfoId int) {
+// DeleteChartInfoToEs 删除ES中的图表数据
+func DeleteChartInfoToEs(chartInfoId int) {
 	var err error
 	defer func() {
 		if err != nil {
@@ -55,12 +69,15 @@ func EsDeleteChartInfo(chartInfoId int) {
 
 // EsSearchChartInfo 搜索图表信息
 func EsSearchChartInfo(keyword string, showSysId int, sourceList []int, noPermissionChartIdList []int, startSize, pageSize int) (list []*data_manage.ChartInfo, total int64, err error) {
-	list, total, err = elastic.SearchChartInfoData(utils.CHART_INDEX_NAME, keyword, showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
+	list, total, err = elastic.SearchChartInfoData(keyword, showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
 	return
 }
 
+// ###### 下面是MY ETA 相关,没有意义了
+
 // EsAddOrEditMyChartInfoByChartInfoId 根据图表id 新增和修改ES中的图表数据
 func EsAddOrEditMyChartInfoByChartInfoId(chartInfoId int) {
+	return
 	errMsg := make([]string, 0)
 	defer func() {
 		if len(errMsg) > 0 {
@@ -91,6 +108,7 @@ func EsAddOrEditMyChartInfoByChartInfoId(chartInfoId int) {
 
 // EsAddOrEditMyChartInfoByMyChartId 根据我的图库id 新增和修改ES中的图表数据
 func EsAddOrEditMyChartInfoByMyChartId(myChartId int) {
+	return
 	errMsg := make([]string, 0)
 	defer func() {
 		if len(errMsg) > 0 {
@@ -120,6 +138,7 @@ func EsAddOrEditMyChartInfoByMyChartId(myChartId int) {
 
 // EsDeleteMyChartInfoByMyChartId 根据我的图库id 删除ES中的图表数据
 func EsDeleteMyChartInfoByMyChartId(myChartId int) {
+	return
 	var err error
 	defer func() {
 		if err != nil {
@@ -133,12 +152,14 @@ func EsDeleteMyChartInfoByMyChartId(myChartId int) {
 
 // EsSearchMyChartInfo 搜索图表信息
 func EsSearchMyChartInfo(keyword string, adminId int, noPermissionChartIdList []int, startSize, pageSize int) (list []*data_manage.MyChartList, total int64, err error) {
+	return
 	list, total, err = elastic.SearchMyChartInfoData(utils.MY_CHART_INDEX_NAME, keyword, adminId, noPermissionChartIdList, startSize, pageSize)
 	return
 }
 
 // EsDeleteMyChartInfoByMyChartIds 根据我的图表IDs删除ES中的我的图表
 func EsDeleteMyChartInfoByMyChartIds(ids []int) {
+	return
 	if len(ids) == 0 {
 		return
 	}

+ 2 - 2
services/data/chart_info_excel_balance.go

@@ -475,7 +475,7 @@ func editBalanceExcelChart(req request.AddBalanceTableChartReq) (chartInfo *data
 	chartInfo.ChartInfoId = int(newId)*/
 
 	//添加es数据
-	//go EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	//go AddOrEditChartInfoToEs(chartInfo.ChartInfoId)
 
 	return
 }
@@ -1478,7 +1478,7 @@ func copyBalanceExcelChart(oldChartInfo *data_manage.ChartInfoView, sysUserId in
 	chartInfo.ChartInfoId = int(newId)*/
 
 	//添加es数据
-	//go EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	//go AddOrEditChartInfoToEs(chartInfo.ChartInfoId)
 
 	return
 }

+ 189 - 0
services/data/chart_info_share.go

@@ -0,0 +1,189 @@
+package data
+
+import (
+	"eta_gn/eta_api/models/data_manage"
+	"strconv"
+	"strings"
+)
+
+// GetAllShareChartListByFromUserId
+// @Description: 根据共享人id获取所有的图表列表
+// @author: Roc
+// @datetime 2024-12-03 10:01:49
+// @param sysUserId int
+// @return item []*data_manage.ShareChartInfoQuery
+// @return err error
+func GetAllShareChartListByFromUserId(sysUserId int) (item []*data_manage.ShareChartInfoQuery, err error) {
+	obj := data_manage.ChartInfoShare{}
+	item, err = obj.GetAllSharedChartInfoListByFromUserId(sysUserId)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// GetAllShareChartListByReceivedUserId
+// @Description: 根据接收人id获取所有的图表列表
+// @author: Roc
+// @datetime 2024-12-03 10:01:49
+// @param sysUserId int
+// @return item []*data_manage.ShareChartInfoQuery
+// @return err error
+func GetAllShareChartListByReceivedUserId(sysUserId int) (item []*data_manage.ShareChartInfoQuery, err error) {
+	obj := data_manage.ChartInfoShare{}
+	item, err = obj.GetAllSharedChartInfoListByReceivedUserId(sysUserId)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// GetChartClassifyItemListByShareChartInfoQueryList
+// @Description: 根据共享的图表来获取分类和图表的树形结构
+// @author: Roc
+// @datetime 2024-12-03 11:12:26
+// @param items []*data_manage.ShareChartInfoQuery
+// @return item data_manage.ChartClassifyItemList
+// @return err error
+func GetChartClassifyItemListByShareChartInfoQueryList(items []*data_manage.ShareChartInfoQuery) (item []*data_manage.UserShareChartClassifyItem, err error) {
+	// 所有分类
+	chartClassifyItemListMap := make(map[int][]*data_manage.ChartClassifyItems)
+	classifyIdList := make([]int, 0)
+
+	for _, v := range items {
+		chartClassifyItem := &data_manage.ChartClassifyItems{
+			ChartClassifyId:     v.ChartClassifyId,
+			ChartInfoId:         v.ChartInfoId,
+			ChartClassifyName:   v.ChartName,
+			ChartClassifyNameEn: v.ChartNameEn,
+			//ParentId:            0,
+			//Level:               0,
+			Sort:       v.Sort,
+			UniqueCode: v.UniqueCode,
+			Source:     v.Source,
+			//SourceName:          "",
+			SysUserId:       v.SysUserId,
+			SysUserRealName: v.SysUserRealName,
+			DateType:        v.DateType,
+			StartDate:       v.StartDate,
+			EndDate:         v.EndDate,
+			ChartType:       v.ChartType,
+			Calendar:        v.Calendar,
+			SeasonStartDate: v.SeasonStartDate,
+			SeasonEndDate:   v.SeasonEndDate,
+			//Children:            nil,
+			Button:           data_manage.ChartClassifyItemsButton{},
+			IsJoinPermission: v.IsJoinPermission,
+			HaveOperaAuth:    true,
+			//ChartClassifyIdPath: "",
+		}
+		chartClassifyItemList, ok := chartClassifyItemListMap[v.ChartClassifyId]
+		if !ok {
+			chartClassifyItemList = make([]*data_manage.ChartClassifyItems, 0)
+		}
+		chartClassifyItemListMap[v.ChartClassifyId] = append(chartClassifyItemList, chartClassifyItem)
+		classifyIdList = append(classifyIdList, v.ChartClassifyId)
+	}
+
+	// 组成一个分类树形结构
+	{
+		// 根据分类id获取分类
+		classifyItemsList, tmpErr := data_manage.GetChartClassifyItemsByIdList(classifyIdList)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		allClassifyIdList := make([]int, 0)
+		// 获取分类的完整路径id集合(子级、父级、顶级)
+		allClassifyIdStrList := make([]string, 0)
+		for _, v := range classifyItemsList {
+			allClassifyIdStrList = append(allClassifyIdStrList, v.ChartClassifyIdPath)
+		}
+		if len(allClassifyIdStrList) > 0 {
+			allClassifyIdStrList = strings.Split(strings.Join(allClassifyIdStrList, ","), ",")
+		}
+		for _, v := range allClassifyIdStrList {
+			classifyId, tmpErr := strconv.Atoi(v)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			allClassifyIdList = append(allClassifyIdList, classifyId)
+		}
+
+		classifyItemsList, err = data_manage.GetChartClassifyItemsByIdList(allClassifyIdList)
+		if err != nil {
+			return
+		}
+
+		tmpList := GetChartClassifyTreeRecursiveAndInsert(classifyItemsList, 0, chartClassifyItemListMap)
+
+		// 再转一下就好了
+		obj := data_manage.ChartClassifyItems{}
+		item = obj.ToUserShareChartClassifyItemByList(tmpList)
+
+		//根据sort值排序
+		//sort.Sort(item)
+	}
+
+	return
+}
+
+// GetAllEditSharedChartInfoIdListByReceivedUserId
+// @Description: 获取所有我收到的共享的、可以编辑的图表id列表
+// @author: Roc
+// @datetime 2024-12-25 14:17:10
+// @param userId int
+// @return editShareChartInfoIdList []int
+// @return err error
+func GetAllEditSharedChartInfoIdListByReceivedUserId(userId int, chartInfoIdList []int) (editShareChartInfoIdList []int, err error) {
+	shareObj := data_manage.ChartInfoShare{}
+	editShareChartInfoIdList, err = shareObj.GetAllEditSharedChartInfoIdListByReceivedUserId(userId, chartInfoIdList)
+
+	return
+}
+
+// GetAllEditSharedChartInfoIdMapByReceivedUserId
+// @Description: 获取所有我收到的共享的、可以编辑的图表id map
+// @author: Roc
+// @datetime 2024-12-25 14:19:22
+// @param userId int
+// @return editShareChartInfoIdMap map[int]bool
+// @return err error
+func GetAllEditSharedChartInfoIdMapByReceivedUserId(userId int) (editShareChartInfoIdMap map[int]bool, err error) {
+	editShareChartInfoIdMap = make(map[int]bool)
+	idList, err := GetAllEditSharedChartInfoIdListByReceivedUserId(userId, []int{})
+	if err != nil {
+		return
+	}
+
+	for _, v := range idList {
+		editShareChartInfoIdMap[v] = true
+	}
+
+	return
+}
+
+// GetAllEditSharedChartInfoIdMapByReceivedUserIdAndChartInfoIdList
+// @Description: 获取所有我收到的共享的、可以编辑的图表id map
+// @author: Roc
+// @datetime 2024-12-25 14:19:22
+// @param userId int
+// @return editShareChartInfoIdMap map[int]bool
+// @return err error
+func GetAllEditSharedChartInfoIdMapByReceivedUserIdAndChartInfoIdList(userId int, chartInfoIdList []int) (editShareChartInfoIdMap map[int]bool, err error) {
+	editShareChartInfoIdMap = make(map[int]bool)
+	idList, err := GetAllEditSharedChartInfoIdListByReceivedUserId(userId, chartInfoIdList)
+	if err != nil {
+		return
+	}
+
+	for _, v := range idList {
+		editShareChartInfoIdMap[v] = true
+	}
+
+	return
+}

+ 58 - 0
services/data/collect_chart.go

@@ -0,0 +1,58 @@
+package data
+
+import (
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+// GetChartCollectClassifyTreeRecursive 递归获取分类树形结构
+func GetChartCollectClassifyTreeRecursive(list []*data_manage.ChartCollectClassifyItem, parentId int) []*data_manage.ChartCollectClassifyItem {
+	res := make([]*data_manage.ChartCollectClassifyItem, 0)
+	for _, v := range list {
+		if v.ParentId == parentId {
+			t := GetChartCollectClassifyTreeRecursive(list, v.ClassifyId)
+			if len(t) > 0 {
+				v.Children = t
+			}
+			res = append(res, v)
+		}
+	}
+	return res
+}
+
+// GetChartCollectClassifyChildIds 获取分类的子分类IDs
+func GetChartCollectClassifyChildIds(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.ChartCollectClassify)
+	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.ChartCollectClassifyId] {
+			continue
+		}
+		pathArr := strings.Split(v.LevelPath, ",")
+		if len(pathArr) > 0 && utils.InArrayByStr(pathArr, strClassifyId) {
+			classifyIds = append(classifyIds, v.ChartCollectClassifyId)
+			exists[v.ChartCollectClassifyId] = true
+		}
+	}
+	return
+}

部分文件因为文件数量过多而无法显示