浏览代码

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

zqbao 3 月之前
父节点
当前提交
14d8965bac
共有 92 个文件被更改,包括 12206 次插入2822 次删除
  1. 34 1
      controllers/bi_dashboard.go
  2. 7 61
      controllers/data_manage/chart_classify.go
  3. 20 42
      controllers/data_manage/chart_info.go
  4. 3 8
      controllers/data_manage/correlation/correlation_chart_classify.go
  5. 3 14
      controllers/data_manage/correlation/correlation_chart_info.go
  6. 3 14
      controllers/data_manage/cross_variety/chart_info.go
  7. 2 9
      controllers/data_manage/cross_variety/classify.go
  8. 458 0
      controllers/data_manage/data_approve/data_approve.go
  9. 126 0
      controllers/data_manage/data_approve/data_approve_flow.go
  10. 2 2
      controllers/data_manage/data_manage_permission/data_move.go
  11. 22 15
      controllers/data_manage/edb_classify.go
  12. 329 84
      controllers/data_manage/edb_info.go
  13. 0 70
      controllers/data_manage/edb_info_calculate.go
  14. 655 0
      controllers/data_manage/edb_info_share.go
  15. 764 0
      controllers/data_manage/edb_public.go
  16. 1191 0
      controllers/data_manage/edb_public_classify.go
  17. 0 13
      controllers/data_manage/excel/custom_analysis_edb.go
  18. 0 58
      controllers/data_manage/excel/excel_info.go
  19. 4 26
      controllers/data_manage/future_good/future_good_chart_classify.go
  20. 0 404
      controllers/data_manage/future_good/future_good_edb_info.go
  21. 4 24
      controllers/data_manage/line_equation/line_chart_classify.go
  22. 3 14
      controllers/data_manage/line_equation/line_chart_info.go
  23. 3 14
      controllers/data_manage/line_feature/chart_info.go
  24. 4 24
      controllers/data_manage/line_feature/classify.go
  25. 0 27
      controllers/data_manage/manual.go
  26. 0 244
      controllers/data_manage/multiple_graph_config.go
  27. 2 11
      controllers/data_manage/my_chart.go
  28. 4 4
      controllers/data_manage/predict_edb_classify.go
  29. 6 10
      controllers/data_manage/predict_edb_info.go
  30. 3 8
      controllers/data_manage/range_analysis/chart_classify.go
  31. 3 14
      controllers/data_manage/range_analysis/chart_info.go
  32. 1 1
      controllers/data_manage/wind_data.go
  33. 690 0
      controllers/fix.go
  34. 383 41
      controllers/knowledge/resource.go
  35. 7 0
      controllers/report_v2.go
  36. 0 4
      controllers/resource.go
  37. 0 14
      controllers/sys_admin.go
  38. 1 7
      go.mod
  39. 0 23
      go.sum
  40. 1 0
      models/bi_dashboard/bi_dashboard.go
  41. 13 1
      models/bi_dashboard/bi_dashboard_detail.go
  42. 3 0
      models/business_conf.go
  43. 162 23
      models/data_manage/chart_classify.go
  44. 8 2
      models/data_manage/chart_info.go
  45. 223 0
      models/data_manage/data_approve/data_approve.go
  46. 198 0
      models/data_manage/data_approve/data_approve_flow.go
  47. 115 0
      models/data_manage/data_approve/data_approve_message.go
  48. 90 0
      models/data_manage/data_approve/data_approve_node.go
  49. 152 0
      models/data_manage/data_approve/data_approve_record.go
  50. 57 0
      models/data_manage/data_approve/data_approve_relation.go
  51. 21 0
      models/data_manage/data_approve/request/approve.go
  52. 22 0
      models/data_manage/data_approve/request/approve_flow.go
  53. 5 0
      models/data_manage/data_approve/request/approve_message.go
  54. 88 0
      models/data_manage/data_approve/response/approve.go
  55. 46 0
      models/data_manage/data_approve/response/approve_flow.go
  56. 24 0
      models/data_manage/data_approve/response/approve_message.go
  57. 161 22
      models/data_manage/edb_classify.go
  58. 13 0
      models/data_manage/edb_collect.go
  59. 147 48
      models/data_manage/edb_info.go
  60. 227 0
      models/data_manage/edb_info_share.go
  61. 257 0
      models/data_manage/public_edb_classify.go
  62. 68 0
      models/data_manage/public_edb_info.go
  63. 32 0
      models/data_manage/request/edb_info_share.go
  64. 55 0
      models/data_manage/request/edb_public.go
  65. 17 0
      models/data_manage/response/edb_info_share.go
  66. 49 4
      models/knowledge/knowledge_resource.go
  67. 51 0
      models/knowledge/knowledge_resource_bi_dashboard_detail.go
  68. 2 2
      models/report_v2.go
  69. 342 0
      routers/commentsRouter.go
  70. 10 0
      routers/router.go
  71. 47 1
      services/bi_dashboard.go
  72. 574 48
      services/data/chart_classify.go
  73. 1199 0
      services/data/data_approve/approve.go
  74. 174 0
      services/data/data_approve/approve_flow.go
  75. 89 0
      services/data/data_approve/approve_message.go
  76. 31 0
      services/data/data_approve/approve_node.go
  77. 37 0
      services/data/data_approve/constant.go
  78. 8 5
      services/data/data_manage_permission/data_move.go
  79. 59 0
      services/data/data_manage_permission/edb.go
  80. 401 258
      services/data/edb_classify.go
  81. 18 2
      services/data/edb_info.go
  82. 135 0
      services/data/edb_info_share.go
  83. 44 0
      services/data/edb_public.go
  84. 835 0
      services/data/edb_public_classify.go
  85. 1 1
      services/edb_info_replace.go
  86. 726 0
      services/elastic/edb_info.go
  87. 45 1092
      services/elastic/elastic.go
  88. 221 0
      services/knowledge/es.go
  89. 134 2
      services/knowledge/resource.go
  90. 2 0
      utils/config.go
  91. 13 4
      utils/constants.go
  92. 17 2
      utils/elastic.go

+ 34 - 1
controllers/bi_dashboard.go

@@ -100,16 +100,21 @@ func (this *BIDaShboardController) AddDashboard() {
 		return
 	}
 	detailList := make([]*bi_dashboard.BiDashboardDetail, 0)
+	var isAddResource bool
 	for i, v := range req.List {
 		item := &bi_dashboard.BiDashboardDetail{
 			BiDashboardId: int(id),
 			Type:          v.Type,
 			UniqueCode:    v.UniqueCode,
+			Conf:          v.Conf,
 			Sort:          i + 1,
 			CreateTime:    time.Now(),
 			ModifyTime:    time.Now(),
 		}
 		detailList = append(detailList, item)
+		if v.Type == 3 {
+			isAddResource = true
+		}
 	}
 	err = bi_dashboard.AddBiDashboardDetailMulti(detailList)
 	if err != nil {
@@ -117,11 +122,22 @@ func (this *BIDaShboardController) AddDashboard() {
 		br.ErrMsg = "新增详情失败,Err:" + err.Error()
 		return
 	}
+	if isAddResource {
+		msg, err := services.SaveBiDashboardKnowledgeResource(item.BiDashboardId, this.SysUser.AdminId)
+		if err != nil {
+			if msg == "" {
+				msg = "新增知识资源失败"
+			}
+			br.Msg = msg
+			br.ErrMsg = "新增知识资源失败,Err:" + err.Error()
+			return
+		}
+
+	}
 
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "新增成功"
-	//br.Data =
 }
 
 // EditPpt
@@ -179,15 +195,20 @@ func (this *BIDaShboardController) EditDashboard() {
 	}
 
 	detailList := make([]*bi_dashboard.BiDashboardDetail, 0)
+	isEditResource := false
 	for _, v := range req.List {
 		item := &bi_dashboard.BiDashboardDetail{
 			BiDashboardId: req.BiDashboardId,
 			Type:          v.Type,
 			UniqueCode:    v.UniqueCode,
+			Conf:          v.Conf,
 			Sort:          v.Sort,
 			CreateTime:    time.Now(),
 			ModifyTime:    time.Now(),
 		}
+		if v.Type == 3 {
+			isEditResource = true
+		}
 		detailList = append(detailList, item)
 	}
 	err = bi_dashboard.AddBiDashboardDetailMulti(detailList)
@@ -196,6 +217,18 @@ func (this *BIDaShboardController) EditDashboard() {
 		br.ErrMsg = "新增详情失败,Err:" + err.Error()
 		return
 	}
+	if isEditResource {
+		// 添加知识资源引用
+		msg, err := services.SaveBiDashboardKnowledgeResource(item.BiDashboardId, this.SysUser.AdminId)
+		if err != nil {
+			if msg == "" {
+				msg = "编辑知识资源失败"
+			}
+			br.Msg = msg
+			br.ErrMsg = "编辑知识资源失败,Err:" + err.Error()
+			return
+		}
+	}
 
 	br.Ret = 200
 	br.Success = true

+ 7 - 61
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()
@@ -451,12 +430,6 @@ func (this *ChartClassifyController) DeleteChartClassifyCheck() {
 			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
@@ -579,12 +552,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 = "该目录下存在关联指标,不可删除"
@@ -933,7 +900,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 +941,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 = "获取失败"

+ 20 - 42
controllers/data_manage/chart_info.go

@@ -2027,7 +2027,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 +2061,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 +2146,6 @@ func (this *ChartInfoController) ChartInfoSearch() {
 // @Title 图表模糊搜索(从es获取)
 // @Description  图表模糊搜索(从es获取)
 // @Param   Keyword   query   string  true       "图表名称"
-// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
 // @Success 200 {object} data_manage.ChartInfo
 // @router /chart_info/search_by_es [get]
 func (this *ChartInfoController) ChartInfoSearchByEs() {
@@ -2183,12 +2176,7 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 
 	keyword := this.GetString("Keyword")
 
-	//只看我的
-	isShowMe, _ := this.GetBool("IsShowMe")
-	showSysId := 0
-	if isShowMe {
-		showSysId = sysUser.AdminId
-	}
+	showSysId := sysUser.AdminId
 
 	var searchList []*data_manage.ChartInfo
 	var total int64
@@ -3089,26 +3077,26 @@ func (this *ChartInfoController) CopyChartInfo() {
 	//	return
 	//}
 	//判断图表是否存在
-	var condition string
-	var pars []interface{}
-	condition += " AND chart_classify_id=? "
-	pars = append(pars, req.ChartClassifyId)
+	//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)
-
-	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)
@@ -4245,13 +4233,3 @@ func (this *ChartInfoController) ChartInfoImgSetBySvg() {
 	br.Data = resp
 	return
 }
-
-// 修复ES中的指标和图表数据
-//func init() {
-//	// 更新ES中的指标数据
-//	data.AddOrEditAllEdbInfoToEs()
-//	// 更新es中的图表数据
-//	data.AddAllChartInfo()
-//
-//	fmt.Println("全部es数据修复完成")
-//}

+ 3 - 8
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 {
@@ -154,7 +149,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()

+ 3 - 14
controllers/data_manage/correlation/correlation_chart_info.go

@@ -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)
@@ -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)

+ 3 - 14
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)
@@ -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}
 

+ 2 - 9
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
 		}

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

@@ -0,0 +1,458 @@
+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   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")
+	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")
+	classifyId, _ := this.GetInt("ClassifyId")
+	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, classifyId, timeType, sortField, sortRule, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 2:
+		list, total, msg, err = dataApproveServ.SolvedDataApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 3:
+		list, total, msg, err = dataApproveServ.MyApplyDataApproves(sysUser.AdminId, classifyId, 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	"当前页页码"
+// @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")
+	// 分页
+	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, 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 = "操作成功"
+}

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

@@ -0,0 +1,126 @@
+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"
+)
+
+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
+	}
+
+	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
+	}
+
+	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 = "获取失败"

+ 22 - 15
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()
@@ -177,7 +177,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 +185,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 +244,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 +709,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()
@@ -926,7 +926,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 +1070,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()
@@ -1238,10 +1239,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 +1257,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()

+ 329 - 84
controllers/data_manage/edb_info.go

@@ -1742,7 +1742,9 @@ func (this *EdbInfoController) EdbInfoFilter() {
 // @Param   IsAddPredictEdb   query   bool  false       "是否查询添加预测指标"
 // @Param   PageSize   query   int  true       "每页数据条数"
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
-// @Param   EdbType   query   int  false       "指标类型:0-基础和计算;1-基础指标;2-计算指标"
+// @Param   EdbType   query   int  false       "指标类型:0-基础和计算;1-基础指标;2-计算指标;3-衍生指标"
+// @Param   EdbAuth   query   int  false       "指标权限:0-全部;1-我的;2-公共"
+// @Param   EdbCollect   query   int  false       "指标收藏状态:0-全部;1-已收藏"
 // @Success 200 {object} data_manage.EdbInfoList
 // @router /edb_info/filter_by_es [get]
 func (this *EdbInfoController) EdbInfoFilterByEs() {
@@ -1777,95 +1779,89 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 
 	frequency := this.GetString("Frequency") //频度
 
-	isAddPredictEdb, _ := this.GetBool("IsAddPredictEdb") //是否查询添加预测指标
+	//isAddPredictEdb, _ := this.GetBool("IsAddPredictEdb") //是否查询添加预测指标
 
-	edbType, _ := this.GetInt("EdbType", 0) // 指标类型:0-基础和计算;1-基础指标;2-计算指标
+	// 指标类型数组:1-基础指标;2-计算指标;3-预测指标
+	edbTypeList := make([]int, 0)
+	edbInfoType := -1                            // 指标范围
+	edbTypeStr := this.GetString("EdbType", "0") // 指标类型:0-基础和计算;1-基础指标;2-计算指标;3-预测指标
+	{
+		if edbTypeStr == `` || edbTypeStr == `0` {
+			edbTypeList = []int{1, 2}
+			edbInfoType = 0
+		} else {
+			var hasEdb, hasPredictEdb bool
+			tmpEdbTypeList := strings.Split(edbTypeStr, `,`)
+			for _, v := range tmpEdbTypeList {
+				edbType, err := strconv.Atoi(v)
+				if err != nil {
+					br.Msg = "EdbType异常"
+					br.ErrMsg = "EdbType异常,Err:" + err.Error()
+					return
+				}
+
+				// 指标类型
+				switch edbType {
+				case 1, 2:
+					hasEdb = true
+					edbTypeList = append(edbTypeList, edbType)
+				case 3:
+					hasPredictEdb = true
+					edbTypeList = []int{1, 2}
+				}
+			}
+
+			// 只有数据查看和指标加工
+			if hasEdb && !hasPredictEdb {
+				edbInfoType = 0
+			} else if !hasEdb && hasPredictEdb {
+				// 只有预测指标
+				edbInfoType = 1
+			}
+		}
+	}
+
+	edbAuth, _ := this.GetInt("EdbAuth", 0) // 指标权限范围,0-全部;1-我的;2-公共
+
+	edbCollect, _ := this.GetInt("EdbCollect", 0) // 指标收藏状态:0-全部;1-已收藏
 
 	var edbInfoList []*data_manage.EdbInfoList
 	var err error
 
-	// 无权限指标 和 无权限指标分类id
-	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, err := data_manage_permission.GetUserAllEdbAndClassifyNoPermissionList(this.SysUser.AdminId, utils.EDB_INFO_TYPE, edbType)
+	// 无权限指标 和 无权限指标分类id(只考虑)
+	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, err := data_manage_permission.GetUserAllEdbAndClassifyNoPermissionListV2(this.SysUser.AdminId)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + 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)
+	// 收藏的指标id
+	collectEdbInfoIdList := make([]int, 0)
+	if edbCollect == 1 {
+		collectEdbInfoIdList, err = data_manage.GetUserAllCollectEdbInfoIdList(this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取收藏指标配置数据失败,Err:" + err.Error()
+			return
 		}
-		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)
-		}
+	var keyWordArr []string
+	keyWordArr = append(keyWordArr, keyWord)
 
-		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, "年度")
-		}
+	newKeyWord := strings.Split(keyWord, " ")
+	keyWordArr = append(keyWordArr, newKeyWord...)
 
-		//频度
-		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, frequency, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, collectEdbInfoIdList, edbTypeList, edbInfoType, edbAuth, this.SysUser.AdminId, sortMap)
 
-		total, edbInfoList, err = data_manage.GetEdbInfoFilterList(condition, pars, startSize, pageSize)
-	}
 	if err != nil {
 		edbInfoList = make([]*data_manage.EdbInfoList, 0)
 	}
@@ -1903,8 +1899,8 @@ func (this *EdbInfoController) EdbInfoFilterByEs() {
 			return
 		}
 
-		// 如果是ES的话,需要重新查一下指标的信息,主要是为了把是否授权字段找出来
-		if isEs {
+		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+		{
 			edbInfoIdList := make([]int, 0)
 			for i := 0; i < edbInfoListLen; i++ {
 				edbInfoIdList = append(edbInfoIdList, edbInfoList[i].EdbInfoId)
@@ -3217,7 +3213,7 @@ func (this *EdbInfoController) AllEdbInfoByEs() {
 		keyWordArr = append(keyWordArr, newKeyWord...)
 
 		// 普通的搜索
-		total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, -1, frequency, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, edbType)
+		total, edbInfoList, err = elastic.SearchEdbInfoData(keyWord, startSize, pageSize, filterSource, source, frequency, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, []int{}, []int{1, 2}, -1, 0, this.SysUser.AdminId, map[string]string{})
 		isEs = true
 	} else {
 		var condition string
@@ -3807,11 +3803,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 +3841,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 {
@@ -4597,3 +4594,251 @@ func (this *EdbInfoController) ChartImageSetBySvg() {
 	br.Success = true
 	br.Msg = "保存成功"
 }
+
+// EdbInfoFilterByEs
+// @Title 指标筛选接口
+// @Description 指标筛选接口
+// @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-计算指标;3-衍生指标"
+// @Param   EdbAuth   query   int  false       "指标权限:0-全部;1-我的;2-公共"
+// @Param   EdbCollect   query   int  false       "指标收藏状态:0-全部;1-已收藏"
+// @Success 200 {object} data_manage.EdbInfoList
+// @router /edb_info/batch_move [get]
+func (this *EdbInfoController) BatchMoveEdb() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	// TODO 移动指标
+	var err error
+	req := data_manage.EsEdbReq{}
+	err = this.ParseForm(&req)
+	if err != nil {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误"
+		return
+	}
+	var total int64
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	keyWord := this.GetString("KeyWord")
+	keyWord = strings.TrimSpace(keyWord) //移除字符串首尾空格
+	filterSource, _ := this.GetInt("FilterSource")
+	if filterSource <= 0 {
+		filterSource = 1
+	}
+	//指标来源
+	source, _ := this.GetInt("Source")
+
+	frequency := this.GetString("Frequency") //频度
+
+	//isAddPredictEdb, _ := this.GetBool("IsAddPredictEdb") //是否查询添加预测指标
+
+	// 指标类型数组:1-基础指标;2-计算指标;3-预测指标
+	edbTypeList := make([]int, 0)
+	edbInfoType := -1                            // 指标范围
+	edbTypeStr := this.GetString("EdbType", "0") // 指标类型:0-基础和计算;1-基础指标;2-计算指标;3-预测指标
+	{
+		if edbTypeStr == `` || edbTypeStr == `0` {
+			edbTypeList = []int{1, 2}
+			edbInfoType = 0
+		} else {
+			var hasEdb, hasPredictEdb bool
+			tmpEdbTypeList := strings.Split(edbTypeStr, `,`)
+			for _, v := range tmpEdbTypeList {
+				edbType, err := strconv.Atoi(v)
+				if err != nil {
+					br.Msg = "EdbType异常"
+					br.ErrMsg = "EdbType异常,Err:" + err.Error()
+					return
+				}
+
+				// 指标类型
+				switch edbType {
+				case 1, 2:
+					hasEdb = true
+					edbTypeList = append(edbTypeList, edbType)
+				case 3:
+					hasPredictEdb = true
+					edbTypeList = []int{1, 2}
+				}
+			}
+
+			// 只有数据查看和指标加工
+			if hasEdb && !hasPredictEdb {
+				edbInfoType = 0
+			} else if !hasEdb && hasPredictEdb {
+				// 只有预测指标
+				edbInfoType = 1
+			}
+		}
+	}
+
+	edbAuth, _ := this.GetInt("EdbAuth", 0) // 指标权限范围,0-全部;1-我的;2-公共
+
+	edbCollect, _ := this.GetInt("EdbCollect", 0) // 指标收藏状态:0-全部;1-已收藏
+
+	var edbInfoList []*data_manage.EdbInfoList
+
+	// 无权限指标 和 无权限指标分类id(只考虑)
+	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, err := data_manage_permission.GetUserAllEdbAndClassifyNoPermissionListV2(this.SysUser.AdminId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+		return
+	}
+
+	// 收藏的指标id
+	collectEdbInfoIdList := make([]int, 0)
+	if edbCollect == 1 {
+		collectEdbInfoIdList, err = data_manage.GetUserAllCollectEdbInfoIdList(this.SysUser.AdminId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取收藏指标配置数据失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	var keyWordArr []string
+	keyWordArr = append(keyWordArr, keyWord)
+
+	newKeyWord := strings.Split(keyWord, " ")
+	keyWordArr = append(keyWordArr, newKeyWord...)
+
+	sortMap := make(map[string]string)
+	// 如果没有搜索关键词,则默认根据指标编码倒序排序
+	if keyWord == `` {
+		sortMap["EdbInfoId"] = `desc`
+	}
+
+	// 普通的搜索
+	total, edbInfoList, err = elastic.SearchEdbInfoData(keyWord, startSize, pageSize, filterSource, source, frequency, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, collectEdbInfoIdList, edbTypeList, edbInfoType, edbAuth, this.SysUser.AdminId, sortMap)
+
+	if err != nil {
+		edbInfoList = make([]*data_manage.EdbInfoList, 0)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+
+	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)
+	}
+
+	// 当前列表中的分类map
+	classifyMap := make(map[int]*data_manage.EdbClassify)
+	if edbInfoListLen > 0 {
+		classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList)
+		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
+		}
+
+		// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+		{
+			edbInfoIdList := make([]int, 0)
+			for i := 0; i < edbInfoListLen; i++ {
+				edbInfoIdList = append(edbInfoIdList, edbInfoList[i].EdbInfoId)
+				tmpEdbInfo := edbInfoList[i]
+				if currClassify, ok := classifyMap[tmpEdbInfo.ClassifyId]; ok {
+					edbInfoList[i].HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(tmpEdbInfo.IsJoinPermission, currClassify.IsJoinPermission, tmpEdbInfo.EdbInfoId, tmpEdbInfo.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
+				}
+			}
+
+			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 i := 0; i < edbInfoListLen; i++ {
+				tmpEdbInfo, ok := edbInfoMap[edbInfoList[i].EdbInfoId]
+				if !ok {
+					continue
+				}
+				edbInfoList[i].IsJoinPermission = tmpEdbInfo.IsJoinPermission
+			}
+		}
+
+		// 权限校验
+		for i := 0; i < edbInfoListLen; i++ {
+			tmpEdbInfoItem := edbInfoList[i]
+			if currClassify, ok := classifyMap[tmpEdbInfoItem.ClassifyId]; ok {
+				edbInfoList[i].HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(tmpEdbInfoItem.IsJoinPermission, currClassify.IsJoinPermission, tmpEdbInfoItem.EdbInfoId, tmpEdbInfoItem.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
+			}
+		}
+	}
+
+	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 + ")"
+			}
+		}
+	}
+	//新增搜索词记录
+	{
+		searchKeyword := new(data_manage.SearchKeyword)
+		searchKeyword.KeyWord = keyWord
+		searchKeyword.CreateTime = time.Now()
+		go data_manage.AddSearchKeyword(searchKeyword)
+	}
+
+	// 不返回无权限的指标
+	respList := make([]*data_manage.EdbInfoList, 0)
+	for _, v := range edbInfoList {
+		if v.HaveOperaAuth {
+			respList = append(respList, v)
+		}
+	}
+
+	resp := data_manage.EdbInfoFilterDataResp{
+		Paging: page,
+		List:   respList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 0 - 70
controllers/data_manage/edb_info_calculate.go

@@ -1068,76 +1068,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代码接口

+ 655 - 0
controllers/data_manage/edb_info_share.go

@@ -0,0 +1,655 @@
+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/services/data"
+	"eta_gn/eta_api/services/elastic"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strings"
+)
+
+// 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
+	}
+	_, err := data_manage.GetEdbInfoById(edbInfoId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	//// TODO 权限校验
+	//{
+	//	classifyMap := make(map[int]*data_manage.EdbClassifyIdItems)
+	//	for _, v := range classifyList {
+	//		classifyMap[v.ClassifyId] = v
+	//	}
+	//	if currClassify, ok := classifyMap[edbInfo.ClassifyId]; ok {
+	//		haveOperaAuth, err := data_manage_permission.CheckEdbPermission(edbInfo.IsJoinPermission, currClassify.IsJoinPermission, c.SysUser.AdminId, edbInfo.EdbInfoId, edbInfo.ClassifyId)
+	//		if err != nil {
+	//			br.Msg = err.Error()
+	//			br.ErrMsg = "校验指标权限失败,err:" + err.Error()
+	//			return
+	//		}
+	//		resp.HaveOperaAuth = haveOperaAuth
+	//	}
+	//}
+
+	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
+	if len(list) > 0 {
+		resp.ShareType = list[0].ShareType
+	}
+
+	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
+	}
+
+	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
+	go 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
+	}
+
+	// TODO 不确定加了用户这个顶级,会不会对前端造成一定影响
+	// 我收到的
+	{
+		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.EdbClassifyItemList
+		for _, v := range nodeList {
+			index, ok := receivedMap[v.SysUserId]
+			if !ok {
+				index = len(receivedMap)
+				item := &data_manage.EdbClassifyItems{
+					ClassifyId:       v.SysUserId,
+					EdbInfoId:        0,
+					ClassifyType:     0,
+					ClassifyName:     v.SysUserRealName,
+					ClassifyNameEn:   "",
+					ParentId:         0,
+					RootId:           0,
+					Level:            0,
+					Sort:             0,
+					UniqueCode:       "",
+					Source:           0,
+					SourceName:       "",
+					SysUserId:        v.SysUserId,
+					SysUserRealName:  v.SysUserRealName,
+					StartDate:        "",
+					EdbCode:          "",
+					EdbType:          0,
+					Children:         []*data_manage.EdbClassifyItems{},
+					Button:           data_manage.EdbClassifyItemsButton{},
+					IsJoinPermission: 0,
+					HaveOperaAuth:    false,
+					ClassifyIdPath:   "",
+				}
+				receivedList = append(receivedList, item)
+			}
+			receivedList[index].Children = append(receivedList[index].Children, v)
+		}
+
+		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)
+	}
+
+	// 分类筛选
+	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
+	}
+
+	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{2} // 普通指标中的计算指标
+
+	// 指标分享状态: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 // 选择范围是:只有我的指标
+
+	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 {
+		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
+		}
+	}
+
+	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
+	}
+
+	if len(selectEdbInfoIdList) > 30 {
+		br.Msg = `指标数量不能超过30个`
+		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{2} // 普通指标中的计算指标
+
+	// 指标分享状态: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
+}

+ 764 - 0
controllers/data_manage/edb_public.go

@@ -0,0 +1,764 @@
+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"
+)
+
+// EdbPublicController 公共指标
+type EdbPublicController struct {
+	controllers.BaseAuthController
+}
+
+// RemoveCheck
+// @Title 删除检测接口
+// @Description 删除检测接口
+// @Param	request	body data_manage.ClassifyDeleteCheckReq true "type json string"
+// @Success 200 Ret=200 检测成功
+// @router /edb_public/remove/check [post]
+func (c *EdbPublicController) RemoveCheck() {
+	// TODO
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req data_manage.ClassifyDeleteCheckReq
+	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.IsSendEmail = false
+		return
+	}
+	deleteStatus, tipsMsg, tableList, err, errMsg := data.DeleteEdbPublicCheck(req.EdbInfoId, 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
+}
+
+// Remove
+// @Title 删除公共分类/指标
+// @Description 删除公共分类/指标接口
+// @Param	request	body data_manage.DeleteEdbClassifyReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /edb_public/remove [post]
+func (c *EdbPublicController) Remove() {
+	// TODO
+	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.DeleteEdbClassifyReq
+	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.IsSendEmail = false
+		return
+	}
+
+	nextItem, _, err, errMsg := data.Delete(req.ClassifyId, req.EdbInfoId, 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
+}
+
+// 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
+	}
+
+	// 待处理的资产
+	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.EdbPublicDefault {
+				br.Msg = `选择指标中存在已经公开/提交审批的指标,请仅选择未公开指标!`
+				br.IsSendEmail = false
+				return
+			}
+		}
+	}
+
+	// 校验是否开启了审批流
+	opening, e := dataApproveSerice.CheckOpenApprove(dataApproveSerice.DataTypeEdb)
+	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(dataApproveSerice.DataTypeEdb, dataApproveSerice.DataApproveStatePass, dataPublicItemList)
+	} else {
+
+		_, err = dataApproveSerice.SubmitDataApprove(dataApproveSerice.DataTypeEdb, dataPublicItemList, title, strings.TrimSpace(req.Description), c.SysUser.AdminId, c.SysUser.RealName)
+		if err != nil {
+			br.Msg = "提交审批失败"
+			br.ErrMsg = "提交审批失败, Err: " + err.Error()
+			return
+		}
+	}
+
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// 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()
+	}()
+
+	// TODO 单个指标撤销的时候,需要校验状态,然后撤销
+	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
+	}
+
+	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
+	}
+
+	// 待处理的资产
+	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.EdbPublicDefault {
+				br.Msg = `选择指标中存在已经公开/提交审批的指标,请仅选择未公开指标!`
+				br.IsSendEmail = false
+				return
+			}
+		}
+	}
+
+	// 校验是否开启了审批流
+	opening, e := dataApproveSerice.CheckOpenApprove(dataApproveSerice.DataTypeEdb)
+	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(dataApproveSerice.DataTypeEdb, dataApproveSerice.DataApproveStatePass, dataPublicItemList)
+	} else {
+
+		_, err = dataApproveSerice.SubmitDataApprove(dataApproveSerice.DataTypeEdb, dataPublicItemList, title, strings.TrimSpace(req.Description), c.SysUser.AdminId, c.SysUser.RealName)
+		if err != nil {
+			br.Msg = "提交审批失败"
+			br.ErrMsg = "提交审批失败, Err: " + err.Error()
+			return
+		}
+	}
+
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// 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, edbTypeList, edbInfoType, edbAuth, sortMap := getSearchPar(req)
+
+	total, edbInfoList, err := elastic.SearchEdbInfoDataByPublic(keyword, startSize, pageSize, searchEdbPublicList, 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 {
+		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
+		}
+	}
+
+	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获取数据
+
+	edbInfoList := make([]*data_manage.EdbInfoList, 0)
+	tmpEdbInfoList, err := getAllEdbInfoListByPublic(req, c.SysUser.AdminId)
+
+	// 如果有过滤指标,那么就过滤吧
+	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
+	}
+
+	edbInfoListLen := len(edbInfoList)
+
+	// 因为是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
+		}
+	}
+
+	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
+}
+
+// getSearchPar
+// @Description: 获取查询参数
+// @author: Roc
+// @datetime 2024-12-05 14:13:25
+// @param req request.SearchPublicEdbReq
+// @return keyword string
+// @return searchEdbPublicList []int
+// @return sourceList []int
+// @return classifyIdList []int
+// @return edbTypeList []int
+// @return edbInfoType int
+// @return edbAuth int
+// @return sortMap map[string]string
+func getSearchPar(req request.SearchPublicEdbReq) (keyword string, searchEdbPublicList, sourceList, classifyIdList, edbTypeList []int, edbInfoType, edbAuth int, sortMap map[string]string) {
+	keyword = req.Keyword
+	keyword = strings.TrimSpace(keyword) //移除字符串首尾空格
+
+	//指标来源
+	sourceList = req.SourceList
+
+	// 选择的分类
+	classifyIdList = req.ClassifyIdList
+
+	// 指标公开状态:1:未公开,2:已提交;3:已公开。可多选,默认是未公开
+	edbPublicList := req.EdbPublicList
+	if len(edbPublicList) <= 0 {
+		edbPublicList = []int{1}
+	}
+
+	edbInfoType = 0        // 普通指标
+	edbTypeList = []int{2} // 普通指标中的计算指标
+	edbAuth = 1            // 选择范围是:只有我的指标
+
+	searchEdbPublicList = make([]int, 0) // 0:全部,1:未公开,2:已提交;3:已公开
+	if len(edbPublicList) > 0 && !utils.InArrayByInt(edbPublicList, 0) {
+		// 不含全部
+		for _, v := range edbPublicList {
+			switch v {
+			case 1: // 未公开
+				searchEdbPublicList = append(searchEdbPublicList, utils.EdbPublicDefault)
+			case 2: // 已提交
+				searchEdbPublicList = append(searchEdbPublicList, utils.EdbPublicCommit, utils.EdbPublicReject)
+			case 3: // 已公开
+				searchEdbPublicList = append(searchEdbPublicList, utils.EdbPublicSuccess)
+
+			}
+		}
+	} else {
+		searchEdbPublicList = []int{0, 1, 2, 3}
+	}
+
+	sortMap = make(map[string]string)
+	// 如果没有搜索关键词,则默认根据指标编码倒序排序
+	if keyword == `` {
+		sortMap["EdbInfoId"] = `desc`
+	}
+
+	return
+
+}
+
+// getAllEdbInfoListByPublic
+// @Description: 获取所有的指标列表
+// @author: Roc
+// @datetime 2024-12-04 15:43:14
+// @param req request.SetEdbChartPermissionReq
+// @param userId int
+// @return edbInfoIdList []*data_manage.EdbInfoList
+// @return err error
+func getAllEdbInfoListByPublic(req request.AllSearchPublicEdbReq, userId int) (edbInfoList []*data_manage.EdbInfoList, err error) {
+	// 获取查询参数
+	keyword, searchEdbPublicList, sourceList, edbClassifyIdList, edbTypeList, edbInfoType, edbAuth, sortMap := getSearchPar(req.SearchPublicEdbReq)
+
+	_, edbInfoList, err = getAllEdbInfoDataByPublic(keyword, 1, searchEdbPublicList, sourceList, edbClassifyIdList, edbTypeList, edbInfoType, edbAuth, userId, sortMap)
+	if err != nil {
+		return
+	}
+
+	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 getAllEdbInfoDataByPublic(keyword string, currPage int, searchEdbPublicList, 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.SearchEdbInfoDataByPublic(keyword, startSize, pageSize, searchEdbPublicList, sourceList, classifyIdList, edbTypeList, edbInfoType, edbAuth, sysUserId, sortMap)
+	if err != nil {
+		return
+	}
+
+	page := paging.GetPaging(currPage, pageSize, int(total))
+	if !page.IsEnd {
+		_, nextList, tmpErr := getAllEdbInfoDataByPublic(keyword, page.NextIndex, searchEdbPublicList, sourceList, classifyIdList, edbTypeList, edbInfoType, edbAuth, sysUserId, sortMap)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		list = append(list, nextList...)
+	}
+
+	return
+}

+ 1191 - 0
controllers/data_manage/edb_public_classify.go

@@ -0,0 +1,1191 @@
+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 {
+			// 查询当前公共分类信息
+			for _, v := range allEdbInfo {
+				v.HaveOperaAuth = true
+				button := data.GetEdbOpButton(c.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+				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, req.Level, 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
+		}
+		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.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+			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
+}
+
+// Items
+// @Title 获取所有公共分类接口-不包含指标
+// @Description 获取所有公共分类接口-不包含指标
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/items [get]
+func (c *EdbPublicClassifyController) Items() {
+	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 {
+		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 {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	nodeAll := make([]*data_manage.EdbClassifyItems, 0)
+	for k := range rootList {
+		rootNode := rootList[k]
+		data.EdbClassifyItemsMakeTree(classifyAll, rootNode)
+		nodeAll = append(nodeAll, rootNode)
+	}
+	resp := new(data_manage.EdbClassifyListResp)
+	resp.AllNodes = nodeAll
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// EdbClassifyMove
+// @Title 公共分类移动接口
+// @Description 公共分类移动接口
+// @Success 200 {object} data_manage.MoveEdbClassifyReq
+// @router /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.MoveEdbClassify(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 = "移动成功"
+}
+
+// ItemsV2
+// @Title 公共分类列表
+// @Description 公共分类列表接口
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/items/v2 [get]
+func (c *EdbPublicClassifyController) ItemsV2() {
+	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
+	}
+	// 已授权公共分类id
+	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(c.SysUser.AdminId, 0)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
+		return
+	}
+	//allEdbInfo, err := data_manage.GetEdbInfoAll(0)
+	//if err != nil && !utils.IsErrNoRow(err) {
+	//	br.Msg = "获取失败"
+	//	br.ErrMsg = "获取数据失败,Err:" + err.Error()
+	//	return
+	//}
+	//edbInfoMap := make(map[int][]*data_manage.EdbClassifyItems)
+	//for _, v := range allEdbInfo {
+	//	button := data.GetEdbOpButton(c.SysUser, v.SysUserId)
+	//	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)
+	}
+	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)
+	//if !button.AddButton {
+	//	canOpClassify = false
+	//}
+
+	resp := data_manage.EdbClassifyListResp{
+		AllNodes:      nodeAll,
+		CanOpClassify: canOpClassify,
+		Language:      language,
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ClassifyEdbInfoList
+// @Title 获取公共分类下指标接口
+// @Description 获取公共分类下指标接口
+// @Param   ClassifyId   query   int  true       "公共分类id"
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/edb_info/list [get]
+func (c *EdbPublicClassifyController) ClassifyEdbInfoList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	classifyId, _ := c.GetInt("ClassifyId")
+	if classifyId <= 0 {
+		br.Msg = "参数错误,请刷新页面"
+		return
+	}
+
+	classifyInfo, err := data_manage.GetEdbClassifyById(classifyId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取公共分类信息失败,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
+	}
+
+	// 指标类型(基础指标,预测指标)
+	edbType := 0
+	switch classifyInfo.ClassifyType {
+	case utils.EdbClassifyTypeBase:
+		edbType = 1
+	case utils.EdbClassifyTypeCalculate:
+		edbType = 2
+	}
+	// 无权限指标 和 无权限指标公共分类id
+	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, err := data_manage_permission.GetUserAllEdbAndClassifyNoPermissionList(c.SysUser.AdminId, utils.EDB_INFO_TYPE, edbType)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+		return
+	}
+
+	allEdbInfo, err := data_manage.GetEdbInfoByClassifyId(classifyId, utils.EDB_INFO_TYPE, edbType, 0, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	list := make([]*data_manage.EdbClassifyItems, 0)
+
+	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
+		}
+		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(c.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
+			v.Button = button
+
+			list = append(list, v)
+		}
+	}
+
+	resp := new(data_manage.ClassifyEdbInfoListResp)
+	resp.EdbInfoList = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ItemsV3
+// @Title 公共分类列表
+// @Description 公共分类列表接口
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/items/v3 [get]
+func (c *EdbPublicClassifyController) ItemsV3() {
+	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
+	//}
+
+	// TODO:9级改造
+	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
+	}
+	rootTwoList, err := data_manage.GetEdbClassifyByParentIdTwo(int8(classifyType))
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	classifyAll, err := data_manage.GetEdbClassifyAllV2(int8(classifyType))
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	// 已授权公共分类id
+	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(c.SysUser.AdminId, 0)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
+		return
+	}
+
+	rootTwoMap := make(map[int][]*data_manage.EdbClassifyItems)
+	for _, v := range rootTwoList {
+		// 数据权限
+		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+		// 按钮权限
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+		v.Button = button
+
+		rootTwoMap[v.ParentId] = append(rootTwoMap[v.ParentId], v)
+	}
+	rootTwoChildMap := 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)
+		v.Button = button
+		if v.Level == 3 {
+			rootTwoChildMap[v.ParentId] = append(rootTwoChildMap[v.ParentId], v)
+		}
+	}
+
+	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 := rootTwoMap[v.ClassifyId]; ok {
+			v.Children = existItems
+			for _, item := range existItems {
+				// 数据权限
+				v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+				// 按钮权限
+				button := data.GetEdbClassifyOpButton(c.SysUser, item.SysUserId, v.HaveOperaAuth)
+				item.Button = button
+
+				if existItems, ok := rootTwoChildMap[item.ClassifyId]; ok {
+					for _, existItem := range existItems {
+						// 数据权限
+						v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+						// 按钮权限
+						button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+						button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
+						existItem.Button = button
+					}
+					item.Children = existItems
+				} else {
+					items := make([]*data_manage.EdbClassifyItems, 0)
+					item.Children = items
+				}
+			}
+		} else {
+			items := make([]*data_manage.EdbClassifyItems, 0)
+			v.Children = items
+		}
+		nodeAll = append(nodeAll, v)
+	}
+	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 = nodeAll
+	resp.Language = language
+	resp.CanOpClassify = canOpClassify
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 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


+ 4 - 26
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()

+ 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")
-//}

+ 4 - 24
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()

+ 3 - 14
controllers/data_manage/line_equation/line_chart_info.go

@@ -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)
@@ -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}
 

+ 3 - 14
controllers/data_manage/line_feature/chart_info.go

@@ -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)
@@ -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}
 

+ 4 - 24
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()

+ 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()

+ 6 - 10
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{}
@@ -1082,6 +1079,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 +1100,9 @@ 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)
-		}
+
+		total, edbInfoList, err = elastic.SearchEdbInfoData(keyWord, startSize, pageSize, filterSource, source, frequency, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, []int{}, []int{1, 2}, 1, 0, this.SysUser.AdminId, map[string]string{})
+
 		isEs = true
 	} else {
 		var condition string

+ 3 - 8
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 {
@@ -153,7 +148,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()

+ 3 - 14
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)

+ 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()

+ 690 - 0
controllers/fix.go

@@ -0,0 +1,690 @@
+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 := 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 := 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 := 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 := 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数据修复完成")
+}

+ 383 - 41
controllers/knowledge/resource.go

@@ -9,9 +9,6 @@ import (
 	knowledgeServ "eta_gn/eta_api/services/knowledge"
 	"eta_gn/eta_api/utils"
 	"fmt"
-	"github.com/h2non/filetype"
-	"github.com/rdlucklib/rdluck_tools/paging"
-	"github.com/tealeg/xlsx"
 	"html"
 	"io/ioutil"
 	"os"
@@ -19,6 +16,10 @@ import (
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/h2non/filetype"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
 )
 
 // 分类
@@ -35,13 +36,14 @@ type ResourceController struct {
 // @Param   StartDate   query   string  true       "开始时间"
 // @Param   EndDate   query   string  true       "结束时间"
 // @Param   Frequency   query   string  true       "频度"
-// @Param   ClassifyIdFirst   query   int  true       "一级分类id"
-// @Param   ClassifyIdSecond   query   int  true       "二级分类id"
-// @Param   ClassifyIdThird   query   int  true       "三级分类id"
+// @Param   ClassifyIds   query   int  true       "分类id, 多选, 英文逗号分隔"
 // @Param   State   query   int  true       "状态"
 // @Param   KeyWord   query   string  true       "搜索关键词"
 // @Param   PublishSort   query   string  true       "desc:降序,asc 升序(预留)"
 // @Param   FilterReportType   query   string  true       "筛选事件类型,1:公共研报,2:共享研报,3:我的研报"
+// @Param   IncludeFile   query   string  true       "是否包含文件, no:不包含"
+// @Param   SourceFrom   query   string  true       "来源, 用英文逗号分隔"
+// @Param   IsShowMe   query   string  true       "只看我, false:全部, true:只看我"
 // @Success 200 {object} knowledge.KnowledgeResourceListResp
 // @router /resource/list [get]
 func (this *ResourceController) List() {
@@ -64,6 +66,10 @@ func (this *ResourceController) List() {
 
 	sourceFrom := this.GetString("SourceFrom")
 
+	includeFile := this.GetString("IncludeFile")
+
+	IsShowMe, _ := this.GetBool("IsShowMe")
+
 	var startSize int
 	if pageSize <= 0 {
 		pageSize = utils.PageSize20
@@ -79,6 +85,15 @@ func (this *ResourceController) List() {
 	condition += ` AND resource_type = ? `
 	pars = append(pars, resourceType)
 
+	if includeFile == "no" {
+		condition += ` AND is_file = ? `
+		pars = append(pars, 0)
+	}
+	if IsShowMe {
+		condition += ` AND admin_id = ? `
+		pars = append(pars, this.SysUser.AdminId)
+	}
+
 	if keyWord != "" {
 		//按照空格划分为关键词数组
 		keyWordArr := strings.Split(keyWord, " ")
@@ -263,6 +278,241 @@ func (this *ResourceController) List() {
 	br.Data = resp
 }
 
+// Search
+// @Title 获取事件列表接口
+// @Description 获取事件列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   TimeType     query string true  "筛选的时间类别:publish_time(发布时间),modify_time(更新时间);approve_time(审批时间)"
+// @Param   StartDate   query   string  true       "开始时间"
+// @Param   EndDate   query   string  true       "结束时间"
+// @Param   Frequency   query   string  true       "频度"
+// @Param   ClassifyIds   query   int  true       "分类id, 多选, 英文逗号分隔"
+// @Param   SysUserIds   query   int  true       "用户id, 多选, 英文逗号分隔"
+// @Param   State   query   int  true       "状态"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Param   PublishSort   query   string  true       "desc:降序,asc 升序(预留)"
+// @Param   FilterReportType   query   string  true       "筛选事件类型,1:公共研报,2:共享研报,3:我的研报"
+// @Param   IncludeFile   query   string  true       "是否包含文件, no:不包含"
+// @Param   SourceFrom   query   string  true       "来源, 用英文逗号分隔"
+// @Param   IsShowMe   query   string  true       "只看我, false:全部, true:只看我"
+// @Success 200 {object} knowledge.KnowledgeResourceListResp
+// @router /resource/search_by_es [get]
+func (this *ResourceController) Search() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	classifyIds := this.GetString("ClassifyIds")
+	// 添加人
+	addUserIds := this.GetString("SysUserIds")
+	// 标签
+	tagIds := this.GetString("TagIds")
+
+	keyWord := this.GetString("Keyword")
+	resourceType, _ := this.GetInt("ResourceType")
+
+	sourceFrom := this.GetString("SourceFrom")
+
+	includeFile := this.GetString("IncludeFile")
+
+	IsShowMe, _ := this.GetBool("IsShowMe")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	isIncludeFile := true
+	if includeFile == "no" {
+		isIncludeFile = false
+	}
+	var searchUserIds []int
+	if addUserIds != "" {
+		// 转成数组,并把类型转成int
+		addUserIdsArr := strings.Split(addUserIds, ",")
+		for _, v := range addUserIdsArr {
+			addUserId, _ := strconv.Atoi(v)
+			searchUserIds = append(searchUserIds, addUserId)
+		}
+	}
+	var myId int
+	if IsShowMe {
+		myId = this.SysUser.AdminId
+	}
+
+	var sourceFromArr []string
+	if sourceFrom != "" {
+		sourceFromArr = strings.Split(sourceFrom, ",")
+	}
+	var classifyIdsInt []int
+	if classifyIds != "" {
+		//转成数组,并把类型转成int
+		classifyIdsArr := strings.Split(classifyIds, ",")
+		for _, v := range classifyIdsArr {
+			classifyId, _ := strconv.Atoi(v)
+			classifyIdsInt = append(classifyIdsInt, classifyId)
+		}
+	}
+	var tagIdsInt []int
+	if tagIds != "" {
+		//转成数组,并把类型转成int
+		tagIdsArr := strings.Split(tagIds, ",")
+		for _, v := range tagIdsArr {
+			tagId, _ := strconv.Atoi(v)
+			tagIdsInt = append(tagIdsInt, tagId)
+		}
+	}
+	listTmp, total, err := knowledgeServ.SearchKnowledgeResourceByEs(
+		resourceType,
+		keyWord,
+		searchUserIds,
+		myId,
+		classifyIdsInt,
+		sourceFromArr,
+		tagIdsInt,
+		isIncludeFile,
+		startSize,
+		pageSize,
+	)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	var list []*knowledge.KnowledgeResourceList
+	// 整理分类ID
+	classifyFullNameMap := make(map[int]string)
+	classifyIdsArr := make([]int, 0)
+	for _, v := range listTmp {
+		classifyIdsArr = append(classifyIdsArr, v.ClassifyId)
+	}
+	// 获取分类列表
+	classifyList, err := knowledge.GetFullClassifyListByIdList(classifyIdsArr, resourceType)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range classifyList {
+		name := v.ClassifyName
+		if v.ParentName != "" {
+			name = v.ParentName + "/" + name
+		}
+		if v.RootName != "" {
+			name = v.RootName + "/" + name
+		}
+		classifyFullNameMap[v.ClassifyId] = name
+	}
+
+	// 整理标签ID
+	tagNameMap := make(map[int]string)
+	tagIdsArr := make([]int, 0)
+	for _, v := range listTmp {
+		tagIdsArr = append(tagIdsArr, v.TagId)
+	}
+	// 获取标签列表
+	tagObj := new(knowledge.KnowledgeTag)
+	tagList, err := tagObj.GetListByIdList(tagIdsArr, resourceType)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+	}
+	for _, v := range tagList {
+		tagNameMap[v.TagId] = v.TagName
+	}
+
+	for _, v := range listTmp {
+		var startTime, endTime string
+		if v.StartTime != nil && !v.StartTime.IsZero() {
+			startTime = v.StartTime.In(time.Local).Format(utils.FormatDateTime)
+			if resourceType == knowledge.KnowledgeResourceTypeOpinion || resourceType == knowledge.KnowledgeResourceTypeKnow {
+				startTime = v.StartTime.In(time.Local).Format(utils.FormatDate)
+			}
+		}
+		if v.EndTime != nil && !v.EndTime.IsZero() {
+			endTime = v.EndTime.In(time.Local).Format(utils.FormatDateTime)
+			if resourceType == knowledge.KnowledgeResourceTypeOpinion || resourceType == knowledge.KnowledgeResourceTypeKnow {
+				endTime = v.EndTime.In(time.Local).Format(utils.FormatDate)
+			}
+		}
+		modifyTime := v.ModifyTime.In(time.Local).Format(utils.FormatDateTime)
+		createTime := v.CreateTime.In(time.Local).Format(utils.FormatDateTime)
+		tmp := &knowledge.KnowledgeResourceList{
+			KnowledgeResourceId: v.KnowledgeResourceId,
+			ResourceType:        v.ResourceType,
+			ClassifyId:          v.ClassifyId,
+			Title:               v.Title,
+			Content:             v.Content,
+			CreateTime:          createTime,
+			ModifyTime:          modifyTime,
+			State:               v.State,
+			ResourceCode:        v.ResourceCode,
+			AdminId:             v.AdminId,
+			AdminRealName:       v.AdminRealName,
+			SourceFrom:          v.SourceFrom,
+			TagId:               v.TagId,
+			StartTime:           startTime,
+			EndTime:             endTime,
+		}
+
+		classifyName, ok := classifyFullNameMap[tmp.ClassifyId]
+		if ok {
+			tmp.ClassifyFullName = classifyName
+		}
+		tagName, ok := tagNameMap[v.TagId]
+		if ok {
+			tmp.TagName = tagName
+		}
+		list = append(list, tmp)
+	}
+
+	// list := make([]*knowledge.KnowledgeResourceList, 0, len(knowledges))
+	// for _, v := range knowledges {
+	// 	item := new(knowledge.KnowledgeResourceList)
+	// 	item.KnowledgeResourceId = v.KnowledgeResourceId
+	// 	item.ResourceType = v.ResourceType
+	// 	item.ClassifyId = v.ClassifyId
+	// 	item.Title = v.Title
+	// 	item.CreateTime = v.CreateTime.Format(utils.FormatDateTime)
+	// 	item.ModifyTime = v.ModifyTime.Format(utils.FormatDateTime)
+	// 	item.State = v.State
+	// 	item.Content = v.Content
+	// 	item.ResourceCode = v.ResourceCode
+	// 	item.AdminId = v.AdminId
+	// 	item.AdminRealName = v.AdminRealName
+	// 	item.SourceFrom = v.SourceFrom
+	// 	item.TagId = v.TagId
+	// 	if v.StartTime != nil {
+	// 		item.StartTime = v.StartTime.Format(utils.FormatDateTime)
+	// 	}
+	// 	if v.EndTime != nil {
+	// 		item.EndTime = v.EndTime.Format(utils.FormatDateTime)
+	// 	}
+	// 	list = append(list, item)
+	// }
+
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+	resp := new(knowledge.KnowledgeResourceListResp)
+	resp.Paging = page
+	resp.List = list
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
 // Add
 // @Title 新增事件接口
 // @Description 新增事件(区分事件类型)
@@ -282,57 +532,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 {
-		if req.StartTime == "" {
-			br.Msg = "开始时间必填"
-			br.ErrMsg = "开始时间必填"
+		if req.ClassifyId <= 0 {
+			br.Msg = "分类必填"
+			br.ErrMsg = "分类必填"
+			br.IsSendEmail = false
 			return
 		}
-	}
-	item, err, errMsg := knowledgeServ.AddResource(&req, sysUser)
-	if err != nil {
-		br.Msg = "保存失败"
-		if errMsg != "" {
-			br.Msg = errMsg
+		if req.ResourceType == knowledge.KnowledgeResourceTypeEvent || req.ResourceType == knowledge.KnowledgeResourceTypePolicy {
+			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
@@ -800,6 +1052,13 @@ func (this *ResourceController) Delete() {
 		br.ErrMsg = "删除事件失败, Err: " + err.Error()
 		return
 	}
+	go func() {
+		item.IsDelete = 1
+		er := knowledgeServ.EsAddOrEditKnowledgeResource(item)
+		if er != nil {
+			utils.FileLog.Info("知识资源id:" + strconv.Itoa(req.KnowledgeResourceId) + ",删除事件同步es失败, Err: " + er.Error())
+		}
+	}()
 
 	br.Ret = 200
 	br.Success = true
@@ -1185,3 +1444,86 @@ func (this *ResourceController) TemplateDownload() {
 	br.Success = true
 	br.Msg = "下载成功"
 }
+
+// BiDashboardTmpResourceList
+// @Title 获取bi看报中的知识资源列表
+// @Description 获取bi看报中的知识资源列表
+// @Success 200 {object} models.EdbdataClassifyResp
+// @Param   biDashboardDetailId   query   int  true       "看板详情ID"
+// @router /resource/bi_dashboard/list [get]
+func (this *ResourceController) BiDashboardCacheResourceList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	biDashboardDetailId, _ := this.GetInt("BiDashboardDetailId")
+
+	resp, msg, err := knowledgeServ.GetKnowledgeResourceTmpList(biDashboardDetailId, this.SysUser.AdminId)
+	if err != nil {
+		if msg == "" {
+			msg = "获取数据失败"
+		}
+		br.Msg = msg
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// BiDashboardResourceSave
+// @Title 将知识资源库添加到bi看板
+// @Description 将知识资源库添加到bi看板
+// @Param	request	body knowledge.DeleteReq true "type json string"
+// @Success 200 {object} models.EdbdataClassifyResp
+// @router /resource/bi_dashboard/save [post]
+func (this *ResourceController) BiDashboardResourceSave() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req knowledge.BiDashboardResourceAddReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析失败"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+
+	if len(req.KnowledgeResourceList) == 0 {
+		// 则删除缓存中的数据
+		err := utils.Rc.Delete(utils.CACHE_KEY_BI_DASHBOARD_PREPARE_RESOURCE + strconv.Itoa(this.SysUser.AdminId))
+		if err != nil {
+			br.Msg = "添加失败"
+			br.ErrMsg = "删除缓存失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "添加成功"
+		br.Ret = 200
+		br.Success = true
+		return
+	}
+	cacheData, err := json.Marshal(req)
+	if err != nil {
+		br.Msg = "添加失败"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	err = utils.Rc.Put(utils.CACHE_KEY_BI_DASHBOARD_PREPARE_RESOURCE+strconv.Itoa(this.SysUser.AdminId), cacheData, time.Hour*24)
+	if err != nil {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "添加成功"
+	br.Ret = 200
+	br.Success = true
+
+}

+ 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 用户信息配置接口

+ 1 - 7
go.mod

@@ -5,12 +5,9 @@ go 1.21.7
 require (
 	baliance.com/gooxml v1.0.1
 	github.com/PuerkitoBio/goquery v1.9.1
-	github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.2
-	github.com/alibabacloud-go/alimt-20181012/v2 v2.2.0
 	github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.6
 	github.com/alibabacloud-go/dm-20151123/v2 v2.0.9
 	github.com/alibabacloud-go/tea v1.2.2
-	github.com/alibabacloud-go/tea-utils/v2 v2.0.5
 	github.com/aliyun/alibaba-cloud-sdk-go v1.62.695
 	github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
 	github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
@@ -56,11 +53,8 @@ require (
 	github.com/alibabacloud-go/debug v1.0.0 // indirect
 	github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
 	github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
-	github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 // indirect
-	github.com/alibabacloud-go/tea-fileform v1.1.1 // indirect
-	github.com/alibabacloud-go/tea-oss-sdk v1.1.3 // indirect
-	github.com/alibabacloud-go/tea-oss-utils v1.1.0 // indirect
 	github.com/alibabacloud-go/tea-utils v1.3.6 // indirect
+	github.com/alibabacloud-go/tea-utils/v2 v2.0.5 // indirect
 	github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
 	github.com/aliyun/credentials-go v1.3.1 // indirect
 	github.com/andybalholm/cascadia v1.3.2 // indirect

+ 0 - 23
go.sum

@@ -22,8 +22,6 @@ github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8L
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/PuerkitoBio/goquery v1.9.1 h1:mTL6XjbJTZdpfL+Gwl5U2h1l9yEkJjhmlTeV9VPW7UI=
 github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
-github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.2 h1:enQwehstpeaAnsyse1Aqb6r0sU5UJbiNvIqVmPo+KWI=
-github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.2/go.mod h1:SQq4xfIdvf6WYKSDxAJc+xOJdolt+/bc1jnQKMtPMvQ=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
@@ -33,10 +31,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo=
 github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
-github.com/alibabacloud-go/alimt-20181012/v2 v2.2.0 h1:9AwDOjOZvhycl60jlXuMBSSl52rpWlcAuwxJOAQM4Bo=
-github.com/alibabacloud-go/alimt-20181012/v2 v2.2.0/go.mod h1:4gZhZ+BvRg/k14Z8SZnmu86zNqjslSpcC1wFl0jabl4=
-github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.0/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
-github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.2/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
 github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.6 h1:y1K+zKhpWcxso8zqI03CcYuwgyZPFwQdwAQOXAeuOVM=
 github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.6/go.mod h1:CzQnh+94WDnJOnKZH5YRyouL+OOcdBnXY5VWAf0McgI=
 github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
@@ -46,36 +40,20 @@ github.com/alibabacloud-go/dm-20151123/v2 v2.0.9 h1:3OPVk25YWcJ48whyVCFOf168dafh
 github.com/alibabacloud-go/dm-20151123/v2 v2.0.9/go.mod h1:AhCnEI1csfLmYL5fS5TbrxPR2xZZHRQ9MmkF04Iyez8=
 github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
 github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
-github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
 github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY=
 github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
-github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 h1:L0TIjr9Qh/SLVc1yPhFkcB9+9SbCNK/jPq4ZKB5zmnc=
-github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1/go.mod h1:EKxBRDLcMzwl4VLF/1WJwlByZZECJawPXUvinKMsTTs=
 github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg=
 github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
 github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
-github.com/alibabacloud-go/tea v1.1.10/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
-github.com/alibabacloud-go/tea v1.1.12/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
 github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
-github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
 github.com/alibabacloud-go/tea v1.2.1/go.mod h1:qbzof29bM/IFhLMtJPrgTGK3eauV5J2wSyEUo4OEmnA=
 github.com/alibabacloud-go/tea v1.2.2 h1:aTsR6Rl3ANWPfqeQugPglfurloyBJY85eFy7Gc1+8oU=
 github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk=
-github.com/alibabacloud-go/tea-fileform v1.1.1 h1:1YG6erAP3joQ0XdCXYIotuD7zyOM6qCR49xkp5FZDeU=
-github.com/alibabacloud-go/tea-fileform v1.1.1/go.mod h1:ZeCV91o4ISmxidd686f0ebdS5EDHWU+vW+TkjLhrsFE=
-github.com/alibabacloud-go/tea-oss-sdk v1.1.3 h1:EhAHI6edMeqgkZEqP7r4nc9iMWAUBKGxJHoBsOSKTtU=
-github.com/alibabacloud-go/tea-oss-sdk v1.1.3/go.mod h1:yUnodpR3Bf2rudLE7V/Gft5txjJF30Pk+hH77K/Eab0=
-github.com/alibabacloud-go/tea-oss-utils v1.1.0 h1:y65crjjcZ2Pbb6UZtC2deuIZHDVTS3IaDWE7M9nVLRc=
-github.com/alibabacloud-go/tea-oss-utils v1.1.0/go.mod h1:PFCF12e9yEKyBUIn7X1IrF/pNjvxgkHy0CgxX4+xRuY=
 github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
 github.com/alibabacloud-go/tea-utils v1.3.6 h1:bVjrxHztM8hAs6nOfLWCgxQfAtKb9RgFFMV6J3rdvB4=
 github.com/alibabacloud-go/tea-utils v1.3.6/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
-github.com/alibabacloud-go/tea-utils/v2 v2.0.0/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
-github.com/alibabacloud-go/tea-utils/v2 v2.0.4/go.mod h1:sj1PbjPodAVTqGTA3olprfeeqqmwD0A5OQz94o9EuXQ=
 github.com/alibabacloud-go/tea-utils/v2 v2.0.5 h1:EUakYEUAwr6L3wLT0vejIw2rc0IA1RSXDwLnIb3f2vU=
 github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4=
-github.com/alibabacloud-go/tea-xml v1.1.1/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
-github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
 github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0=
 github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
 github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
@@ -802,7 +780,6 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
 golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

+ 1 - 0
models/bi_dashboard/bi_dashboard.go

@@ -82,6 +82,7 @@ type AddDashboardListReq struct {
 	Type       int
 	UniqueCode string
 	Sort       int
+	Conf       string
 }
 
 type EditDashboardReq struct {

+ 13 - 1
models/bi_dashboard/bi_dashboard_detail.go

@@ -8,7 +8,8 @@ import (
 type BiDashboardDetail struct {
 	BiDashboardDetailId int       `gorm:"primaryKey;autoIncrement;column:bi_dashboard_detail_id" ` // bi看板id
 	BiDashboardId       int       `gorm:"column:bi_dashboard_id" `                                 // 看板id
-	Type                int       `gorm:"column:type" `                                            // 1图表 2表格
+	Type                int       `gorm:"column:type" `                                            // 1图表 2表格 3知识资源库
+	Conf                string    `gorm:"column:conf" `                                            // 配置信息
 	UniqueCode          string    `gorm:"column:unique_code;size:32;not null" `                    // 报告唯一编码
 	Sort                int       `gorm:"column:sort" `                                            // 排序字段
 	CreateTime          time.Time `gorm:"column:create_time" `                                     // 创建时间
@@ -20,12 +21,23 @@ func (m *BiDashboardDetail) TableName() string {
 	return "bi_dashboard_detail"
 }
 
+func (m *BiDashboardDetail) Insert() (err error) {
+	return global.DEFAULT_DmSQL.Create(m).Error
+}
+
 func GetBiDashboardDetailById(id int) (list []*BiDashboardDetail, err error) {
 	err = global.DEFAULT_DmSQL.Table("bi_dashboard_detail").Where("bi_dashboard_id IN ?", id).Find(&list).Error
 
 	return
 }
 
+// GetBiDashboardDetailIdByBidashboardIdAndType 获取看板详情id
+func GetBiDashboardDetailIdByBidashboardIdAndType(bid int, t int) (ids []int, err error) {
+	sql := "SELECT bi_dashboard_detail_id FROM bi_dashboard_detail WHERE bi_dashboard_id = ? AND type = ?"
+	err = global.DEFAULT_DmSQL.Raw(sql, bid, t).Scan(&ids).Error
+	return
+}
+
 // multiAdd
 func AddBiDashboardDetailMulti(items []*BiDashboardDetail) (err error) {
 	return global.DEFAULT_DmSQL.CreateInBatches(items, 100).Error

+ 3 - 0
models/business_conf.go

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

+ 162 - 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 操作按钮
@@ -388,3 +422,108 @@ 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
+}

+ 8 - 2
models/data_manage/chart_info.go

@@ -87,7 +87,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 +96,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 += ` AND sys_user_id = ? `
+	}
+
+	sql += ` ORDER BY sort asc,chart_info_id ASC `
 	err = o.Raw(sql, sourceList).Scan(&items).Error
 
 	return

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

@@ -0,0 +1,223 @@
+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
+	}
+
+	if len(relationList) > 0 {
+		for _, v := range relationList {
+			v.DataApproveId = dataApprove.DataApproveId
+		}
+		err = db.CreateInBatches(relationList, utils.MultiAddNum).Error
+		if err != nil {
+			return
+		}
+	}
+
+	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.* 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
+}

+ 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
+}

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

@@ -0,0 +1,115 @@
+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
+	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
+	Content       string
+	Remark        string
+	DataApproveId string
+	ApproveState  string
+	IsRead        string
+	CreateTime    string
+	ModifyTime    string
+}{
+	Id:            "id",
+	SendUserId:    "send_user_id",
+	ReceiveUserId: "receive_user_id",
+	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
+}

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

@@ -0,0 +1,57 @@
+package data_approve
+
+import (
+	"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
+}

+ 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:"资产类型"`
+}

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

@@ -0,0 +1,22 @@
+package request
+
+type DataApproveFlowSaveReq struct {
+	DataType int
+	FlowName string
+	Nodes    []Node
+}
+
+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"`
+}

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

@@ -0,0 +1,88 @@
+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"`
+	DataClassify int    `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:"申请人姓名"`
+	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:"-"`
+}

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

@@ -0,0 +1,46 @@
+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:"节点信息"`
+}
+
+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
+}

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

@@ -0,0 +1,24 @@
+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"`
+	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:"修改时间"`
+}

+ 161 - 22
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
 }
@@ -53,9 +51,9 @@ type AddEdbClassifyReq struct {
 // @param classifyType uint8
 // @return count int
 // @return err error
-func GetEdbClassifyCount(classifyName string, parentId 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
+func GetEdbClassifyCount(classifyName 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=? AND classify_type = ? AND sys_user_id = ?  `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyName, classifyType, sysUserId).Scan(&count).Error
 
 	return
 }
@@ -69,9 +67,9 @@ 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) {
-	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
+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 = ? AND sys_user_id = ? `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyNameEn, classifyType, sysUserId).Scan(&count).Error
 
 	return
 }
@@ -161,9 +159,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 +196,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 +205,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 +239,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 {
@@ -520,9 +529,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 +561,135 @@ 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
+}

+ 13 - 0
models/data_manage/edb_collect.go

@@ -236,6 +236,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"`

+ 147 - 48
models/data_manage/edb_info.go

@@ -20,54 +20,56 @@ 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"`
 }
 
 type EdbInfoFullClassify struct {
@@ -409,6 +411,10 @@ type EdbInfoList struct {
 	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:"设置公开的时间"`
 }
 
 type EdbDataInsertConfigItem struct {
@@ -495,6 +501,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)
@@ -1287,6 +1304,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"`
@@ -2050,3 +2130,22 @@ 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
+}
+
+// SetEdbInfoImageReq 设置指标图片
+type EsEdbReq struct {
+	KeyWord  string `description:"关键字" form:"KeyWord"`
+	ImageUrl string `description:"指标图片地址" form:"ImageUrl"`
+}

+ 227 - 0
models/data_manage/edb_info_share.go

@@ -0,0 +1,227 @@
+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 (?) ", m.TableName())
+	err = tx.Exec(sql, edbInfoIdList).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."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
+}
+
+// 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."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
+	return
+}

+ 257 - 0
models/data_manage/public_edb_classify.go

@@ -0,0 +1,257 @@
+package data_manage
+
+import (
+	"eta_gn/eta_api/global"
+	"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
+}
+
+// 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
+}

+ 68 - 0
models/data_manage/public_edb_info.go

@@ -0,0 +1,68 @@
+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_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, 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 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.EdbPublicSuccess, 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.EdbPublicSuccess {
+		sql += `,public_time = now() `
+	}
+	sql += ` WHERE edb_info_id in (?) `
+	err = global.DmSQL["data"].Exec(sql, status, edbInfoIdList).Error
+
+	return
+}

+ 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:可编辑"`
+}

+ 55 - 0
models/data_manage/request/edb_public.go

@@ -0,0 +1,55 @@
+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:"分类选择,如果不指定分类,那么就是所有分类"`
+	CurrentIndex   int    `description:"当前页页码,从1开始"`
+	PageSize       int    `description:"每页数据条数"`
+}
+
+// AllSearchPublicEdbReq
+// @Description: 获取所有指标列表(设置公开的时候)请求结构体
+type AllSearchPublicEdbReq struct {
+	SearchPublicEdbReq
+	EdbIdList   []int `description:"选中的指标id列表"`
+	NoEdbIdList []int `description:"未选中的指标id列表"`
+	IsSelectAll bool  `description:"是否选择所有指标"`
+}
+
+// SetPublicEdbPermissionReq
+// @Description: 设置数据权限请求
+type SetPublicEdbPermissionReq struct {
+	SearchPublicEdbReq
+	EdbIdList   []int `description:"选中的指标id列表"`
+	NoEdbIdList []int `description:"未选中的指标id列表"`
+	IsSelectAll bool  `description:"是否选择所有指标"`
+}

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

@@ -0,0 +1,17 @@
+package response
+
+import "eta_gn/eta_api/models/data_manage"
+
+// EdbInfoShareUserResp
+// @Description: 获取指标分享用户列表
+type EdbInfoShareUserResp struct {
+	ShareType int8                        `description:"分享类型,1:仅查看;2:可编辑"`
+	List      []*data_manage.EdbInfoShare `description:"分享用户列表"`
+}
+
+// EdbShareListResp
+// @Description: 共享列表
+type EdbShareListResp struct {
+	Send     data_manage.EdbClassifyItemList
+	Received data_manage.EdbClassifyItemList `description:"收到的共享"`
+}

+ 49 - 4
models/knowledge/knowledge_resource.go

@@ -4,8 +4,9 @@ import (
 	"eta_gn/eta_api/global"
 	"eta_gn/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 const (
@@ -37,6 +38,7 @@ type KnowledgeResource struct {
 	EndTime             *time.Time `gorm:"column:end_time"`
 	IsFile              int        `gorm:"column:is_file;default:0;NOT NULL"`
 	FileUrl             string     `gorm:"column:file_url"`
+	IsDelete            int        `gorm:"column:is_delete;default:0;NOT NULL"`
 }
 
 func (m *KnowledgeResource) TableName() string {
@@ -63,6 +65,7 @@ type KnowledgeResourceList struct {
 	TagId               int    `gorm:"column:tag_id;default:0;NOT NULL"`
 	StartTime           string `gorm:"column:start_time"`
 	EndTime             string `gorm:"column:end_time"`
+	Content             string `gorm:"-"`
 	ClassifyFullName    string
 	TagName             string
 }
@@ -72,8 +75,15 @@ type KnowledgeResourceListResp struct {
 	Paging *paging.PagingItem `description:"分页数据"`
 }
 
+func GetBatchKnowledgeResource(batchSize int, id int) (items []*KnowledgeResource, err error) {
+	sql := `SELECT * FROM knowledge_resource WHERE knowledge_resource_id>=? AND is_delete=0 ORDER BY knowledge_resource_id ASC LIMIT ?`
+	pars := []interface{}{id, batchSize}
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
 func GetKnowledgeResourcePageList(condition string, pars []interface{}, startSize, pageSize int) (items []*KnowledgeResource, err error) {
-	sql := `SELECT * FROM knowledge_resource WHERE 1=1  `
+	sql := `SELECT * FROM knowledge_resource WHERE 1=1  AND is_delete=0 `
 	if condition != "" {
 		sql += condition
 	}
@@ -95,7 +105,7 @@ func GetKnowledgeResourceIdList(condition string, pars []interface{}) (items []i
 }
 
 func GetKnowledgeResourceListCount(condition string, pars []interface{}) (count int, err error) {
-	sql := `SELECT COUNT(1) AS count  FROM knowledge_resource WHERE 1=1 `
+	sql := `SELECT COUNT(1) AS count  FROM knowledge_resource WHERE 1=1 AND is_delete=0 `
 	if condition != "" {
 		sql += condition
 	}
@@ -103,9 +113,30 @@ func GetKnowledgeResourceListCount(condition string, pars []interface{}) (count
 	return
 }
 
+func GetKnowledgeResourcePageByIds(ids []int, startSize, pageSize int) (items []*KnowledgeResource, err error) {
+	if len(ids) == 0 {
+		return
+	}
+	sql := `SELECT * FROM knowledge_resource WHERE knowledge_resource_id in (?) ORDER BY modify_time DESC LIMIT ?,?`
+
+	err = global.DmSQL["rddp"].Raw(sql, ids, startSize, pageSize).Find(&items).Error
+	return
+}
+
+func GetKnowledgeResourceByIds(ids []int) (items []*KnowledgeResource, err error) {
+	if len(ids) == 0 {
+		return
+	}
+	sql := `SELECT * FROM knowledge_resource WHERE knowledge_resource_id in (?) ORDER BY modify_time`
+
+	err = global.DmSQL["rddp"].Raw(sql, ids).Find(&items).Error
+	return
+}
+
+// Delete逻辑删除
 func (m *KnowledgeResource) Delete(knowledgeResourceIds int) (err error) {
 
-	sql := ` DELETE FROM knowledge_resource WHERE knowledge_resource_id =? `
+	sql := ` UPDATE knowledge_resource SET is_delete = 1 WHERE knowledge_resource_id =? `
 	err = global.DmSQL["rddp"].Exec(sql, knowledgeResourceIds).Error
 	return
 }
@@ -277,3 +308,17 @@ func (m *KnowledgeResource) UpdateClassifyIdByIds(ids []int, classifyId int, res
 	err = global.DmSQL["rddp"].Exec(sql, pars...).Error
 	return
 }
+
+type BiDashboardResourceAddReq struct {
+	BiDashboardDetailId   int                        `description:"Bi看板详情"`
+	KnowledgeResourceList []KnowledgeResourceMapItem `description:"知识资源id"`
+}
+type BiDashboardResourceAddResp struct {
+	BiDashboardDetailId   int                      `description:"Bi看板详情"`
+	KnowledgeResourceList []*KnowledgeResourceList `description:"知识资源列表"`
+}
+
+type KnowledgeResourceMapItem struct {
+	KnowledgeResourceId int
+	ResourceType        int
+}

+ 51 - 0
models/knowledge/knowledge_resource_bi_dashboard_detail.go

@@ -0,0 +1,51 @@
+package knowledge
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"time"
+)
+
+type KnowledgeResourceBiDashboardDetail struct {
+	Id                    int       `gorm:"column:id;primary_key"`
+	BiDashboardDetailId   int       `gorm:"column:bi_dashboard_detail_id;comment:关联的BI仪表盘详情ID"`
+	KnowledgeResourceId   int       `gorm:"column:knowledge_resource_id;comment:关联的知识库资源ID"`
+	KnowledgeResourceType int       `gorm:"column:knowledge_resource_type;comment:知识库资源类型:0事件库,1政策库,2观点库,3知识库"`
+	CreateTime            time.Time `gorm:"column:create_time;comment:创建时间"`
+}
+
+func (KnowledgeResourceBiDashboardDetail) TableName() string {
+	return "knowledge_resource_bi_dashboard_detail"
+}
+
+func (k *KnowledgeResourceBiDashboardDetail) BatchAdd(items []*KnowledgeResourceBiDashboardDetail) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	tx := global.DmSQL["rddp"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	sql := `DELETE FROM knowledge_resource_bi_dashboard_detail WHERE bi_dashboard_detail_id =? `
+	err = tx.Exec(sql, items[0].BiDashboardDetailId).Error
+	if err != nil {
+		return
+	}
+	err = global.DmSQL["rddp"].CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func GetKnowledgeResourceIdsByCondition(condition string, pars []interface{}) (resourceIds []int, err error) {
+	sql := "SELECT knowledge_resource_id FROM knowledge_resource_bi_dashboard_detail WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&resourceIds).Error
+	return
+}

+ 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)

+ 342 - 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",
@@ -3742,6 +3832,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{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoController"],
         beego.ControllerComments{
             Method: "EdbChartList",
@@ -4183,6 +4282,222 @@ 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: "EdbClassifyMove",
+            Router: `/edb_classify/move`,
+            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: "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: "ClassifyEdbInfoList",
+            Router: `/edb_public/classify/edb_info/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: "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: "Items",
+            Router: `/edb_public/classify/items`,
+            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: "ItemsV2",
+            Router: `/edb_public/classify/items/v2`,
+            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: "ItemsV3",
+            Router: `/edb_public/classify/items/v3`,
+            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: "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: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:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "Remove",
+            Router: `/edb_public/remove`,
+            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: "RemoveCheck",
+            Router: `/edb_public/remove/check`,
+            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",
@@ -5020,6 +5335,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
+        beego.ControllerComments{
+            Method: "BiDashboardCacheResourceList",
+            Router: `/resource/bi_dashboard/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
+        beego.ControllerComments{
+            Method: "BiDashboardResourceSave",
+            Router: `/resource/bi_dashboard/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
         beego.ControllerComments{
             Method: "Delete",
@@ -5092,6 +5425,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
+        beego.ControllerComments{
+            Method: "Search",
+            Router: `/resource/search_by_es`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
         beego.ControllerComments{
             Method: "GetSourceFrom",

+ 10 - 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"
@@ -160,6 +161,15 @@ func init() {
 				&data_manage.FactorEdbSeriesController{},
 				&data_manage.EdbCollectController{},
 				&data_manage.EdbCollectClassifyController{},
+				&data_manage.EdbInfoShareController{},
+				&data_manage.EdbPublicController{},
+				&data_manage.EdbPublicClassifyController{},
+			),
+			web.NSNamespace("/data_approve",
+				web.NSInclude(
+					&data_approve.DataApproveController{},
+					&data_approve.DataApproveFlowController{},
+				),
 			),
 		),
 		web.NSNamespace("/my_chart",

+ 47 - 1
services/bi_dashboard.go

@@ -3,13 +3,59 @@ package services
 import (
 	"encoding/json"
 	"eta_gn/eta_api/models/bi_dashboard"
+	"eta_gn/eta_api/models/knowledge"
 	"eta_gn/eta_api/utils"
 	"fmt"
+	"strconv"
 	"time"
-)
 
+	"github.com/go-redis/redis/v8"
+)
 
+func SaveBiDashboardKnowledgeResource(dashboardId, adminId int) (msg string, err error) {
+	ids, err := bi_dashboard.GetBiDashboardDetailIdByBidashboardIdAndType(dashboardId, 3)
+	if err != nil {
+		return
+	}
+	if len(ids) == 0 {
+		return
+	}
 
+	data, er := utils.Rc.RedisBytes(utils.CACHE_KEY_BI_DASHBOARD_PREPARE_RESOURCE + strconv.Itoa(adminId))
+	req := new(knowledge.BiDashboardResourceAddReq)
+	if er != nil {
+		if er == redis.Nil {
+			msg = "暂无知识库"
+			err = nil
+			return
+		}
+		msg = "知识资源库添加失败"
+		return
+	}
+	if err = json.Unmarshal(data, &req); err != nil {
+		msg = "知识资源库添加失败"
+	}
+	defer func() {
+		if err == nil {
+			utils.Rc.Delete(utils.CACHE_KEY_BI_DASHBOARD_PREPARE_RESOURCE + strconv.Itoa(adminId))
+		}
+	}()
+	insertMapping := make([]*knowledge.KnowledgeResourceBiDashboardDetail, 0, len(req.KnowledgeResourceList))
+	for _, v := range req.KnowledgeResourceList {
+		tmp := new(knowledge.KnowledgeResourceBiDashboardDetail)
+		tmp.BiDashboardDetailId = ids[0]
+		tmp.KnowledgeResourceId = v.KnowledgeResourceId
+		tmp.KnowledgeResourceType = 3
+		tmp.CreateTime = time.Now()
+		insertMapping = append(insertMapping, tmp)
+	}
+	obj := new(knowledge.KnowledgeResourceBiDashboardDetail)
+	err = obj.BatchAdd(insertMapping)
+	if err != nil {
+		msg = "知识资源库添加失败"
+	}
+	return
+}
 
 // UpdateBiDashboardEditing 更新看板编辑状态
 func UpdateBiDashboardEditing(boardId, status, userId int, userName string) (ret bi_dashboard.BiDashboardEditingCache, err error) {

+ 574 - 48
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) {
 	// 没有数据权限就直接返回
@@ -175,26 +209,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 +244,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 +258,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 +275,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 +340,8 @@ func EditChartClassify(chartClassifyId, source int, chartClassifyName, lang stri
 
 	// 需要变更的字段
 	updateCols := make([]string, 0)
+	// 旧完整路径  , 新的完整路径
+	var oldClassifyNamePath, newClassifyNamePath string
 
 	// 语言版本校验
 	switch lang {
@@ -319,27 +366,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
@@ -512,12 +573,298 @@ 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)
+
+	// 移动对象为分类, 判断分类是否存在
+	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
+}
+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)
 
 	// 移动对象为分类, 判断分类是否存在
@@ -805,6 +1152,185 @@ func moveChartClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify,
 	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) {
 	//判断是否是挂在顶级目录下
 	targetClassify, err := data_manage.GetChartClassifyById(targetClassifyId)

+ 1199 - 0
services/data/data_approve/approve.go

@@ -0,0 +1,1199 @@
+package data_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/models/data_manage"
+	dataApproveModel "eta_gn/eta_api/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"sort"
+	"strings"
+	"time"
+)
+
+var (
+	timeField   = map[int]string{1: fmt.Sprintf("a.%s", dataApproveModel.DataApproveRecordCols.CreateTime), 2: fmt.Sprintf("a.%s", dataApproveModel.DataApproveRecordCols.NodeApproveTime), 3: fmt.Sprintf("b.%s", dataApproveModel.DataApproveCols.ApproveTime)}
+	myTimeField = map[int]string{1: dataApproveModel.DataApproveCols.CreateTime, 3: dataApproveModel.DataApproveCols.ApproveTime}
+	orderRules  = map[int]string{1: "ASC", 2: "DESC"}
+)
+
+func PassDataApprove(approveId int, adminId int) (msg string, err error) {
+	approveItem, e := dataApproveModel.GetDataApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		return
+	}
+
+	if approveItem.State != DataApproveStateApproving {
+		msg = "审批状态有误, 请刷新页面"
+		err = fmt.Errorf("审批状态有误, State: %d", approveItem.State)
+		return
+	}
+
+	var ApprovePars []interface{}
+	ApproveCond := ` AND data_approve_id =? AND approve_user_id =? AND state =? `
+	ApprovePars = append(ApprovePars, approveId, adminId, DataApproveStateApproving)
+
+	recordItem, er := dataApproveModel.GetDataApproveRecordByCondition(ApproveCond, ApprovePars)
+	if er != nil {
+		if utils.IsErrNoRow(er) {
+			msg = "无权审批"
+			err = er
+			return
+		}
+		msg = "操作失败"
+		return
+	}
+
+	// 查询审批流和审批流节点
+	flowItem, e := dataApproveModel.GetDataApproveFlowById(approveItem.FlowId)
+	if e != nil {
+		err = fmt.Errorf("获取审批流失败, Err: %s", e.Error())
+		return
+	}
+	nodePars := make([]interface{}, 0)
+	nodeCond := ` AND data_approve_flow_id =? AND curr_version =? `
+	nodePars = append(nodePars, flowItem.DataApproveFlowId, flowItem.CurrVersion)
+	nodeItems, e := dataApproveModel.GetDataApproveNodeByCondition(nodeCond, nodePars)
+	if e != nil {
+		err = fmt.Errorf("ApproveNodes GetItemsByCondition err: %s", e.Error())
+		return
+	}
+	if len(nodeItems) == 0 {
+		err = fmt.Errorf("无审批节点")
+		return
+	}
+	nodeMap := make(map[int]*dataApproveModel.DataApproveNode)
+	for _, v := range nodeItems {
+		nodeMap[v.DataApproveNodeId] = v
+	}
+
+	// 取出审批记录的节点
+	currNodeItem := nodeMap[recordItem.NodeId]
+	if currNodeItem == nil {
+		err = fmt.Errorf("当前节点信息有误")
+		return
+	}
+	currNode, e := FormatDataApproveNode2Item(currNodeItem)
+	if e != nil {
+		err = fmt.Errorf("当前节点信息有误, Err: %s", e.Error())
+		return
+	}
+	now := time.Now().Local()
+	recordItem.State = DataApproveStatePass
+	recordItem.ApproveTime = now
+	recordItem.ModifyTime = now
+	recordItem.NodeState = DataApproveStatePass
+	recordItem.NodeApproveUserId = recordItem.ApproveUserId
+	recordItem.NodeApproveUserName = recordItem.ApproveUserName
+	recordItem.NodeApproveTime = now
+
+	recordCols := []string{"State", "ApproveTime", "ModifyTime", "NodeState", "NodeApproveUserId", "NodeApproveUserName", "NodeApproveTime"}
+	lastApprove := false
+
+	// 依次审批
+	if currNode.ApproveType == NodeApproveTypeRoll {
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+
+		// 检查依次审批情况
+		sort.Slice(currNode.Users, func(k, j int) bool {
+			return currNode.Users[k].Sort < currNode.Users[j].Sort
+		})
+		userLen := len(currNode.Users)
+		//lastRoll := false
+		nextUser := new(response.DataApproveNodeUser) // 下一个审批人, 为nil则表示当前审批人即为最后
+		for k, v := range currNode.Users {
+			// 当前审批人
+			if v.UserId == adminId && recordItem.ApproveUserSort == v.Sort {
+				if (k + 1) < userLen {
+					nextUser = currNode.Users[k+1]
+				}
+			}
+		}
+		// 当前节点下一个审批人, 生成下一个审批记录且return
+		if nextUser.UserId > 0 {
+			newRecord := new(dataApproveModel.DataApproveRecord)
+			newRecord.DataApproveId = recordItem.DataApproveId
+			newRecord.State = DataApproveStateApproving
+			newRecord.NodeId = currNode.DataApproveNodeId
+			newRecord.PrevNodeId = currNode.PrevNodeId
+			newRecord.NextNodeId = currNode.NextNodeId
+			newRecord.ApproveType = currNode.ApproveType
+			newRecord.ApproveUserId = nextUser.UserId
+			newRecord.ApproveUserName = nextUser.UserName
+			newRecord.ApproveUserSort = nextUser.Sort
+			newRecord.CreateTime = now
+			newRecord.ModifyTime = now
+			newRecord.NodeState = DataApproveStateApproving
+			if e = newRecord.Create(); e != nil {
+				err = fmt.Errorf("生成审批记录失败, Err: %s", e.Error())
+				return
+			}
+
+			// 推送审批消息
+			go func() {
+				messageItem := new(dataApproveModel.DataApproveMessage)
+				messageItem.SendUserId = approveItem.ApplyUserId
+				messageItem.ReceiveUserId = nextUser.UserId
+				messageItem.Content = "您有新的待办任务"
+				messageItem.Remark = fmt.Sprintf("%s提交的【%s】需要您审批,请及时处理", approveItem.ApplyUserName, approveItem.Title)
+				messageItem.DataApproveId = approveItem.DataApproveId
+				messageItem.ApproveState = DataApproveStateApproving
+				messageItem.CreateTime = now
+				messageItem.ModifyTime = now
+				if e = messageItem.Create(); e != nil {
+					utils.FileLog.Info(fmt.Sprintf("PassDataApprove message err: %s", e.Error()))
+					return
+				}
+			}()
+			return
+		}
+
+		// 更新审批当前节点并进入下一个节点
+		if currNode.NextNodeId > 0 {
+			nextNode := nodeMap[currNode.NextNodeId]
+			approveItem.CurrNodeId = currNode.NextNodeId
+			approveItem.ModifyTime = now
+			if e = approveItem.Update([]string{"CurrNodeId", "ModifyTime"}); e != nil {
+				err = fmt.Errorf("更新审批当前节点失败, Err: %s", e.Error())
+				return
+			}
+			err = BuildNextNodeRecordAndMsg(nextNode, approveItem.DataApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.Title)
+			return
+		} else {
+			// 最后一个节点
+			lastApprove = true
+		}
+	}
+
+	// 会签
+	if currNode.ApproveType == NodeApproveTypeAll {
+		// 查询其他审批人是否已审批
+		otherCond := ` AND data_approve_id =? AND node_id =? AND approve_user_id <> ? `
+		otherPars := make([]interface{}, 0)
+		otherPars = append(otherPars, approveItem.DataApproveId, recordItem.NodeId, adminId)
+		otherRecords, e := dataApproveModel.GetDataApproveRecordItemsByCondition(otherCond, otherPars)
+		if e != nil {
+			err = fmt.Errorf("获取节点审批记录失败, Err: %s", e.Error())
+			return
+		}
+		otherPass := true
+		for _, v := range otherRecords {
+			if v.State != DataApproveStatePass {
+				otherPass = false
+			}
+		}
+
+		// 其他人未审批, 仅更新当前审批记录
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+
+		// 其他人已审批且为最后节点
+		if otherPass && currNode.NextNodeId == 0 {
+			lastApprove = true
+		}
+
+		// 其他人已审批且不为最后节点, 进入下一节点
+		if otherPass && currNode.NextNodeId > 0 {
+			nextNode := nodeMap[currNode.NextNodeId]
+			approveItem.CurrNodeId = currNode.NextNodeId
+			approveItem.ModifyTime = now
+			if e = approveItem.Update([]string{"CurrNodeId", "ModifyTime"}); e != nil {
+				err = fmt.Errorf("更新审批当前节点失败, Err: %s", e.Error())
+				return
+			}
+			err = BuildNextNodeRecordAndMsg(nextNode, approveItem.DataApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.Title)
+			return
+		}
+	}
+
+	// 或签
+	if currNode.ApproveType == NodeApproveTypeAny {
+		// 需检查一下审批的当前节点和记录的节点是否匹配, 不匹配可能是因为另外的审批人已通过, 所以此处应给提示
+		// 前端也有做相应的判断,但是两个人同时进入审批详情页时就可能出现这种情况
+		if approveItem.CurrNodeId != recordItem.NodeId {
+			msg = "该节点已完成审批, 请刷新页面"
+			return
+		}
+
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+
+		// 将该审批的同一个节点的记录标记为已审批
+		if e = recordItem.UpdateNodeState(recordItem.DataApproveId, recordItem.NodeId, recordItem.NodeState, recordItem.NodeApproveUserId, recordItem.NodeApproveUserName, recordItem.NodeApproveTime); e != nil {
+			err = fmt.Errorf("更新同一节点的其他审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+
+		if currNode.NextNodeId == 0 {
+			lastApprove = true
+		}
+		if currNode.NextNodeId > 0 {
+			nextNode := nodeMap[currNode.NextNodeId]
+			approveItem.CurrNodeId = currNode.NextNodeId
+			approveItem.ModifyTime = now
+			if e = approveItem.Update([]string{"CurrNodeId", "ModifyTime"}); e != nil {
+				err = fmt.Errorf("更新审批当前节点失败, Err: %s", e.Error())
+				return
+			}
+			err = BuildNextNodeRecordAndMsg(nextNode, approveItem.DataApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.Title)
+			return
+		}
+	}
+
+	// 最后一个审批, 更新审批记录、审批、报告状态、推送消息给申请人
+	if lastApprove {
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+		approveItem.State = DataApproveStatePass
+		approveItem.ApproveTime = now
+		approveItem.ModifyTime = now
+		approveCols := []string{"State", "ApproveTime", "ModifyTime"}
+		if e = approveItem.Update(approveCols); e != nil {
+			err = fmt.Errorf("更新审批信息失败, Err: %s", e.Error())
+			return
+		}
+		if e = updateDataApproveState(approveItem, DataApproveStatePass); e != nil {
+			err = fmt.Errorf("更新报告审批状态失败, Err: %s", e.Error())
+			return
+		}
+
+		go func() {
+			messageItem := new(dataApproveModel.DataApproveMessage)
+			messageItem.SendUserId = adminId
+			messageItem.ReceiveUserId = approveItem.ApplyUserId
+			messageItem.Content = "您提交的审批已通过"
+			messageItem.Remark = fmt.Sprintf("您提交的【%s】已通过", approveItem.Title)
+			messageItem.DataApproveId = approveItem.DataApproveId
+			messageItem.ApproveState = DataApproveStatePass
+			messageItem.CreateTime = now
+			messageItem.ModifyTime = now
+			if e = messageItem.Create(); e != nil {
+				utils.FileLog.Info(fmt.Sprintf("PassDataApprove message err: %s", e.Error()))
+				return
+			}
+		}()
+	}
+	return
+
+}
+
+// BuildNextNodeRecordAndMsg 生成下一个节点的审批记录并推送消息
+func BuildNextNodeRecordAndMsg(approveNodeItem *dataApproveModel.DataApproveNode, approveId, sysAdminId int, sysAdminName, title string) (err error) {
+	if approveNodeItem == nil {
+		err = fmt.Errorf("approve node nil")
+		return
+	}
+
+	// 根据节点审批方式生成审批记录
+	now := time.Now().Local()
+	approveNode, e := FormatDataApproveNode2Item(approveNodeItem)
+	if e != nil {
+		err = fmt.Errorf("FormatDataApproveNode2Item err: %s", e.Error())
+		return
+	}
+	if len(approveNode.Users) == 0 {
+		err = fmt.Errorf("审批节点用户有误")
+		return
+	}
+	newRecords := make([]*dataApproveModel.DataApproveRecord, 0)
+	sort.Slice(approveNode.Users, func(k, j int) bool {
+		return approveNode.Users[k].Sort < approveNode.Users[j].Sort
+	})
+	for _, u := range approveNode.Users {
+		r := new(dataApproveModel.DataApproveRecord)
+		r.DataApproveId = approveId
+		r.State = DataApproveStateApproving
+		r.NodeId = approveNode.DataApproveNodeId
+		r.PrevNodeId = approveNode.PrevNodeId
+		r.NextNodeId = approveNode.NextNodeId
+		r.ApproveType = approveNode.ApproveType
+		r.ApproveUserId = u.UserId
+		r.ApproveUserName = u.UserName
+		r.ApproveUserSort = u.Sort
+		r.CreateTime = now
+		r.ModifyTime = now
+		r.NodeState = DataApproveStateApproving // 当前节点审批状态
+		newRecords = append(newRecords, r)
+		// 依次审批仅生成一条记录
+		if approveNode.ApproveType == NodeApproveTypeRoll {
+			break
+		}
+	}
+
+	recordOb := new(dataApproveModel.DataApproveRecord)
+	if e = recordOb.CreateMulti(newRecords); e != nil {
+		err = fmt.Errorf("生成节点审批记录失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送审批消息
+	go func() {
+		messageOb := new(dataApproveModel.DataApproveMessage)
+		messages := make([]*dataApproveModel.DataApproveMessage, 0)
+		for _, v := range newRecords {
+			m := new(dataApproveModel.DataApproveMessage)
+			m.SendUserId = sysAdminId
+			m.ReceiveUserId = v.ApproveUserId
+			m.Content = "您有新的待办任务"
+			m.Remark = fmt.Sprintf("%s提交的【%s】需要您审批,请及时处理", sysAdminName, title)
+			m.DataApproveId = approveId
+			m.ApproveState = DataApproveStateApproving
+			m.CreateTime = now
+			m.ModifyTime = now
+			messages = append(messages, m)
+		}
+		e = messageOb.CreateMulti(messages)
+		if e != nil {
+			utils.FileLog.Info(fmt.Sprintf("BuildNextNodeRecordAndMsg messages err: %s", e.Error()))
+			return
+		}
+	}()
+
+	return
+}
+
+// updateDataApproveState 更新待审批资产的审批状态
+func updateDataApproveState(dataApprove *dataApproveModel.DataApprove, state int) (err error) {
+	// TODO 根据审批单去通过、驳回公开图库申请
+	obj := dataApproveModel.DataApproveRelation{}
+	dataList, err := obj.GetListByDataApproveId(dataApprove.DataApproveId)
+	if err != nil {
+		return
+	}
+
+	dataItemList := make([]SetDataPublicItem, 0)
+	for _, v := range dataList {
+		dataItemList = append(dataItemList, SetDataPublicItem{ClassifyId: v.ClassifyId, DataId: v.DataId})
+	}
+
+	err = UpdatePublicByDataList(dataApprove.DataType, state, dataItemList)
+
+	return
+}
+
+// UpdatePublicByDataList
+// @Description: 更新公共资产权限
+// @author: Roc
+// @datetime 2024-12-06 13:44:20
+// @param dataType int
+// @param dataApproveState int
+// @param dataList []SetDataPublicItem
+// @return err error
+func UpdatePublicByDataList(dataType, dataApproveState int, dataList []SetDataPublicItem) (err error) {
+	dataIdList := make([]int, 0)
+	for _, v := range dataList {
+		dataIdList = append(dataIdList, v.DataId)
+	}
+	switch dataType {
+	case DataTypeEdb:
+		switch dataApproveState {
+		case DataApproveStateApproving:
+			err = data_manage.UpdatePublicEdb(dataIdList, utils.EdbPublicSuccess)
+		case DataApproveStatePass:
+			for _, dataItem := range dataList {
+				err = data_manage.UpdatePublicEdbSuccess(dataItem.DataId, dataItem.ClassifyId)
+			}
+		case DataApproveStateRefuse:
+			err = data_manage.UpdatePublicEdb(dataIdList, utils.EdbPublicReject)
+		case DataApproveStateCancel:
+			err = data_manage.UpdatePublicEdb(dataIdList, utils.EdbPublicDefault)
+		}
+
+		// 更新ES
+		for _, dataId := range dataIdList {
+			data.AddOrEditEdbInfoToEs(dataId)
+		}
+	// 指标库
+	case DataTypeChart:
+		// 图库
+		// TODO
+	}
+
+	return
+}
+
+func ProcessingDataApprove(adminId, dataType, timeType, sortField, sortRule, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.DataApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ? AND b.%s = ? AND a.%s = ?`, dataApproveModel.DataApproveRecordCols.State, dataApproveModel.DataApproveCols.State, dataApproveModel.DataApproveRecordCols.ApproveUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, DataApproveStateApproving, DataApproveStateApproving, adminId)
+	order := ""
+
+	// 筛选条件
+	if dataType > 0 {
+		cond += fmt.Sprintf(` AND b.%s = ?`, dataApproveModel.DataApproveCols.DataType)
+		pars = append(pars, dataType)
+	}
+	if timeType <= 0 {
+		timeType = 1
+	}
+	if timeType == 1 && startTime != "" && endTime != "" {
+		_, e := time.Parse(utils.FormatDate, startTime)
+		if e != nil {
+			msg = "开始时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime, e := time.Parse(utils.FormatDate, endTime)
+		if e != nil {
+			msg = "结束时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime = tmpEndTime.AddDate(0, 0, 1)
+		cond += fmt.Sprintf(` AND (b.%s BETWEEN ? AND ?)`, dataApproveModel.DataApproveCols.CreateTime)
+		pars = append(pars, startTime, tmpEndTime)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND b.%s LIKE ?`, dataApproveModel.DataApproveCols.Title)
+		pars = append(pars, kw)
+	}
+	if sortField > 0 && sortRule > 0 {
+		orderField := timeField[sortField]
+		if orderField == "" {
+			msg = "时间排序字段有误"
+			return
+		}
+		orderRule := orderRules[sortRule]
+		if orderRule == "" {
+			msg = "时间排序方式有误"
+			return
+		}
+		order = fmt.Sprintf("%s %s", orderField, orderRule)
+	}
+	total, e := dataApproveModel.GetApprovingDataApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovingDataApproveCount err: %s", e.Error())
+		return
+	}
+	list, e := dataApproveModel.GetApprovingDataApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovingDataApprovePageList err: %s", e.Error())
+		return
+	}
+
+	respList = toDataApproveItemOrmResp(list)
+	respTotal = total
+	return
+}
+
+// SolvedDataApprove 已处理的审批
+func SolvedDataApprove(adminId, dataType, timeType, sortField, sortRule, approveState, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.DataApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ? AND a.%s IN (?)`, dataApproveModel.DataApproveRecordCols.ApproveUserId, dataApproveModel.DataApproveRecordCols.NodeState)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId, []int{DataApproveStatePass, DataApproveStateRefuse})
+	order := ""
+
+	// 筛选条件
+	if dataType > 0 {
+		cond += fmt.Sprintf(` AND b.%s = ?`, dataApproveModel.DataApproveCols.DataType)
+		pars = append(pars, dataType)
+	}
+	if timeType > 0 && startTime != "" && endTime != "" {
+		_, e := time.Parse(utils.FormatDate, startTime)
+		if e != nil {
+			msg = "开始时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime, e := time.Parse(utils.FormatDate, endTime)
+		if e != nil {
+			msg = "结束时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime = tmpEndTime.AddDate(0, 0, 1)
+		cond += fmt.Sprintf(` AND (%s BETWEEN ? AND ?)`, timeField[timeType])
+		pars = append(pars, startTime, tmpEndTime)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND b.%s LIKE ?`, dataApproveModel.DataApproveCols.Title)
+		pars = append(pars, kw)
+	}
+	if sortField > 0 && sortRule > 0 {
+		orderField := timeField[sortField]
+		if orderField == "" {
+			msg = "时间排序字段有误"
+			return
+		}
+		orderRule := orderRules[sortRule]
+		if orderRule == "" {
+			msg = "时间排序方式有误"
+			return
+		}
+		order = fmt.Sprintf("%s %s", orderField, orderRule)
+	}
+	if approveState > 0 {
+		cond += fmt.Sprintf(` AND a.%s = ?`, dataApproveModel.DataApproveRecordCols.NodeState)
+		pars = append(pars, approveState)
+	}
+	total, e := dataApproveModel.GetApprovedDataApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovedDataApproveCount err: %s", e.Error())
+		return
+	}
+	list, e := dataApproveModel.GetApprovedDataApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovedDataApprovePageList err: %s", e.Error())
+		return
+	}
+
+	for _, v := range list {
+		// 这个时候的状态,用审批状态
+		v.RecordState = v.NodeState
+		v.ApproveTime = v.NodeApproveTime
+	}
+	respList = toDataApproveItemOrmResp(list)
+	respTotal = total
+	return
+}
+
+func MyApplyDataApproves(adminId, dataType, timeType, sortField, sortRule, approveState, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.DataApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ?`, dataApproveModel.DataApproveCols.ApplyUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	order := ""
+
+	// 筛选条件
+	if dataType > 0 {
+		cond += fmt.Sprintf(` AND a.%s = ?`, dataApproveModel.DataApproveCols.DataType)
+		pars = append(pars, dataType)
+	}
+	if timeType > 0 && startTime != "" && endTime != "" {
+		_, e := time.Parse(utils.FormatDate, startTime)
+		if e != nil {
+			msg = "开始时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime, e := time.Parse(utils.FormatDate, endTime)
+		if e != nil {
+			msg = "结束时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTimeStr := tmpEndTime.AddDate(0, 0, 1).Format(utils.FormatDate)
+		cond += fmt.Sprintf(` AND (%s BETWEEN ? AND ?)`, myTimeField[timeType])
+		pars = append(pars, startTime, tmpEndTimeStr)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND a.%s LIKE ?`, dataApproveModel.DataApproveCols.Title)
+		pars = append(pars, kw)
+	}
+	if sortField > 0 && sortRule > 0 {
+		orderField := myTimeField[sortField]
+		if orderField == "" {
+			msg = "时间排序字段有误"
+			return
+		}
+		orderRule := orderRules[sortRule]
+		if orderRule == "" {
+			msg = "时间排序方式有误"
+			return
+		}
+		order = fmt.Sprintf("%s %s", orderField, orderRule)
+	}
+	if approveState > 0 {
+		cond += fmt.Sprintf(` AND a.%s = ?`, dataApproveModel.DataApproveRecordCols.State)
+		pars = append(pars, approveState)
+	}
+	total, e := dataApproveModel.GetApplyDataApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApplyDataApproveCount err: %s", e.Error())
+		return
+	}
+	respTotal = total
+	list, e := dataApproveModel.GetApplyDataApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApplyDataApprovePageList err: %s", e.Error())
+		return
+	}
+	respList = toDataApproveItemOrmResp(list)
+	return
+}
+
+func GetApproveDetail(approveId int) (resp *response.DataApproveDetail, msg string, err error) {
+	approveItem, e := dataApproveModel.GetDataApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批已被删除, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "获取失败"
+		err = fmt.Errorf("GetItemById err: %s", e.Error())
+		return
+	}
+
+	// 审批信息
+	detail := new(response.DataApproveDetail)
+	detail.Approve = new(response.DataApproveDetailItem)
+	detail.Approve.DataApproveId = approveItem.DataApproveId
+	detail.Approve.State = approveItem.State
+	detail.Approve.FlowId = approveItem.FlowId
+	detail.Approve.FlowVersion = approveItem.FlowVersion
+	detail.Approve.StartNodeId = approveItem.StartNodeId
+	detail.Approve.CurrNodeId = approveItem.CurrNodeId
+	detail.Approve.ApplyUserId = approveItem.ApplyUserId
+	detail.Approve.ApplyUserName = approveItem.ApplyUserName
+	detail.Approve.ApproveTime = utils.TimeTransferString(utils.FormatDateTime, approveItem.ApproveTime)
+	detail.Approve.CreateTime = utils.TimeTransferString(utils.FormatDateTime, approveItem.CreateTime)
+	detail.Approve.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, approveItem.ModifyTime)
+
+	// 审批节点
+	nodeOb := new(dataApproveModel.DataApproveNode)
+	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, dataApproveModel.DataApproveNodeCols.DataApproveFlowId, dataApproveModel.DataApproveNodeCols.CurrVersion)
+	nodePars := make([]interface{}, 0)
+	nodePars = append(nodePars, approveItem.FlowId, approveItem.FlowVersion)
+	nodeItems, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetItemsByCondition err: %s", e.Error())
+		return
+	}
+
+	// 审批记录
+	recordOb := new(dataApproveModel.DataApproveRecord)
+	recordCond := fmt.Sprintf(` AND %s = ?`, dataApproveModel.DataApproveRecordCols.DataApproveId)
+	recordPars := make([]interface{}, 0)
+	recordPars = append(recordPars, approveItem.DataApproveId)
+	recordItems, e := recordOb.GetItemsByCondition(recordCond, recordPars, []string{}, fmt.Sprintf("%s DESC", dataApproveModel.DataApproveRecordCols.ApproveTime))
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetItemsByCondition err: %s", e.Error())
+		return
+	}
+	recordMap := make(map[string]*dataApproveModel.DataApproveRecord)
+	for _, v := range recordItems {
+		k := fmt.Sprintf("%d-%d", v.NodeId, v.ApproveUserId)
+		recordMap[k] = v
+	}
+
+	// 审批流节点详情
+	detail.ApproveFlowNodes = make([]*response.DataApproveDetailNodes, 0)
+	for _, v := range nodeItems {
+		t := new(response.DataApproveDetailNodes)
+		t.DataApproveNodeId = v.DataApproveNodeId
+		t.DataApproveFlowId = v.DataApproveFlowId
+		t.PrevNodeId = v.PrevNodeId
+		t.NextNodeId = v.NextNodeId
+		t.NodeType = v.NodeType
+		t.ApproveType = v.ApproveType
+		t.Users = make([]*response.DataApproveDetailNodeUser, 0)
+		us := make([]*response.DataApproveNodeUserReq, 0)
+		if v.Users != "" {
+			e = json.Unmarshal([]byte(v.Users), &us)
+			if e != nil {
+				msg = "获取失败"
+				err = fmt.Errorf("json.Unmarshal err: %s", e.Error())
+				return
+			}
+		}
+		for _, vu := range us {
+			u := new(response.DataApproveDetailNodeUser)
+			u.UserType = vu.UserType
+			u.UserId = vu.UserId
+			u.UserName = vu.UserName
+			u.Sort = vu.Sort
+			// 审批记录
+			k := fmt.Sprintf("%d-%d", v.DataApproveNodeId, vu.UserId)
+			r := recordMap[k]
+			if r != nil {
+				u.ApproveRecord = new(response.DataApproveDetailNodeUserRecord)
+				u.ApproveRecord.DataApproveRecordId = r.DataApproveRecordId
+				u.ApproveRecord.State = r.State
+				u.ApproveRecord.ApproveUserId = r.ApproveUserId
+				u.ApproveRecord.ApproveUserName = r.ApproveUserName
+				u.ApproveRecord.ApproveRemark = r.ApproveRemark
+				u.ApproveRecord.ApproveTime = utils.TimeTransferString(utils.FormatDateTime, r.ApproveTime)
+			}
+			t.Users = append(t.Users, u)
+		}
+		sort.Slice(t.Users, func(k, j int) bool {
+			return t.Users[k].Sort < t.Users[j].Sort
+		})
+		detail.ApproveFlowNodes = append(detail.ApproveFlowNodes, t)
+	}
+
+	// 返回审批数据明细
+	dataList := make([]response.DataApproveDetailData, 0)
+	{
+		obj := new(dataApproveModel.DataApproveRelation)
+		dataItemList, tmpErr := obj.GetListByDataApproveId(approveItem.DataApproveId)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		dataIdList := make([]int, 0)
+		dataIdClassifyIdMap := make(map[int]int)
+		for _, v := range dataItemList {
+			dataIdList = append(dataIdList, v.DataId)
+			dataIdClassifyIdMap[v.DataId] = v.ClassifyId
+		}
+
+		switch approveItem.DataType {
+		case DataTypeEdb: // 指标库
+			tmpList, tmpErr := data_manage.GetEdbInfoByIdList(dataIdList)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			for _, v := range tmpList {
+				item := response.DataApproveDetailData{
+					DataId:       v.EdbInfoId,
+					DataName:     v.EdbName,
+					DataCode:     v.UniqueCode,
+					DataClassify: dataIdClassifyIdMap[v.EdbInfoId],
+				}
+				dataList = append(dataList, item)
+			}
+		case DataTypeChart: // 图库
+			tmpList, tmpErr := data_manage.GetChartInfoByIdList(dataIdList)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			for _, v := range tmpList {
+				item := response.DataApproveDetailData{
+					DataId:       v.ChartInfoId,
+					DataName:     v.ChartName,
+					DataCode:     v.UniqueCode,
+					DataClassify: dataIdClassifyIdMap[v.ChartInfoId],
+				}
+				dataList = append(dataList, item)
+			}
+		}
+	}
+
+	detail.DataList = dataList
+	resp = detail
+	return
+}
+
+func DataApproveRefuse(DataApproveId, adminId int, approveRemark string) (msg string, err error) {
+	approveItem, e := dataApproveModel.GetDataApproveById(DataApproveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetDataApproveById err: %s", e.Error())
+		return
+	}
+	if approveItem.State != DataApproveStateApproving {
+		msg = "审批状态有误, 请刷新页面"
+		err = fmt.Errorf("审批状态有误, State: %d", approveItem.State)
+		return
+	}
+
+	// 校验审批记录和审批
+	recordOb := new(dataApproveModel.DataApproveRecord)
+	recordCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ?`, dataApproveModel.DataApproveRecordCols.DataApproveId, dataApproveModel.DataApproveRecordCols.ApproveUserId, dataApproveModel.DataApproveRecordCols.State)
+	recordPars := make([]interface{}, 0)
+	recordPars = append(recordPars, approveItem.DataApproveId, adminId, DataApproveStateApproving)
+	recordItem, e := recordOb.GetItemByCondition(recordCond, recordPars, "")
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "无权审批"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 驳回审批
+	if e = refuseDataApprove(approveItem, recordItem, approveRemark, adminId); e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("RefuseDataApprove err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// refuseDataApprove 驳回审批
+func refuseDataApprove(approveItem *dataApproveModel.DataApprove, recordItem *dataApproveModel.DataApproveRecord, approveRemark string, sysAdminId int) (err error) {
+	if approveItem == nil {
+		err = fmt.Errorf("审批信息有误")
+		return
+	}
+	if recordItem == nil {
+		err = fmt.Errorf("审批记录有误")
+		return
+	}
+
+	// 更新审批记录
+	now := time.Now().Local()
+	recordItem.State = DataApproveStateRefuse
+	recordItem.ApproveRemark = approveRemark
+	recordItem.ApproveTime = now
+	recordItem.ModifyTime = now
+
+	recordItem.NodeState = DataApproveStateRefuse
+	recordItem.NodeApproveUserId = recordItem.ApproveUserId
+	recordItem.NodeApproveUserName = recordItem.ApproveUserName
+	recordItem.NodeApproveTime = now
+
+	recordCols := []string{"State", "ApproveRemark", "ApproveTime", "ModifyTime", "NodeState", "NodeApproveUserId", "NodeApproveUserName", "NodeApproveTime"}
+	if e := recordItem.Update(recordCols); e != nil {
+		err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 将该审批的同一个节点的记录标记为已审批
+	if e := recordItem.UpdateNodeState(recordItem.DataApproveId, recordItem.NodeId, recordItem.NodeState, recordItem.NodeApproveUserId, recordItem.NodeApproveUserName, recordItem.NodeApproveTime); e != nil {
+		err = fmt.Errorf("更新同一节点的其他审批记录状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 驳回-更新审批, 报告状态, 推送消息
+	approveItem.State = DataApproveStateRefuse
+	approveItem.ApproveRemark = approveRemark
+	approveItem.ApproveTime = now
+	approveItem.ModifyTime = now
+	approveCols := []string{"State", "ApproveRemark", "ApproveTime", "ModifyTime"}
+	if e := approveItem.Update(approveCols); e != nil {
+		err = fmt.Errorf("更新审批状态失败, Err: %s", e.Error())
+		return
+	}
+
+	if e := updateDataApproveState(approveItem, DataApproveStateRefuse); e != nil {
+		err = fmt.Errorf("更新报告状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送驳回消息给申请人
+	go func() {
+		messageItem := new(dataApproveModel.DataApproveMessage)
+		messageItem.SendUserId = sysAdminId
+		messageItem.ReceiveUserId = approveItem.ApplyUserId
+		messageItem.Content = "您提交的审批被驳回"
+		messageItem.Remark = fmt.Sprintf("您提交的【%s】已被驳回", approveItem.Title)
+		messageItem.DataApproveId = approveItem.DataApproveId
+		messageItem.ApproveState = DataApproveStateRefuse
+		messageItem.CreateTime = now
+		messageItem.ModifyTime = now
+		if e := messageItem.Create(); e != nil {
+			utils.FileLog.Info(fmt.Sprintf("ApproveData message err: %s", e.Error()))
+			return
+		}
+	}()
+	return
+}
+
+func DataApproveCancel(DataApproveId, adminId int, adminName string) (msg string, err error) {
+	approveItem, e := dataApproveModel.GetDataApproveById(DataApproveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批已被删除, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetDataApproveById err: %s", e.Error())
+		return
+	}
+	if approveItem.ApplyUserId != adminId {
+		msg = "非申请人不可撤销"
+		err = fmt.Errorf("非申请人不可撤销")
+		return
+	}
+
+	// 撤销审批
+	e = cancelDataApprove(approveItem, approveItem.DataApproveId, adminId, adminName)
+	if e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("cancelDataApprove err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// cancelDataApprove 撤回审批
+func cancelDataApprove(item *dataApproveModel.DataApprove, approveId, sysAdminId int, sysAdminName string) (err error) {
+	// todo
+	//// 默认内部审批, 如果是走的第三方审批, 那么仅修改状态
+	//confMap, e := models.GetBusinessConf()
+	//if e != nil {
+	//	err = fmt.Errorf("GetBusinessConf err: %s", e.Error())
+	//	return
+	//}
+	//openMap := map[string]bool{"false": false, "true": true}
+	//openApprove := openMap[confMap[models.BusinessConfIsDataApprove]]
+	//if !openApprove {
+	//	//err = fmt.Errorf("未开启审批")
+	//	return
+	//}
+
+	// 修改审批信息状态
+	approveItem, e := dataApproveModel.GetDataApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			err = e
+			return
+		}
+		err = fmt.Errorf("approve GetItemById err: %s", e.Error())
+		return
+	}
+	if approveItem.State == DataApproveStateCancel {
+		return
+	}
+	approveItem.State = DataApproveStateCancel
+	approveItem.ModifyTime = time.Now()
+	cols := []string{"State", "ModifyTime"}
+	if e = approveItem.Update(cols); e != nil {
+		err = fmt.Errorf("approve Update err: %s", e.Error())
+		return
+	}
+
+	// 修改报告状态
+	e = updateDataApproveState(approveItem, DataApproveStateCancel)
+	if e != nil {
+		err = fmt.Errorf("更新报告审批撤回失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送撤回消息
+	go func() {
+		recordOb := new(dataApproveModel.DataApproveRecord)
+		recordCond := fmt.Sprintf(` AND %s = ?`, dataApproveModel.DataApproveRecordCols.DataApproveId)
+		recordPars := make([]interface{}, 0)
+		recordPars = append(recordPars, approveId)
+		recordItems, e := recordOb.GetItemsByCondition(recordCond, recordPars, []string{}, "")
+		if e != nil {
+			utils.FileLog.Info(fmt.Sprintf("approve record GetItemsByCondition err: %s", e.Error()))
+			return
+		}
+
+		messageOb := new(dataApproveModel.DataApproveMessage)
+		messages := make([]*dataApproveModel.DataApproveMessage, 0)
+		for _, v := range recordItems {
+			m := new(dataApproveModel.DataApproveMessage)
+			m.SendUserId = sysAdminId
+			m.ReceiveUserId = v.ApproveUserId
+			m.Content = fmt.Sprintf("%s提交的【%s】已撤回", sysAdminName, approveItem.Title)
+			m.DataApproveId = approveId
+			m.ApproveState = DataApproveStateCancel
+			m.CreateTime = time.Now().Local()
+			m.ModifyTime = time.Now().Local()
+			messages = append(messages, m)
+		}
+		e = messageOb.CreateMulti(messages)
+		if e != nil {
+			utils.FileLog.Info(fmt.Sprintf("CancelDataApprove messages err: %s", e.Error()))
+			return
+		}
+	}()
+	return
+}
+
+// CheckOpenApprove 校验报告是否开启了审批流
+func CheckOpenApprove(dataType int) (opening bool, err error) {
+	// 查询对应分类是否有审批流
+	flowOb := new(dataApproveModel.DataApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, dataApproveModel.DataApproveFlowCols.DataType)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, dataType)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			return
+		}
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 查看审批节点
+	if flowItem.DataApproveFlowId > 0 {
+
+		nodeOb := new(dataApproveModel.DataApproveNode)
+		nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ? `, dataApproveModel.DataApproveNodeCols.DataApproveFlowId, dataApproveModel.DataApproveNodeCols.CurrVersion)
+		nodePars := make([]interface{}, 0)
+		nodePars = append(nodePars, flowItem.DataApproveFlowId, flowItem.CurrVersion)
+		nodeItems, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
+		if e != nil {
+			err = e
+			return
+		}
+
+		// 如果有审批节点,那么就确实有审批流,那么就返回true
+		if len(nodeItems) > 0 {
+			opening = true
+			return
+		}
+	}
+
+	return
+}
+
+type SetDataPublicItem struct {
+	DataId     int
+	ClassifyId int
+}
+
+// SubmitDataApprove
+// @Description: 提交审批
+// @author: Roc
+// @datetime 2024-12-06 10:13:40
+// @param dataType int
+// @param dataIdList []int
+// @param title string
+// @param description string
+// @param sysAdminId int
+// @param sysAdminName string
+// @return approveId int
+// @return err error
+func SubmitDataApprove(dataType int, dataList []SetDataPublicItem, title, description string, sysAdminId int, sysAdminName string) (approveId int, err error) {
+	// 查询审批流
+	flowOb := new(dataApproveModel.DataApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, dataApproveModel.DataApproveFlowCols.DataType)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, dataType)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil {
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 查询审批节点
+	nodeOb := new(dataApproveModel.DataApproveNode)
+	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, dataApproveModel.DataApproveNodeCols.DataApproveFlowId, dataApproveModel.DataApproveNodeCols.CurrVersion)
+	nodePars := make([]interface{}, 0)
+	nodePars = append(nodePars, flowItem.DataApproveFlowId, flowItem.CurrVersion)
+	nodeItems, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
+	if e != nil {
+		err = fmt.Errorf("ApproveNodes GetItemsByCondition err: %s", e.Error())
+		return
+	}
+	if len(nodeItems) == 0 {
+		err = fmt.Errorf("无审批节点")
+		return
+	}
+
+	// 取出首个节点
+	firstNodeItem := new(dataApproveModel.DataApproveNode)
+	for _, v := range nodeItems {
+		if v.PrevNodeId == 0 {
+			firstNodeItem = v
+			continue
+		}
+	}
+	if firstNodeItem == nil {
+		err = fmt.Errorf("首个审批节点有误")
+		return
+	}
+
+	// 审批信息
+	now := time.Now().Local()
+	newApprove := new(dataApproveModel.DataApprove)
+	newApprove.Title = title
+	newApprove.ApproveRemark = description
+	newApprove.DataType = dataType
+	newApprove.State = DataApproveStateApproving
+	newApprove.FlowId = flowItem.DataApproveFlowId
+	newApprove.FlowVersion = flowItem.CurrVersion
+	newApprove.StartNodeId = firstNodeItem.DataApproveNodeId
+	newApprove.CurrNodeId = firstNodeItem.DataApproveNodeId
+	newApprove.ApplyUserId = sysAdminId
+	newApprove.ApplyUserName = sysAdminName
+	newApprove.CreateTime = now
+	newApprove.ModifyTime = now
+
+	relationList := make([]*dataApproveModel.DataApproveRelation, 0)
+	for _, dataItem := range dataList {
+		relationList = append(relationList, &dataApproveModel.DataApproveRelation{
+			DataApproveRelationId: 0,
+			DataApproveId:         0,
+			DataId:                dataItem.DataId,
+			ClassifyId:            dataItem.ClassifyId,
+			CreateTime:            now,
+		})
+	}
+	e = dataApproveModel.AddDataApprove(newApprove, relationList)
+	if e != nil {
+		err = fmt.Errorf("生成审批信息失败, Err: %s", e.Error())
+		return
+	}
+
+	approveId = newApprove.DataApproveId
+
+	// 生成节点审批记录
+	err = BuildNextNodeRecordAndMsg(firstNodeItem, newApprove.DataApproveId, sysAdminId, sysAdminName, newApprove.Title)
+
+	return
+}
+
+func toDataApproveItemOrmResp(src []*dataApproveModel.DataApproveItemOrm) (res []*response.DataApproveItemOrmResp) {
+	for _, v := range src {
+		r := new(response.DataApproveItemOrmResp)
+		r.DataApproveId = v.DataApproveId
+		r.DataApproveRecordId = v.DataApproveRecordId
+		r.Title = v.Title
+		r.DataType = v.DataType
+		r.State = v.State
+		r.RecordState = v.RecordState
+		r.FlowId = v.FlowId
+		r.FlowVersion = v.FlowVersion
+		r.StartNodeId = v.StartNodeId
+		r.CurrNodeId = v.CurrNodeId
+		r.ApplyUserId = v.ApplyUserId
+		r.ApplyUserName = v.ApplyUserName
+		r.ApproveRemark = v.ApproveRemark
+		r.ApproveTime = utils.TimeTransferString(utils.FormatDateTime, v.ApproveTime)
+		r.HandleTime = utils.TimeTransferString(utils.FormatDateTime, v.HandleTime)
+		r.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime)
+		r.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime)
+		r.NodeState = v.NodeState
+		res = append(res, r)
+	}
+	return
+}
+
+// CheckHasDataApproving
+// @Description: 查询是否还存在带审批的审批单
+// @author: Roc
+// @datetime 2024-12-06 10:43:00
+// @return ok bool
+// @return err error
+func CheckHasDataApproving() (ok bool, err error) {
+	count, err := dataApproveModel.GetDataApproveCountByState(DataApproveStateApproving)
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		ok = true
+	}
+	return
+}

+ 174 - 0
services/data/data_approve/approve_flow.go

@@ -0,0 +1,174 @@
+package data_approve
+
+import (
+	"encoding/json"
+	DataApprove "eta_gn/eta_api/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/data_approve/request"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+// SaveDataApproveFlow 保存审批流
+func SaveDataApproveFlow(flow *request.DataApproveFlowSaveReq) (ok bool, msg string, err error) {
+
+	flowInfo, err := DataApprove.GetDataApproveFlowByDataType(flow.DataType)
+	if err != nil {
+		if !utils.IsErrNoRow(err) {
+			msg = "保存审批流失败, 查找审批流失败"
+			return
+		}
+	}
+
+	if flowInfo.DataApproveFlowId <= 0 {
+		// 之前没有过记录,所以走新增
+		var remark string
+		switch flow.DataType {
+		case 1:
+			remark = `指标审批`
+		case 2:
+			remark = `图表审批`
+		}
+		t := &DataApprove.DataApproveFlow{
+			FlowName:    flow.FlowName,
+			DataType:    flow.DataType,
+			Remark:      remark,
+			CurrVersion: 1,
+			CreateTime:  time.Now(),
+			ModifyTime:  time.Now(),
+		}
+		flowNodeItems := make([]*DataApprove.DataApproveNode, 0)
+		for _, node := range flow.Nodes {
+			flowNode := new(DataApprove.DataApproveNode)
+			flowNode.ApproveType = node.ApproveType
+			flowNode.CurrVersion = t.CurrVersion
+			userBytes, er := json.Marshal(node.Users)
+			if er != nil {
+				err = er
+				msg = "保存审批流失败"
+				return
+			}
+			flowNode.Users = string(userBytes)
+			flowNode.CreatedTime = time.Now()
+			flowNodeItems = append(flowNodeItems, flowNode)
+		}
+		err = t.Add(flowNodeItems)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		ok = true
+	} else {
+		ok, err = CheckDeleteDataApproveFlow(flowInfo.DataApproveFlowId)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		if !ok {
+			msg = "保存审批流失败, 存在还未审批的报告"
+			return
+		}
+		var updateCols []string
+		if flowInfo.FlowName != flow.FlowName {
+			flowInfo.FlowName = flow.FlowName
+			updateCols = append(updateCols, "flow_name")
+		}
+		flowInfo.CurrVersion += 1
+		flowInfo.ModifyTime = time.Now()
+		updateCols = append(updateCols, "modify_time", "curr_version")
+
+		biFlowNodeItems := make([]*DataApprove.DataApproveNode, 0)
+		for _, node := range flow.Nodes {
+			flowNode := new(DataApprove.DataApproveNode)
+			flowNode.ApproveType = node.ApproveType
+			flowNode.CurrVersion = flowInfo.CurrVersion
+			userBytes, er := json.Marshal(node.Users)
+			if er != nil {
+				err = er
+				msg = "保存审批流失败"
+				return
+			}
+			flowNode.Users = string(userBytes)
+			flowNode.CreatedTime = time.Now()
+			biFlowNodeItems = append(biFlowNodeItems, flowNode)
+		}
+
+		err = flowInfo.Update(updateCols, biFlowNodeItems)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		ok = true
+	}
+	return
+}
+
+// GetDataApproveFlowDetail 获取审批流详情
+func GetDataApproveFlowDetail(dataType int) (detail *response.DataApproveFlowDetailResp, msg string, err error) {
+	flowInfo, err := DataApprove.GetDataApproveFlowByDataType(dataType)
+	if err != nil && !utils.IsErrNoRow(err) {
+		msg = "获取审批流详情失败"
+		return
+	}
+	flowNodes := make([]*DataApprove.DataApproveNode, 0)
+
+	// 如果有配置的话
+	if flowInfo.DataApproveFlowId > 0 {
+		flowNodes, err = DataApprove.GetDataApproveNodeByFlowIdAndVersionId(flowInfo.DataApproveFlowId, flowInfo.CurrVersion)
+		if err != nil {
+			msg = "获取审批流详情失败"
+			return
+		}
+	}
+
+	detail, err = FormatFlowAndNodesItem2Detail(flowInfo, flowNodes)
+	if err != nil {
+		msg = "获取审批流详情失败"
+		return
+	}
+	return
+}
+
+// CheckDeleteDataApproveFlow 检查是否可以删除审批流
+func CheckDeleteDataApproveFlow(flowId int) (ok bool, err error) {
+	flowInfo, err := DataApprove.GetDataApproveFlowById(flowId)
+	if err != nil {
+		return
+	}
+	// 检查是否存在还未审批的Bi看报
+	approveList, err := DataApprove.GetDataApproveByFlowIdAndVersionId(flowInfo.DataApproveFlowId, flowInfo.CurrVersion)
+	if err != nil {
+		return
+	}
+	for _, v := range approveList {
+		if v.State == DataApproveStateApproving {
+			return false, nil
+		}
+	}
+
+	ok = true
+	return
+}
+
+func FormatFlowAndNodesItem2Detail(flowItem *DataApprove.DataApproveFlow, nodeItems []*DataApprove.DataApproveNode) (detail *response.DataApproveFlowDetailResp, err error) {
+	if flowItem == nil {
+		return
+	}
+	detail = new(response.DataApproveFlowDetailResp)
+	detail.DataApproveFlowId = flowItem.DataApproveFlowId
+	detail.FlowName = flowItem.FlowName
+	detail.DataType = flowItem.DataType
+	detail.CreateTime = utils.TimeTransferString(utils.FormatDateTime, flowItem.CreateTime)
+	detail.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, flowItem.ModifyTime)
+	detail.Nodes = make([]*response.DataApproveNodeItem, 0)
+	for _, v := range nodeItems {
+		t, e := FormatDataApproveNode2Item(v)
+		if e != nil {
+			err = fmt.Errorf("format node err: %s", e.Error())
+			return
+		}
+		detail.Nodes = append(detail.Nodes, t)
+	}
+	return
+}

+ 89 - 0
services/data/data_approve/approve_message.go

@@ -0,0 +1,89 @@
+package data_approve
+
+import (
+	DataApprove "eta_gn/eta_api/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+func GetDataApproveMessage(adminId, startSize, pageSize int) (list []*response.DataApproveMessageItem, total, unread int, msg string, err error) {
+	cond := fmt.Sprintf(` AND %s = ?`, DataApprove.DataApproveMessageCols.ReceiveUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	order := fmt.Sprintf(`%s ASC, %s DESC`, DataApprove.DataApproveMessageCols.IsRead, DataApprove.DataApproveMessageCols.CreateTime)
+
+	messageOb := new(DataApprove.DataApproveMessage)
+	total, e := messageOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("message.GetCountByCondition, Err: %s", e.Error())
+		return
+	}
+	tmpList, e := messageOb.GetPageItemsByCondition(cond, pars, []string{}, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("message.GetPageItemsByCondition, Err: %s", e.Error())
+		return
+	}
+	for _, v := range tmpList {
+		t := FormatDataApproveMessage2Item(v)
+		list = append(list, t)
+	}
+
+	// 未读消息数
+	cond += fmt.Sprintf(` AND %s = ?`, DataApprove.DataApproveMessageCols.IsRead)
+	pars = append(pars, 0)
+	unreadTotal, e := messageOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("message.GetCountByCondition, Err: %s", e.Error())
+		return
+	}
+	unread = unreadTotal
+	return
+}
+
+func ReadBiMessage(msgId int, adminId int) (msg string, err error) {
+	messageOb := new(DataApprove.DataApproveMessage)
+	messageItem, e := messageOb.GetItemById(msgId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "消息不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "获取失败"
+		err = fmt.Errorf("message.GetItemById, Err: %s", e.Error())
+		return
+	}
+	messageItem.IsRead = 1
+	messageItem.ModifyTime = time.Now().Local()
+	cols := []string{"IsRead", "ModifyTime"}
+	if e = messageItem.Update(cols); e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("message.Update, Err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// FormatDataApproveMessage2Item 格式化报告审批消息
+func FormatDataApproveMessage2Item(origin *DataApprove.DataApproveMessage) (item *response.DataApproveMessageItem) {
+	item = new(response.DataApproveMessageItem)
+	if origin == nil {
+		return
+	}
+	item.Id = origin.Id
+	item.SendUserId = origin.SendUserId
+	item.ReceiveUserId = origin.ReceiveUserId
+	item.Content = origin.Content
+	item.Remark = origin.Remark
+	item.DataApproveId = origin.DataApproveId
+	item.ApproveState = origin.ApproveState
+	item.IsRead = origin.IsRead
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	return
+}

+ 31 - 0
services/data/data_approve/approve_node.go

@@ -0,0 +1,31 @@
+package data_approve
+
+import (
+	"encoding/json"
+	DataApprove "eta_gn/eta_api/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	"fmt"
+)
+
+// FormatDataApproveNode2Item 格式化报告审批节点信息
+func FormatDataApproveNode2Item(origin *DataApprove.DataApproveNode) (item *response.DataApproveNodeItem, err error) {
+	if origin == nil {
+		return
+	}
+	item = new(response.DataApproveNodeItem)
+	item.DataApproveNodeId = origin.DataApproveNodeId
+	item.DataApproveFlowId = origin.DataApproveFlowId
+	item.PrevNodeId = origin.PrevNodeId
+	item.NextNodeId = origin.NextNodeId
+	item.NodeType = origin.NodeType
+	item.ApproveType = origin.ApproveType
+	item.Users = make([]*response.DataApproveNodeUser, 0)
+	if origin.Users != "" {
+		e := json.Unmarshal([]byte(origin.Users), &item.Users)
+		if e != nil {
+			err = fmt.Errorf("node users unmarshal err: %s", e.Error())
+			return
+		}
+	}
+	return
+}

+ 37 - 0
services/data/data_approve/constant.go

@@ -0,0 +1,37 @@
+package data_approve
+
+// 看板状态
+const (
+	BiStateUnpublished = 1 // 未公开
+	// BiStatePublished   = 2 // 已发布
+	// BiStateWaitSubmit  = 3 // 待提交
+	BiStateWaitApprove = 4 // 待审批
+	BiStateRefused     = 5 // 已驳回
+	BiStatePass        = 6 // 已通过
+)
+
+const (
+	DataTypeEdb   = 1 // 指标审批
+	DataTypeChart = 2 // 图库审批
+)
+
+// 节点审批方式
+const (
+	NodeApproveTypeRoll = 1 // 依次审批
+	NodeApproveTypeAll  = 2 // 会签
+	NodeApproveTypeAny  = 3 // 或签
+)
+
+// 节点审批人类型
+const (
+	NodeUserTypeNormal = "user" // 用户
+	NodeUserTypeRole   = "role" // 角色
+)
+
+// 报告审批状态
+const (
+	DataApproveStateApproving = 1 // 待审批
+	DataApproveStatePass      = 2 // 已审批
+	DataApproveStateRefuse    = 3 // 已驳回
+	DataApproveStateCancel    = 4 // 已撤销
+)

+ 8 - 5
services/data/data_manage_permission/data_move.go

@@ -24,7 +24,7 @@ import (
 // @param subSource int
 // @return resp data_manage.EdbChartClassifyResp
 // @return err error
-func GetEdbChartClassifyList(source, subSource int) (resp data_manage.EdbChartClassifyResp, err error) {
+func GetEdbChartClassifyList(source, subSource, sysUserId int) (resp data_manage.EdbChartClassifyResp, err error) {
 	switch source {
 	case 1: //手工数据指标
 		list, e := models.GetEdbdataClassify(0)
@@ -56,8 +56,11 @@ func GetEdbChartClassifyList(source, subSource int) (resp data_manage.EdbChartCl
 		if source == 7 {
 			classifyType = utils.EdbClassifyTypeCalculate
 		}
+		if classifyType == utils.EdbClassifyTypeBase {
+			sysUserId = 0
+		}
 		// 考虑到后面可以会迭代到10层, 这里直接用递归处理
-		classifyAll, e := data_manage.GetAllEdbClassifyByType(classifyType)
+		classifyAll, e := data_manage.GetAllEdbClassifyByType(classifyType, sysUserId)
 		if e != nil && !utils.IsErrNoRow(e) {
 			err = e
 			return
@@ -67,7 +70,7 @@ func GetEdbChartClassifyList(source, subSource int) (resp data_manage.EdbChartCl
 	case 4:
 		//ETA预测指标
 		// 考虑到后面可以会迭代到10层, 这里直接用递归
-		classifyAll, e := data_manage.GetAllEdbClassifyByType(1)
+		classifyAll, e := data_manage.GetAllEdbClassifyByType(1, sysUserId)
 		if e != nil && !utils.IsErrNoRow(e) {
 			err = e
 			return
@@ -293,7 +296,7 @@ func GetMoveEdbChartList(source, subSource, userId int, keyword, classify string
 		}
 
 		// 获取所有的图表分类
-		firstClassifyList, tmpErr := data_manage.GetChartClassifyByParentId(0, 1)
+		firstClassifyList, tmpErr := data_manage.GetChartClassifyByParentId(0, 1, userId)
 		if tmpErr != nil {
 			err = tmpErr
 			return
@@ -304,7 +307,7 @@ func GetMoveEdbChartList(source, subSource, userId int, keyword, classify string
 			firstClassifyNameMap[v.ChartClassifyId] = v.ChartClassifyName
 			firstClassifyNameEnMap[v.ChartClassifyId] = v.ChartClassifyNameEn
 		}
-		secondClassList, tmpErr := data_manage.GetChartClassifyAll(1)
+		secondClassList, tmpErr := data_manage.GetChartClassifyAll(1, userId)
 		if tmpErr != nil {
 			err = tmpErr
 			return

+ 59 - 0
services/data/data_manage_permission/edb.go

@@ -169,6 +169,7 @@ func CheckEdbPermission(edbIsJoinPermission, edbClassifyIsJoinPermission, userId
 // @return classifyIdList
 // @return err
 func GetUserAllEdbAndClassifyNoPermissionList(userId, edbInfoType, edbType int) (edbIdList, classifyIdList []int, err error) {
+	// TODO 这块需要调整掉,只获取数据查看的
 	edbIdList = make([]int, 0)
 	classifyIdList = make([]int, 0)
 
@@ -231,3 +232,61 @@ func GetUserAllEdbAndClassifyNoPermissionList(userId, edbInfoType, edbType int)
 
 	return
 }
+
+// GetUserAllEdbAndClassifyNoPermissionListV2
+// @Description: 根据用户获取已经未授权的指标ID列表和指标分类ID列表(仅有数据查看(基础的普通指标)的指标了)
+// @param userId
+// @return edbIdList
+// @return classifyIdList
+// @return err
+func GetUserAllEdbAndClassifyNoPermissionListV2(userId int) (edbIdList, classifyIdList []int, err error) {
+	edbIdList = make([]int, 0)
+	classifyIdList = make([]int, 0)
+	// 获取所有无权限指标id列表
+	{
+		isJoinPermissionEdbIdList, tmpErr := data_manage.GetIsJoinPermissionEdbInfoIdList(utils.EDB_INFO_TYPE, utils.EdbTypeBase)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		// 获取有权限的指标ID列表
+		hasPermissionEdbIdList, tmpErr := data_manage_permission.GetPermissionEdbIdList(userId, 0)
+		if tmpErr != nil {
+			err = tmpErr
+			fmt.Println("获取授权指标列表失败, err:", tmpErr)
+			return
+		}
+		for _, edbId := range isJoinPermissionEdbIdList {
+			if !utils.InArrayByInt(hasPermissionEdbIdList, edbId) {
+				edbIdList = append(edbIdList, edbId)
+			}
+		}
+	}
+
+	// 获取所有无权限指标分类id列表
+	{
+		classifyType := 0
+
+		isJoinPermissionEdbClassifyIdList, tmpErr := data_manage.GetIsJoinPermissionEdbClassifyIdList(classifyType)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		// 获取有权限的指标分类ID列表
+		hasPermissionClassifyIdList, tmpErr := data_manage_permission.GetPermissionEdbClassifyIdList(userId, 0)
+		if tmpErr != nil {
+			err = tmpErr
+			fmt.Println("获取授权指标分类列表失败, err:", err)
+			return
+		}
+		for _, classifyId := range isJoinPermissionEdbClassifyIdList {
+			if !utils.InArrayByInt(hasPermissionClassifyIdList, classifyId) {
+				classifyIdList = append(classifyIdList, classifyId)
+			}
+		}
+	}
+
+	return
+}

+ 401 - 258
services/data/edb_classify.go

@@ -32,7 +32,12 @@ func GetClassifyTreeRecursive(list []*data_manage.EdbClassifyItems, parentId int
 	res := make([]*data_manage.EdbClassifyItems, 0)
 	for _, v := range list {
 		if v.ParentId == parentId {
-			v.Children = GetClassifyTreeRecursive(list, v.ClassifyId)
+			children := GetClassifyTreeRecursive(list, v.ClassifyId)
+			if v.Children == nil {
+				v.Children = children
+			} else {
+				v.Children = append(v.Children, children...)
+			}
 			res = append(res, v)
 		}
 	}
@@ -258,9 +263,9 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 		var count int
 		switch lang {
 		case utils.EnLangVersion:
-			count, err = data_manage.GetEdbClassifyEnCount(classifyName, parentId, classifyType)
+			count, err = data_manage.GetEdbClassifyEnCount(classifyName, parentId, sysUserId, classifyType)
 		default:
-			count, err = data_manage.GetEdbClassifyCount(classifyName, parentId, classifyType)
+			count, err = data_manage.GetEdbClassifyCount(classifyName, parentId, sysUserId, classifyType)
 		}
 		if err != nil {
 			errMsg = `判断名称是否已存在失败`
@@ -288,6 +293,7 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 	}
 	//查询顶级rootId
 	rootId := 0
+	var classifyNamePath, classifyIdPath string
 	if parentId > 0 {
 		parentClassify, tErr := data_manage.GetEdbClassifyById(parentId)
 		if tErr != nil {
@@ -301,31 +307,52 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 			return
 		}
 		rootId = parentClassify.RootId
+
+		classifyNamePath = fmt.Sprint(parentClassify.ClassifyNamePath, "|", classifyName)
+		classifyIdPath = fmt.Sprint(parentClassify.ClassifyIdPath, ",")
+	} else {
+		classifyNamePath = classifyName
 	}
 
 	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
 	classifyInfo = &data_manage.EdbClassify{
 		//ClassifyId:      0,
-		ClassifyType:    classifyType,
-		ClassifyName:    classifyName,
-		ClassifyNameEn:  classifyName,
-		ParentId:        parentId,
-		RootId:          rootId,
-		HasData:         0,
-		CreateTime:      time.Now(),
-		ModifyTime:      time.Now(),
-		SysUserId:       sysUserId,
-		SysUserRealName: sysUserName,
-		Level:           level + 1,
-		UniqueCode:      utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
-		Sort:            maxSort + 1,
+		ClassifyType:     classifyType,
+		ClassifyName:     classifyName,
+		ClassifyNameEn:   classifyName,
+		ParentId:         parentId,
+		RootId:           rootId,
+		HasData:          0,
+		CreateTime:       time.Now(),
+		ModifyTime:       time.Now(),
+		SysUserId:        sysUserId,
+		SysUserRealName:  sysUserName,
+		Level:            level + 1,
+		UniqueCode:       utils.MD5(utils.DATA_PREFIX + "_" + timestamp),
+		Sort:             maxSort + 1,
+		ClassifyNamePath: classifyNamePath,
 	}
-	newId, err := data_manage.AddEdbClassify(classifyInfo)
+	err = data_manage.AddEdbClassify(classifyInfo)
 	if err != nil {
 		errMsg = "保存分类失败"
 		return
 	}
 
+	// 更改分类id完整路径path
+	updateCols := []string{"ClassifyIdPath"}
+	classifyInfo.ClassifyIdPath = fmt.Sprint(classifyIdPath, classifyInfo.ClassifyId)
+
+	if parentId == 0 { //一级目录的rootId等于自己本身
+		classifyInfo.RootId = classifyInfo.ClassifyId
+		updateCols = append(updateCols, "RootId")
+
+	}
+	err = classifyInfo.Update(updateCols)
+	if err != nil {
+		errMsg = "更新分类失败"
+		return
+	}
+
 	// 继承分类权限
 	{
 		source := utils.EdbPermissionSourceBase
@@ -335,17 +362,7 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 		if classifyType == utils.EdbClassifyTypeCalculate {
 			source = utils.EdbPermissionSourceCalculate
 		}
-		go data_manage_permission.InheritParentClassify(source, int(classifyType), int(newId), classifyInfo.ParentId, classifyInfo.ClassifyName)
-	}
-
-	if parentId == 0 { //一级目录的rootId等于自己本身
-		classifyInfo.ClassifyId = int(newId)
-		classifyInfo.RootId = int(newId)
-		err = classifyInfo.Update([]string{"RootId"})
-		if err != nil {
-			errMsg = "更新分类失败"
-			return
-		}
+		go data_manage_permission.InheritParentClassify(source, int(classifyType), classifyInfo.ClassifyId, classifyInfo.ParentId, classifyInfo.ClassifyName)
 	}
 
 	return
@@ -392,6 +409,9 @@ func EditEdbClassify(classifyId int, classifyName, lang string, sysUser *system.
 	// 需要变更的字段
 	updateCols := make([]string, 0)
 
+	// 旧完整路径  , 新的完整路径
+	var oldClassifyNamePath, newClassifyNamePath string
+
 	switch lang {
 	case utils.EnLangVersion:
 		// 名字相同,那么就直接返回
@@ -400,7 +420,7 @@ func EditEdbClassify(classifyId int, classifyName, lang string, sysUser *system.
 		}
 
 		// 判断名称是否已存在
-		count, tmpErr := data_manage.GetEdbClassifyEnCount(classifyName, item.ParentId, item.ClassifyType)
+		count, tmpErr := data_manage.GetEdbClassifyEnCount(classifyName, item.ParentId, sysUser.AdminId, item.ClassifyType)
 		if tmpErr != nil {
 			err = tmpErr
 			errMsg = "判断名称是否已存在失败"
@@ -422,27 +442,44 @@ func EditEdbClassify(classifyId int, classifyName, lang string, sysUser *system.
 			return
 		}
 
-		// 判断名称是否已存在
-		count, tmpErr := data_manage.GetEdbClassifyCount(classifyName, item.ParentId, item.ClassifyType)
-		if tmpErr != nil {
-			err = tmpErr
-			errMsg = "判断名称是否已存在失败"
-			return
-		}
-		if count > 0 {
-			errMsg = "分类名称已存在,请重新输入"
-			err = errors.New(errMsg)
-			return
+		//// 判断名称是否已存在
+		//count, tmpErr := data_manage.GetEdbClassifyCount(classifyName, item.ParentId, sysUser.AdminId, item.ClassifyType)
+		//if tmpErr != nil {
+		//	err = tmpErr
+		//	errMsg = "判断名称是否已存在失败"
+		//	return
+		//}
+		//if count > 0 {
+		//	errMsg = "分类名称已存在,请重新输入"
+		//	err = errors.New(errMsg)
+		//	return
+		//}
+
+		// 旧完整路径
+		oldClassifyNamePath = item.ClassifyNamePath
+
+		if item.ParentId > 0 {
+			parentItem, tmpErr := data_manage.GetEdbClassifyById(item.ParentId)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			newClassifyNamePath = fmt.Sprint(parentItem.ClassifyNamePath, "|", classifyName)
+		} else {
+			newClassifyNamePath = classifyName
 		}
+
+		// 更新自己的信息
 		item.ClassifyName = classifyName
+		item.ClassifyNamePath = newClassifyNamePath
 		item.LastModifyUserId = sysUser.AdminId
 		item.LastModifyUserRealName = sysUser.RealName
-		updateCols = append(updateCols, "ClassifyName", "LastModifyUserId", "LastModifyUserRealName")
+		updateCols = append(updateCols, "ClassifyName", "ClassifyNamePath", "LastModifyUserId", "LastModifyUserRealName")
 	}
 
 	// 修改数据
 	if len(updateCols) > 0 {
-		err = item.Update(updateCols)
+		err = item.UpdateEdbClassifyNameAndNamePath(updateCols, oldClassifyNamePath, newClassifyNamePath)
 		if err != nil {
 			errMsg = "保存失败"
 		}
@@ -989,6 +1026,11 @@ func MoveEdbClassify(req data_manage.MoveEdbClassifyReq, sysUser *system.Admin,
 			err = errors.New("获取分类信息失败,Err:" + err.Error())
 			return
 		}
+		if edbClassifyInfo.SysUserId != sysUser.AdminId {
+			errMsg = "不是本人目录,您没有操作权限"
+			err = errors.New(errMsg)
+			return
+		}
 		if parentClassifyId > 0 && parentEdbClassifyInfo.Level == 6 {
 			errMsg = "最高只支持添加6级分类"
 			err = errors.New(errMsg)
@@ -1047,6 +1089,13 @@ func MoveEdbClassify(req data_manage.MoveEdbClassifyReq, sysUser *system.Admin,
 			err = errors.New("获取分类信息失败,Err:" + err.Error())
 			return
 		}
+
+		if edbInfo.SysUserId != sysUser.AdminId {
+			errMsg = "不是本人指标,您没有操作权限"
+			err = errors.New(errMsg)
+			return
+		}
+
 		if parentClassifyId == 0 {
 			errMsg = "移动失败,指标必须挂在分类下"
 			err = errors.New(errMsg)
@@ -1111,67 +1160,84 @@ func MoveEdbClassify(req data_manage.MoveEdbClassifyReq, sysUser *system.Admin,
 		nextSort = nextEdbInfo.Sort
 	}
 
-	err, errMsg = moveEdbClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify, edbInfo, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	err, errMsg = moveEdbOrClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify, edbInfo, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
 	return
 }
 
-// moveEdbClassify 移动指标分类
-func moveEdbClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify *data_manage.EdbClassify, edbInfo, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
-	updateCol := make([]string, 0)
+// moveEdbOrClassify 移动指标分类
+func moveEdbOrClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify *data_manage.EdbClassify, edbInfo, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
 
-	// 移动对象为分类, 判断分类是否存在
 	if edbClassifyInfo != nil {
-		oldParentId := edbClassifyInfo.ParentId
-		oldLevel := edbClassifyInfo.Level
-		var classifyIds []int
-		if oldParentId != parentClassifyId {
-			//更新子分类对应的level
-			childList, e, m := GetChildClassifyByClassifyId(edbClassifyInfo.ClassifyId)
-			if e != nil {
-				errMsg = "移动失败"
-				err = errors.New("查询子分类失败,Err:" + e.Error() + m)
-				return
-			}
+		// 移动分类
+		return moveEdbClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	} else {
+		// 移动指标
+		return moveEdb(prevClassify, nextClassify, edbInfo, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	}
 
-			if len(childList) > 0 {
-				for _, v := range childList {
-					if v.ClassifyId == edbClassifyInfo.ClassifyId {
-						continue
-					}
-					classifyIds = append(classifyIds, v.ClassifyId)
+	return
+}
+
+// moveEdb
+// @Description: 移动指标
+// @author: Roc
+// @datetime 2024-11-26 16:07:37
+// @param prevClassify *data_manage.EdbClassify
+// @param nextClassify *data_manage.EdbClassify
+// @param edbInfo *data_manage.EdbInfo
+// @param prevEdbInfo *data_manage.EdbInfo
+// @param nextEdbInfo *data_manage.EdbInfo
+// @param parentClassifyId int
+// @param prevSort int
+// @param nextSort int
+// @param classifyType uint8
+// @return err error
+// @return errMsg string
+func moveEdb(prevClassify, nextClassify *data_manage.EdbClassify, edbInfo, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
+	updateCol := make([]string, 0)
+
+	if edbInfo == nil {
+		errMsg = "当前指标不存在"
+		err = errors.New(errMsg)
+		return
+	}
+	//如果改变了分类,那么移动该指标数据
+	if edbInfo.ClassifyId != parentClassifyId {
+		edbInfo.ClassifyId = parentClassifyId
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "ClassifyId", "ModifyTime")
+	}
+	if prevSort > 0 {
+		//如果是移动在两个兄弟节点之间
+		if nextSort > 0 {
+			//下一个兄弟节点
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevSort == nextSort || prevSort == edbInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+
+				//变更分类
+				if prevClassify != nil {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr, classifyType)
+				} else {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
 				}
-			}
-		}
-		//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
-		if edbClassifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
-			if edbClassifyInfo.Level != parentEdbClassifyInfo.Level+1 { //禁止层级调整
-				errMsg = "移动失败"
-				err = errors.New("不支持目录层级变更")
-				return
-			}
-			edbClassifyInfo.ParentId = parentEdbClassifyInfo.ClassifyId
-			edbClassifyInfo.RootId = parentEdbClassifyInfo.RootId
-			edbClassifyInfo.Level = parentEdbClassifyInfo.Level + 1
-			edbClassifyInfo.ModifyTime = time.Now()
-			updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime")
-		} else if edbClassifyInfo.ParentId != parentClassifyId && parentClassifyId == 0 {
-			errMsg = "移动失败"
-			err = errors.New("不支持目录层级变更")
-			return
-		}
 
-		if prevSort > 0 {
-			//如果是移动在两个兄弟节点之间
-			if nextSort > 0 {
-				//下一个兄弟节点
-				//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
-				if prevSort == nextSort || prevSort == edbClassifyInfo.Sort {
+				//变更指标
+				if prevEdbInfo != nil {
 					//变更兄弟节点的排序
-					updateSortStr := `sort + 2`
-
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+				} else {
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+				}
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextSort-prevSort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
 					//变更分类
 					if prevClassify != nil {
-						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr, classifyType)
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr, classifyType)
 					} else {
 						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
 					}
@@ -1183,128 +1249,167 @@ func moveEdbClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextC
 					} else {
 						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
 					}
-				} else {
-					//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
-					if nextSort-prevSort == 1 {
-						//变更兄弟节点的排序
-						updateSortStr := `sort + 1`
-
-						//变更分类
-						if prevClassify != nil {
-							_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr, classifyType)
-						} else {
-							_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
-						}
-
-						//变更指标
-						if prevEdbInfo != nil {
-							//变更兄弟节点的排序
-							_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
-						} else {
-							_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
-						}
-
-					}
 				}
 			}
+		}
 
-			edbClassifyInfo.Sort = prevSort + 1
-			edbClassifyInfo.ModifyTime = time.Now()
-			updateCol = append(updateCol, "Sort", "ModifyTime")
-		} else if prevClassify == nil && nextClassify == nil && prevEdbInfo == nil && nextEdbInfo == nil && parentClassifyId > 0 {
-			//处理只拖动到目录里,默认放到目录底部的情况
-			var maxSort int
-			maxSort, err = GetEdbClassifyMaxSort(parentClassifyId, classifyType)
-			if err != nil {
-				errMsg = "移动失败"
-				err = errors.New("查询组内排序信息失败,Err:" + err.Error())
-				return
-			}
-			edbClassifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
-			edbClassifyInfo.ModifyTime = time.Now()
-			updateCol = append(updateCol, "Sort", "ModifyTime")
+		edbInfo.Sort = prevSort + 1
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else if prevClassify == nil && nextClassify == nil && prevEdbInfo == nil && nextEdbInfo == nil && parentClassifyId > 0 {
+		//处理只拖动到目录里,默认放到目录底部的情况
+		var maxSort int
+		maxSort, err = GetEdbClassifyMaxSort(parentClassifyId, classifyType)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+			return
+		}
+		edbInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, tmpErr := data_manage.GetFirstEdbClassifyByParentId(parentClassifyId)
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.ClassifyId > 0 && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr, classifyType)
+			//该分类下的所有指标也需要+1
+			_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, 0, updateSortStr)
 		} else {
-			// 拖动到父级分类的第一位
-			firstClassify, tmpErr := data_manage.GetFirstEdbClassifyByParentId(parentClassifyId)
-			if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			//如果该分类下存在指标,且第一个指标的排序等于0,那么需要调整排序
+			firstEdb, tErr := data_manage.GetFirstEdbInfoByClassifyId(parentClassifyId)
+			if tErr != nil && !utils.IsErrNoRow(tErr) {
 				errMsg = "移动失败"
-				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
 				return
 			}
 
 			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
-			if firstClassify != nil && firstClassify.ClassifyId > 0 && firstClassify.Sort == 0 {
+			if firstEdb != nil && firstEdb.ClassifyId > 0 && firstEdb.Sort == 0 {
 				updateSortStr := ` sort + 1 `
-				_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr, classifyType)
-				//该分类下的所有指标也需要+1
-				_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, 0, updateSortStr)
-			} else {
-				//如果该分类下存在指标,且第一个指标的排序等于0,那么需要调整排序
-				firstEdb, tErr := data_manage.GetFirstEdbInfoByClassifyId(parentClassifyId)
-				if tErr != nil && !utils.IsErrNoRow(tErr) {
-					errMsg = "移动失败"
-					err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
-					return
-				}
-
-				//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
-				if firstEdb != nil && firstEdb.ClassifyId > 0 && firstEdb.Sort == 0 {
-					updateSortStr := ` sort + 1 `
-					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, firstEdb.EdbInfoId-1, updateSortStr)
-					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, 0, updateSortStr, classifyType)
-				}
+				_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, firstEdb.EdbInfoId-1, updateSortStr)
+				_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, 0, updateSortStr, classifyType)
 			}
+		}
+
+		edbInfo.Sort = 0 //那就是排在第一位
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
 
-			edbClassifyInfo.Sort = 0 //那就是排在第一位
-			edbClassifyInfo.ModifyTime = time.Now()
-			updateCol = append(updateCol, "Sort", "ModifyTime")
+	//更新
+	if len(updateCol) > 0 {
+		err = edbInfo.Update(updateCol)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("修改失败,Err:" + err.Error())
+			return
 		}
+	}
 
-		//更新
-		if len(updateCol) > 0 {
-			err = edbClassifyInfo.Update(updateCol)
-			if err != nil {
-				errMsg = "移动失败"
-				err = errors.New("修改失败,Err:" + err.Error())
-				return
-			}
-			//更新对应分类的root_id和层级
-			if oldParentId != parentClassifyId {
-				if len(classifyIds) > 0 {
-					levelStep := edbClassifyInfo.Level - oldLevel
-					err = data_manage.UpdateEdbClassifyChildByParentClassifyId(classifyIds, edbClassifyInfo.RootId, levelStep)
-					if err != nil {
-						errMsg = "移动失败"
-						err = errors.New("更新子分类失败,Err:" + err.Error())
-						return
-					}
+	return
+}
+
+// moveEdbClassify
+// @Description: 移动指标分类
+// @author: Roc
+// @datetime 2024-11-26 16:07:44
+// @param parentEdbClassifyInfo *data_manage.EdbClassify
+// @param edbClassifyInfo *data_manage.EdbClassify
+// @param prevClassify *data_manage.EdbClassify
+// @param nextClassify *data_manage.EdbClassify
+// @param edbInfo *data_manage.EdbInfo
+// @param prevEdbInfo *data_manage.EdbInfo
+// @param nextEdbInfo *data_manage.EdbInfo
+// @param parentClassifyId int
+// @param prevSort int
+// @param nextSort int
+// @param classifyType uint8
+// @return err error
+// @return errMsg string
+func moveEdbClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify *data_manage.EdbClassify, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
+	updateCol := make([]string, 0)
+
+	// 移动对象为分类, 判断分类是否存在
+	oldParentId := edbClassifyInfo.ParentId
+	oldLevel := edbClassifyInfo.Level
+	var classifyIds []int
+	if oldParentId != parentClassifyId {
+		//更新子分类对应的level
+		childList, e, m := GetChildClassifyByClassifyId(edbClassifyInfo.ClassifyId)
+		if e != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询子分类失败,Err:" + e.Error() + m)
+			return
+		}
+
+		if len(childList) > 0 {
+			for _, v := range childList {
+				if v.ClassifyId == edbClassifyInfo.ClassifyId {
+					continue
 				}
+				classifyIds = append(classifyIds, v.ClassifyId)
 			}
 		}
-	} else {
-		if edbInfo == nil {
-			errMsg = "当前指标不存在"
-			err = errors.New(errMsg)
+	}
+	//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	if edbClassifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
+		if edbClassifyInfo.Level != parentEdbClassifyInfo.Level+1 { //禁止层级调整
+			errMsg = "移动失败"
+			err = errors.New("不支持目录层级变更")
 			return
 		}
-		//如果改变了分类,那么移动该指标数据
-		if edbInfo.ClassifyId != parentClassifyId {
-			edbInfo.ClassifyId = parentClassifyId
-			edbInfo.ModifyTime = time.Now()
-			updateCol = append(updateCol, "ClassifyId", "ModifyTime")
-		}
-		if prevSort > 0 {
-			//如果是移动在两个兄弟节点之间
-			if nextSort > 0 {
-				//下一个兄弟节点
-				//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
-				if prevSort == nextSort || prevSort == edbInfo.Sort {
+		edbClassifyInfo.ParentId = parentEdbClassifyInfo.ClassifyId
+		edbClassifyInfo.RootId = parentEdbClassifyInfo.RootId
+		edbClassifyInfo.Level = parentEdbClassifyInfo.Level + 1
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime")
+	} else if edbClassifyInfo.ParentId != parentClassifyId && parentClassifyId == 0 {
+		errMsg = "移动失败"
+		err = errors.New("不支持目录层级变更")
+		return
+	}
+
+	if prevSort > 0 {
+		//如果是移动在两个兄弟节点之间
+		if nextSort > 0 {
+			//下一个兄弟节点
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevSort == nextSort || prevSort == edbClassifyInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+
+				//变更分类
+				if prevClassify != nil {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr, classifyType)
+				} else {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+				}
+
+				//变更指标
+				if prevEdbInfo != nil {
 					//变更兄弟节点的排序
-					updateSortStr := `sort + 2`
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+				} else {
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+				}
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextSort-prevSort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
 
 					//变更分类
 					if prevClassify != nil {
-						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr, classifyType)
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr, classifyType)
 					} else {
 						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
 					}
@@ -1316,91 +1421,101 @@ func moveEdbClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextC
 					} else {
 						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
 					}
-				} else {
-					//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
-					if nextSort-prevSort == 1 {
-						//变更兄弟节点的排序
-						updateSortStr := `sort + 1`
-						//变更分类
-						if prevClassify != nil {
-							_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr, classifyType)
-						} else {
-							_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
-						}
-
-						//变更指标
-						if prevEdbInfo != nil {
-							//变更兄弟节点的排序
-							_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
-						} else {
-							_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
-						}
-					}
+
 				}
 			}
+		}
 
-			edbInfo.Sort = prevSort + 1
-			edbInfo.ModifyTime = time.Now()
-			updateCol = append(updateCol, "Sort", "ModifyTime")
-		} else if prevClassify == nil && nextClassify == nil && prevEdbInfo == nil && nextEdbInfo == nil && parentClassifyId > 0 {
-			//处理只拖动到目录里,默认放到目录底部的情况
-			var maxSort int
-			maxSort, err = GetEdbClassifyMaxSort(parentClassifyId, classifyType)
-			if err != nil {
-				errMsg = "移动失败"
-				err = errors.New("查询组内排序信息失败,Err:" + err.Error())
-				return
-			}
-			edbInfo.Sort = maxSort + 1 //那就是排在组内最后一位
-			edbInfo.ModifyTime = time.Now()
-			updateCol = append(updateCol, "Sort", "ModifyTime")
+		edbClassifyInfo.Sort = prevSort + 1
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else if prevClassify == nil && nextClassify == nil && prevEdbInfo == nil && nextEdbInfo == nil && parentClassifyId > 0 {
+		//处理只拖动到目录里,默认放到目录底部的情况
+		var maxSort int
+		maxSort, err = GetEdbClassifyMaxSort(parentClassifyId, classifyType)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+			return
+		}
+		edbClassifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, tmpErr := data_manage.GetFirstEdbClassifyByParentId(parentClassifyId)
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.ClassifyId > 0 && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr, classifyType)
+			//该分类下的所有指标也需要+1
+			_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, 0, updateSortStr)
 		} else {
-			// 拖动到父级分类的第一位
-			firstClassify, tmpErr := data_manage.GetFirstEdbClassifyByParentId(parentClassifyId)
-			if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			//如果该分类下存在指标,且第一个指标的排序等于0,那么需要调整排序
+			firstEdb, tErr := data_manage.GetFirstEdbInfoByClassifyId(parentClassifyId)
+			if tErr != nil && !utils.IsErrNoRow(tErr) {
 				errMsg = "移动失败"
-				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
 				return
 			}
 
 			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
-			if firstClassify != nil && firstClassify.ClassifyId > 0 && firstClassify.Sort == 0 {
+			if firstEdb != nil && firstEdb.ClassifyId > 0 && firstEdb.Sort == 0 {
 				updateSortStr := ` sort + 1 `
-				_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr, classifyType)
-				//该分类下的所有指标也需要+1
-				_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, 0, updateSortStr)
-			} else {
-				//如果该分类下存在指标,且第一个指标的排序等于0,那么需要调整排序
-				firstEdb, tErr := data_manage.GetFirstEdbInfoByClassifyId(parentClassifyId)
-				if tErr != nil && !utils.IsErrNoRow(tErr) {
+				_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, firstEdb.EdbInfoId-1, updateSortStr)
+				_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, 0, updateSortStr, classifyType)
+			}
+		}
+
+		edbClassifyInfo.Sort = 0 //那就是排在第一位
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	oldClassifyIdPath := edbClassifyInfo.ClassifyIdPath
+	oldClassifyNamePath := edbClassifyInfo.ClassifyNamePath
+	newClassifyNamePath := fmt.Sprint(parentEdbClassifyInfo.ClassifyNamePath, `|`, edbClassifyInfo.ClassifyName)
+	newClassifyIdPath := fmt.Sprint(parentEdbClassifyInfo.ClassifyIdPath, `,`, edbClassifyInfo.ClassifyId)
+
+	//更新
+	if len(updateCol) > 0 {
+		edbClassifyInfo.ClassifyNamePath = newClassifyNamePath
+		edbClassifyInfo.ClassifyIdPath = newClassifyIdPath
+		updateCol = append(updateCol, "ClassifyNamePath", "ClassifyIdPath")
+
+		err = edbClassifyInfo.Update(updateCol)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("修改失败,Err:" + err.Error())
+			return
+		}
+		//更新对应分类的root_id和层级
+		if oldParentId != parentClassifyId {
+			if len(classifyIds) > 0 {
+				levelStep := edbClassifyInfo.Level - oldLevel
+				err = data_manage.UpdateEdbClassifyChildByParentClassifyId(classifyIds, edbClassifyInfo.RootId, levelStep)
+				if err != nil {
 					errMsg = "移动失败"
-					err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
+					err = errors.New("更新子分类失败,Err:" + err.Error())
 					return
 				}
-
-				//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
-				if firstEdb != nil && firstEdb.ClassifyId > 0 && firstEdb.Sort == 0 {
-					updateSortStr := ` sort + 1 `
-					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, firstEdb.EdbInfoId-1, updateSortStr)
-					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, 0, updateSortStr, classifyType)
-				}
 			}
 
-			edbInfo.Sort = 0 //那就是排在第一位
-			edbInfo.ModifyTime = time.Now()
-			updateCol = append(updateCol, "Sort", "ModifyTime")
-		}
-
-		//更新
-		if len(updateCol) > 0 {
-			err = edbInfo.Update(updateCol)
-			if err != nil {
-				errMsg = "移动失败"
-				err = errors.New("修改失败,Err:" + err.Error())
-				return
+			// 更改了上级分类,那么需要同步去更改自己的分类全路径
+			tmpErr := data_manage.UpdateEdbClassifyNameAndNamePathByOldClassifyIdPath(oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath)
+			if tmpErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("更新分类全路径失败,分类id:%d;失败原因Err:%s", edbClassifyInfo.ClassifyId, tmpErr.Error()))
 			}
 		}
+
 	}
+
 	return
 }
 
@@ -1500,3 +1615,31 @@ func GetEdbClassifyMaxSort(parentId int, classifyType uint8) (maxSort int, err e
 	}
 	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 GetAllChildClassifyByParentId(parentId int) (targetList []*data_manage.EdbClassifyItems, err error, errMsg string) {
+	//判断是否是挂在顶级目录下
+	parentClassify, err := data_manage.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, classify_id asc`
+
+	targetList, err = data_manage.GetChildEdbClassifyListByParentId(fmt.Sprint(parentClassify.ClassifyIdPath, ",%"), orderStr)
+
+	return
+}

+ 18 - 2
services/data/edb_info.go

@@ -702,15 +702,31 @@ func AddEdbInfo(secName, unit, frequency, noticeTime, mobile string, classifyId,
 // AddOrEditEdbInfoToEs 添加/修改ES中的指标
 func AddOrEditEdbInfoToEs(edbInfoId int) {
 	//添加es
-	itemInfo, _ := data_manage.GetEdbInfoByCondition("AND edb_info_id=?", []interface{}{edbInfoId})
+	itemInfo, _ := data_manage.GetEdbInfoEsByCondition("AND edb_info_id=?", []interface{}{edbInfoId})
+	obj := data_manage.EdbInfoShare{}
+	list, _ := obj.GetListByEdbInfoId(edbInfoId)
+	sharedList := make([]int, 0)
+	for _, v := range list {
+		sharedList = append(sharedList, v.SysUserId)
+	}
+	itemInfo.SharedUserIdList = sharedList
+
 	go elastic.EsAddOrEditEdbInfoData(utils.DATA_INDEX_NAME, strconv.Itoa(itemInfo.EdbInfoId), itemInfo)
 }
 
 // AddOrEditAllEdbInfoToEs 修复ES中的所有指标
 func AddOrEditAllEdbInfoToEs() {
 	//添加es
-	total, itemInfoList, _ := data_manage.GetEdbInfoFilterList("", []interface{}{}, 0, 100000)
+	total, itemInfoList, _ := data_manage.GetEsEdbInfo("", []interface{}{}, 0, 100000)
+	obj := data_manage.EdbInfoShare{}
 	for k, itemInfo := range itemInfoList {
+		list, _ := obj.GetListByEdbInfoId(itemInfo.EdbInfoId)
+		sharedList := make([]int, 0)
+		for _, v := range list {
+			sharedList = append(sharedList, v.SysUserId)
+		}
+		itemInfo.SharedUserIdList = sharedList
+
 		elastic.EsAddOrEditEdbInfoData(utils.DATA_INDEX_NAME, strconv.Itoa(itemInfo.EdbInfoId), itemInfo)
 		fmt.Println("剩余", int(total)-k-1, "条指标数据")
 	}

+ 135 - 0
services/data/edb_info_share.go

@@ -0,0 +1,135 @@
+package data
+
+import (
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/utils"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// GetAllShareEdbListByFromUserId
+// @Description: 根据共享人id获取所有的指标列表
+// @author: Roc
+// @datetime 2024-12-03 10:01:49
+// @param sysUserId int
+// @return item []*data_manage.ShareEdbInfoQuery
+// @return err error
+func GetAllShareEdbListByFromUserId(sysUserId int) (item []*data_manage.ShareEdbInfoQuery, err error) {
+	obj := data_manage.EdbInfoShare{}
+	item, err = obj.GetAllSharedEdbInfoListByFromUserId(sysUserId)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// GetAllShareEdbListByReceivedUserId
+// @Description: 根据接收人id获取所有的指标列表
+// @author: Roc
+// @datetime 2024-12-03 10:01:49
+// @param sysUserId int
+// @return item []*data_manage.ShareEdbInfoQuery
+// @return err error
+func GetAllShareEdbListByReceivedUserId(sysUserId int) (item []*data_manage.ShareEdbInfoQuery, err error) {
+	obj := data_manage.EdbInfoShare{}
+	item, err = obj.GetAllSharedEdbInfoListByReceivedUserId(sysUserId)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// GetEdbClassifyItemListByShareEdbInfoQueryList
+// @Description: 根据共享的指标来获取分类和指标的树形结构
+// @author: Roc
+// @datetime 2024-12-03 11:12:26
+// @param items []*data_manage.ShareEdbInfoQuery
+// @return item data_manage.EdbClassifyItemList
+// @return err error
+func GetEdbClassifyItemListByShareEdbInfoQueryList(items []*data_manage.ShareEdbInfoQuery) (item data_manage.EdbClassifyItemList, err error) {
+	// 所有分类
+	edbClassifyItemListMap := make(map[int][]*data_manage.EdbClassifyItems)
+	classifyIdList := make([]int, 0)
+
+	for _, v := range items {
+		edbClassifyItem := &data_manage.EdbClassifyItems{
+			ClassifyId: v.ClassifyId,
+			EdbInfoId:  v.EdbInfoId,
+			//ParentId:   v.ClassifyId,
+			//ClassifyType:     v.ClassifyT,
+			ClassifyName:    v.EdbName,
+			ClassifyNameEn:  v.EdbNameEn,
+			Sort:            v.Sort,
+			UniqueCode:      v.UniqueCode,
+			Source:          v.Source,
+			SourceName:      v.SourceName,
+			SysUserId:       v.SysUserId,
+			SysUserRealName: v.SysUserRealName,
+			StartDate:       v.StartDate.Format(utils.FormatDate),
+			EdbCode:         v.EdbCode,
+			EdbType:         v.EdbType,
+			//Children:         nil,
+			Button:           data_manage.EdbClassifyItemsButton{},
+			IsJoinPermission: v.IsJoinPermission,
+			HaveOperaAuth:    false,
+			ClassifyIdPath:   "",
+		}
+		edbClassifyItemList, ok := edbClassifyItemListMap[v.ClassifyId]
+		if ok {
+			edbClassifyItemListMap[v.ClassifyId] = []*data_manage.EdbClassifyItems{edbClassifyItem}
+			continue
+		}
+		edbClassifyItemListMap[v.ClassifyId] = append(edbClassifyItemList, edbClassifyItem)
+		classifyIdList = append(classifyIdList, v.ClassifyId)
+	}
+
+	// 组成一个分类树形结构
+	{
+		// 根据分类id获取分类
+		classifyItemsList, tmpErr := data_manage.GetEdbClassifyItemsByIdList(classifyIdList)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		allClassifyIdList := make([]int, 0)
+		// 获取分类的完整路径id集合(子级、父级、顶级)
+		allClassifyIdStrList := make([]string, 0)
+		for _, v := range classifyItemsList {
+			allClassifyIdStrList = append(allClassifyIdStrList, v.ClassifyIdPath)
+		}
+		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.GetEdbClassifyItemsByIdList(allClassifyIdList)
+		if err != nil {
+			return
+		}
+
+		for _, v := range classifyItemsList {
+			if edbClassifyItemList, ok := edbClassifyItemListMap[v.ClassifyId]; ok {
+				if v.Children == nil {
+					v.Children = edbClassifyItemList
+				} else {
+					v.Children = append(v.Children, edbClassifyItemList...)
+				}
+			}
+		}
+
+		item = GetClassifyTreeRecursive(classifyItemsList, 0)
+		//根据sort值排序
+		sort.Sort(item)
+	}
+
+	return
+}

+ 44 - 0
services/data/edb_public.go

@@ -0,0 +1,44 @@
+package data
+
+import (
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/system"
+)
+
+// DeleteEdbPublicCheck
+// @Description: 移除指标公共检测
+// @author: Roc
+// @datetime 2024-12-05 10:23:01
+// @param classifyId int
+// @param edbInfoId int
+// @param sysUser *system.Admin
+// @return deleteStatus int
+// @return tipsMsg string
+// @return tableList []*data_manage.ExcelBaseInfo
+// @return err error
+// @return errMsg string
+func DeleteEdbPublicCheck(edbInfoId int, sysUser *system.Admin) (deleteStatus int, tipsMsg string, tableList []*data_manage.ExcelBaseInfo, err error, errMsg string) {
+	// TODO 操作权限校验
+	{
+
+	}
+
+	// 移除指标
+	if edbInfoId > 0 {
+
+		// TODO 需要判断该指标是否被其他人给收藏了
+
+		//if edbInfo == nil {
+		//	errMsg = "指标已删除,请刷新页面"
+		//	return
+		//}
+		//if chartCount > 0 {
+		//	deleteStatus = 3
+		//	tipsMsg = "当前指标已用作画图,不可删除"
+		//	return
+		//}
+		return
+	}
+
+	return
+}

+ 835 - 0
services/data/edb_public_classify.go

@@ -0,0 +1,835 @@
+package data
+
+import (
+	"errors"
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/system"
+	"eta_gn/eta_api/services/data/data_manage_permission"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strconv"
+	"time"
+)
+
+// AddEdbPublicClassify
+// @Description: 添加公共指标分类
+// @author: Roc
+// @datetime 2024-12-04 18:00:22
+// @param classifyName string
+// @param parentId int
+// @param level int
+// @param classifyType uint8
+// @param sysUserId int
+// @param sysUserName string
+// @return classifyInfo *data_manage.EdbPublicClassify
+// @return err error
+// @return errMsg string
+func AddEdbPublicClassify(classifyName string, parentId, level int, classifyType uint8, sysUserId int, sysUserName string) (classifyInfo *data_manage.EdbPublicClassify, err error, errMsg string) {
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	// 校验分类名称相同的数量
+	{
+		var count int
+		count, err = edbPublicClassifyObj.GetEdbClassifyCount(classifyName, parentId, classifyType)
+		if err != nil {
+			errMsg = `判断名称是否已存在失败`
+			return
+		}
+		if count > 0 {
+			errMsg = `分类名称已存在,请重新输入`
+			err = errors.New(errMsg)
+			return
+		}
+	}
+
+	// 层级校验
+	if level > utils.EdbClassifyMaxLevel {
+		errMsg = fmt.Sprintf("最高只支持添加%d级分类", level)
+		return
+	}
+
+	//获取该层级下最大的排序数
+	maxSort, err := GetEdbPublicClassifyMaxSort(parentId, classifyType)
+	if err != nil {
+		errMsg = "获取失败"
+		err = errors.New("查询排序信息失败,Err:" + err.Error())
+		return
+	}
+	//查询顶级rootId
+	rootId := 0
+	var classifyNamePath, classifyIdPath string
+	if parentId > 0 {
+		parentClassify, tErr := edbPublicClassifyObj.GetEdbClassifyById(parentId)
+		if tErr != nil {
+			if utils.IsErrNoRow(tErr) {
+				errMsg = "父级分类不存在"
+				err = errors.New(errMsg)
+				return
+			}
+			errMsg = "获取失败"
+			err = errors.New("获取分类信息失败,Err:" + tErr.Error())
+			return
+		}
+		rootId = parentClassify.RootId
+
+		classifyNamePath = fmt.Sprint(parentClassify.EdbPublicClassifyNamePath, "|", classifyName)
+		classifyIdPath = fmt.Sprint(parentClassify.EdbPublicClassifyIdPath, ",")
+	} else {
+		classifyNamePath = classifyName
+	}
+
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	classifyInfo = &data_manage.EdbPublicClassify{
+		//EdbPublicClassifyId:       0,
+		ClassifyType:              classifyType,
+		EdbPublicClassifyName:     classifyName,
+		ParentId:                  parentId,
+		HasData:                   0,
+		RootId:                    rootId,
+		CreateTime:                time.Now(),
+		ModifyTime:                time.Now(),
+		SysUserId:                 sysUserId,
+		SysUserRealName:           sysUserName,
+		Level:                     level + 1,
+		UniqueCode:                utils.MD5(utils.PUBLIC_CLASSIFY_PREFIX + "_" + timestamp),
+		Sort:                      maxSort + 1,
+		LastModifyUserId:          sysUserId,
+		LastModifyUserRealName:    sysUserName,
+		EdbPublicClassifyNamePath: classifyNamePath,
+		EdbPublicClassifyIdPath:   "",
+	}
+	err = classifyInfo.Add()
+	if err != nil {
+		errMsg = "保存分类失败"
+		return
+	}
+
+	// 更改分类id完整路径path
+	updateCols := []string{"EdbPublicClassifyIdPath"}
+	classifyInfo.EdbPublicClassifyIdPath = fmt.Sprint(classifyIdPath, classifyInfo.EdbPublicClassifyId)
+	if parentId == 0 { //一级目录的rootId等于自己本身
+		classifyInfo.RootId = classifyInfo.EdbPublicClassifyId
+		updateCols = append(updateCols, "RootId")
+
+	}
+	err = classifyInfo.Update(updateCols)
+	if err != nil {
+		errMsg = "更新分类失败"
+		return
+	}
+
+	return
+}
+
+// EditEdbPublicClassify
+// @Description: 编辑指标分类
+// @author: Roc
+// @datetime 2024-12-05 09:29:38
+// @param classifyId int
+// @param classifyName string
+// @param sysUser *system.Admin
+// @return err error
+// @return errMsg string
+func EditEdbPublicClassify(classifyId int, classifyName string, sysUser *system.Admin) (err error, errMsg string) {
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	item, err := edbPublicClassifyObj.GetEdbClassifyById(classifyId)
+	if err != nil {
+		errMsg = `修改失败`
+		return
+	}
+
+	// TODO 操作权限校验
+	{
+	}
+
+	// 需要变更的字段
+	updateCols := make([]string, 0)
+
+	// 旧完整路径  , 新的完整路径
+	var oldClassifyNamePath, newClassifyNamePath string
+
+	// 名字相同,那么就直接返回
+	if item.EdbPublicClassifyName == classifyName {
+		return
+	}
+
+	// 判断名称是否已存在
+	count, tmpErr := edbPublicClassifyObj.GetEdbClassifyCount(classifyName, item.ParentId, item.ClassifyType)
+	if tmpErr != nil {
+		err = tmpErr
+		errMsg = "判断名称是否已存在失败"
+		return
+	}
+	if count > 0 {
+		errMsg = "分类名称已存在,请重新输入"
+		err = errors.New(errMsg)
+		return
+	}
+
+	// 旧完整路径
+	oldClassifyNamePath = item.EdbPublicClassifyNamePath
+
+	if item.ParentId > 0 {
+		parentItem, tmpErr := edbPublicClassifyObj.GetEdbClassifyById(item.ParentId)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		newClassifyNamePath = fmt.Sprint(parentItem.EdbPublicClassifyNamePath, "|", classifyName)
+	} else {
+		newClassifyNamePath = classifyName
+	}
+
+	// 更新自己的信息
+	item.EdbPublicClassifyName = classifyName
+	item.EdbPublicClassifyNamePath = newClassifyNamePath
+	item.LastModifyUserId = sysUser.AdminId
+	item.LastModifyUserRealName = sysUser.RealName
+	updateCols = append(updateCols, "EdbPublicClassifyName", "EdbPublicClassifyNamePath", "LastModifyUserId", "LastModifyUserRealName")
+
+	// 修改数据
+	if len(updateCols) > 0 {
+		err = item.UpdateEdbClassifyNameAndNamePath(updateCols, oldClassifyNamePath, newClassifyNamePath)
+		if err != nil {
+			errMsg = "保存失败"
+		}
+	}
+
+	return
+}
+
+// GetEdbPublicClassifyMaxSort
+// @Description: 获取最大排序值
+// @author: Roc
+// @datetime 2024-12-04 16:54:57
+// @param parentId int
+// @param classifyType uint8
+// @return maxSort int
+// @return err error
+func GetEdbPublicClassifyMaxSort(parentId int, classifyType uint8) (maxSort int, err error) {
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	//获取该层级下最大的排序数
+	classifyMaxSort, err := edbPublicClassifyObj.GetEdbClassifyMaxSort(parentId, classifyType)
+	if err != nil {
+		return
+	}
+	maxSort = classifyMaxSort
+	edbMaxSort, err := data_manage.GetEdbInfoMaxSortByClassifyId(parentId)
+	if err != nil {
+		return
+	}
+	if maxSort < edbMaxSort {
+		maxSort = edbMaxSort
+	}
+
+	return
+}
+
+// DeleteEdbPublicClassifyCheck 删除检测
+func DeleteEdbPublicClassifyCheck(classifyId int, sysUser *system.Admin) (deleteStatus int, tipsMsg string, allClassifyIdList []int, tableList []*data_manage.ExcelBaseInfo, err error, errMsg string) {
+	// TODO 操作权限校验
+	{
+
+	}
+
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	// 查找当前分类
+	item, tmpErr := edbPublicClassifyObj.GetEdbClassifyById(classifyId)
+	if tmpErr != nil {
+		errMsg = `查找分类失败`
+		err = tmpErr
+		return
+	}
+
+	// 查找分类下所有子分类
+	childClassifyIdList, tmpErr := item.GetAllChildClassifyIdList()
+	if tmpErr != nil {
+		errMsg = `查找下级分类失败`
+		err = tmpErr
+		return
+	}
+	allClassifyIdList = childClassifyIdList
+	allClassifyIdList = append(allClassifyIdList, item.EdbPublicClassifyId)
+
+	// 判断分类下,是否含有指标
+	{
+		//判断分类下,是否含有指标
+		count, tmpErr := edbPublicClassifyObj.GetEdbInfoCountByClassifyIdList(allClassifyIdList)
+		if tmpErr != nil {
+			errMsg = "删除失败"
+			err = errors.New("分类下是否含有指标失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		if count > 0 {
+			deleteStatus = 1
+			tipsMsg = "目录关联指标不可删除"
+			return
+		}
+	}
+
+	// 子目录数量校验
+	if len(childClassifyIdList) > 0 {
+		deleteStatus = 2
+		tipsMsg = "确认删除当前目录及包含的子目录吗"
+		return
+	}
+
+	return
+}
+
+// DeleteEdbPublicClassify 删除分类/指标
+func DeleteEdbPublicClassify(classifyId int, sysUser *system.Admin, requestBody, requestUrl string) (nextItem *data_manage.EdbInfo, tableList []*data_manage.ExcelBaseInfo, err error, errMsg string) {
+	//删除分类校验
+	deleteStatus, tipsMsg, allClassifyIdList, _, err, errMsg := DeleteEdbPublicClassifyCheck(classifyId, sysUser)
+	// 0:可以;2:删除子目录;1:不可删除(有关联指标)
+	if deleteStatus == 1 {
+		if tipsMsg != `` {
+			errMsg = tipsMsg
+		}
+		if err == nil {
+			err = errors.New(errMsg)
+		}
+		return
+	}
+
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	err = edbPublicClassifyObj.BatchesDel(allClassifyIdList)
+	if err != nil {
+		errMsg = "删除失败"
+		return
+	}
+
+	return
+}
+
+// MoveEdbClassify 移动指标分类
+func MoveEdbPublicClassify(req data_manage.MoveEdbClassifyReq, sysUser *system.Admin, classifyType uint8) (err error, errMsg string) {
+	// req.ClassifyId, req.ParentClassifyId, req.PrevClassifyId, req.NextClassifyId
+	classifyId := req.ClassifyId
+	parentClassifyId := req.ParentClassifyId
+	prevClassifyId := req.PrevClassifyId
+	nextClassifyId := req.NextClassifyId
+
+	edbInfoId := req.EdbInfoId
+	prevEdbInfoId := req.PrevEdbInfoId
+	nextEdbInfoId := req.NextEdbInfoId
+
+	//首先确定移动的对象是分类还是指标
+	//判断上一个节点是分类还是指标
+	//判断下一个节点是分类还是指标
+	//同时更新分类目录下的分类sort和指标sort
+	//更新当前移动的分类或者指标sort
+
+	var parentEdbClassifyInfo *data_manage.EdbClassify
+	if parentClassifyId > 0 {
+		parentEdbClassifyInfo, err = data_manage.GetEdbClassifyById(parentClassifyId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上级分类信息失败,Err:" + err.Error())
+			return
+		}
+	}
+
+	//如果有传入 上一个兄弟节点分类id
+	var (
+		edbClassifyInfo *data_manage.EdbClassify
+		prevClassify    *data_manage.EdbClassify
+		nextClassify    *data_manage.EdbClassify
+
+		edbInfo     *data_manage.EdbInfo
+		prevEdbInfo *data_manage.EdbInfo
+		nextEdbInfo *data_manage.EdbInfo
+		prevSort    int
+		nextSort    int
+	)
+
+	// 移动对象为分类, 判断权限
+	if edbInfoId == 0 {
+		edbClassifyInfo, err = data_manage.GetEdbClassifyById(classifyId)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				errMsg = "当前分类不存在"
+				err = errors.New("获取分类信息失败,Err:" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取分类信息失败,Err:" + err.Error())
+			return
+		}
+		if edbClassifyInfo.SysUserId != sysUser.AdminId {
+			errMsg = "不是本人目录,您没有操作权限"
+			err = errors.New(errMsg)
+			return
+		}
+		if parentClassifyId > 0 && parentEdbClassifyInfo.Level == 6 {
+			errMsg = "最高只支持添加6级分类"
+			err = errors.New(errMsg)
+			return
+		}
+		// 如果是移动目录, 那么校验一下父级目录下是否有重名目录
+		exists, e := data_manage.GetEdbClassifyByParentIdAndName(parentClassifyId, edbClassifyInfo.ClassifyName, classifyId, classifyType)
+		if e != nil && !utils.IsErrNoRow(e) {
+			errMsg = "移动失败"
+			err = fmt.Errorf("获取父级分类下的同名分类失败, Err: %s", e.Error())
+			return
+		}
+		if exists != nil && exists.ClassifyId > 0 {
+			errMsg = "移动失败,分类名称已存在"
+			return
+		}
+
+		// 权限校验
+		{
+			// 已授权分类id
+			permissionClassifyIdList, tmpErr := data_manage_permission.GetUserEdbClassifyPermissionList(sysUser.AdminId, classifyId)
+			if tmpErr != nil {
+				errMsg = "移动失败"
+				err = errors.New("获取已授权分类id数据失败,Err:" + tmpErr.Error())
+				return
+			}
+			// 数据权限
+			haveOperaAuth := data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(edbClassifyInfo.IsJoinPermission, edbClassifyInfo.ClassifyId, permissionClassifyIdList)
+
+			if edbClassifyInfo.ClassifyType == 0 { // 普通指标
+				button := GetEdbClassifyOpButton(sysUser, edbClassifyInfo.SysUserId, haveOperaAuth)
+				if !button.MoveButton {
+					errMsg = "无操作权限"
+					err = errors.New(errMsg)
+					return
+				}
+			} else if edbClassifyInfo.ClassifyType == 1 { // 预测指标
+				button := GetPredictEdbClassifyOpButton(sysUser, edbClassifyInfo.SysUserId, haveOperaAuth)
+				if !button.MoveButton {
+					errMsg = "无操作权限"
+					err = errors.New(errMsg)
+					return
+				}
+			}
+		}
+
+	} else {
+		edbInfo, err = data_manage.GetEdbInfoById(req.EdbInfoId)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				errMsg = "当前指标不存在"
+				err = errors.New("获取分类信息失败,Err:" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取分类信息失败,Err:" + err.Error())
+			return
+		}
+
+		if edbInfo.SysUserId != sysUser.AdminId {
+			errMsg = "不是本人指标,您没有操作权限"
+			err = errors.New(errMsg)
+			return
+		}
+
+		if parentClassifyId == 0 {
+			errMsg = "移动失败,指标必须挂在分类下"
+			err = errors.New(errMsg)
+			return
+		}
+
+		var haveOperaAuth bool
+		// 权限校验
+		{
+			haveOperaAuth, err = data_manage_permission.CheckEdbPermissionByEdbInfoId(edbInfo.EdbInfoId, edbInfo.ClassifyId, edbInfo.IsJoinPermission, sysUser.AdminId)
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("获取指标权限信息失败,Err:" + err.Error())
+				return
+			}
+		}
+
+		// 移动权限校验
+		button := GetEdbOpButton(sysUser, edbInfo.SysUserId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth)
+		if !button.MoveButton {
+			errMsg = "无操作权限"
+			err = errors.New(errMsg)
+			return
+		}
+	}
+
+	if prevClassifyId > 0 {
+		prevClassify, err = data_manage.GetEdbClassifyById(prevClassifyId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		prevSort = prevClassify.Sort
+	} else if prevEdbInfoId > 0 {
+		prevEdbInfo, err = data_manage.GetEdbInfoById(prevEdbInfoId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		prevSort = prevEdbInfo.Sort
+	}
+
+	if nextClassifyId > 0 {
+		//下一个兄弟节点
+		nextClassify, err = data_manage.GetEdbClassifyById(nextClassifyId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		nextSort = nextClassify.Sort
+	} else if nextEdbInfoId > 0 {
+		//下一个兄弟节点
+		nextEdbInfo, err = data_manage.GetEdbInfoById(nextEdbInfoId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		nextSort = nextEdbInfo.Sort
+	}
+
+	err, errMsg = moveEdbOrClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify, edbInfo, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	return
+}
+
+// moveEdbOrClassify 移动指标分类
+func moveEdbOrPublicClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify *data_manage.EdbClassify, edbInfo, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
+
+	if edbClassifyInfo != nil {
+		// 移动分类
+		return moveEdbClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	} else {
+		// 移动指标
+		return moveEdb(prevClassify, nextClassify, edbInfo, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	}
+
+	return
+}
+
+// moveEdb
+// @Description: 移动指标
+// @author: Roc
+// @datetime 2024-11-26 16:07:37
+// @param prevClassify *data_manage.EdbClassify
+// @param nextClassify *data_manage.EdbClassify
+// @param edbInfo *data_manage.EdbInfo
+// @param prevEdbInfo *data_manage.EdbInfo
+// @param nextEdbInfo *data_manage.EdbInfo
+// @param parentClassifyId int
+// @param prevSort int
+// @param nextSort int
+// @param classifyType uint8
+// @return err error
+// @return errMsg string
+func movePublicEdb(prevClassify, nextClassify *data_manage.EdbClassify, edbInfo, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
+	updateCol := make([]string, 0)
+
+	if edbInfo == nil {
+		errMsg = "当前指标不存在"
+		err = errors.New(errMsg)
+		return
+	}
+	//如果改变了分类,那么移动该指标数据
+	if edbInfo.ClassifyId != parentClassifyId {
+		edbInfo.ClassifyId = parentClassifyId
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "ClassifyId", "ModifyTime")
+	}
+	if prevSort > 0 {
+		//如果是移动在两个兄弟节点之间
+		if nextSort > 0 {
+			//下一个兄弟节点
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevSort == nextSort || prevSort == edbInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+
+				//变更分类
+				if prevClassify != nil {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr, classifyType)
+				} else {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+				}
+
+				//变更指标
+				if prevEdbInfo != nil {
+					//变更兄弟节点的排序
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+				} else {
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+				}
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextSort-prevSort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+					//变更分类
+					if prevClassify != nil {
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr, classifyType)
+					} else {
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+					}
+
+					//变更指标
+					if prevEdbInfo != nil {
+						//变更兄弟节点的排序
+						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+					} else {
+						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+					}
+				}
+			}
+		}
+
+		edbInfo.Sort = prevSort + 1
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else if prevClassify == nil && nextClassify == nil && prevEdbInfo == nil && nextEdbInfo == nil && parentClassifyId > 0 {
+		//处理只拖动到目录里,默认放到目录底部的情况
+		var maxSort int
+		maxSort, err = GetEdbClassifyMaxSort(parentClassifyId, classifyType)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+			return
+		}
+		edbInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, tmpErr := data_manage.GetFirstEdbClassifyByParentId(parentClassifyId)
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.ClassifyId > 0 && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr, classifyType)
+			//该分类下的所有指标也需要+1
+			_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, 0, updateSortStr)
+		} else {
+			//如果该分类下存在指标,且第一个指标的排序等于0,那么需要调整排序
+			firstEdb, tErr := data_manage.GetFirstEdbInfoByClassifyId(parentClassifyId)
+			if tErr != nil && !utils.IsErrNoRow(tErr) {
+				errMsg = "移动失败"
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
+				return
+			}
+
+			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+			if firstEdb != nil && firstEdb.ClassifyId > 0 && firstEdb.Sort == 0 {
+				updateSortStr := ` sort + 1 `
+				_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, firstEdb.EdbInfoId-1, updateSortStr)
+				_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, 0, updateSortStr, classifyType)
+			}
+		}
+
+		edbInfo.Sort = 0 //那就是排在第一位
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	//更新
+	if len(updateCol) > 0 {
+		err = edbInfo.Update(updateCol)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("修改失败,Err:" + err.Error())
+			return
+		}
+	}
+
+	return
+}
+
+// moveEdbClassify
+// @Description: 移动指标分类
+// @author: Roc
+// @datetime 2024-11-26 16:07:44
+// @param parentEdbClassifyInfo *data_manage.EdbClassify
+// @param edbClassifyInfo *data_manage.EdbClassify
+// @param prevClassify *data_manage.EdbClassify
+// @param nextClassify *data_manage.EdbClassify
+// @param edbInfo *data_manage.EdbInfo
+// @param prevEdbInfo *data_manage.EdbInfo
+// @param nextEdbInfo *data_manage.EdbInfo
+// @param parentClassifyId int
+// @param prevSort int
+// @param nextSort int
+// @param classifyType uint8
+// @return err error
+// @return errMsg string
+func moveEdbPublicClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify *data_manage.EdbClassify, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
+	updateCol := make([]string, 0)
+
+	// 移动对象为分类, 判断分类是否存在
+	oldParentId := edbClassifyInfo.ParentId
+	oldLevel := edbClassifyInfo.Level
+	var classifyIds []int
+	if oldParentId != parentClassifyId {
+		//更新子分类对应的level
+		childList, e, m := GetChildClassifyByClassifyId(edbClassifyInfo.ClassifyId)
+		if e != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询子分类失败,Err:" + e.Error() + m)
+			return
+		}
+
+		if len(childList) > 0 {
+			for _, v := range childList {
+				if v.ClassifyId == edbClassifyInfo.ClassifyId {
+					continue
+				}
+				classifyIds = append(classifyIds, v.ClassifyId)
+			}
+		}
+	}
+	//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	if edbClassifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
+		if edbClassifyInfo.Level != parentEdbClassifyInfo.Level+1 { //禁止层级调整
+			errMsg = "移动失败"
+			err = errors.New("不支持目录层级变更")
+			return
+		}
+		edbClassifyInfo.ParentId = parentEdbClassifyInfo.ClassifyId
+		edbClassifyInfo.RootId = parentEdbClassifyInfo.RootId
+		edbClassifyInfo.Level = parentEdbClassifyInfo.Level + 1
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime")
+	} else if edbClassifyInfo.ParentId != parentClassifyId && parentClassifyId == 0 {
+		errMsg = "移动失败"
+		err = errors.New("不支持目录层级变更")
+		return
+	}
+
+	if prevSort > 0 {
+		//如果是移动在两个兄弟节点之间
+		if nextSort > 0 {
+			//下一个兄弟节点
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevSort == nextSort || prevSort == edbClassifyInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+
+				//变更分类
+				if prevClassify != nil {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr, classifyType)
+				} else {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+				}
+
+				//变更指标
+				if prevEdbInfo != nil {
+					//变更兄弟节点的排序
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+				} else {
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+				}
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextSort-prevSort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+
+					//变更分类
+					if prevClassify != nil {
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr, classifyType)
+					} else {
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+					}
+
+					//变更指标
+					if prevEdbInfo != nil {
+						//变更兄弟节点的排序
+						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+					} else {
+						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+					}
+
+				}
+			}
+		}
+
+		edbClassifyInfo.Sort = prevSort + 1
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else if prevClassify == nil && nextClassify == nil && prevEdbInfo == nil && nextEdbInfo == nil && parentClassifyId > 0 {
+		//处理只拖动到目录里,默认放到目录底部的情况
+		var maxSort int
+		maxSort, err = GetEdbClassifyMaxSort(parentClassifyId, classifyType)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+			return
+		}
+		edbClassifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, tmpErr := data_manage.GetFirstEdbClassifyByParentId(parentClassifyId)
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.ClassifyId > 0 && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr, classifyType)
+			//该分类下的所有指标也需要+1
+			_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, 0, updateSortStr)
+		} else {
+			//如果该分类下存在指标,且第一个指标的排序等于0,那么需要调整排序
+			firstEdb, tErr := data_manage.GetFirstEdbInfoByClassifyId(parentClassifyId)
+			if tErr != nil && !utils.IsErrNoRow(tErr) {
+				errMsg = "移动失败"
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
+				return
+			}
+
+			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+			if firstEdb != nil && firstEdb.ClassifyId > 0 && firstEdb.Sort == 0 {
+				updateSortStr := ` sort + 1 `
+				_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, firstEdb.EdbInfoId-1, updateSortStr)
+				_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, 0, updateSortStr, classifyType)
+			}
+		}
+
+		edbClassifyInfo.Sort = 0 //那就是排在第一位
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	//更新
+	if len(updateCol) > 0 {
+		err = edbClassifyInfo.Update(updateCol)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("修改失败,Err:" + err.Error())
+			return
+		}
+		//更新对应分类的root_id和层级
+		if oldParentId != parentClassifyId {
+			if len(classifyIds) > 0 {
+				levelStep := edbClassifyInfo.Level - oldLevel
+				err = data_manage.UpdateEdbClassifyChildByParentClassifyId(classifyIds, edbClassifyInfo.RootId, levelStep)
+				if err != nil {
+					errMsg = "移动失败"
+					err = errors.New("更新子分类失败,Err:" + err.Error())
+					return
+				}
+			}
+		}
+
+	}
+
+	return
+}

+ 1 - 1
services/edb_info_replace.go

@@ -84,7 +84,7 @@ func DealReplaceEdbCache() {
 func ReplaceEdbInExcel(oldEdbInfo, newEdbInfo *data_manage.EdbInfo) (err error) {
 	defer func() {
 		if err != nil {
-			go alarm_msg.SendAlarmMsg("替换表格中的指标失败提醒,errmsg:"+err.Error(), 3)
+			go alarm_msg.SendAlarmMsg("替换表格中的指标失败提醒,errMsg:"+err.Error(), 3)
 		}
 	}()
 	//查询和指标相关的时间序列表格和混合表格

+ 726 - 0
services/elastic/edb_info.go

@@ -0,0 +1,726 @@
+package elastic
+
+import (
+	"context"
+	"encoding/json"
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/olivere/elastic/v7"
+)
+
+// EsAddOrEditEdbInfoData 新增/修改es中的指标数据
+func EsAddOrEditEdbInfoData(indexName, docId string, item *data_manage.EdbInfoEs) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("EsAddOrEditData Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
+	if err != nil {
+		fmt.Println("新增失败:", err.Error())
+		return err
+	}
+	fmt.Println(resp)
+	if resp.Status == 0 {
+		fmt.Println("新增成功", resp.Result)
+		err = nil
+	} else {
+		fmt.Println("AddData", resp.Status, resp.Result)
+	}
+	return
+}
+
+// searchEdbInfoData 查询es中的指标数据
+func searchEdbInfoData(indexName string, mustMap, mustNotMap []interface{}, shouldMapList []map[string]interface{}, sortList []interface{}, from, size int) (total int64, list []*data_manage.EdbInfoList, err error) {
+	list = make([]*data_manage.EdbInfoList, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("searchEdbInfoData Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	//queryString := elastic.NewQueryStringQuery(keywordStr)
+	//boolQueryJson, err := json.Marshal(queryString)
+	//if err != nil {
+	//	fmt.Println("boolQueryJson err:", err)
+	//} else {
+	//	fmt.Println("boolQueryJson ", string(boolQueryJson))
+	//}
+
+	highlight := elastic.NewHighlight()
+	highlight = highlight.Fields(elastic.NewHighlighterField("EdbCode"), elastic.NewHighlighterField("EdbName"))
+	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
+
+	//query := elastic.RawStringQuery(`{"match_all":{}}`)
+
+	//关键字匹配
+	for _, shouldMap := range shouldMapList {
+		mustMap = append(mustMap, map[string]interface{}{
+			"bool": shouldMap,
+		})
+	}
+
+	queryMap := map[string]interface{}{
+		"query": map[string]interface{}{
+			"bool": map[string]interface{}{
+				"must":     mustMap,
+				"must_not": mustNotMap,
+				//"should":   shouldMap,
+			},
+		},
+	}
+
+	//根据条件数量统计
+	requestTotalHits := client.Count(indexName).BodyJson(queryMap)
+	total, err = requestTotalHits.Do(context.Background())
+	if err != nil {
+		return
+	}
+
+	queryMap["from"] = from
+	queryMap["size"] = size
+
+	// 如果有指定排序,那么就按照排序来
+	if len(sortList) > 0 {
+		queryMap["sort"] = sortList
+	}
+
+	jsonBytes, _ := json.Marshal(queryMap)
+	fmt.Println(string(jsonBytes))
+
+	//queryString := elastic.NewMatchQuery("EdbCode", keywordStr)
+	//request := client.Search(indexName).Highlight(highlight).From(from).Size(size).Query(queryString)
+
+	request := client.Search(indexName).Highlight(highlight).Source(queryMap) // sets the JSON request
+
+	//requestJson, err := json.Marshal(request)
+	//if err != nil {
+	//	fmt.Println("requestJson err:", err)
+	//}
+	//fmt.Println("requestJson ", string(requestJson))
+	searchMap := make(map[string]string)
+
+	searchResp, err := request.Do(context.Background())
+	if err != nil {
+		return
+	}
+	fmt.Println(searchResp)
+	fmt.Println(searchResp.Status)
+	if searchResp.Status != 0 {
+		return
+	}
+	//total = searchResp.TotalHits()
+	if searchResp.Hits != nil {
+		for _, v := range searchResp.Hits.Hits {
+			if _, ok := searchMap[v.Id]; !ok {
+				itemJson, tmpErr := v.Source.MarshalJSON()
+				if tmpErr != nil {
+					err = tmpErr
+					fmt.Println("movieJson err:", err)
+					return
+				}
+				edbInfoItem := new(data_manage.EdbInfoList)
+				tmpErr = json.Unmarshal(itemJson, &edbInfoItem)
+				if tmpErr != nil {
+					fmt.Println("json.Unmarshal movieJson err:", tmpErr)
+					err = tmpErr
+					return
+				}
+				if len(v.Highlight["EdbCode"]) > 0 {
+					edbInfoItem.EdbCode = v.Highlight["EdbCode"][0]
+				}
+				if len(v.Highlight["EdbName"]) > 0 {
+					edbInfoItem.EdbCode = v.Highlight["EdbName"][0]
+				}
+				list = append(list, edbInfoItem)
+				searchMap[v.Id] = v.Id
+			}
+		}
+	}
+
+	return
+}
+
+// SearchEdbInfoData
+// @Description: 查询es中的指标数据
+// @author: Roc
+// @datetime 2024-11-29 10:22:25
+// @param keywordStr string
+// @param from int
+// @param size int
+// @param filterSource int
+// @param source int
+// @param frequency string
+// @param noPermissionEdbInfoIdList []int
+// @param noPermissionEdbClassifyIdList []int
+// @param collectEdbInfoIdList []int
+// @param edbTypeList []int
+// @param edbInfoType int 指标类型,0:ETA指标库(基础指标+计算指标);1:预测指标
+// @param edbAuth int 指标权限范围,0-全部;1-我的;2-公共
+// @param sysUserId int
+// @return total int64
+// @return list []*data_manage.EdbInfoList
+// @return err error
+func SearchEdbInfoData(keywordStr string, from, size, filterSource, source int, frequency string, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, collectEdbInfoIdList, edbTypeList []int, edbInfoType, edbAuth, sysUserId int, sortMap map[string]string) (total int64, list []*data_manage.EdbInfoList, err error) {
+	indexName := utils.DATA_INDEX_NAME
+	list = make([]*data_manage.EdbInfoList, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("SearchEdbInfoData Err:", err.Error())
+		}
+	}()
+
+	highlight := elastic.NewHighlight()
+	highlight = highlight.Fields(elastic.NewHighlighterField("EdbCode"), elastic.NewHighlighterField("EdbName"))
+	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
+
+	mustMap := make([]interface{}, 0)
+	mustNotMap := make([]interface{}, 0)
+
+	switch filterSource {
+	case 2:
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"Frequency.keyword": "月度",
+				//"Frequency.keyword": "月度",
+			},
+		})
+	case 3:
+	case 4:
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"EdbType": 1,
+			},
+		})
+	case 5:
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"Source": 6,
+			},
+		})
+	case 6:
+		mustMap = append(mustMap, map[string]interface{}{
+			"match": map[string]interface{}{
+				"Frequency.keyword": "年度",
+			},
+		})
+	}
+
+	//指标来源
+	if source > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"Source": source,
+				//"Frequency.keyword": "月度",
+			},
+		})
+	}
+
+	if frequency != "" {
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"Frequency.keyword": frequency,
+				//"Frequency.keyword": "月度",
+			},
+		})
+	}
+
+	// noPermissionEdbInfoIdList 无权限指标id
+	if len(noPermissionEdbInfoIdList) > 0 {
+		mustNotMap = append(mustNotMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"EdbInfoId": noPermissionEdbInfoIdList,
+				//"Frequency.keyword": "月度",
+			},
+		})
+	}
+
+	// noPermissionEdbInfoIdList 无权限指标id
+	if len(noPermissionEdbClassifyIdList) > 0 {
+		mustNotMap = append(mustNotMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"ClassifyId": noPermissionEdbClassifyIdList,
+				//"Frequency.keyword": "月度",
+			},
+		})
+	}
+
+	// collectEdbInfoIdList 收藏的指标id
+	if len(collectEdbInfoIdList) > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"EdbInfoId": collectEdbInfoIdList,
+			},
+		})
+	}
+
+	// 指标类型:0-基础+计算;1-基础指标;2-计算指标;3-预测指标
+	if len(edbTypeList) > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"EdbType": edbTypeList,
+			},
+		})
+	}
+
+	if edbInfoType >= 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"EdbInfoType": edbInfoType,
+			},
+		})
+	}
+
+	shouldMapList := make([]map[string]interface{}, 0)
+
+	// 指标名称、编码匹配
+	if keywordStr != `` {
+		// 默认使用中文名字字段去匹配
+		keywordNameKey := `EdbName`
+		shouldMap := map[string]interface{}{
+			"should": []interface{}{
+				map[string]interface{}{
+					"match": map[string]interface{}{
+						"EdbCode": keywordStr,
+						//"Frequency.keyword": "月度",
+					},
+				},
+				map[string]interface{}{
+					"match": map[string]interface{}{
+						keywordNameKey: keywordStr,
+						//"Frequency.keyword": "月度",
+					},
+				},
+			},
+		}
+		shouldMapList = append(shouldMapList, shouldMap)
+	}
+
+	// 指标与用户的权限匹配
+	{
+		shouldTermList := make([]map[string]interface{}, 0)
+		//指标权限范围,0-全部;1-我的;2-公共
+		switch edbAuth {
+		case 1:
+			// 自己的指标
+			shouldTermList = append(shouldTermList, map[string]interface{}{
+				"term": map[string]interface{}{
+					"SysUserId": sysUserId,
+				},
+			})
+		case 2:
+			// 公开的指标
+			shouldTermList = append(shouldTermList, map[string]interface{}{
+				"term": map[string]interface{}{
+					"PublicStatus": utils.EdbPublicSuccess,
+				},
+			})
+		default:
+			// 自己的指标
+			shouldTermList = append(shouldTermList, map[string]interface{}{
+				"term": map[string]interface{}{
+					"SysUserId": sysUserId,
+				},
+			})
+			// 分享给我的指标
+			shouldTermList = append(shouldTermList, map[string]interface{}{
+				"terms": map[string]interface{}{
+					"SharedUserIdList": []int{sysUserId},
+				},
+			})
+			// 公开的指标
+			shouldTermList = append(shouldTermList, map[string]interface{}{
+				"term": map[string]interface{}{
+					"PublicStatus": utils.EdbPublicSuccess,
+				},
+			})
+
+		}
+
+		shouldMap := map[string]interface{}{
+			"should": shouldTermList,
+		}
+		shouldMapList = append(shouldMapList, shouldMap)
+	}
+
+	// 排序
+	sortList := make([]interface{}, 0)
+	// 如果没有关键字,那么就走指标id倒序
+
+	for orderKey, orderType := range sortMap {
+		sortEdbInfoId := map[string]interface{}{
+			orderKey: map[string]interface{}{
+				"order": orderType,
+			},
+		}
+		sortList = append(sortList, sortEdbInfoId)
+	}
+
+	return searchEdbInfoData(indexName, mustMap, mustNotMap, shouldMapList, sortList, from, size)
+}
+
+// searchEdbInfoData 查询es中的指标数量
+func searchEdbInfoDataTotal(indexName string, query elastic.Query) (total int64, err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("searchEdbInfoDataV2 Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	//根据条件数量统计
+	requestTotalHits := client.Count(indexName).Query(query)
+	total, err = requestTotalHits.Do(context.Background())
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// searchEdbInfoData 查询es中的指标数据
+func searchEdbInfoDataList(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (list []*data_manage.EdbInfoList, err error) {
+	list = make([]*data_manage.EdbInfoList, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("searchEdbInfoDataV2 Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+	// 高亮
+	highlight := elastic.NewHighlight()
+	highlight = highlight.Fields(elastic.NewHighlighterField("EdbCode"), elastic.NewHighlighterField("EdbName"))
+	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
+
+	request := client.Search(indexName).Highlight(highlight).From(from).Size(size) // sets the JSON request
+
+	// 如果有指定排序,那么就按照排序来
+	if len(sortList) > 0 {
+		for _, v := range sortList {
+			request = request.SortBy(v)
+		}
+	}
+
+	searchMap := make(map[string]string)
+
+	searchResp, err := request.Query(query).Do(context.Background())
+	if err != nil {
+		return
+	}
+	//fmt.Println(searchResp)
+	//fmt.Println(searchResp.Status)
+	if searchResp.Status != 0 {
+		return
+	}
+	//total = searchResp.TotalHits()
+	if searchResp.Hits != nil {
+		for _, v := range searchResp.Hits.Hits {
+			if _, ok := searchMap[v.Id]; !ok {
+				itemJson, tmpErr := v.Source.MarshalJSON()
+				if tmpErr != nil {
+					err = tmpErr
+					fmt.Println("movieJson err:", err)
+					return
+				}
+				edbInfoItem := new(data_manage.EdbInfoList)
+				tmpErr = json.Unmarshal(itemJson, &edbInfoItem)
+				if tmpErr != nil {
+					fmt.Println("json.Unmarshal movieJson err:", tmpErr)
+					err = tmpErr
+					return
+				}
+				if len(v.Highlight["EdbCode"]) > 0 {
+					edbInfoItem.EdbCode = v.Highlight["EdbCode"][0]
+				}
+				if len(v.Highlight["EdbName"]) > 0 {
+					edbInfoItem.EdbCode = v.Highlight["EdbName"][0]
+				}
+				list = append(list, edbInfoItem)
+				searchMap[v.Id] = v.Id
+			}
+		}
+	}
+
+	return
+}
+
+// searchEdbInfoData 查询es中的指标数据
+func searchEdbInfoDataV2(indexName string, query elastic.Query, sortList []*elastic.FieldSort, from, size int) (total int64, list []*data_manage.EdbInfoList, err error) {
+	total, err = searchEdbInfoDataTotal(indexName, query)
+	if err != nil {
+		return
+	}
+
+	// 获取列表数据
+	list, err = searchEdbInfoDataList(indexName, query, sortList, from, size)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// SearchEdbInfoDataByShared
+// @Description: 查询es中的指标数据
+// @author: Roc
+// @datetime 2024-11-29 10:22:25
+// @param keywordStr string
+// @param from int
+// @param size int
+// @param filterSource int
+// @param source int
+// @param frequency string
+// @param noPermissionEdbInfoIdList []int
+// @param noPermissionEdbClassifyIdList []int
+// @param collectEdbInfoIdList []int
+// @param edbTypeList []int
+// @param edbInfoType int 指标类型,0:ETA指标库(基础指标+计算指标);1:预测指标
+// @param edbAuth int 指标权限范围,0-全部;1-我的;2-公共
+// @param sysUserId int
+// @return total int64
+// @return list []*data_manage.EdbInfoList
+// @return err error
+func SearchEdbInfoDataByShared(keywordStr string, from, size, edbShare int, sourceList, classifyIdList, edbTypeList []int, edbInfoType, edbAuth, sysUserId int, sortMap map[string]string) (total int64, list []*data_manage.EdbInfoList, err error) {
+	indexName := utils.DATA_INDEX_NAME
+	list = make([]*data_manage.EdbInfoList, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("SearchEdbInfoData Err:", err.Error())
+		}
+	}()
+
+	query := elastic.NewBoolQuery()
+
+	//指标来源
+	if len(sourceList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range sourceList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("Source", termsList...))
+	}
+
+	// classifyIdList 指定分类下的指标
+	if len(classifyIdList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range classifyIdList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("ClassifyId", termsList...))
+	}
+
+	// 指标类型:0-基础+计算;1-基础指标;2-计算指标;3-预测指标
+	if len(edbTypeList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range edbTypeList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("EdbType", termsList...))
+	}
+
+	// 如果指定了分享状态,那么就添加分享状态的筛选
+	// 0:全部,1:未共享,2:已共享
+	switch edbShare {
+	case 1:
+		// 筛选 SharedUserIdList 为空的文档
+		query = query.MustNot(elastic.NewExistsQuery("SharedUserIdList"))
+	case 2:
+		// 筛选 SharedUserIdList 不为空的文档
+		query = query.Must(elastic.NewExistsQuery("SharedUserIdList"))
+	}
+
+	if edbInfoType >= 0 {
+		query = query.Must(elastic.NewTermQuery("EdbInfoType", edbInfoType))
+	}
+
+	// 指标名称、编码匹配
+	if keywordStr != `` {
+		// 默认使用中文名字字段去匹配
+		keywordNameKey := `EdbName`
+		query = query.Must(elastic.NewMultiMatchQuery(keywordStr, keywordNameKey, "EdbCode"))
+	}
+
+	// 指标与用户的权限匹配
+	{
+		//指标权限范围,0-全部;1-我的;2-公共
+		switch edbAuth {
+		case 1:
+			// 自己的指标
+			query = query.Must(elastic.NewTermQuery(`SysUserId`, sysUserId))
+		case 2:
+			// 公开的指标
+			query = query.Must(elastic.NewTermQuery(`PublicStatus`, utils.EdbPublicSuccess))
+		default:
+			tmpShouldQuery := elastic.NewBoolQuery()
+			// 自己的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermQuery(`SysUserId`, sysUserId))
+			// 分享给我的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermsQuery(`SharedUserIdList`, sysUserId))
+			//公开的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermQuery(`PublicStatus`, utils.EdbPublicSuccess))
+			//shouldQuery = shouldQuery.Should(tmpShouldQuery)
+			query = query.Must(tmpShouldQuery)
+		}
+	}
+
+	// 排序
+	sortList := make([]*elastic.FieldSort, 0)
+	// 如果没有关键字,那么就走指标id倒序
+
+	for orderKey, orderType := range sortMap {
+		switch orderType {
+		case "asc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Asc())
+		case "desc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Desc())
+
+		}
+
+	}
+
+	return searchEdbInfoDataV2(indexName, query, sortList, from, size)
+}
+
+// SearchEdbInfoDataByPublic
+// @Description: 查询es中的指标数据
+// @author: Roc
+// @datetime 2024-12-05 13:33:36
+// @param keywordStr string
+// @param from int
+// @param size int
+// @param edbPublicList []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 SearchEdbInfoDataByPublic(keywordStr string, from, size int, edbPublicList, sourceList, classifyIdList, edbTypeList []int, edbInfoType, edbAuth, sysUserId int, sortMap map[string]string) (total int64, list []*data_manage.EdbInfoList, err error) {
+	indexName := utils.DATA_INDEX_NAME
+	list = make([]*data_manage.EdbInfoList, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("SearchEdbInfoData Err:", err.Error())
+		}
+	}()
+
+	query := elastic.NewBoolQuery()
+
+	//指标来源
+	if len(sourceList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range sourceList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("Source", termsList...))
+	}
+
+	// classifyIdList 指定分类下的指标
+	if len(classifyIdList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range classifyIdList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("ClassifyId", termsList...))
+	}
+
+	// 指标类型:0-基础+计算;1-基础指标;2-计算指标;3-预测指标
+	if len(edbTypeList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range edbTypeList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("EdbType", termsList...))
+	}
+
+	// 如果指定了指标公开状态,那么就添加指标公开状态的筛选
+	// 公开状态;0:未公开;1:审批中;2:已驳回;3:已公开
+	if len(edbPublicList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range edbPublicList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("PublicStatus", termsList...))
+	}
+
+	if edbInfoType >= 0 {
+		query = query.Must(elastic.NewTermQuery("EdbInfoType", edbInfoType))
+	}
+
+	// 指标名称、编码匹配
+	if keywordStr != `` {
+		// 默认使用中文名字字段去匹配
+		keywordNameKey := `EdbName`
+		query = query.Must(elastic.NewMultiMatchQuery(keywordStr, keywordNameKey, "EdbCode"))
+	}
+
+	// 指标与用户的权限匹配
+	{
+		//指标权限范围,0-全部;1-我的;2-公共
+		switch edbAuth {
+		case 1:
+			// 自己的指标
+			query = query.Must(elastic.NewTermQuery(`SysUserId`, sysUserId))
+		case 2:
+			// 公开的指标
+			query = query.Must(elastic.NewTermQuery(`PublicStatus`, utils.EdbPublicSuccess))
+		default:
+			tmpShouldQuery := elastic.NewBoolQuery()
+			// 自己的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermQuery(`SysUserId`, sysUserId))
+			// 分享给我的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermsQuery(`SharedUserIdList`, sysUserId))
+			//公开的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermQuery(`PublicStatus`, utils.EdbPublicSuccess))
+			//shouldQuery = shouldQuery.Should(tmpShouldQuery)
+			query = query.Must(tmpShouldQuery)
+		}
+	}
+
+	// 排序
+	sortList := make([]*elastic.FieldSort, 0)
+	// 如果没有关键字,那么就走指标id倒序
+
+	for orderKey, orderType := range sortMap {
+		switch orderType {
+		case "asc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Asc())
+		case "desc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Desc())
+
+		}
+
+	}
+
+	return searchEdbInfoDataV2(indexName, query, sortList, from, size)
+}
+
+// EsDeleteEdbInfoData 删除es中的指标数据
+func EsDeleteEdbInfoData(indexName, docId string) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("EsDeleteEdbInfoData Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	resp, err := client.Delete().Index(indexName).Id(docId).Do(context.Background())
+	fmt.Println(resp)
+	if err != nil {
+		return
+	}
+	if resp.Status == 0 {
+		fmt.Println("删除成功")
+	} else {
+		fmt.Println("AddData", resp.Status, resp.Result)
+	}
+	return
+}

+ 45 - 1092
services/elastic/elastic.go

@@ -8,888 +8,60 @@ import (
 	"eta_gn/eta_api/models/data_manage"
 	"eta_gn/eta_api/utils"
 	"fmt"
-	"github.com/olivere/elastic/v7"
-	"strconv"
-	"strings"
-)
-
-// indexName:索引名称
-// mappingJson:表结构
-func EsCreateIndex(indexName, mappingJson string) (err error) {
-	client := utils.EsClient
-
-	//定义表结构
-	exists, err := client.IndexExists(indexName).Do(context.Background()) //<5>
-	if err != nil {
-		return
-	}
-	if !exists {
-		resp, err := client.CreateIndex(indexName).BodyJson(mappingJson).Do(context.Background())
-		//BodyJson(bodyJson).Do(context.Background())
-		if err != nil {
-			fmt.Println("CreateIndex Err:" + err.Error())
-			return err
-		}
-		fmt.Println(resp.Index, resp.ShardsAcknowledged, resp.Acknowledged)
-	} else {
-		fmt.Println(indexName + " 已存在")
-	}
-	return
-}
-
-// 删除数据
-func EsDeleteData(indexName, docId string) (err error) {
-	client := utils.EsClient
-
-	resp, err := client.Delete().Index(indexName).Id(docId).Do(context.Background())
-	fmt.Println(resp)
-	if err != nil {
-		return
-	}
-	if resp.Status == 0 {
-		fmt.Println("删除成功")
-	} else {
-		fmt.Println("AddData", resp.Status, resp.Result)
-	}
-	return
-}
-
-func MappingModify(indexName, mappingJson string) {
-	client := utils.EsClient
-	result, err := client.PutMapping().Index(indexName).BodyString(mappingJson).Do(context.Background())
-	fmt.Println(err)
-	fmt.Println(result)
-	return
-}
-
-// EsAddOrEditEdbInfoData 新增/修改es中的指标数据
-func EsAddOrEditEdbInfoData(indexName, docId string, item *data_manage.EdbInfoList) (err error) {
-	defer func() {
-		if err != nil {
-			fmt.Println("EsAddOrEditData Err:", err.Error())
-		}
-	}()
-	client := utils.EsClient
-
-	resp, err := client.Index().Index(indexName).Id(docId).BodyJson(item).Do(context.Background())
-	if err != nil {
-		fmt.Println("新增失败:", err.Error())
-		return err
-	}
-	fmt.Println(resp)
-	if resp.Status == 0 {
-		fmt.Println("新增成功", resp.Result)
-		err = nil
-	} else {
-		fmt.Println("AddData", resp.Status, resp.Result)
-	}
-	return
-}
-
-// SearchEdbInfoData 查询es中的指标数据
-func SearchEdbInfoData(indexName, keywordStr string, from, size, filterSource, source int, edbInfoType int8, frequency string, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList []int, edbType int) (total int64, list []*data_manage.EdbInfoList, err error) {
-	list = make([]*data_manage.EdbInfoList, 0)
-	defer func() {
-		if err != nil {
-			fmt.Println("EsAddOrEditData Err:", err.Error())
-		}
-	}()
-
-	highlight := elastic.NewHighlight()
-	highlight = highlight.Fields(elastic.NewHighlighterField("EdbCode"), elastic.NewHighlighterField("EdbName"))
-	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
-
-	//var source map[string]interface{}
-	//source := map[string]interface{}{
-	//	"query": map[string]interface{}{
-	//		"match_all": map[string]interface{}{},
-	//	},
-	//}
-	mustMap := make([]interface{}, 0)
-	mustNotMap := make([]interface{}, 0)
-
-	//source := map[string]interface{}{
-	//	"query": map[string]interface{}{
-	//		"bool": map[string]interface{}{
-	//			"must": map[string]interface{}{
-	//				"query_string": map[string]interface{}{
-	//					"query":  keywordStr,
-	//					"fields": []string{"EdbCode", "EdbName"},
-	//				},
-	//			},
-	//		},
-	//	},
-	//}
-
-	switch filterSource {
-	case 2:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"filter": []interface{}{
-		//				map[string]interface{}{
-		//					"term": map[string]interface{}{
-		//						"Frequency.keyword": "月度",
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"Frequency.keyword": "月度",
-					//"Frequency.keyword": "月度",
-				},
-			},
-		}
-	case 3:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"must_not": []interface{}{
-		//				map[string]interface{}{
-		//					"match": map[string]interface{}{
-		//						"Frequency.keyword": "日度",
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-
-		////注释掉,所有频度都可以变频 2022-08-31 14:31:28
-		//mustNotMap = []interface{}{
-		//	map[string]interface{}{
-		//		"match": map[string]interface{}{
-		//			"Frequency.keyword": "日度",
-		//			//"Frequency.keyword": "月度",
-		//		},
-		//	},
-		//}
-	case 4:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"filter": []interface{}{
-		//				map[string]interface{}{
-		//					"term": map[string]interface{}{
-		//						"EdbType": 1,
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"EdbType": 1,
-				},
-			},
-		}
-	case 5:
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"Source": 6,
-				},
-			},
-		}
-	case 6:
-		mustNotMap = []interface{}{
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"Frequency.keyword": "年度",
-				},
-			},
-		}
-	}
-
-	//指标来源
-	if source > 0 {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"Source": source,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	if frequency != "" {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"Frequency.keyword": frequency,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	// noPermissionEdbInfoIdList 无权限指标id
-	if len(noPermissionEdbInfoIdList) > 0 {
-		mustNotMap = append(mustNotMap, map[string]interface{}{
-			"terms": map[string]interface{}{
-				"EdbInfoId": noPermissionEdbInfoIdList,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	// noPermissionEdbInfoIdList 无权限指标id
-	if len(noPermissionEdbClassifyIdList) > 0 {
-		mustNotMap = append(mustNotMap, map[string]interface{}{
-			"terms": map[string]interface{}{
-				"ClassifyId": noPermissionEdbClassifyIdList,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	// 指标类型:普通指标、预测指标(小于0 代表不区分指标是普通还是预测)
-	if edbInfoType >= 0 {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"EdbInfoType": edbInfoType,
-			},
-		})
-	}
-
-	// 指标类型:0-基础+计算;1-基础指标;2-计算指标
-	if edbType > 0 {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"EdbType": edbType,
-			},
-		})
-	}
-
-	//普通指标
-	//mustMap = append(mustMap, map[string]interface{}{
-	//	"term": map[string]interface{}{
-	//		"EdbInfoType": 0,
-	//		//"Frequency.keyword": "月度",
-	//	},
-	//})
-
-	//关键字匹配
-	//shouldMap := map[string]interface{}{
-	//	"should": []interface{}{
-	//		map[string]interface{}{
-	//			"match": map[string]interface{}{
-	//				"EdbCode": keywordStr,
-	//				//"Frequency.keyword": "月度",
-	//			},
-	//		},
-	//		map[string]interface{}{
-	//			"match": map[string]interface{}{
-	//				"EdbName": keywordStr,
-	//				//"Frequency.keyword": "月度",
-	//			},
-	//		},
-	//		map[string]interface{}{
-	//			"match": map[string]interface{}{
-	//				"EdbNameEn": keywordStr,
-	//				//"Frequency.keyword": "月度",
-	//			},
-	//		},
-	//	},
-	//}
-
-	// 默认使用中文名字字段去匹配
-	keywordNameKey := `EdbName`
-	// 如果没有中文,则使用英文名称字段去匹配
-	if !utils.ContainsChinese(keywordStr) {
-		keywordNameKey = `EdbNameEn`
-	}
-	shouldMap := map[string]interface{}{
-		"should": []interface{}{
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"EdbCode": keywordStr,
-					//"Frequency.keyword": "月度",
-				},
-			},
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					keywordNameKey: keywordStr,
-					//"Frequency.keyword": "月度",
-				},
-			},
-		},
-	}
-
-	//mustMap = append(mustMap, map[string]interface{}{
-	//	"bool": shouldMap,
-	//})
-
-	return searchEdbInfoData(indexName, mustMap, mustNotMap, shouldMap, from, size)
-}
-
-func SearchEdbInfoDataBak(indexName, keywordStr string, from, size, filterSource, source int, frequency string) (total int64, list []*data_manage.EdbInfoList, err error) {
-	list = make([]*data_manage.EdbInfoList, 0)
-	defer func() {
-		if err != nil {
-			fmt.Println("EsAddOrEditData Err:", err.Error())
-		}
-
-		for _, v := range list {
-			v.ConvertToResp()
-		}
-	}()
-	client := utils.EsClient
-
-	//queryString := elastic.NewQueryStringQuery(keywordStr)
-	//boolQueryJson, err := json.Marshal(queryString)
-	//if err != nil {
-	//	fmt.Println("boolQueryJson err:", err)
-	//} else {
-	//	fmt.Println("boolQueryJson ", string(boolQueryJson))
-	//}
-
-	highlight := elastic.NewHighlight()
-	highlight = highlight.Fields(elastic.NewHighlighterField("EdbCode"), elastic.NewHighlighterField("EdbName"))
-	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
-
-	//query := elastic.RawStringQuery(`{"match_all":{}}`)
-
-	//var source map[string]interface{}
-	//source := map[string]interface{}{
-	//	"query": map[string]interface{}{
-	//		"match_all": map[string]interface{}{},
-	//	},
-	//}
-	mustMap := make([]interface{}, 0)
-	mustNotMap := make([]interface{}, 0)
-
-	//source := map[string]interface{}{
-	//	"query": map[string]interface{}{
-	//		"bool": map[string]interface{}{
-	//			"must": map[string]interface{}{
-	//				"query_string": map[string]interface{}{
-	//					"query":  keywordStr,
-	//					"fields": []string{"EdbCode", "EdbName"},
-	//				},
-	//			},
-	//		},
-	//	},
-	//}
-
-	switch filterSource {
-	case 2:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"filter": []interface{}{
-		//				map[string]interface{}{
-		//					"term": map[string]interface{}{
-		//						"Frequency.keyword": "月度",
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"Frequency.keyword": "月度",
-					//"Frequency.keyword": "月度",
-				},
-			},
-		}
-	case 3:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"must_not": []interface{}{
-		//				map[string]interface{}{
-		//					"match": map[string]interface{}{
-		//						"Frequency.keyword": "日度",
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-
-		////注释掉,所有频度都可以变频 2022-08-31 14:31:28
-		//mustNotMap = []interface{}{
-		//	map[string]interface{}{
-		//		"match": map[string]interface{}{
-		//			"Frequency.keyword": "日度",
-		//			//"Frequency.keyword": "月度",
-		//		},
-		//	},
-		//}
-	case 4:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"filter": []interface{}{
-		//				map[string]interface{}{
-		//					"term": map[string]interface{}{
-		//						"EdbType": 1,
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"EdbType": 1,
-				},
-			},
-		}
-	case 5:
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"Source": 6,
-				},
-			},
-		}
-	case 6:
-		mustNotMap = []interface{}{
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"Frequency.keyword": "年度",
-				},
-			},
-		}
-	}
-
-	//指标来源
-	if source > 0 {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"Source": source,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	if frequency != "" {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"Frequency.keyword": frequency,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	//普通指标
-	//mustMap = append(mustMap, map[string]interface{}{
-	//	"term": map[string]interface{}{
-	//		"EdbInfoType": 0,
-	//		//"Frequency.keyword": "月度",
-	//	},
-	//})
-
-	//关键字匹配
-	shouldMap := map[string]interface{}{
-		"should": []interface{}{
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"EdbCode": keywordStr,
-					//"Frequency.keyword": "月度",
-				},
-			},
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"EdbName": keywordStr,
-					//"Frequency.keyword": "月度",
-				},
-			},
-
-			// 因为关键词被分了,所以需要用下面的语句来让他 整个词 查询,从而加重整词的权重
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"EdbCode": map[string]interface{}{
-						"query":    keywordStr,
-						"operator": "and",
-					},
-					//"Frequency.keyword": "月度",
-				},
-			},
-
-			// 因为关键词被分了,所以需要用下面的语句来让他 整个词 查询,从而加重整词的权重
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"EdbName": map[string]interface{}{
-						"query":    keywordStr,
-						"operator": "and",
-					},
-					//"Frequency.keyword": "月度",
-				},
-			},
-		},
-	}
-	mustMap = append(mustMap, map[string]interface{}{
-		"bool": shouldMap,
-	})
-
-	queryMap := map[string]interface{}{
-		"query": map[string]interface{}{
-			"bool": map[string]interface{}{
-				"must":     mustMap,
-				"must_not": mustNotMap,
-				//"should":   shouldMap,
-			},
-		},
-	}
-
-	//根据条件数量统计
-	requestTotalHits := client.Count(indexName).BodyJson(queryMap)
-	total, err = requestTotalHits.Do(context.Background())
-	if err != nil {
-		return
-	}
-
-	queryMap["from"] = from
-	queryMap["size"] = size
-	jsonBytes, _ := json.Marshal(queryMap)
-	fmt.Println(string(jsonBytes))
-
-	//queryStr := fmt.Sprintf(`{"query":{"bool":{"must":{"query_string":{"query":"%s","fields":["EdbCode","EdbName"]}}}}}`, keywordStr)
-	//switch filterSource {
-	//case 2:
-	//	queryStr = fmt.Sprintf(`{"query":{"bool":{"must":{"query_string":{"query":"%s","fields":["EdbCode","EdbName"]}},"filter":{"term":{"Frequency.keyword":"%s"}}}}}`, keywordStr, "月度")
-	//case 3:
-	//	queryStr = fmt.Sprintf(`{"query":{"bool":{"must":{"query_string":{"query":"%s","fields":["EdbCode","EdbName"]}},"must_not":[{"match":{"Frequency.keyword":"%s"}}]}}}`, keywordStr, "日度")
-	//case 4:
-	//	queryStr = fmt.Sprintf(`{"query":{"bool":{"must":{"query_string":{"query":"%s","fields":["EdbCode","EdbName"]}},"must_not":[{"match":{"EdbType":1}}]}}}`, keywordStr)
-	//}
-	//queryString := elastic.RawStringQuery(queryStr)
-	//fmt.Println("queryString:", queryString)
-
-	//queryString := elastic.NewMatchQuery("EdbCode", keywordStr)
-	//request := client.Search(indexName).Highlight(highlight).From(from).Size(size).Query(queryString)
-
-	request := client.Search(indexName).Highlight(highlight).Source(queryMap) // sets the JSON request
-
-	//requestJson, err := json.Marshal(request)
-	//if err != nil {
-	//	fmt.Println("requestJson err:", err)
-	//}
-	//fmt.Println("requestJson ", string(requestJson))
-	searchMap := make(map[string]string)
-
-	searchResp, err := request.Do(context.Background())
-	if err != nil {
-		return
-	}
-	fmt.Println(searchResp)
-	fmt.Println(searchResp.Status)
-	if searchResp.Status != 0 {
-		return
-	}
-	if searchResp.Hits != nil {
-		for _, v := range searchResp.Hits.Hits {
-			if _, ok := searchMap[v.Id]; !ok {
-				itemJson, tmpErr := v.Source.MarshalJSON()
-				if tmpErr != nil {
-					err = tmpErr
-					fmt.Println("movieJson err:", err)
-					return
-				}
-				edbInfoItem := new(data_manage.EdbInfoList)
-				tmpErr = json.Unmarshal(itemJson, &edbInfoItem)
-				if tmpErr != nil {
-					fmt.Println("json.Unmarshal movieJson err:", tmpErr)
-					err = tmpErr
-					return
-				}
-				if len(v.Highlight["EdbCode"]) > 0 {
-					edbInfoItem.EdbCode = v.Highlight["EdbCode"][0]
-				}
-				if len(v.Highlight["EdbName"]) > 0 {
-					edbInfoItem.EdbCode = v.Highlight["EdbName"][0]
-				}
-				list = append(list, edbInfoItem)
-				searchMap[v.Id] = v.Id
-			}
-		}
-	}
-
-	//for _, v := range result {
-	//	fmt.Println(v)
-	//}
-	return
-}
-
-// SearchAddPredictEdbInfoData 查询允许添加预测指标的数据
-func SearchAddPredictEdbInfoData(indexName, keywordStr string, noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList []int, from, size, edbType int) (total int64, list []*data_manage.EdbInfoList, err error) {
-	list = make([]*data_manage.EdbInfoList, 0)
-	defer func() {
-		if err != nil {
-			fmt.Println("EsAddOrEditData Err:", err.Error())
-		}
-
-		for _, v := range list {
-			v.ConvertToResp()
-		}
-	}()
-
-	highlight := elastic.NewHighlight()
-	highlight = highlight.Fields(elastic.NewHighlighterField("EdbCode"), elastic.NewHighlighterField("EdbName"))
-	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
-
-	mustMap := make([]interface{}, 0)
-	mustNotMap := make([]interface{}, 0)
-
-	mustNotMap = []interface{}{
-		//map[string]interface{}{
-		//	"terms": map[string]interface{}{
-		//		"Frequency.keyword": []string{"日度", "周度", "月度"},
-		//	},
-		//	//"match": map[string]interface{}{
-		//	//	"Frequency": []string{"日度", "周度", "月度"},
-		//	//	//"Frequency.keyword": []string{"日度", "周度", "月度"},
-		//	//},
-		//},
-	}
-
-	// 指标类型:普通指标、预算指标
-	mustMap = append(mustMap, map[string]interface{}{
-		"term": map[string]interface{}{
-			"EdbInfoType": 0,
-		},
-	})
-	mustMap = append(mustMap, map[string]interface{}{
-		"terms": map[string]interface{}{
-			"Frequency.keyword": []string{"日度", "周度", "月度"},
-		},
-	})
-
-	// 指标类型: 1-基础指标; 2-计算指标
-	if edbType > 0 {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"EdbType": edbType,
-			},
-		})
-	}
-
-	//关键字匹配
-	//shouldMap := map[string]interface{}{
-	//	"should": []interface{}{
-	//		map[string]interface{}{
-	//			"match": map[string]interface{}{
-	//				"EdbCode": keywordStr,
-	//				//"Frequency.keyword": "月度",
-	//			},
-	//		},
-	//		map[string]interface{}{
-	//			"match": map[string]interface{}{
-	//				"EdbName": keywordStr,
-	//				//"Frequency.keyword": "月度",
-	//			},
-	//		},
-	//		map[string]interface{}{
-	//			"match": map[string]interface{}{
-	//				"EdbNameEn": keywordStr,
-	//				//"Frequency.keyword": "月度",
-	//			},
-	//		},
-	//	},
-	//}
-
-	// 默认使用中文名字字段去匹配
-	keywordNameKey := `EdbName`
-	// 如果没有中文,则使用英文名称字段去匹配
-	if !utils.ContainsChinese(keywordStr) {
-		keywordNameKey = `EdbNameEn`
-	}
-	shouldMap := map[string]interface{}{
-		"should": []interface{}{
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"EdbCode": keywordStr,
-					//"Frequency.keyword": "月度",
-				},
-			},
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					keywordNameKey: keywordStr,
-					//"Frequency.keyword": "月度",
-				},
-			},
-		},
-	}
-
-	// noPermissionEdbInfoIdList 无权限指标id
-	if len(noPermissionEdbInfoIdList) > 0 {
-		mustNotMap = append(mustNotMap, map[string]interface{}{
-			"terms": map[string]interface{}{
-				"EdbInfoId": noPermissionEdbInfoIdList,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	// noPermissionEdbClassifyIdList 无权限指标分类id
-	if len(noPermissionEdbClassifyIdList) > 0 {
-		mustNotMap = append(mustNotMap, map[string]interface{}{
-			"terms": map[string]interface{}{
-				"ClassifyId": noPermissionEdbClassifyIdList,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
+	"strconv"
+	"strings"
 
-	return searchEdbInfoData(indexName, mustMap, mustNotMap, shouldMap, from, size)
-}
+	"github.com/olivere/elastic/v7"
+)
 
-// searchEdbInfoData 查询es中的指标数据
-func searchEdbInfoData(indexName string, mustMap, mustNotMap []interface{}, shouldMap map[string]interface{}, from, size int) (total int64, list []*data_manage.EdbInfoList, err error) {
-	list = make([]*data_manage.EdbInfoList, 0)
-	defer func() {
-		if err != nil {
-			fmt.Println("EsAddOrEditData Err:", err.Error())
-		}
-	}()
+// indexName:索引名称
+// mappingJson:表结构
+func EsCreateIndex(indexName, mappingJson string) (err error) {
 	client := utils.EsClient
 
-	//queryString := elastic.NewQueryStringQuery(keywordStr)
-	//boolQueryJson, err := json.Marshal(queryString)
-	//if err != nil {
-	//	fmt.Println("boolQueryJson err:", err)
-	//} else {
-	//	fmt.Println("boolQueryJson ", string(boolQueryJson))
-	//}
-
-	highlight := elastic.NewHighlight()
-	highlight = highlight.Fields(elastic.NewHighlighterField("EdbCode"), elastic.NewHighlighterField("EdbName"))
-	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
-
-	//query := elastic.RawStringQuery(`{"match_all":{}}`)
-
-	//关键字匹配
-	mustMap = append(mustMap, map[string]interface{}{
-		"bool": shouldMap,
-	})
-
-	queryMap := map[string]interface{}{
-		"query": map[string]interface{}{
-			"bool": map[string]interface{}{
-				"must":     mustMap,
-				"must_not": mustNotMap,
-				//"should":   shouldMap,
-			},
-		},
-	}
-
-	//根据条件数量统计
-	requestTotalHits := client.Count(indexName).BodyJson(queryMap)
-	total, err = requestTotalHits.Do(context.Background())
+	//定义表结构
+	exists, err := client.IndexExists(indexName).Do(context.Background()) //<5>
 	if err != nil {
 		return
 	}
+	if !exists {
+		resp, err := client.CreateIndex(indexName).BodyJson(mappingJson).Do(context.Background())
+		//BodyJson(bodyJson).Do(context.Background())
+		if err != nil {
+			fmt.Println("CreateIndex Err:" + err.Error())
+			return err
+		}
+		fmt.Println(resp.Index, resp.ShardsAcknowledged, resp.Acknowledged)
+	} else {
+		fmt.Println(indexName + " 已存在")
+	}
+	return
+}
 
-	queryMap["from"] = from
-	queryMap["size"] = size
-	jsonBytes, _ := json.Marshal(queryMap)
-	fmt.Println(string(jsonBytes))
-
-	//queryStr := fmt.Sprintf(`{"query":{"bool":{"must":{"query_string":{"query":"%s","fields":["EdbCode","EdbName"]}}}}}`, keywordStr)
-	//switch filterSource {
-	//case 2:
-	//	queryStr = fmt.Sprintf(`{"query":{"bool":{"must":{"query_string":{"query":"%s","fields":["EdbCode","EdbName"]}},"filter":{"term":{"Frequency.keyword":"%s"}}}}}`, keywordStr, "月度")
-	//case 3:
-	//	queryStr = fmt.Sprintf(`{"query":{"bool":{"must":{"query_string":{"query":"%s","fields":["EdbCode","EdbName"]}},"must_not":[{"match":{"Frequency.keyword":"%s"}}]}}}`, keywordStr, "日度")
-	//case 4:
-	//	queryStr = fmt.Sprintf(`{"query":{"bool":{"must":{"query_string":{"query":"%s","fields":["EdbCode","EdbName"]}},"must_not":[{"match":{"EdbType":1}}]}}}`, keywordStr)
-	//}
-	//queryString := elastic.RawStringQuery(queryStr)
-	//fmt.Println("queryString:", queryString)
-
-	//queryString := elastic.NewMatchQuery("EdbCode", keywordStr)
-	//request := client.Search(indexName).Highlight(highlight).From(from).Size(size).Query(queryString)
-
-	request := client.Search(indexName).Highlight(highlight).Source(queryMap) // sets the JSON request
-
-	//requestJson, err := json.Marshal(request)
-	//if err != nil {
-	//	fmt.Println("requestJson err:", err)
-	//}
-	//fmt.Println("requestJson ", string(requestJson))
-	searchMap := make(map[string]string)
+// EsDeleteIndex 删除索引
+func EsDeleteIndex(indexName string) (err error) {
+	client := utils.EsClient
 
-	searchResp, err := request.Do(context.Background())
+	//定义表结构
+	exists, err := client.IndexExists(indexName).Do(context.Background()) //<5>
 	if err != nil {
 		return
 	}
-	fmt.Println(searchResp)
-	fmt.Println(searchResp.Status)
-	if searchResp.Status != 0 {
-		return
-	}
-	//total = searchResp.TotalHits()
-	if searchResp.Hits != nil {
-		for _, v := range searchResp.Hits.Hits {
-			if _, ok := searchMap[v.Id]; !ok {
-				itemJson, tmpErr := v.Source.MarshalJSON()
-				if tmpErr != nil {
-					err = tmpErr
-					fmt.Println("movieJson err:", err)
-					return
-				}
-				edbInfoItem := new(data_manage.EdbInfoList)
-				tmpErr = json.Unmarshal(itemJson, &edbInfoItem)
-				if tmpErr != nil {
-					fmt.Println("json.Unmarshal movieJson err:", tmpErr)
-					err = tmpErr
-					return
-				}
-				if len(v.Highlight["EdbCode"]) > 0 {
-					edbInfoItem.EdbCode = v.Highlight["EdbCode"][0]
-				}
-				if len(v.Highlight["EdbName"]) > 0 {
-					edbInfoItem.EdbCode = v.Highlight["EdbName"][0]
-				}
-				list = append(list, edbInfoItem)
-				searchMap[v.Id] = v.Id
-			}
+	if exists {
+		resp, err := client.DeleteIndex(indexName).Do(context.Background())
+		if err != nil {
+			fmt.Println("DeleteIndex Err:" + err.Error())
+			return err
 		}
+		fmt.Println(resp.Acknowledged)
+	} else {
+		fmt.Println(indexName + " 不存在")
 	}
-
 	return
 }
 
-// EsDeleteEdbInfoData 删除es中的指标数据
-func EsDeleteEdbInfoData(indexName, docId string) (err error) {
-	defer func() {
-		if err != nil {
-			fmt.Println("EsDeleteEdbInfoData Err:", err.Error())
-		}
-	}()
+// 删除数据
+func EsDeleteData(indexName, docId string) (err error) {
 	client := utils.EsClient
 
 	resp, err := client.Delete().Index(indexName).Id(docId).Do(context.Background())
@@ -905,6 +77,14 @@ func EsDeleteEdbInfoData(indexName, docId string) (err error) {
 	return
 }
 
+func MappingModify(indexName, mappingJson string) {
+	client := utils.EsClient
+	result, err := client.PutMapping().Index(indexName).BodyString(mappingJson).Do(context.Background())
+	fmt.Println(err)
+	fmt.Println(result)
+	return
+}
+
 // EsAddOrEditReport 新增编辑es报告
 func EsAddOrEditReport(indexName, docId string, item *models.ElasticReportDetail) (err error) {
 	defer func() {
@@ -1461,230 +641,3 @@ func SearchMyChartInfoData(indexName, keywordStr string, adminId int, noPermissi
 	//}
 	return
 }
-
-// SearchEdbInfoDataByAdminId 查询es中的指标数据
-func SearchEdbInfoDataByAdminId(indexName, keywordStr string, from, size, filterSource, source int, edbInfoType uint8, frequency string, adminId int) (total int64, list []*data_manage.EdbInfoList, err error) {
-	list = make([]*data_manage.EdbInfoList, 0)
-	defer func() {
-		if err != nil {
-			fmt.Println("EsAddOrEditData Err:", err.Error())
-		}
-		for _, v := range list {
-			v.ConvertToResp()
-		}
-	}()
-
-	highlight := elastic.NewHighlight()
-	highlight = highlight.Fields(elastic.NewHighlighterField("EdbCode"), elastic.NewHighlighterField("EdbName"))
-	highlight = highlight.PreTags("<font color='red'>").PostTags("</font>")
-
-	//var source map[string]interface{}
-	//source := map[string]interface{}{
-	//	"query": map[string]interface{}{
-	//		"match_all": map[string]interface{}{},
-	//	},
-	//}
-	mustMap := make([]interface{}, 0)
-	mustNotMap := make([]interface{}, 0)
-
-	//source := map[string]interface{}{
-	//	"query": map[string]interface{}{
-	//		"bool": map[string]interface{}{
-	//			"must": map[string]interface{}{
-	//				"query_string": map[string]interface{}{
-	//					"query":  keywordStr,
-	//					"fields": []string{"EdbCode", "EdbName"},
-	//				},
-	//			},
-	//		},
-	//	},
-	//}
-
-	switch filterSource {
-	case 2:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"filter": []interface{}{
-		//				map[string]interface{}{
-		//					"term": map[string]interface{}{
-		//						"Frequency.keyword": "月度",
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"Frequency.keyword": "月度",
-					//"Frequency.keyword": "月度",
-				},
-			},
-		}
-	case 3:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"must_not": []interface{}{
-		//				map[string]interface{}{
-		//					"match": map[string]interface{}{
-		//						"Frequency.keyword": "日度",
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-
-		////注释掉,所有频度都可以变频 2022-08-31 14:31:28
-		//mustNotMap = []interface{}{
-		//	map[string]interface{}{
-		//		"match": map[string]interface{}{
-		//			"Frequency.keyword": "日度",
-		//			//"Frequency.keyword": "月度",
-		//		},
-		//	},
-		//}
-	case 4:
-		//source = map[string]interface{}{
-		//	"query": map[string]interface{}{
-		//		"bool": map[string]interface{}{
-		//			"must": map[string]interface{}{
-		//				"query_string": map[string]interface{}{
-		//					"query": keywordStr,
-		//				},
-		//			},
-		//			"filter": []interface{}{
-		//				map[string]interface{}{
-		//					"term": map[string]interface{}{
-		//						"EdbType": 1,
-		//					},
-		//				}},
-		//		},
-		//	},
-		//}
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"EdbType": 1,
-				},
-			},
-		}
-	case 5:
-		mustMap = []interface{}{
-			map[string]interface{}{
-				"term": map[string]interface{}{
-					"Source": 6,
-				},
-			},
-		}
-	case 6:
-		mustNotMap = []interface{}{
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"Frequency.keyword": "年度",
-				},
-			},
-		}
-	}
-
-	//指标来源
-	if source > 0 {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"Source": source,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	if frequency != "" {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"Frequency.keyword": frequency,
-				//"Frequency.keyword": "月度",
-			},
-		})
-	}
-
-	// 指标类型:普通指标、预算指标
-	mustMap = append(mustMap, map[string]interface{}{
-		"term": map[string]interface{}{
-			"EdbInfoType": edbInfoType,
-		},
-	})
-
-	//普通指标
-	//mustMap = append(mustMap, map[string]interface{}{
-	//	"term": map[string]interface{}{
-	//		"EdbInfoType": 0,
-	//		//"Frequency.keyword": "月度",
-	//	},
-	//})
-
-	//关键字匹配
-	//shouldMap := map[string]interface{}{
-	//	"should": []interface{}{
-	//		map[string]interface{}{
-	//			"match": map[string]interface{}{
-	//				"EdbCode": keywordStr,
-	//				//"Frequency.keyword": "月度",
-	//			},
-	//		},
-	//		map[string]interface{}{
-	//			"match": map[string]interface{}{
-	//				"EdbName": keywordStr,
-	//				//"Frequency.keyword": "月度",
-	//			},
-	//		},
-	//	},
-	//}
-
-	// 默认使用中文名字字段去匹配
-	keywordNameKey := `EdbName`
-	// 如果没有中文,则使用英文名称字段去匹配
-	if !utils.ContainsChinese(keywordStr) {
-		keywordNameKey = `EdbNameEn`
-	}
-	shouldMap := map[string]interface{}{
-		"should": []interface{}{
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					"EdbCode": keywordStr,
-					//"Frequency.keyword": "月度",
-				},
-			},
-			map[string]interface{}{
-				"match": map[string]interface{}{
-					keywordNameKey: keywordStr,
-					//"Frequency.keyword": "月度",
-				},
-			},
-		},
-	}
-
-	mustMap = append(mustMap, map[string]interface{}{
-		"bool": shouldMap,
-	})
-
-	//创建人
-	if adminId > 0 {
-		mustMap = append(mustMap, map[string]interface{}{
-			"term": map[string]interface{}{
-				"SysUserId": adminId,
-			},
-		})
-	}
-
-	return searchEdbInfoData(indexName, mustMap, mustNotMap, shouldMap, from, size)
-}

+ 221 - 0
services/knowledge/es.go

@@ -0,0 +1,221 @@
+package knowledge
+
+import (
+	"context"
+	"encoding/json"
+	"eta_gn/eta_api/models/knowledge"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"html"
+	"strconv"
+	"strings"
+
+	"github.com/PuerkitoBio/goquery"
+)
+
+// SearchChartInfoData 查询es中的图表数据
+func SearchKnowledgeResourceByEs(resourceType int, keywordStr string, showSysIds []int, myId int, classifyIds []int, sourceList []string, tagIds []int, isIncludeFile bool, from, size int) (list []*knowledge.KnowledgeResource, total int64, err error) {
+	indexName := utils.EsKnowledgeResourceIndexName
+	list = make([]*knowledge.KnowledgeResource, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("SearchKnowledgeResource Err:", err.Error())
+			utils.FileLog.Info("SearchKnowledgeResource Err:", err.Error())
+		}
+	}()
+	client := utils.EsClient
+
+	mustMap := make([]interface{}, 0)
+
+	mustMap = append(mustMap, map[string]interface{}{
+		"term": map[string]interface{}{
+			"ResourceType": resourceType,
+		},
+	})
+
+	//指标来源
+	if len(showSysIds) > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"AdminId": showSysIds,
+			},
+		})
+	}
+	if myId > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"AdminId": myId,
+			},
+		})
+	}
+	if len(tagIds) > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"TagId": tagIds,
+			},
+		})
+	}
+	if len(sourceList) > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"SourceFrom": sourceList,
+			},
+		})
+	}
+	if len(classifyIds) > 0 {
+		mustMap = append(mustMap, map[string]interface{}{
+			"terms": map[string]interface{}{
+				"ClassifyId": classifyIds,
+			},
+		})
+	}
+
+	mustMap = append(mustMap, map[string]interface{}{
+		"term": map[string]interface{}{
+			"IsDelete": 0,
+		},
+	})
+	if !isIncludeFile {
+		mustMap = append(mustMap, map[string]interface{}{
+			"term": map[string]interface{}{
+				"IsFile": 0,
+			},
+		})
+	}
+
+	if keywordStr != "" {
+		shouldMap := map[string]interface{}{
+			"should": []interface{}{
+				map[string]interface{}{
+					"match": map[string]interface{}{
+						"Title": keywordStr,
+					},
+				},
+				// 因为关键词被分了,所以需要用下面的语句来让他 整个词 查询,从而加重整词的权重
+				map[string]interface{}{
+					"match": map[string]interface{}{
+						"Title": map[string]interface{}{
+							"query":    keywordStr,
+							"operator": "and",
+						},
+					},
+				},
+			},
+		}
+		mustMap = append(mustMap, map[string]interface{}{
+			"bool": shouldMap,
+		})
+	}
+
+	queryMap := map[string]interface{}{
+		"query": map[string]interface{}{
+			"bool": map[string]interface{}{
+				"must": mustMap,
+			},
+		},
+	}
+
+	//根据条件数量统计
+	requestTotalHits := client.Count(indexName).BodyJson(queryMap)
+	total, err = requestTotalHits.Do(context.Background())
+	if err != nil {
+		return
+	}
+
+	// 分页查询
+	queryMap["from"] = from
+	queryMap["size"] = size
+
+	if keywordStr == "" {
+		sortMap := []map[string]interface{}{
+			{
+				"StartTime.keyword": map[string]interface{}{
+					"order": "desc", // 按照开始时间倒序排列
+				},
+			},
+		}
+		queryMap["sort"] = sortMap
+
+	}
+
+	request := client.Search(indexName).Source(queryMap) // sets the JSON request
+	searchMap := make(map[string]string)
+
+	searchResp, err := request.Do(context.Background())
+	if err != nil {
+		return
+	}
+	if searchResp.Status != 0 {
+		jsonBytes, _ := json.Marshal(queryMap)
+		utils.FileLog.Info("search json:%s,SearchKnowledgeResourceByEs Status:%d", string(jsonBytes), searchResp.Status)
+		return
+	}
+
+	if searchResp.Hits != nil {
+		for _, v := range searchResp.Hits.Hits {
+			if _, ok := searchMap[v.Id]; !ok {
+				itemJson, tmpErr := v.Source.MarshalJSON()
+				if tmpErr != nil {
+					err = tmpErr
+					utils.FileLog.Info("search json:%s,SearchKnowledgeResourceByEs Hits Source err:%s", string(itemJson), tmpErr.Error())
+					return
+				}
+				knowledgeItem := new(knowledge.KnowledgeResource)
+				tmpErr = json.Unmarshal(itemJson, &knowledgeItem)
+				if err != nil {
+					utils.FileLog.Info("json.Unmarshal KnowledgeResource err:%s", err.Error())
+					err = tmpErr
+					return
+				}
+				list = append(list, knowledgeItem)
+				searchMap[v.Id] = v.Id
+			}
+		}
+	}
+	return
+}
+
+func ExtractTextFromResourceContent(content string) (text string) {
+	content = html.UnescapeString(content)
+	doc, err := goquery.NewDocumentFromReader(strings.NewReader(content))
+	if err != nil {
+		return
+	}
+	text = doc.Text()
+	text = strings.ReplaceAll(text, "\n", "")
+	return
+}
+
+// EsAddOrEditKnowledgeResource 新增/修改es中的知识资源数据
+func EsAddOrEditKnowledgeResource(item *knowledge.KnowledgeResource) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("EsAddOrEditData Err:", err.Error())
+			utils.FileLog.Info("EsAddOrEditKnowledgeResource err:", err)
+		}
+	}()
+	indexName := utils.EsKnowledgeResourceIndexName
+	client := utils.EsClient
+	if item.IsFile == 0 {
+		content := ExtractTextFromResourceContent(item.Content)
+		contentRunes := []rune(content)
+		if len(contentRunes) > 60 {
+			item.Content = string(contentRunes[:60])
+		} else {
+			item.Content = content
+		}
+	}
+	request := client.Index().Index(indexName).Id(strconv.Itoa(item.KnowledgeResourceId)).BodyJson(item)
+	response, err := request.Do(context.Background())
+	if err != nil {
+		jsonBytes, _ := json.Marshal(item)
+		utils.FileLog.Info("add json:%s,EsAddOrEditKnowledgeResource err:%s", string(jsonBytes), err.Error())
+		return
+	}
+	if response.Status == 0 {
+		err = nil
+	} else {
+		fmt.Println("EsAddOrEditKnowledgeResource:", response.Status, response.Result)
+	}
+	return
+}

+ 134 - 2
services/knowledge/resource.go

@@ -1,6 +1,7 @@
 package knowledge
 
 import (
+	"encoding/json"
 	"errors"
 	"eta_gn/eta_api/models/knowledge"
 	"eta_gn/eta_api/models/system"
@@ -8,11 +9,14 @@ import (
 	"eta_gn/eta_api/services/alarm_msg"
 	"eta_gn/eta_api/utils"
 	"fmt"
-	"github.com/tealeg/xlsx"
 	"html"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/go-redis/redis/v8"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
 )
 
 func AddResource(req *knowledge.AddReq, sysUser *system.Admin) (item *knowledge.KnowledgeResource, err error, errMsg string) {
@@ -148,9 +152,11 @@ func AddResource(req *knowledge.AddReq, sysUser *system.Admin) (item *knowledge.
 		err = fmt.Errorf("保存失败,Err:" + err.Error())
 		return
 	}
-	//todo 是否需要保存到es中
+	// 保存到es中
+	go EsAddOrEditKnowledgeResource(item)
 	return
 }
+
 func EditResource(resourceInfo *knowledge.KnowledgeResource, req knowledge.EditReq, sysUser *system.Admin) (err error, errMsg string) {
 	errMsg = `保存失败`
 	var startTime time.Time
@@ -274,6 +280,7 @@ func EditResource(resourceInfo *knowledge.KnowledgeResource, req knowledge.EditR
 	if err != nil {
 		return
 	}
+	go EsAddOrEditKnowledgeResource(resourceInfo)
 	return
 }
 
@@ -1053,3 +1060,128 @@ func addExcelResource(req *knowledge.AddReq, sysUser *system.Admin) (err error,
 	//todo 是否需要保存到es中
 	return
 }
+
+func GetKnowledgeResourceTmpList(dashboardDetailId, adminId int) (resp *knowledge.BiDashboardResourceAddResp, msg string, err error) {
+	if dashboardDetailId <= 0 {
+		data, er := utils.Rc.RedisBytes(utils.CACHE_KEY_BI_DASHBOARD_PREPARE_RESOURCE + strconv.Itoa(adminId))
+		req := new(knowledge.BiDashboardResourceAddReq)
+		if er != nil {
+			if er == redis.Nil {
+				msg = "暂无知识库"
+				err = nil
+				return
+			}
+			msg = "获取知识库模板列表失败"
+			return
+		}
+		if err = json.Unmarshal(data, &req); err != nil {
+			msg = "获取知识库模板列表失败"
+		}
+
+		selectedIds := make([]int, 0)
+		for _, item := range req.KnowledgeResourceList {
+			selectedIds = append(selectedIds, item.KnowledgeResourceId)
+		}
+		knowledgeList, er := knowledge.GetKnowledgeResourceByIds(selectedIds)
+		if er != nil {
+			msg = "获取知识库模板列表失败"
+			return
+		}
+		resp = new(knowledge.BiDashboardResourceAddResp)
+		resp.KnowledgeResourceList = toKnowledgeResourceList(knowledgeList)
+	} else {
+		condition := ` AND bi_dashboard_detail_id = ? `
+		pars := []interface{}{dashboardDetailId}
+		resourceIds, er := knowledge.GetKnowledgeResourceIdsByCondition(condition, pars)
+		if er != nil {
+			msg = "获取知识库模板列表失败"
+			return
+		}
+		if len(resourceIds) == 0 {
+			msg = "暂无知识库"
+			return
+		}
+		resp = new(knowledge.BiDashboardResourceAddResp)
+		knowledgeList, er := knowledge.GetKnowledgeResourceByIds(resourceIds)
+		if er != nil {
+			msg = "获取知识库模板列表失败"
+			return
+		}
+		resp.BiDashboardDetailId = dashboardDetailId
+		resp.KnowledgeResourceList = toKnowledgeResourceList(knowledgeList)
+	}
+	return
+}
+
+func GetKnowledgeResourceList(dashboardDetailId int) (resp *knowledge.KnowledgeResourceListResp, msg string, err error) {
+	// var startSize int
+	// if pageSize <= 0 {
+	// 	pageSize = utils.PageSize20
+	// }
+	// if currentIndex <= 0 {
+	// 	currentIndex = 1
+	// }
+	// startSize = utils.StartIndex(currentIndex, pageSize)
+
+	condition := ` AND bi_dashboard_detail_id = ? `
+	var pars = []interface{}{dashboardDetailId}
+
+	resourceIds, err := knowledge.GetKnowledgeResourceIdsByCondition(condition, pars)
+	if err != nil {
+		msg = "获取知识库列表失败"
+		return
+	}
+	if len(resourceIds) == 0 {
+		resp = &knowledge.KnowledgeResourceListResp{
+			List:   make([]*knowledge.KnowledgeResourceList, 0),
+			Paging: &paging.PagingItem{},
+		}
+		return
+	}
+
+	knowledgeList, err := knowledge.GetKnowledgeResourceByIds(resourceIds)
+	if err != nil {
+		msg = "获取知识库列表失败"
+		return
+	}
+
+	resp = new(knowledge.KnowledgeResourceListResp)
+	resp.List = toKnowledgeResourceList(knowledgeList)
+
+	return
+}
+
+func toKnowledgeResourceList(list []*knowledge.KnowledgeResource) (res []*knowledge.KnowledgeResourceList) {
+	for _, item := range list {
+		resItem := &knowledge.KnowledgeResourceList{
+			KnowledgeResourceId: item.KnowledgeResourceId,
+			ResourceType:        item.ResourceType,
+			ClassifyId:          item.ClassifyId,
+			Title:               item.Title,
+			State:               item.State,
+			ResourceCode:        item.ResourceCode,
+			AdminId:             item.AdminId,
+			AdminRealName:       item.AdminRealName,
+			SourceFrom:          item.SourceFrom,
+			TagId:               item.TagId,
+			CreateTime:          utils.TimeTransferString(utils.FormatDateTime, item.CreateTime),
+			ModifyTime:          utils.TimeTransferString(utils.FormatDateTime, item.ModifyTime),
+		}
+		if item.StartTime != nil {
+			if item.ResourceType == knowledge.KnowledgeResourceTypeEvent || item.ResourceType == knowledge.KnowledgeResourceTypePolicy {
+				resItem.StartTime = utils.TimeTransferString(utils.FormatDateTime, *item.StartTime)
+			} else {
+				resItem.StartTime = utils.TimeTransferString(utils.FormatDate, *item.StartTime)
+			}
+		}
+		if item.EndTime != nil {
+			if item.ResourceType == knowledge.KnowledgeResourceTypeEvent || item.ResourceType == knowledge.KnowledgeResourceTypePolicy {
+				resItem.EndTime = utils.TimeTransferString(utils.FormatDateTime, *item.EndTime)
+			} else {
+				resItem.EndTime = utils.TimeTransferString(utils.FormatDate, *item.EndTime)
+			}
+		}
+		res = append(res, resItem)
+	}
+	return
+}

+ 2 - 0
utils/config.go

@@ -127,6 +127,7 @@ var (
 	MY_CHART_INDEX_NAME            string //研究图库(MY ETA)索引
 	EsSemanticAnalysisDocIndexName string //ES语义分析文档索引名
 	SmartReportIndexName           string //智能研报ES索引
+	EsKnowledgeResourceIndexName   string //ES知识库索引
 )
 
 var (
@@ -527,6 +528,7 @@ func init() {
 		EsEnglishReportIndexName = config["es_english_report_index_name"]
 		EsSemanticAnalysisDocIndexName = config["es_semantic_analysis_doc_index_name"]
 		SmartReportIndexName = config["es_smart_report_index_name"]
+		EsKnowledgeResourceIndexName = config["es_knowledge_resource_index_name"]
 	}
 
 	CrmEtaServerUrl = config["crm_eta_server_url"]

+ 13 - 4
utils/constants.go

@@ -179,9 +179,10 @@ const (
 )
 
 const (
-	DATA_PREFIX       = "hz_data"
-	CHART_PREFIX      = "hz_chart"
-	EXCEL_DATA_PREFIX = "hz_excel_data"
+	DATA_PREFIX            = "hz_data"
+	CHART_PREFIX           = "hz_chart"
+	EXCEL_DATA_PREFIX      = "hz_excel_data"
+	PUBLIC_CLASSIFY_PREFIX = "hz_data_public_classify"
 )
 
 const (
@@ -214,7 +215,8 @@ const (
 
 	CACHE_EDB_TERMINAL_CODE_URL = "edb:terminal_code:edb_code:" // 指标与终端关系的缓存
 
-	CACHE_KEY_REPLACE_EDB = "eta:replace_edb" //系统用户操作日志队列
+	CACHE_KEY_REPLACE_EDB                   = "eta:replace_edb"                   //系统用户操作日志队列
+	CACHE_KEY_BI_DASHBOARD_PREPARE_RESOURCE = "eta:bi_dashboard:prepare_resource" // 准备引用到看板的知识资源
 )
 
 // 模板消息推送类型
@@ -454,6 +456,13 @@ const (
 	EdbPermissionSourceCalculate = 7 // 指标权限来源-计算指标
 )
 
+const (
+	EdbPublicDefault = 0 // 指标公开状态-默认未提交
+	EdbPublicCommit  = 1 // 指标公开状态-已提交
+	EdbPublicReject  = 2 // 指标公开状态-已驳回
+	EdbPublicSuccess = 3 // 指标公开状态-成功
+)
+
 // BaseEdbRefreshStartDate 指标的基础刷新开始日期
 const BaseEdbRefreshStartDate = `1899-01-01`
 

+ 17 - 2
utils/elastic.go

@@ -2,16 +2,31 @@ package utils
 
 import (
 	"github.com/olivere/elastic/v7"
+	"log"
+	"os"
 )
 
 // EsClient es客户端
 var EsClient *elastic.Client
 
 func initEs() {
-	client, err := elastic.NewClient(
+	var logInfo *log.Logger
+	if RunMode == `debug` {
+		logInfo = log.New(os.Stderr, "", log.LstdFlags)
+	}
+
+	clientOptionFuncList := []elastic.ClientOptionFunc{
 		elastic.SetURL(ES_URL),
 		elastic.SetBasicAuth(ES_USERNAME, ES_PASSWORD),
-		elastic.SetSniff(false))
+		elastic.SetSniff(false),
+	}
+	if logInfo != nil {
+		clientOptionFuncList = append(clientOptionFuncList, elastic.SetTraceLog(logInfo))
+	}
+
+	client, err := elastic.NewClient(
+		clientOptionFuncList...,
+	)
 	EsClient = client
 	if err != nil {
 		panic("ElasticSearch连接失败,err:" + err.Error())

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