Jelajahi Sumber

Merge remote-tracking branch 'origin/master' into pool/295

Roc 1 hari lalu
induk
melakukan
6357b30218
100 mengubah file dengan 11622 tambahan dan 1407 penghapusan
  1. 53 0
      cache/wechat_platform.go
  2. 4 4
      controllers/ai/ai.go
  3. 3 3
      controllers/ai/ai_file.go
  4. 4 4
      controllers/ai/ai_pormpt.go
  5. 18 18
      controllers/ai/ai_summary.go
  6. 15 6
      controllers/banner.go
  7. 22 2
      controllers/base_auth.go
  8. 7 7
      controllers/bi_dashboard.go
  9. 2 2
      controllers/business_conf.go
  10. 4 3
      controllers/classify.go
  11. 4 4
      controllers/cloud_disk.go
  12. 2 2
      controllers/commodity_trade_base_index.go
  13. 4 4
      controllers/company_seller.go
  14. 529 0
      controllers/data_manage/ai_predict_model/classify.go
  15. 668 0
      controllers/data_manage/ai_predict_model/framework.go
  16. 986 0
      controllers/data_manage/ai_predict_model/index.go
  17. 5 5
      controllers/data_manage/baiinfo_data.go
  18. 3 2
      controllers/data_manage/base_from_ly_index_controller.go
  19. 1152 0
      controllers/data_manage/base_from_radish_research.go
  20. 518 0
      controllers/data_manage/base_from_radish_research_classify.go
  21. 1 1
      controllers/data_manage/base_from_rzd_index_controller.go
  22. 105 75
      controllers/data_manage/base_from_ths_hf.go
  23. 2 2
      controllers/data_manage/base_from_ths_hf_classify.go
  24. 78 15
      controllers/data_manage/bloomberg_data.go
  25. 45 19
      controllers/data_manage/business_data.go
  26. 11 3
      controllers/data_manage/ccf_data.go
  27. 429 177
      controllers/data_manage/chart_classify.go
  28. 61 1
      controllers/data_manage/chart_common.go
  29. 2 2
      controllers/data_manage/chart_edb_config.go
  30. 38 16
      controllers/data_manage/chart_framework.go
  31. 316 62
      controllers/data_manage/chart_info.go
  32. 10 4
      controllers/data_manage/chart_theme.go
  33. 1653 0
      controllers/data_manage/clarksons_data.go
  34. 5 5
      controllers/data_manage/com_trade.go
  35. 29 31
      controllers/data_manage/correlation/correlation_chart_classify.go
  36. 34 30
      controllers/data_manage/correlation/correlation_chart_info.go
  37. 30 25
      controllers/data_manage/cross_variety/chart_info.go
  38. 10 10
      controllers/data_manage/cross_variety/classify.go
  39. 5 5
      controllers/data_manage/cross_variety/tag.go
  40. 5 5
      controllers/data_manage/cross_variety/variety.go
  41. 2 2
      controllers/data_manage/data_manage_permission/message.go
  42. 175 17
      controllers/data_manage/edb_classify.go
  43. 144 108
      controllers/data_manage/edb_info.go
  44. 12 7
      controllers/data_manage/edb_info_calculate.go
  45. 22 13
      controllers/data_manage/edb_info_refresh.go
  46. 42 14
      controllers/data_manage/edb_info_relation.go
  47. 3 2
      controllers/data_manage/eia_steo.go
  48. 21 10
      controllers/data_manage/excel/balance_table.go
  49. 20 9
      controllers/data_manage/excel/custom_analysis.go
  50. 1 1
      controllers/data_manage/excel/custom_analysis_edb.go
  51. 15 15
      controllers/data_manage/excel/excel_classify.go
  52. 463 38
      controllers/data_manage/excel/excel_info.go
  53. 2 2
      controllers/data_manage/factor_edb_series.go
  54. 52 29
      controllers/data_manage/fenwei_data.go
  55. 15 0
      controllers/data_manage/fix.go
  56. 13 13
      controllers/data_manage/future_good/future_good_chart_classify.go
  57. 46 41
      controllers/data_manage/future_good/future_good_chart_info.go
  58. 6 6
      controllers/data_manage/future_good/future_good_edb_info.go
  59. 9 9
      controllers/data_manage/future_good/future_good_profit_chart_info.go
  60. 59 10
      controllers/data_manage/gl_data.go
  61. 1045 0
      controllers/data_manage/gpr_risk_data.go
  62. 22 0
      controllers/data_manage/jiayue_edb_source.go
  63. 13 13
      controllers/data_manage/line_equation/line_chart_classify.go
  64. 27 23
      controllers/data_manage/line_equation/line_chart_info.go
  65. 61 41
      controllers/data_manage/line_feature/chart_info.go
  66. 13 13
      controllers/data_manage/line_feature/classify.go
  67. 11 13
      controllers/data_manage/manual.go
  68. 45 11
      controllers/data_manage/manual_edb.go
  69. 17 10
      controllers/data_manage/multiple_graph_config.go
  70. 76 59
      controllers/data_manage/my_chart.go
  71. 61 18
      controllers/data_manage/mysteel_chemical_data.go
  72. 5 5
      controllers/data_manage/predict_edb_classify.go
  73. 205 89
      controllers/data_manage/predict_edb_info.go
  74. 1045 0
      controllers/data_manage/purang_data.go
  75. 13 13
      controllers/data_manage/range_analysis/chart_classify.go
  76. 27 23
      controllers/data_manage/range_analysis/chart_info.go
  77. 5 5
      controllers/data_manage/sci_data.go
  78. 51 20
      controllers/data_manage/sci_hq_data.go
  79. 50 25
      controllers/data_manage/smm_api.go
  80. 7 4
      controllers/data_manage/smm_data.go
  81. 6 1
      controllers/data_manage/stl/stl.go
  82. 8 8
      controllers/data_manage/supply_analysis/variety.go
  83. 10 7
      controllers/data_manage/supply_analysis/variety_edb.go
  84. 8 8
      controllers/data_manage/supply_analysis/variety_plant.go
  85. 6 6
      controllers/data_manage/usda_fas_data.go
  86. 7 7
      controllers/data_manage/wind_data.go
  87. 10 8
      controllers/data_manage/yongyi_data.go
  88. 309 0
      controllers/data_source/data_source.go
  89. 7 8
      controllers/data_source/sci99.go
  90. 25 26
      controllers/data_stat/edb_source_stat.go
  91. 5 3
      controllers/document_manage/document_manage_controller.go
  92. 14 2
      controllers/english_report/email.go
  93. 5 5
      controllers/english_report/en_permission.go
  94. 8 8
      controllers/english_report/english_classify.go
  95. 3 3
      controllers/english_report/english_company.go
  96. 2 2
      controllers/english_report/english_company_todo.go
  97. 5 5
      controllers/english_report/english_video.go
  98. 1 1
      controllers/english_report/policy_report.go
  99. 134 14
      controllers/english_report/report.go
  100. 256 0
      controllers/eta_forum/eta_forum.go

+ 53 - 0
cache/wechat_platform.go

@@ -0,0 +1,53 @@
+package cache
+
+import (
+	"eta/eta_api/utils"
+	"fmt"
+)
+
+type WechatArticleOp struct {
+	Source           string
+	WechatPlatformId int
+}
+
+// AddWechatArticleOpToCache
+// @Description: 将公众号文章操作加入缓存
+// @param wechatPlatformId
+// @param source
+// @return bool
+func AddWechatArticleOpToCache(wechatPlatformId int, source string) bool {
+	record := new(WechatArticleOp)
+	record.Source = source
+	record.WechatPlatformId = wechatPlatformId
+	if utils.Re == nil {
+		err := utils.Rc.LPush(utils.CACHE_WECHAT_PLATFORM_ARTICLE, record)
+
+		utils.FileLog.Info(fmt.Sprintf("将公众号文章操作 加入缓存 AddWechatArticleOpToCache LPush: 操作类型:%s,公众号id:%d", source, wechatPlatformId))
+		if err != nil {
+			fmt.Println("AddWechatArticleOpToCache LPush Err:" + err.Error())
+		}
+		return true
+	}
+	return false
+}
+
+// AddWechatArticleLlmOpToCache
+// @Description: 将公众号文章llm操作加入缓存
+// @param wechatPlatformId
+// @param source
+// @return bool
+func AddWechatArticleLlmOpToCache(wechatPlatformId int, source string) bool {
+	record := new(WechatArticleOp)
+	record.Source = source
+	record.WechatPlatformId = wechatPlatformId
+	if utils.Re == nil {
+		err := utils.Rc.LPush(utils.CACHE_WECHAT_PLATFORM_ARTICLE_KNOWLEDGE, record)
+
+		utils.FileLog.Info(fmt.Sprintf("将公众号文章llm操作加入缓存 加入缓存 AddWechatArticleLlmOpToCache LPush: 操作类型:%s,公众号id:%d", source, wechatPlatformId))
+		if err != nil {
+			fmt.Println("AddWechatArticleOpToCache LPush Err:" + err.Error())
+		}
+		return true
+	}
+	return false
+}

+ 4 - 4
controllers/ai/ai.go

@@ -71,7 +71,7 @@ func (this *AiController) List() {
 	//根据提问,获取信息
 	askUuid := utils.MD5(req.Ask)
 	chatMode, err := aimod.GetAiChatByAsk(askUuid)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取数据失败!"
 		br.ErrMsg = "获取数据失败,GetAiChatByAsk,Err:" + err.Error()
 		return
@@ -88,7 +88,7 @@ func (this *AiController) List() {
 		//获取主题下的所有信息
 		//AiChatTopicId
 		historyList, err := aimod.GetAiChatList(req.AiChatTopicId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取主题历史数据失败!"
 			br.ErrMsg = "获取主题历史数据失败,Err:" + err.Error()
 			return
@@ -317,12 +317,12 @@ func (this *AiController) TopicEdit() {
 		return
 	}
 	topic, err := aimod.GetAiChatTopicByTopicName(req.TopicName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "编辑失败!"
 		br.ErrMsg = "获取数据失败!Err:" + err.Error()
 		return
 	}
-	if topic != nil && topic.AiChatTopicId != req.AiChatTopicId {
+	if topic != nil && topic.AiChatTopicId != req.AiChatTopicId && topic.AiChatTopicId > 0 {
 		br.Msg = "话题名称已存在,请重新修改!"
 		return
 	}

+ 3 - 3
controllers/ai/ai_file.go

@@ -110,7 +110,7 @@ func (this *AiFileController) FileUpload() {
 		aiChatTopicObj.AiChatTopicId = aiChatTopicId
 		topic, err := aiChatTopicObj.GetAiChatTopicById()
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "获取数据失败!"
 				br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error()
 				return
@@ -283,7 +283,7 @@ func (this *AiFileController) FileRetrieve() {
 		aiChatTopicObj.AiChatTopicId = req.AiChatTopicId
 		topic, err := aiChatTopicObj.GetAiChatTopicById()
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "获取数据失败!"
 				br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error()
 				return
@@ -301,7 +301,7 @@ func (this *AiFileController) FileRetrieve() {
 	//获取主题下的所有信息
 	//AiChatTopicId
 	historyList, err := aimod.GetAiChatList(req.AiChatTopicId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取主题历史数据失败!"
 		br.ErrMsg = "获取主题历史数据失败,Err:" + err.Error()
 		return

+ 4 - 4
controllers/ai/ai_pormpt.go

@@ -302,7 +302,7 @@ func (this *AiController) MoveAiPrompt() {
 
 	prompt, err := ai_summary.GetAiPromptById(req.AiPromptId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "当前提示词不存在"
 			br.ErrMsg = "当前提示词不存在"
 			return
@@ -321,7 +321,7 @@ func (this *AiController) MoveAiPrompt() {
 	if req.PrevAiPromptId > 0 {
 		prevPrompt, err = ai_summary.GetAiPromptById(req.PrevAiPromptId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				err = errors.New("目录下的提示词不存在")
 				return
 			}
@@ -334,7 +334,7 @@ func (this *AiController) MoveAiPrompt() {
 	if req.NextAiPromptId > 0 {
 		nextPrompt, err = ai_summary.GetAiPromptById(req.NextAiPromptId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				err = errors.New("目录下的提示词不存在")
 				return
 			}
@@ -410,4 +410,4 @@ func (this *AiController) SharePrompt() {
 	br.Msg = "操作成功"
 
 	return
-}
+}

+ 18 - 18
controllers/ai/ai_summary.go

@@ -58,7 +58,7 @@ func (this *AiController) AiSummaryClassifyItems() {
 	}
 
 	rootList, err := ai_summary.GetAiSummaryClassifyAndInfoByParentId(aiSummaryClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -68,7 +68,7 @@ func (this *AiController) AiSummaryClassifyItems() {
 	}
 
 	classifyAll, err := ai_summary.GetAiSummaryClassifyAndInfoByParentId(aiSummaryClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -243,7 +243,7 @@ func (this *AiController) DeleteSandboxClassifyCheck() {
 
 	if deleteStatus != 1 {
 		classifyCount, err := ai_summary.GetAiSummaryInfoCountByClassifyId(req.AiSummaryClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "分类下是否含有沙盘失败,Err:" + err.Error()
 			return
@@ -304,7 +304,7 @@ func (this *AiController) DeleteAiSummaryClassify() {
 	if req.AiSummaryClassifyId > 0 && req.AiSummaryId == 0 {
 		//判断是否含有纪要
 		count, err := ai_summary.GetAiSummaryInfoCountByClassifyId(req.AiSummaryClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -328,7 +328,7 @@ func (this *AiController) DeleteAiSummaryClassify() {
 	if req.AiSummaryId > 0 {
 		summaryInfo, err := ai_summary.GetAiSummaryById(req.AiSummaryId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "纪要已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -581,7 +581,7 @@ func (this *AiController) AiSummaryClassifyMove() {
 		} else {
 			// prevId为0,也就是沙盘移到最前端
 			firstClassify, err := ai_summary.GetFirstAiSummaryByClassifyId(req.AiSummaryClassifyId)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "移动失败"
 				br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 				return
@@ -770,7 +770,7 @@ func (this *AiController) AiSummaryClassifyMove() {
 
 		} else {
 			firstClassify, err := ai_summary.GetFirstAiSummaryClassifyByParentId(aiSummaryClassifyInfo.ParentId)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "移动失败"
 				br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 				return
@@ -849,7 +849,7 @@ func (this *AiController) AiSummaryList() {
 
 	if aiSummaryClassifyId > 0 {
 		sandboxClassifyIds, err := ai_summary.GetAiSummaryClassify(aiSummaryClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取图表信息失败"
 			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 			return
@@ -870,7 +870,7 @@ func (this *AiController) AiSummaryList() {
 
 	//获取图表信息
 	list, err := ai_summary.GetAiSummaryListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取纪要信息失败"
 		br.ErrMsg = "获取纪要信息失败,Err:" + err.Error()
@@ -887,7 +887,7 @@ func (this *AiController) AiSummaryList() {
 		list[i].ParentIds = ids
 	}
 	resp := new(ai_summary.AiSummaryListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*ai_summary.AiSummaryItems, 0)
 		resp.Paging = page
 		resp.List = items
@@ -898,7 +898,7 @@ func (this *AiController) AiSummaryList() {
 	}
 
 	dataCount, err := ai_summary.GetAiSummaryListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -934,7 +934,7 @@ func (this *AiController) AiSummaryDetail() {
 	aiSummaryId, _ := this.GetInt("AiSummaryId")
 
 	detail, err := ai_summary.GetAiSummaryItemById(aiSummaryId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取沙盘信息失败"
 		br.ErrMsg = "获取沙盘信息失败,Err:" + err.Error()
@@ -948,7 +948,7 @@ func (this *AiController) AiSummaryDetail() {
 		item := new(saModel.SaDoc)
 		e := item.GetItemById(detail.SaDocId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "文档已被删除, 请刷新页面"
 				return
 			}
@@ -1137,7 +1137,7 @@ func (this *AiController) GenerateAiSummary() {
 		//获取主题下的所有信息
 		//AiChatTopicId
 		historyList, err := aimod.GetAiChatList(req.AiChatTopicId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取主题历史数据失败!"
 			br.ErrMsg = "获取主题历史数据失败,Err:" + err.Error()
 			return
@@ -1225,7 +1225,7 @@ func (this *AiController) GenerateAiSummary() {
 			aiChatTopicObj.AiChatTopicId = req.AiChatTopicId
 			topic, err := aiChatTopicObj.GetAiChatTopicById()
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					br.Msg = "获取数据失败!"
 					br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error()
 					return
@@ -1461,7 +1461,7 @@ func (this *AiController) GenerateAiSummary() {
 //		aiChatTopicObj.AiChatTopicId = aiChatTopicId
 //		topic, err := aiChatTopicObj.GetAiChatTopicById()
 //		if err != nil {
-//			if err.Error() == utils.ErrNoRow() {
+//			if utils.IsErrNoRow(err) {
 //				br.Msg = "获取数据失败!"
 //				br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error()
 //				return
@@ -1585,14 +1585,14 @@ func (this *AiController) AiSummaryClassifyList() {
 	resp := new(ai_summary.AiSummaryClassifyListResp)
 
 	rootList, err := ai_summary.GetAiSummaryClassifyByParentId(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := ai_summary.GetAiSummaryClassifyAll()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return

+ 15 - 6
controllers/banner.go

@@ -4,7 +4,6 @@ import (
 	"eta/eta_api/models"
 	"eta/eta_api/services"
 	"eta/eta_api/utils"
-	"github.com/h2non/filetype"
 	"io/ioutil"
 	"os"
 	"path"
@@ -53,14 +52,24 @@ func (this *BannerController) Upload() {
 		br.ErrMsg = "读取文件失败, Err: " + e.Error()
 		return
 	}
-	pass := filetype.IsImage(fileData)
-	if !pass {
-		br.Msg = "文件格式有误"
-		br.ErrMsg = "文件格式有误"
+	//pass := filetype.IsImage(fileData)
+	//if !pass {
+	//	br.Msg = "文件格式有误"
+	//	br.ErrMsg = "文件格式有误"
+	//	return
+	//}
+	ext := path.Ext(h.Filename)
+	if !utils.IsValidType(fileData, []utils.SourceType{
+		utils.Image,
+	}, []string{
+		"jpg",
+		"png",
+	}, ext) {
+		br.Msg = "文件格式不支持"
+		br.ErrMsg = "文件格式不支持"
 		return
 	}
 
-	ext := path.Ext(h.Filename)
 	dateDir := time.Now().Format("20060102")
 	uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
 	err = os.MkdirAll(uploadDir, utils.DIR_MOD)

+ 22 - 2
controllers/base_auth.go

@@ -119,7 +119,7 @@ func (c *BaseAuthController) Prepare() {
 
 			session, err := system.GetSysSessionByToken(token)
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					c.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "Token 信息已变更:Token: " + token}, false, false)
 					c.StopRun()
 					return
@@ -148,7 +148,7 @@ func (c *BaseAuthController) Prepare() {
 			}
 			admin, err := system.GetSysUserById(session.SysUserId)
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					c.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "获取admin 信息失败 " + strconv.Itoa(session.SysUserId)}, false, false)
 					c.StopRun()
 					return
@@ -174,12 +174,32 @@ func (c *BaseAuthController) Prepare() {
 				loginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, session.Id)
 				loginInfo, _ := utils.Rc.RedisString(loginKey)
 				if loginInfo == `` {
+					// 超时退出的时候,也记录下当前请求日志,避免数据丢失
+					requestBody, err := url.QueryUnescape(string(c.Ctx.Input.RequestBody))
+					if err != nil {
+						requestBody = string(c.Ctx.Input.RequestBody)
+					}
+					if requestBody == "" {
+						requestBody = c.Ctx.Input.URI()
+					}
+					utils.ApiLog.Info("uri:%s, authorization:%s, requestBody:%s", c.Ctx.Input.URI(), authorization, requestBody)
+
 					c.JSON(models.BaseResponse{Ret: 408, Msg: "超时未操作,系统自动退出!", ErrMsg: "超时未操作,系统自动退出!"}, false, false)
 					c.StopRun()
 					return
 				}
 
 				if loginInfo != "1" {
+					// 超时退出的时候,也记录下当前请求日志,避免数据丢失
+					requestBody, err := url.QueryUnescape(string(c.Ctx.Input.RequestBody))
+					if err != nil {
+						requestBody = string(c.Ctx.Input.RequestBody)
+					}
+					if requestBody == "" {
+						requestBody = c.Ctx.Input.URI()
+					}
+					utils.ApiLog.Info("uri:%s, authorization:%s, requestBody:%s", c.Ctx.Input.URI(), authorization, requestBody)
+
 					msg := `该账号于` + admin.LastLoginTime + "在其他网络登录。此客户端已退出登录。"
 					c.JSON(models.BaseResponse{Ret: 408, Msg: msg, ErrMsg: msg}, false, false)
 					c.StopRun()

+ 7 - 7
controllers/bi_dashboard.go

@@ -70,7 +70,7 @@ func (this *BIDaShboardController) AddDashboard() {
 		return
 	}
 	nameItem, err := bi_dashboard.GetDashboardByName(req.BiDashboardName, this.SysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "查询失败"
 		br.ErrMsg = "查询失败,Err:" + err.Error()
 		return
@@ -151,7 +151,7 @@ func (this *BIDaShboardController) EditDashboard() {
 		br.ErrMsg = "获取数据异常,Err:" + err.Error()
 		return
 	}
-	
+
 	// 修改
 	item.BiDashboardName = req.BiDashboardName
 	item.ModifyTime = time.Now()
@@ -728,7 +728,7 @@ func (this *BIDaShboardController) EditDashboardClassify() {
 		return
 	}
 	item, err := bi_dashboard.GetBiDashboardClassifyById(req.BiDashboardClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取数据异常!"
 		br.ErrMsg = "获取数据异常,Err:" + err.Error()
 		return
@@ -1035,7 +1035,7 @@ func (this *BIDaShboardController) PublicCancel() {
 	}
 
 	item, err := bi_dashboard.GetDashboardById(req.BiDashboardId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取数据异常!"
 		br.ErrMsg = "获取数据异常,Err:" + err.Error()
 		return
@@ -1069,7 +1069,7 @@ func (this *BIDaShboardController) HomePage() {
 	}()
 
 	item, err := bi_dashboard.GetBiDashboardHomePageById(this.SysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "数据不存在"
 		br.ErrMsg = "数据不存在,Err:" + err.Error()
 		return
@@ -1127,7 +1127,7 @@ func (this *BIDaShboardController) HomePageSave() {
 	}
 
 	item, err := bi_dashboard.GetBiDashboardHomePageById(this.SysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "首页看板查询失败"
 		br.ErrMsg = "首页看板查询失败,Err:" + err.Error()
 		return
@@ -1257,7 +1257,7 @@ func (this *BIDaShboardController) ChartExcelPermission() {
 	//共享客户组下的用户
 	shareSellerMap := make(map[int]bool, 0)
 	subAdmins, err := system.GetAdminByGroupId(groupId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取销售失败"
 		br.ErrMsg = "获取销售失败,Err:" + err.Error()
 		return

+ 2 - 2
controllers/business_conf.go

@@ -326,7 +326,7 @@ func (this *BusinessConfController) SingleSave() {
 	// 获取配置信息
 	confOb, e := models.GetBusinessConfByKey(req.ConfKey)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "配置不存在"
 			return
 		}
@@ -419,7 +419,7 @@ func (this *BusinessConfController) GetSingle() {
 	// 获取配置信息
 	confOb, e := models.GetBusinessConfByKey(confKey)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "配置不存在"
 			return
 		}

+ 4 - 3
controllers/classify.go

@@ -355,7 +355,7 @@ func (this *ClassifyController) ParentClassify() {
 	parentMenus, e := models.GetClassifyMenuList(menuCond, menuPars)
 	if e != nil {
 		br.Msg = "获取失败"
-		br.ErrMsg = "获取一级分类子目录列表失败"
+		br.ErrMsg = fmt.Sprintf("获取一级分类子目录列表失败, %v", e)
 		return
 	}
 	for i := range parentMenus {
@@ -494,7 +494,7 @@ func (this *ClassifyController) ListClassify() {
 	parentMenus, e := models.GetClassifyMenuList(menuCond, menuPars)
 	if e != nil {
 		br.Msg = "获取失败"
-		br.ErrMsg = "获取一级分类子目录列表失败"
+		br.ErrMsg = fmt.Sprintf("获取一级分类子目录列表失败, %v", e)
 		return
 	}
 	for i := range parentMenus {
@@ -677,6 +677,7 @@ func (this *ClassifyController) TelListClassify() {
 		condition += ` AND classify_name <> '晨报' AND classify_name <> '周报' `
 	}
 	telList, e := models.GetClassifyByCondition(condition, orderRule, pars)
+
 	if e != nil {
 		return
 	}
@@ -766,7 +767,7 @@ func (this *ClassifyController) SetEnabled() {
 	}
 	item, err := models.GetClassifyById(req.ClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			return
 		}

+ 4 - 4
controllers/cloud_disk.go

@@ -64,7 +64,7 @@ func (this *CloudDiskController) MenuCreate() {
 	existCond := ` AND menu_name = ? AND parent_id = ? `
 	existPars := make([]interface{}, 0)
 	existPars = append(existPars, req.MenuName, req.ParentId)
-	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
+	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "操作失败"
 		br.ErrMsg = "获取重名目录失败, Err: " + e.Error()
 		return
@@ -144,7 +144,7 @@ func (this *CloudDiskController) MenuRename() {
 	existCond := ` AND menu_name = ? AND parent_id = ? AND menu_id <> ? `
 	existPars := make([]interface{}, 0)
 	existPars = append(existPars, req.MenuName, menuItem.ParentId, menuItem.MenuId)
-	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
+	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "操作失败"
 		br.ErrMsg = "获取重名目录失败, Err: " + e.Error()
 		return
@@ -578,7 +578,7 @@ func (this *CloudDiskController) ResourceUpload() {
 	existCond := ` AND resource_name = ? AND menu_id = ? `
 	existPars := make([]interface{}, 0)
 	existPars = append(existPars, fileName, menuId)
-	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
+	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "操作失败"
 		br.ErrMsg = "获取重名文件失败, Err: " + e.Error()
 		return
@@ -729,7 +729,7 @@ func (this *CloudDiskController) ResourceRename() {
 	existCond := ` AND resource_name = ? AND menu_id = ? AND resource_id <> ? `
 	existPars := make([]interface{}, 0)
 	existPars = append(existPars, req.ResourceName, resourceItem.MenuId, resourceItem.ResourceId)
-	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
+	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "操作失败"
 		br.ErrMsg = "获取重名文件失败, Err: " + e.Error()
 		return

+ 2 - 2
controllers/commodity_trade_base_index.go

@@ -2639,7 +2639,7 @@ func (this *TradeCommonController) MtjhData() {
 		product.CreateTime = v.CreateTime
 
 		modifyTime, err := data_manage.GetMtjhIndexLatestDate(v.IndexCode)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取更新时间失败"
 			br.ErrMsg = "获取更新时间失败,Err:" + err.Error()
 			return
@@ -2741,7 +2741,7 @@ func (this *TradeCommonController) MtjhSingleData() {
 	}
 
 	modifyTime, err := data_manage.GetMtjhIndexLatestDate(indexCode)
-	if err != nil {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取更新时间失败"
 		br.ErrMsg = "获取更新时间失败,Err:" + err.Error()
 		return

+ 4 - 4
controllers/company_seller.go

@@ -41,9 +41,9 @@ func (this *CompanySellerController) CheckListV2() {
 	productId := services.GetProductId(sysUser.RoleTypeCode)
 	switch productId {
 	case 1:
-		roleCodeTypeStr = `"` + utils.ROLE_TYPE_CODE_FICC_SELLER + `","` + utils.ROLE_TYPE_CODE_FICC_GROUP + `","` + utils.ROLE_TYPE_CODE_FICC_TEAM + `"`
+		roleCodeTypeStr = `'` + utils.ROLE_TYPE_CODE_FICC_SELLER + `','` + utils.ROLE_TYPE_CODE_FICC_GROUP + `','` + utils.ROLE_TYPE_CODE_FICC_TEAM + `'`
 	case 2:
-		roleCodeTypeStr = `"` + utils.ROLE_TYPE_CODE_RAI_SELLER + `","` + utils.ROLE_TYPE_CODE_RAI_GROUP + `"`
+		roleCodeTypeStr = `'` + utils.ROLE_TYPE_CODE_RAI_SELLER + `','` + utils.ROLE_TYPE_CODE_RAI_GROUP + `'`
 	}
 
 	// ficc管理员,不要只查销售
@@ -51,7 +51,7 @@ func (this *CompanySellerController) CheckListV2() {
 		roleCodeTypeStr = ``
 	} else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_ADMIN {
 		// 权益管理员,查看所有权益的账号
-		roleCodeTypeStr = `"` + utils.ROLE_TYPE_CODE_RAI_SELLER + `","` + utils.ROLE_TYPE_CODE_RAI_GROUP + `","` + utils.ROLE_TYPE_CODE_RAI_RESEARCHR + `","` + utils.ROLE_TYPE_CODE_RAI_ADMIN + `"`
+		roleCodeTypeStr = `'` + utils.ROLE_TYPE_CODE_RAI_SELLER + `','` + utils.ROLE_TYPE_CODE_RAI_GROUP + `','` + utils.ROLE_TYPE_CODE_RAI_RESEARCHR + `','` + utils.ROLE_TYPE_CODE_RAI_ADMIN + `'`
 	}
 
 	getAllSeller, _ := this.GetBool("AllSeller", false)
@@ -1726,7 +1726,7 @@ func (this *CompanySellerController) CheckListV2() {
 
 	// 海外销售部-目前无权限, 均可见
 	seaDepartment, e := system.GetSysDepartmentByName("海外销售部")
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取海外销售部失败, Err: " + e.Error()
 		return

+ 529 - 0
controllers/data_manage/ai_predict_model/classify.go

@@ -0,0 +1,529 @@
+package ai_predict_model
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	aiPredictModel "eta/eta_api/models/ai_predict_model"
+	"eta/eta_api/models/data_manage"
+	dataSourceModel "eta/eta_api/models/data_source"
+	"eta/eta_api/services"
+	"eta/eta_api/services/elastic"
+	"eta/eta_api/utils"
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// AiPredictModelClassifyController AI预测模型-分类
+type AiPredictModelClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 分类列表
+// @Description 分类列表
+// @Param   ParentId   query   bool   false   "父级ID"
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /classify/list [get]
+func (this *AiPredictModelClassifyController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	parentId, _ := this.GetInt("ParentId")
+	resp := new(aiPredictModel.AiPredictModelClassifyListResp)
+
+	// (懒加载)仅查询直属分类
+	classifyOb := new(aiPredictModel.AiPredictModelClassify)
+	{
+		cond := fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ParentId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, parentId)
+		list, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", classifyOb.Cols().Sort))
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取子分类失败, %v", e)
+			return
+		}
+		for _, v := range list {
+			resp.AllNodes = append(resp.AllNodes, &aiPredictModel.AiPredictModelClassifyListItem{
+				NodeName:     v.ClassifyName,
+				ClassifyId:   v.AiPredictModelClassifyId,
+				ClassifyName: v.ClassifyName,
+				ParentId:     v.ParentId,
+				Level:        v.Level,
+				Sort:         v.Sort,
+				UniqueCode:   v.UniqueCode,
+			})
+		}
+	}
+
+	// 非顶级目录查询指标
+	indexOb := new(aiPredictModel.AiPredictModelIndex)
+	if parentId > 0 {
+		parentClassify, e := classifyOb.GetItemById(parentId)
+		if e != nil {
+			br.Msg = "父级分类不存在, 请刷新页面"
+			return
+		}
+
+		cond := fmt.Sprintf(" AND %s = ?", indexOb.Cols().ClassifyId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, parentId)
+		list, e := indexOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", indexOb.Cols().Sort))
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取分类下指标失败, %v", e)
+			return
+		}
+		for _, v := range list {
+			resp.AllNodes = append(resp.AllNodes, &aiPredictModel.AiPredictModelClassifyListItem{
+				NodeType:     1,
+				NodeName:     v.IndexName,
+				ClassifyId:   parentClassify.AiPredictModelClassifyId,
+				ClassifyName: parentClassify.ClassifyName,
+				IndexId:      v.AiPredictModelIndexId,
+				IndexCode:    v.IndexCode,
+				IndexName:    v.IndexName,
+				ParentId:     parentId,
+				Sort:         v.Sort,
+				UniqueCode:   v.IndexCode,
+			})
+		}
+	}
+	sort.Slice(resp.AllNodes, func(i, j int) bool {
+		return resp.AllNodes[i].Sort < resp.AllNodes[j].Sort
+	})
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Add
+// @Title 新增分类
+// @Description 新增分类
+// @Param	request	body aiPredictModel.AiPredictModelClassifyAddReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /classify/add [post]
+func (this *AiPredictModelClassifyController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req aiPredictModel.AiPredictModelClassifyAddReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	req.ClassifyName = strings.TrimSpace(req.ClassifyName)
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+	if req.ParentId < 0 {
+		br.Msg = "请选择上级分类"
+		return
+	}
+	if req.Level > 5 {
+		br.Msg = "目前只支持6级目录"
+		return
+	}
+
+	// 校验分类名称
+	classifyOb := new(aiPredictModel.AiPredictModelClassify)
+	{
+		cond := fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ParentId)
+		if this.Lang == utils.EnLangVersion {
+			cond += fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ClassifyNameEn)
+		} else {
+			cond += fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ClassifyName)
+		}
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.ParentId, req.ClassifyName)
+		count, e := classifyOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取分类名称重复数失败, %v", e)
+			return
+		}
+		if count > 0 {
+			br.Msg = "分类名称已存在"
+			return
+		}
+	}
+
+	// 层级路径
+	var levelPath string
+	var rootId int
+	if req.ParentId > 0 {
+		parent, e := classifyOb.GetItemById(req.ParentId)
+		if e != nil {
+			br.Msg = "上级分类有误"
+			br.ErrMsg = fmt.Sprintf("获取上级分类失败, %v", e)
+			return
+		}
+		levelPath = parent.LevelPath
+		rootId = parent.RootId
+	}
+
+	sortMax, e := classifyOb.GetSortMax(req.ParentId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类最大排序失败, %v", e)
+		return
+	}
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	classifyOb.ParentId = req.ParentId
+	classifyOb.ClassifyName = req.ClassifyName
+	classifyOb.ClassifyNameEn = req.ClassifyName
+	classifyOb.Level = req.Level + 1
+	classifyOb.Sort = sortMax + 1
+	classifyOb.SysUserId = sysUser.AdminId
+	classifyOb.SysUserRealName = sysUser.RealName
+	classifyOb.UniqueCode = utils.MD5(classifyOb.TableName() + "_" + timestamp)
+	classifyOb.CreateTime = time.Now().Local()
+	classifyOb.ModifyTime = time.Now().Local()
+	if e = classifyOb.Create(); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("新增分类失败, %v", e)
+		return
+	}
+	if req.ParentId > 0 {
+		// 用英文逗号拼接方便查询
+		classifyOb.LevelPath = fmt.Sprintf("%s,%d", levelPath, classifyOb.AiPredictModelClassifyId)
+		classifyOb.RootId = rootId
+	} else {
+		classifyOb.LevelPath = fmt.Sprint(classifyOb.AiPredictModelClassifyId)
+		classifyOb.RootId = classifyOb.AiPredictModelClassifyId
+	}
+	if e = classifyOb.Update([]string{classifyOb.Cols().LevelPath, classifyOb.Cols().RootId}); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "操作成功"
+	br.Success = true
+}
+
+// Edit
+// @Title 修改分类
+// @Description 修改分类
+// @Param	request	body aiPredictModel.AiPredictModelClassifyEditReq true "type json string"
+// @Success 200 Ret=200 修改成功
+// @router /classify/edit [post]
+func (this *AiPredictModelClassifyController) Edit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req aiPredictModel.AiPredictModelClassifyEditReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.ClassifyId < 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+	req.ClassifyName = strings.TrimSpace(req.ClassifyName)
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+
+	classifyOb := new(aiPredictModel.AiPredictModelClassify)
+	classifyItem, e := classifyOb.GetItemById(req.ClassifyId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "分类不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
+		return
+	}
+
+	// 校验分类名称
+	{
+		cond := fmt.Sprintf(" AND %s <> ?", classifyOb.Cols().PrimaryId)
+		if this.Lang == utils.EnLangVersion {
+			cond += fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ClassifyNameEn)
+		} else {
+			cond += fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ClassifyName)
+		}
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.ClassifyId, req.ClassifyName)
+		count, e := classifyOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取分类名称重复数失败, %v", e)
+			return
+		}
+		if count > 0 {
+			br.Msg = "分类名称已存在"
+			return
+		}
+	}
+	classifyItem.ClassifyName = req.ClassifyName
+	classifyItem.ClassifyNameEn = req.ClassifyName
+	classifyItem.ModifyTime = time.Now().Local()
+	updateCols := []string{classifyOb.Cols().ClassifyName, classifyOb.Cols().ClassifyNameEn, classifyOb.Cols().ModifyTime}
+	if e = classifyItem.Update(updateCols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "操作成功"
+	br.Success = true
+}
+
+// RemoveCheck
+// @Title 删除校验
+// @Description 删除校验
+// @Param	request	body aiPredictModel.AiPredictModelClassifyRemoveReq true "type json string"
+// @Success 200 Ret=200 检测成功
+// @router /classify/remove_check [post]
+func (this *AiPredictModelClassifyController) RemoveCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req aiPredictModel.AiPredictModelClassifyRemoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.ClassifyId < 0 && req.IndexId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+
+	var deleteStatus int
+	var tipsMsg string
+	// 删除分类
+	if req.ClassifyId > 0 && req.IndexId == 0 {
+		count, err := aiPredictModel.GetAiPredictModelIndexCountByClassifyId(req.ClassifyId)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
+			return
+		}
+
+		if count > 0 {
+			deleteStatus = 1
+			tipsMsg = "该分类下关联图表不可删除"
+		}
+	}
+
+	if deleteStatus != 1 && req.IndexId == 0 {
+		classifyCount, err := aiPredictModel.GetAiPredictModelClassifyCountByClassifyId(req.ClassifyId)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "删除失败"
+			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
+			return
+		}
+		if classifyCount > 0 {
+			deleteStatus = 2
+			tipsMsg = "确认删除当前目录及包含的子目录吗"
+		}
+	}
+	if deleteStatus == 0 {
+		tipsMsg = "可删除,进行删除操作"
+	}
+
+	resp := new(data_manage.ChartClassifyDeleteCheckResp)
+	resp.DeleteStatus = deleteStatus
+	resp.TipsMsg = tipsMsg
+	br.Ret = 200
+	br.Msg = "检测成功"
+	br.Success = true
+	br.Data = resp
+}
+
+// Remove
+// @Title 删除分类/标的
+// @Description 删除分类/标的
+// @Param	request	body aiPredictModel.AiPredictModelClassifyRemoveReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /classify/remove [post]
+func (this *AiPredictModelClassifyController) Remove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req aiPredictModel.AiPredictModelClassifyRemoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.ClassifyId < 0 && req.IndexId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+
+	// 删除分类
+	if req.ClassifyId > 0 && req.IndexId == 0 {
+		count, err := aiPredictModel.GetAiPredictModelIndexCountByClassifyId(req.ClassifyId)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "删除失败"
+			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
+			return
+		}
+		if count > 0 {
+			br.Msg = "该目录下存在关联指标,不可删除"
+			br.IsSendEmail = false
+			return
+		}
+		err = aiPredictModel.RemoveAiPredictModelClassify(req.ClassifyId)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "删除失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	// 删除标的
+	if req.IndexId > 0 {
+		indexOb := new(aiPredictModel.AiPredictModelIndex)
+		aiIndex, e := indexOb.GetItemById(req.IndexId)
+		if e != nil {
+			if utils.IsErrNoRow(e) {
+				br.Ret = 200
+				br.Msg = "删除成功"
+				br.Success = true
+				return
+			}
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取标的信息失败, %v", e)
+			return
+		}
+
+		// 删除标的及数据
+		if e = indexOb.RemoveIndexAndData(req.IndexId); e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("删除标的及数据失败, %v", e)
+			return
+		}
+
+		// ES标记删除
+		go func() {
+			indexItem := new(dataSourceModel.SearchDataSource)
+			indexItem.PrimaryId = aiIndex.AiPredictModelIndexId
+			indexItem.IndexName = aiIndex.IndexName
+			indexItem.IndexCode = aiIndex.IndexCode
+			indexItem.ClassifyId = aiIndex.ClassifyId
+			indexItem.Source = utils.DATA_SOURCE_AI_PREDICT_MODEL
+			indexItem.SourceName = "AI预测模型"
+			indexItem.IsDeleted = 1
+			indexItem.CreateTime = utils.TimeTransferString(utils.FormatDateTime, aiIndex.CreateTime)
+			indexItem.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, aiIndex.ModifyTime)
+
+			docId := fmt.Sprintf("%d-%d", indexItem.Source, indexItem.PrimaryId)
+			if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
+				utils.FileLog.Info("AI预测模型-标记删除es失败, %v", e)
+				return
+			}
+		}()
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// Move
+// @Title 移动
+// @Description 移动
+// @Success 200 {object} aiPredictModel.AiPredictModelClassifyMoveReq
+// @router /classify/move [post]
+func (this *AiPredictModelClassifyController) Move() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req aiPredictModel.AiPredictModelClassifyMoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.ClassifyId <= 0 && req.ItemId <= 0 {
+		br.Msg = "请选择分类或指标"
+		return
+	}
+
+	err, errMsg := services.AiPredictModelMoveClassify(req, sysUser)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "移动成功"
+}

+ 668 - 0
controllers/data_manage/ai_predict_model/framework.go

@@ -0,0 +1,668 @@
+package ai_predict_model
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	aiPredictModel "eta/eta_api/models/ai_predict_model"
+	"eta/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// AiPredictModelFrameworkController 模型框架
+type AiPredictModelFrameworkController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 列表
+// @Description 列表
+// @Param   AdminId		query	int		false	"创建人ID"
+// @Param   Visibility	query	int		false	"范围: 0-所有; 1-私有; 2-公开"
+// @Param   Keyword		query	string	false	"关键词"
+// @Success 200 Ret=200 获取成功
+// @router /framework/list [get]
+func (c *AiPredictModelFrameworkController) 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
+	}
+
+	adminId, _ := c.GetInt("AdminId")
+	keyword := c.GetString("Keyword")
+	keyword = strings.TrimSpace(keyword)
+
+	frameworkOb := new(aiPredictModel.AiPredictModelFramework)
+
+	cond := ``
+	pars := make([]interface{}, 0)
+	if adminId > 0 {
+		cond += fmt.Sprintf(` AND %s = ?`, aiPredictModel.AiPredictModelFrameworkColumns.AdminId)
+		pars = append(pars, adminId)
+	}
+	if keyword != "" {
+		cond += fmt.Sprintf(` AND %s LIKE ?`, aiPredictModel.AiPredictModelFrameworkColumns.FrameworkName)
+		pars = append(pars, "%"+keyword+"%")
+	}
+
+	orderRule := `sort ASC, create_time DESC`
+	list, e := frameworkOb.GetItemsByCondition(cond, pars, []string{}, orderRule)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取框架列表失败, Err: " + e.Error()
+		return
+	}
+	resp := make([]*aiPredictModel.AiPredictModelFrameworkItem, 0)
+	for _, v := range list {
+		t := aiPredictModel.FormatAiPredictModelFramework2Item(v, make([]*aiPredictModel.AiPredictModelFrameworkNodeItem, 0))
+		if t.AdminId == sysUser.AdminId || utils.IsAdminRole(sysUser.RoleTypeCode) {
+			t.Button.OpButton = true
+			t.Button.DeleteButton = true
+			t.Button.MoveButton = true
+		}
+		resp = append(resp, t)
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Add
+// @Title 新增框架
+// @Description 新增框架
+// @Param	request	body aiPredictModel.AiPredictModelFrameworkAddReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /framework/add [post]
+func (c *AiPredictModelFrameworkController) Add() {
+	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
+	}
+	// 参数校验
+	var req aiPredictModel.AiPredictModelFrameworkAddReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	req.FrameworkName = strings.TrimSpace(req.FrameworkName)
+	if req.FrameworkName == "" {
+		br.Msg = "框架名称不可为空"
+		return
+	}
+
+	// 重名校验
+	{
+		ob := new(aiPredictModel.AiPredictModelFramework)
+		cond := fmt.Sprintf(` AND %s = ? AND %s = ?`, aiPredictModel.AiPredictModelFrameworkColumns.FrameworkName, aiPredictModel.AiPredictModelFrameworkColumns.AdminId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.FrameworkName, sysUser.AdminId)
+		exist, e := ob.GetItemByCondition(cond, pars)
+		if e != nil && !utils.IsErrNoRow(e) {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取重名框架失败, Err: " + e.Error()
+			return
+		}
+		if exist != nil && exist.AiPredictModelFrameworkId > 0 {
+			br.Msg = "框架名称已存在,请重新输入"
+			return
+		}
+	}
+
+	now := time.Now().Local()
+	frameworkCode := utils.MD5(fmt.Sprint(now.UnixMilli()))
+	item := new(aiPredictModel.AiPredictModelFramework)
+	item.FrameworkName = req.FrameworkName
+	item.FrameworkCode = frameworkCode
+	item.FrameworkImg = req.FrameworkImg
+	item.FrameworkContent = req.FrameworkContent
+	item.AdminId = sysUser.AdminId
+	item.AdminName = sysUser.RealName
+	item.CreateTime = now
+	item.ModifyTime = now
+	nodes := make([]*aiPredictModel.AiPredictModelFrameworkNode, 0)
+	itemNodes := make([]*aiPredictModel.AiPredictModelFrameworkNodeItem, 0)
+	if len(req.Nodes) > 0 {
+		for _, v := range req.Nodes {
+			if v.AiPredictModelIndexId <= 0 {
+				continue
+			}
+			t := new(aiPredictModel.AiPredictModelFrameworkNode)
+			t.FrameworkName = req.FrameworkName
+			t.NodeId = v.NodeId
+			t.NodeName = v.NodeName
+			t.AiPredictModelIndexId = v.AiPredictModelIndexId
+			t.CreateTime = now
+			nodes = append(nodes, t)
+			num := 1
+			// 响应节点数据
+			td := aiPredictModel.FormatAiPredictModelFrameworkNode2Item(t, num, map[int]*aiPredictModel.AiPredictModelIndex{})
+			itemNodes = append(itemNodes, td)
+		}
+	}
+	if e := item.CreateFrameworkAndNodes(item, nodes); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "新增框架及节点失败, Err: " + e.Error()
+		return
+	}
+	detail := aiPredictModel.FormatAiPredictModelFramework2Item(item, itemNodes)
+
+	br.Data = detail
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+	br.IsAddLog = true
+}
+
+// Edit
+// @Title 编辑框架
+// @Description 编辑框架
+// @Param	request	body aiPredictModel.AiPredictModelFrameworkEditReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /framework/edit [post]
+func (c *AiPredictModelFrameworkController) Edit() {
+	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
+	}
+	// 参数校验
+	var req aiPredictModel.AiPredictModelFrameworkEditReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.AiPredictModelFrameworkId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, AiPredictModelFrameworkId: %d", req.AiPredictModelFrameworkId)
+		return
+	}
+	req.FrameworkName = strings.TrimSpace(req.FrameworkName)
+	if req.FrameworkName == "" {
+		br.Msg = "框架名称不可为空"
+		return
+	}
+
+	frameworkOb := new(aiPredictModel.AiPredictModelFramework)
+	item, e := frameworkOb.GetItemById(req.AiPredictModelFrameworkId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "框架不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取框架失败, Err: " + e.Error()
+		return
+	}
+
+	// 操作权限校验
+	if item.AdminId != sysUser.AdminId && !utils.IsAdminRole(sysUser.RoleTypeCode) {
+		br.Msg = "您没有权限操作该框架"
+		return
+	}
+
+	// 重名校验
+	{
+		ob := new(aiPredictModel.AiPredictModelFramework)
+		cond := fmt.Sprintf(` AND %s <> ? AND %s = ? AND %s = ?`, ob.PrimaryId(), aiPredictModel.AiPredictModelFrameworkColumns.FrameworkName, aiPredictModel.AiPredictModelFrameworkColumns.AdminId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.AiPredictModelFrameworkId, req.FrameworkName, sysUser.AdminId)
+		exist, e := ob.GetItemByCondition(cond, pars)
+		if e != nil && !utils.IsErrNoRow(e) {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取重名框架失败, Err: " + e.Error()
+			return
+		}
+		if exist != nil && exist.AiPredictModelFrameworkId > 0 {
+			br.Msg = "框架名称已存在,请重新输入"
+			return
+		}
+	}
+
+	now := time.Now().Local()
+	item.FrameworkName = req.FrameworkName
+	item.FrameworkImg = req.FrameworkImg
+	item.FrameworkContent = req.FrameworkContent
+	item.ModifyTime = now
+	updateCols := []string{"FrameworkName", "FrameworkImg", "FrameworkContent", "ModifyTime"}
+	nodes := make([]*aiPredictModel.AiPredictModelFrameworkNode, 0)
+	itemNodes := make([]*aiPredictModel.AiPredictModelFrameworkNodeItem, 0)
+	if len(req.Nodes) > 0 {
+		for _, v := range req.Nodes {
+			if v.AiPredictModelIndexId <= 0 {
+				continue
+			}
+			t := new(aiPredictModel.AiPredictModelFrameworkNode)
+			t.AiPredictModelFrameworkId = req.AiPredictModelFrameworkId
+			t.FrameworkName = req.FrameworkName
+			t.NodeId = v.NodeId
+			t.NodeName = v.NodeName
+			t.AiPredictModelIndexId = v.AiPredictModelIndexId
+			t.CreateTime = now
+			nodes = append(nodes, t)
+
+			// 响应节点数据
+			td := aiPredictModel.FormatAiPredictModelFrameworkNode2Item(t, 1, map[int]*aiPredictModel.AiPredictModelIndex{})
+			itemNodes = append(itemNodes, td)
+		}
+	}
+	if e := item.EditFrameworkAndNodes(item, updateCols, nodes); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "编辑框架及节点失败, Err: " + e.Error()
+		return
+	}
+	detail := aiPredictModel.FormatAiPredictModelFramework2Item(item, itemNodes)
+
+	br.Data = detail
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+	br.IsAddLog = true
+}
+
+// Remove
+// @Title 删除框架
+// @Description 删除视频
+// @Param	request	body aiPredictModel.AiPredictModelFrameworkRemoveReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /framework/remove [post]
+func (c *AiPredictModelFrameworkController) Remove() {
+	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
+	}
+	// 参数校验
+	var req aiPredictModel.AiPredictModelFrameworkRemoveReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.AiPredictModelFrameworkId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, AiPredictModelFrameworkId: %d", req.AiPredictModelFrameworkId)
+		return
+	}
+
+	ob := new(aiPredictModel.AiPredictModelFramework)
+	item, e := ob.GetItemById(req.AiPredictModelFrameworkId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "操作成功"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取框架失败, Err: " + e.Error()
+		return
+	}
+	if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN && item.AdminId != sysUser.AdminId {
+		br.Msg = "无权操作"
+		return
+	}
+
+	if e := item.RemoveFrameworkAndNodes(req.AiPredictModelFrameworkId); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "删除框架失败, Err: " + e.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+	br.IsAddLog = true
+}
+
+// Rename
+// @Title 重命名框架
+// @Description 重命名框架
+// @Param	request	body aiPredictModel.AiPredictModelFrameworkRenameReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /framework/rename [post]
+func (c *AiPredictModelFrameworkController) Rename() {
+	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
+	}
+	// 参数校验
+	var req aiPredictModel.AiPredictModelFrameworkRenameReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.AiPredictModelFrameworkId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, AiPredictModelFrameworkId: %d", req.AiPredictModelFrameworkId)
+		return
+	}
+	req.FrameworkName = strings.TrimSpace(req.FrameworkName)
+	if req.FrameworkName == "" {
+		br.Msg = "框架名称不可为空"
+		return
+	}
+
+	frameworkOb := new(aiPredictModel.AiPredictModelFramework)
+	item, e := frameworkOb.GetItemById(req.AiPredictModelFrameworkId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "框架不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取框架失败, Err: " + e.Error()
+		return
+	}
+
+	// 操作权限校验
+	if item.AdminId != sysUser.AdminId && !utils.IsAdminRole(sysUser.RoleTypeCode) {
+		br.Msg = "您没有权限操作该框架"
+		return
+	}
+
+	// 重名校验
+	{
+		ob := new(aiPredictModel.AiPredictModelFramework)
+		cond := fmt.Sprintf(` AND %s <> ? AND %s = ? AND %s = ?`, ob.PrimaryId(), aiPredictModel.AiPredictModelFrameworkColumns.FrameworkName, aiPredictModel.AiPredictModelFrameworkColumns.AdminId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.AiPredictModelFrameworkId, req.FrameworkName, sysUser.AdminId)
+		exist, e := ob.GetItemByCondition(cond, pars)
+		if e != nil && !utils.IsErrNoRow(e) {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取重名框架失败, Err: " + e.Error()
+			return
+		}
+		if exist != nil && exist.AiPredictModelFrameworkId > 0 {
+			br.Msg = "框架名称已存在,请重新输入"
+			return
+		}
+	}
+
+	now := time.Now().Local()
+	item.FrameworkName = req.FrameworkName
+	item.ModifyTime = now
+	updateCols := []string{"FrameworkName", "ModifyTime"}
+	if e := item.Update(updateCols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "框架重命名失败, Err: " + e.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Move
+// @Title 移动排序
+// @Description 移动排序
+// @Param	request	body aiPredictModel.AiPredictModelFrameworkMoveReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /framework/move [post]
+func (c *AiPredictModelFrameworkController) Move() {
+	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
+	}
+	// 参数校验
+	var req aiPredictModel.AiPredictModelFrameworkMoveReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.AiPredictModelFrameworkId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, AiPredictModelFrameworkId: %d", req.AiPredictModelFrameworkId)
+		return
+	}
+
+	frameworkOb := new(aiPredictModel.AiPredictModelFramework)
+	item, e := frameworkOb.GetItemById(req.AiPredictModelFrameworkId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "框架不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取框架失败, Err: " + e.Error()
+		return
+	}
+
+	updateCols := make([]string, 0)
+	// 上一个兄弟节点
+	if req.PrevAiPredictModelFrameworkId > 0 {
+		prev, e := frameworkOb.GetItemById(req.PrevAiPredictModelFrameworkId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取上一个兄弟节点失败, Err: " + e.Error()
+			return
+		}
+
+		// 两个兄弟节点之间
+		if req.NextAiPredictModelFrameworkId > 0 {
+			next, e := frameworkOb.GetItemById(req.PrevAiPredictModelFrameworkId)
+			if e != nil {
+				br.Msg = "操作失败"
+				br.ErrMsg = "获取下一个兄弟节点失败, Err: " + e.Error()
+				return
+			}
+			// 如果上一个与下一个排序权重是一致的, 那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2, 自己变成上一个兄弟的排序权重+1
+			if prev.Sort == next.Sort || prev.Sort == item.Sort {
+				strUpdate := `sort + 2`
+				_ = aiPredictModel.UpdateAiPredictModelFrameworkSort(sysUser.AdminId, prev.AiPredictModelFrameworkId, prev.Sort, strUpdate)
+			} else {
+				// 如果下一个排序权重正好是上一个节点的下一层, 那么需要再加一层了
+				if next.Sort-prev.Sort == 1 {
+					//变更兄弟节点的排序
+					strUpdate := `sort + 1`
+					_ = aiPredictModel.UpdateAiPredictModelFrameworkSort(sysUser.AdminId, 0, prev.Sort, strUpdate)
+				}
+			}
+		}
+
+		// 上一个兄弟节点sort+1
+		item.Sort = prev.Sort + 1
+		item.ModifyTime = time.Now()
+		updateCols = append(updateCols, "Sort", "ModifyTime")
+	} else {
+		first, err := aiPredictModel.GetFirstAiPredictModelFramework()
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取我的模型框架排首位的数据失败, Err:" + err.Error()
+			return
+		}
+		if first != nil && first.Sort == 0 {
+			strUpdate := ` sort + 1 `
+			_ = aiPredictModel.UpdateAiPredictModelFrameworkSort(sysUser.AdminId, first.AiPredictModelFrameworkId-1, 0, strUpdate)
+		}
+
+		// 排首位
+		item.Sort = 0
+		item.ModifyTime = time.Now()
+		updateCols = append(updateCols, "Sort", "ModifyTime")
+	}
+
+	if len(updateCols) > 0 {
+		if e := item.Update(updateCols); e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "更新框架排序失败, Err: " + e.Error()
+			return
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Detail
+// @Title 框架详情
+// @Description 框架详情
+// @Param   AiPredictModelFrameworkId  query  int  true  "框架ID"
+// @Success 200 Ret=200 操作成功
+// @router /framework/detail [get]
+func (c *AiPredictModelFrameworkController) 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
+	}
+	frameworkId, _ := c.GetInt("AiPredictModelFrameworkId")
+	if frameworkId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, AiPredictModelFrameworkId: %d", frameworkId)
+		return
+	}
+
+	frameworkOb := new(aiPredictModel.AiPredictModelFramework)
+	item, e := frameworkOb.GetItemById(frameworkId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "框架不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取框架失败, Err: " + e.Error()
+		return
+	}
+
+	// 获取节点
+	nodeOb := new(aiPredictModel.AiPredictModelFrameworkNode)
+	nodeCond := ` AND ai_predict_model_framework_id = ?`
+	nodePars := make([]interface{}, 0)
+	nodePars = append(nodePars, frameworkId)
+	nodes, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取框架节点失败, Err: " + e.Error()
+		return
+	}
+
+	// 模型标的map
+	aiPredictModelIndexMap := make(map[int]*aiPredictModel.AiPredictModelIndex)
+	{
+		aiPredictModelIndexIdList := make([]interface{}, 0)
+		for _, v := range nodes {
+			if v.AiPredictModelIndexId > 0 {
+				aiPredictModelIndexIdList = append(aiPredictModelIndexIdList, v.AiPredictModelIndexId)
+			}
+		}
+
+		indexIdNum := len(aiPredictModelIndexIdList)
+		if indexIdNum > 0 {
+			indexObj := aiPredictModel.AiPredictModelIndex{}
+			indexList, e := indexObj.GetItemsByCondition(` AND ai_predict_model_index_id in (`+utils.GetOrmInReplace(indexIdNum)+`)`, []interface{}{aiPredictModelIndexIdList}, []string{}, "")
+			if e != nil {
+				if utils.IsErrNoRow(e) {
+					br.Msg = "框架不存在, 请刷新页面"
+					return
+				}
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取标的列表失败, Err: " + e.Error()
+				return
+			}
+			for _, v := range indexList {
+				aiPredictModelIndexMap[v.AiPredictModelIndexId] = v
+			}
+		}
+	}
+
+	// 格式化响应数据
+	itemNodes := make([]*aiPredictModel.AiPredictModelFrameworkNodeItem, 0)
+	for _, v := range nodes {
+		if v.NodeId == "" {
+			continue
+		}
+		num := 1
+
+		itemNodes = append(itemNodes, aiPredictModel.FormatAiPredictModelFrameworkNode2Item(v, num, aiPredictModelIndexMap))
+	}
+	detail := aiPredictModel.FormatAiPredictModelFramework2Item(item, itemNodes)
+
+	br.Data = detail
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 986 - 0
controllers/data_manage/ai_predict_model/index.go

@@ -0,0 +1,986 @@
+package ai_predict_model
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	aiPredictModel "eta/eta_api/models/ai_predict_model"
+	dataSourceModel "eta/eta_api/models/data_source"
+	"eta/eta_api/models/system"
+	"eta/eta_api/services"
+	"eta/eta_api/services/elastic"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
+	"os"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// AiPredictModelIndexController AI预测模型标的
+type AiPredictModelIndexController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 标的列表
+// @Description 标的列表
+// @Param   PageSize   query   int   true   "每页数据条数"
+// @Param   CurrentIndex   query   int   true   "当前页页码,从1开始"
+// @Param   ClassifyId   query   int   false   "分类id"
+// @Param   IndexId   query   int   false   "模型标的ID"
+// @Param   Keyword   query   string   false   "搜索关键词"
+// @Success 200 {object} data_manage.ChartListResp
+// @router /index/list [get]
+func (this *AiPredictModelIndexController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	classifyId, _ := this.GetInt("ClassifyId")
+	indexId, _ := this.GetInt("IndexId")
+	keyword := this.GetString("KeyWord")
+	if keyword == "" {
+		keyword = this.GetString("Keyword")
+	}
+	keyword = strings.TrimSpace(keyword)
+	resp := new(aiPredictModel.AiPredictModelIndexPageListResp)
+
+	// 分页
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	// 分类
+	classifyIdName := make(map[int]string)
+	{
+		classifyOb := new(aiPredictModel.AiPredictModelClassify)
+		list, e := classifyOb.GetItemsByCondition("", make([]interface{}, 0), []string{}, "")
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
+			return
+		}
+		for _, v := range list {
+			classifyIdName[v.AiPredictModelClassifyId] = v.ClassifyName
+		}
+	}
+
+	// 筛选条件
+	highlightMap := make(map[int]string)
+	indexOb := new(aiPredictModel.AiPredictModelIndex)
+	var cond string
+	var pars []interface{}
+	{
+		if indexId > 0 {
+			cond += fmt.Sprintf(" AND %s = ?", indexOb.Cols().PrimaryId)
+			pars = append(pars, indexId)
+		}
+		if classifyId > 0 {
+			cond += fmt.Sprintf(" AND %s = ?", indexOb.Cols().ClassifyId)
+			pars = append(pars, classifyId)
+		}
+		//if keyword != "" {
+		//	cond += fmt.Sprintf(" AND %s LIKE ?", indexOb.Cols().IndexName)
+		//	pars = append(pars, fmt.Sprint("%", keyword, "%"))
+		//}
+
+		// 有关键词从es中搜索
+		if keyword != "" {
+			_, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keyword, utils.DATA_SOURCE_AI_PREDICT_MODEL, 0, []int{}, []int{}, []string{}, startSize, pageSize)
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("ES-搜索手工指标列表失败, %v", e)
+				return
+			}
+			if len(list) == 0 {
+				resp.List = make([]*aiPredictModel.AiPredictModelIndexItem, 0)
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				br.Data = resp
+				return
+			}
+			var ids []int
+			for _, v := range list {
+				ids = append(ids, v.PrimaryId)
+				highlightMap[v.PrimaryId] = v.SearchText
+			}
+			cond += fmt.Sprintf(` AND %s IN (%s)`, indexOb.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
+			pars = append(pars, ids)
+		}
+	}
+
+	// 获取列表
+	total, e := indexOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取标的总数失败, %v", e)
+		return
+	}
+	list, e := indexOb.GetPageItemsByCondition(cond, pars, []string{}, "", startSize, pageSize)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取分页列表失败, %v", e)
+		return
+	}
+	pageList := make([]*aiPredictModel.AiPredictModelIndexItem, 0)
+	for _, v := range list {
+		t := v.Format2Item()
+		t.ClassifyName = classifyIdName[v.ClassifyId]
+		// 搜索高亮
+		t.SearchText = v.IndexName
+		s := highlightMap[v.AiPredictModelIndexId]
+		if s != "" {
+			t.SearchText = s
+		}
+		pageList = append(pageList, t)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
+	resp.List = pageList
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Import
+// @Title 导入标的和数据
+// @Description 导入标的和数据
+// @Param   IndexFile   query   file   true   "标的文件"
+// @Success 200 Ret=200 录入成功
+// @router /index/import [post]
+func (this *AiPredictModelIndexController) Import() {
+	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
+	}
+
+	file, _, e := this.GetFile("IndexFile")
+	if e != nil {
+		br.Msg = "导入失败"
+		br.ErrMsg = fmt.Sprintf("获取文件失败, %v", e)
+		return
+	}
+	path := "./static/ai_predict_model_temp_" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
+	defer func() {
+		_ = file.Close()
+		_ = os.Remove(path)
+	}()
+	if e = this.SaveToFile("IndexFile", path); e != nil {
+		br.Msg = "导入失败"
+		br.ErrMsg = fmt.Sprintf("保存文件失败, %v", e)
+		return
+	}
+	xlFile, e := xlsx.OpenFile(path)
+	if e != nil {
+		br.Msg = "导入失败"
+		br.ErrMsg = fmt.Sprintf("打开excel文件失败, %v", e)
+		return
+	}
+
+	// 获取分类和用户,遍历时校验
+	classifyNameId := make(map[string]int)
+	adminNameId := make(map[string]int)
+	{
+		classifyOb := new(aiPredictModel.AiPredictModelClassify)
+		classifyCond := fmt.Sprintf(` AND %s = ?`, classifyOb.Cols().ParentId)
+		classifyPars := make([]interface{}, 0)
+		classifyPars = append(classifyPars, 0) // 只取一级分类(临时过渡方案,业务端只会加一级)
+		classifies, e := classifyOb.GetItemsByCondition(classifyCond, classifyPars, []string{}, "")
+		if e != nil {
+			br.Msg = "导入失败"
+			br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
+			return
+		}
+		for _, v := range classifies {
+			classifyNameId[v.ClassifyName] = v.AiPredictModelClassifyId
+		}
+
+		admins, e := system.GetSysAdminList(``, make([]interface{}, 0), []string{}, "")
+		if e != nil {
+			br.Msg = "导入失败"
+			br.ErrMsg = fmt.Sprintf("获取用户失败, %v", e)
+			return
+		}
+		for _, v := range admins {
+			adminNameId[v.RealName] = v.AdminId
+		}
+	}
+
+	// 遍历sheet页
+	// 列表页:预测标的|分类|模型框架|创建人|预测日期|预测值|预测频度|方向准确率|绝对偏差
+	type ImportDataColKey struct {
+		IndexName string
+		ColKey    int
+		DataDate  time.Time
+	}
+	imports := make(map[string]*aiPredictModel.AiPredictModelImportData)
+	importsData := make(map[string]map[time.Time]*aiPredictModel.AiPredictModelData)
+	importsDailyData := make(map[string]map[time.Time]*aiPredictModel.AiPredictModelData)
+	for sheetKey, sheet := range xlFile.Sheets {
+		maxRow := sheet.MaxRow
+
+		// 列表页
+		if sheetKey == 0 {
+			for i := 0; i < maxRow; i++ {
+				// 忽略首行标题
+				if i < 1 {
+					continue
+				}
+				row := sheet.Row(i)
+				cells := row.Cells
+				if len(cells) < 9 {
+					continue
+				}
+
+				// 标的名称
+				indexName := strings.TrimSpace(cells[0].String())
+				if indexName == "" {
+					continue
+				}
+				if imports[indexName] == nil {
+					imports[indexName] = new(aiPredictModel.AiPredictModelImportData)
+					imports[indexName].Index = new(aiPredictModel.AiPredictModelIndex)
+					imports[indexName].Data = make([]*aiPredictModel.AiPredictModelData, 0)
+				}
+				imports[indexName].Index.IndexName = indexName
+				imports[indexName].Index.CreateTime = time.Now()
+				imports[indexName].Index.ModifyTime = time.Now()
+
+				// 分类
+				classifyName := strings.TrimSpace(cells[1].String())
+				if classifyNameId[classifyName] <= 0 {
+					br.Msg = fmt.Sprintf("分类:%s不存在", classifyName)
+					return
+				}
+				imports[indexName].Index.ClassifyId = classifyNameId[classifyName]
+
+				// 创建人
+				adminName := strings.TrimSpace(cells[3].String())
+				if adminNameId[adminName] <= 0 {
+					br.Msg = fmt.Sprintf("创建人:%s不存在", adminName)
+					return
+				}
+				imports[indexName].Index.SysUserId = adminNameId[adminName]
+				imports[indexName].Index.SysUserRealName = adminName
+
+				// 其余信息
+				imports[indexName].Index.ModelFramework = strings.TrimSpace(cells[2].String())
+				strDate := strings.TrimSpace(cells[4].String())
+				predictDate, _ := utils.GetExcelDate(strDate)
+				imports[indexName].Index.PredictDate = predictDate
+
+				strVal := strings.TrimSpace(cells[5].String())
+				if strVal == "" {
+					continue
+				}
+				predictVal, _ := strconv.ParseFloat(strVal, 64)
+				imports[indexName].Index.PredictValue = predictVal
+				imports[indexName].Index.PredictFrequency = strings.TrimSpace(cells[6].String())
+				imports[indexName].Index.DirectionAccuracy = strings.TrimSpace(cells[7].String())
+				imports[indexName].Index.AbsoluteDeviation = strings.TrimSpace(cells[8].String())
+			}
+		}
+
+		// 月度数据页
+		if sheetKey == 1 {
+			// 每五列为一个指标的数据
+			colKeys := make(map[int]*ImportDataColKey) // 每一列对应的指标名称以及对应的字段序号
+			for i := 0; i < maxRow; i++ {
+				// 首行为指标名称
+				if i == 0 {
+					nameCol := 0
+					row := sheet.Row(i)
+					for ck, cell := range row.Cells {
+						nameCol += 1
+						if nameCol > 5 {
+							nameCol = 1
+						}
+						if nameCol == 1 {
+							// nameCol=1时为指标/数据行则为日期
+							indexName := strings.TrimSpace(cell.String())
+							if indexName == "" {
+								continue
+							}
+							importsData[indexName] = make(map[time.Time]*aiPredictModel.AiPredictModelData)
+
+							colKeys[ck] = &ImportDataColKey{
+								ColKey:    1,
+								IndexName: indexName,
+							}
+
+							// 后面四列分别对应: 实际值|预测值|方向|偏差率, 这里直接加无须考虑是否会越界
+							colKeys[ck+1] = &ImportDataColKey{
+								ColKey:    2,
+								IndexName: indexName,
+							}
+							colKeys[ck+2] = &ImportDataColKey{
+								ColKey:    3,
+								IndexName: indexName,
+							}
+							colKeys[ck+3] = &ImportDataColKey{
+								ColKey:    4,
+								IndexName: indexName,
+							}
+							colKeys[ck+4] = &ImportDataColKey{
+								ColKey:    5,
+								IndexName: indexName,
+							}
+							continue
+						}
+					}
+					continue
+				}
+
+				// 第二行为标题,跳过
+				if i == 1 {
+					continue
+				}
+
+				// 剩余为数据行
+				row := sheet.Row(i)
+				for ck, cell := range row.Cells {
+					if colKeys[ck] == nil {
+						continue
+					}
+					if colKeys[ck].IndexName == "" {
+						continue
+					}
+					switch colKeys[ck].ColKey {
+					case 1:
+						// 日期列
+						strDate := strings.TrimSpace(cell.String())
+						dataDate, _ := utils.GetExcelDate(strDate)
+						if dataDate.IsZero() {
+							continue
+						}
+						colKeys[ck].DataDate = dataDate
+						colKeys[ck+1].DataDate = dataDate
+						colKeys[ck+2].DataDate = dataDate
+						colKeys[ck+3].DataDate = dataDate
+						colKeys[ck+4].DataDate = dataDate
+						importRow := imports[colKeys[ck].IndexName]
+						if importRow == nil {
+							continue
+						}
+						// 新增当前日期数据
+						importsData[colKeys[ck].IndexName][dataDate] = new(aiPredictModel.AiPredictModelData)
+						importsData[colKeys[ck].IndexName][dataDate].DataTime = dataDate
+						importsData[colKeys[ck].IndexName][dataDate].CreateTime = time.Now()
+						importsData[colKeys[ck].IndexName][dataDate].ModifyTime = time.Now()
+						importsData[colKeys[ck].IndexName][dataDate].Source = aiPredictModel.ModelDataSourceMonthly
+					case 2, 3:
+						// 实际值和预测值, 可能为空
+						dataDate := colKeys[ck].DataDate
+						if importsData[colKeys[ck].IndexName][dataDate] == nil {
+							continue
+						}
+						strVal := strings.TrimSpace(cell.String())
+						if strVal == "" {
+							continue
+						}
+						val, _ := strconv.ParseFloat(strVal, 64)
+						if colKeys[ck].ColKey == 2 {
+							importsData[colKeys[ck].IndexName][dataDate].Value.Valid = true
+							importsData[colKeys[ck].IndexName][dataDate].Value.Float64 = val
+						} else {
+							importsData[colKeys[ck].IndexName][dataDate].PredictValue.Valid = true
+							importsData[colKeys[ck].IndexName][dataDate].PredictValue.Float64 = val
+						}
+					case 4, 5:
+						// 方向/偏差率
+						dataDate := colKeys[ck].DataDate
+						if importsData[colKeys[ck].IndexName][dataDate] == nil {
+							continue
+						}
+						str := strings.TrimSpace(cell.String())
+						if str == "" {
+							continue
+						}
+						if colKeys[ck].ColKey == 4 {
+							importsData[colKeys[ck].IndexName][dataDate].Direction = str
+						} else {
+							importsData[colKeys[ck].IndexName][dataDate].DeviationRate = str
+						}
+					default:
+						continue
+					}
+				}
+			}
+		}
+
+		// 日度数据页
+		if sheetKey == 2 {
+			// 每3列为一个指标的数据
+			colKeys := make(map[int]*ImportDataColKey) // 每一列对应的指标名称以及对应的字段序号
+			for i := 0; i < maxRow; i++ {
+				// 首行为指标名称
+				if i == 0 {
+					nameCol := 0
+					row := sheet.Row(i)
+					for ck, cell := range row.Cells {
+						nameCol += 1
+						if nameCol > 3 {
+							nameCol = 1
+						}
+						if nameCol == 1 {
+							// nameCol=1时为指标/数据行则为日期
+							indexName := strings.TrimSpace(cell.String())
+							if indexName == "" {
+								continue
+							}
+							importsDailyData[indexName] = make(map[time.Time]*aiPredictModel.AiPredictModelData)
+
+							colKeys[ck] = &ImportDataColKey{
+								ColKey:    1,
+								IndexName: indexName,
+							}
+
+							// 后面两列分别对应: 实际值|预测值, 这里直接加无须考虑是否会越界
+							colKeys[ck+1] = &ImportDataColKey{
+								ColKey:    2,
+								IndexName: indexName,
+							}
+							colKeys[ck+2] = &ImportDataColKey{
+								ColKey:    3,
+								IndexName: indexName,
+							}
+							continue
+						}
+					}
+					continue
+				}
+
+				// 第二行为标题,遇到"预测值"单元格,需要取出其中的值作为预测图例名称
+				if i == 1 {
+					row := sheet.Row(i)
+					for ck, cell := range row.Cells {
+						if colKeys[ck] == nil {
+							continue
+						}
+						if colKeys[ck].IndexName == "" {
+							continue
+						}
+						if colKeys[ck].ColKey != 3 {
+							continue
+						}
+						if imports[colKeys[ck].IndexName] != nil && imports[colKeys[ck].IndexName].Index != nil {
+							var extraConfig aiPredictModel.AiPredictModelIndexExtraConfig
+							extraConfig.DailyChart.PredictLegendName = strings.TrimSpace(cell.String())
+							b, _ := json.Marshal(extraConfig)
+							imports[colKeys[ck].IndexName].Index.ExtraConfig = string(b)
+						}
+					}
+					continue
+				}
+
+				// 剩余为数据行
+				row := sheet.Row(i)
+				for ck, cell := range row.Cells {
+					if colKeys[ck] == nil {
+						continue
+					}
+					if colKeys[ck].IndexName == "" {
+						continue
+					}
+					switch colKeys[ck].ColKey {
+					case 1:
+						// 日期列
+						strDate := strings.TrimSpace(cell.String())
+						dataDate, _ := utils.GetExcelDate(strDate)
+						if dataDate.IsZero() {
+							continue
+						}
+						colKeys[ck].DataDate = dataDate
+						colKeys[ck+1].DataDate = dataDate
+						colKeys[ck+2].DataDate = dataDate
+						importRow := imports[colKeys[ck].IndexName]
+						if importRow == nil {
+							continue
+						}
+						// 新增当前日期数据
+						importsDailyData[colKeys[ck].IndexName][dataDate] = new(aiPredictModel.AiPredictModelData)
+						importsDailyData[colKeys[ck].IndexName][dataDate].DataTime = dataDate
+						importsDailyData[colKeys[ck].IndexName][dataDate].CreateTime = time.Now()
+						importsDailyData[colKeys[ck].IndexName][dataDate].ModifyTime = time.Now()
+						importsDailyData[colKeys[ck].IndexName][dataDate].Source = aiPredictModel.ModelDataSourceDaily
+					case 2, 3:
+						// 实际值和预测值, 可能为空
+						dataDate := colKeys[ck].DataDate
+						if importsDailyData[colKeys[ck].IndexName][dataDate] == nil {
+							continue
+						}
+						strVal := strings.TrimSpace(cell.String())
+						if strVal == "" {
+							continue
+						}
+						val, _ := strconv.ParseFloat(strVal, 64)
+						if colKeys[ck].ColKey == 2 {
+							importsDailyData[colKeys[ck].IndexName][dataDate].Value.Valid = true
+							importsDailyData[colKeys[ck].IndexName][dataDate].Value.Float64 = val
+						} else {
+							importsDailyData[colKeys[ck].IndexName][dataDate].PredictValue.Valid = true
+							importsDailyData[colKeys[ck].IndexName][dataDate].PredictValue.Float64 = val
+						}
+					default:
+						continue
+					}
+				}
+			}
+		}
+	}
+
+	for indexName, v := range importsData {
+		if imports[indexName] == nil {
+			continue
+		}
+		for _, dateData := range v {
+			imports[indexName].Data = append(imports[indexName].Data, dateData)
+		}
+	}
+	for indexName, v := range importsDailyData {
+		if imports[indexName] == nil {
+			continue
+		}
+		for _, dateData := range v {
+			imports[indexName].Data = append(imports[indexName].Data, dateData)
+		}
+	}
+	importIndexes := make([]*aiPredictModel.AiPredictModelImportData, 0)
+	for _, v := range imports {
+		importIndexes = append(importIndexes, v)
+	}
+
+	// 导入指标
+	if e = services.ImportAiPredictModelIndexAndData(importIndexes); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("导入指标数据失败, %v", e)
+		return
+	}
+
+	// 写入es
+	go func() {
+		for _, v := range importIndexes {
+			indexItem := new(dataSourceModel.SearchDataSource)
+			indexItem.PrimaryId = v.Index.AiPredictModelIndexId
+			indexItem.IndexName = v.Index.IndexName
+			indexItem.IndexCode = v.Index.IndexCode
+			indexItem.ClassifyId = v.Index.ClassifyId
+			indexItem.Source = utils.DATA_SOURCE_AI_PREDICT_MODEL
+			indexItem.SourceName = "AI预测模型"
+			indexItem.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.Index.CreateTime)
+			indexItem.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, v.Index.ModifyTime)
+
+			docId := fmt.Sprintf("%d-%d", indexItem.Source, indexItem.PrimaryId)
+			if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
+				utils.FileLog.Info("AI预测模型-写入es失败, %v", e)
+				continue
+			}
+		}
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Detail
+// @Title 标的详情
+// @Description 标的详情
+// @Param   IndexId   query   int   true   "标的ID"
+// @Success 200 {object} data_manage.ChartListResp
+// @router /index/detail [get]
+func (this *AiPredictModelIndexController) 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
+	}
+	indexId, _ := this.GetInt("IndexId")
+	if indexId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", indexId)
+		return
+	}
+	resp := new(aiPredictModel.AiPredictModelDetailResp)
+
+	indexOb := new(aiPredictModel.AiPredictModelIndex)
+	indexItem, e := indexOb.GetItemById(indexId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "标的已被删除,请刷新页面"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
+		return
+	}
+
+	// 获取标的数据
+	monthData, dailyData := make([]*aiPredictModel.AiPredictModelData, 0), make([]*aiPredictModel.AiPredictModelData, 0)
+	{
+		tableData := make([]*aiPredictModel.AiPredictModelDataItem, 0)
+		dataOb := new(aiPredictModel.AiPredictModelData)
+		dataCond := fmt.Sprintf(` AND %s = ?`, dataOb.Cols().IndexCode)
+		dataPars := make([]interface{}, 0)
+		dataPars = append(dataPars, indexItem.IndexCode)
+		list, e := dataOb.GetItemsByCondition(dataCond, dataPars, []string{}, fmt.Sprintf("%s DESC", dataOb.Cols().DataTime))
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取标的数据失败, %v", e)
+			return
+		}
+
+		// tableData取月度数据,最多显示10条
+		count, limit := 0, 10
+		for _, v := range list {
+			// 日度数据
+			if v.Source == aiPredictModel.ModelDataSourceDaily {
+				dailyData = append(dailyData, v)
+				continue
+			}
+
+			// 月度数据
+			if count < limit {
+				tableData = append(tableData, v.Format2Item())
+				count += 1
+			}
+			monthData = append(monthData, v)
+		}
+		resp.TableData = tableData
+	}
+
+	// 月度图表
+	if len(monthData) > 0 {
+		chartDetail, e := services.GetAiPredictChartDetailByData(indexItem, monthData, aiPredictModel.ModelDataSourceMonthly)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取月度图表失败, %v", e)
+			return
+		}
+		resp.ChartView = chartDetail
+	}
+
+	// 日度图表
+	if len(dailyData) > 0 {
+		dailyChartDetail, e := services.GetAiPredictChartDetailByData(indexItem, dailyData, aiPredictModel.ModelDataSourceDaily)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取日度图表失败, %v", e)
+			return
+		}
+		resp.DailyChartView = dailyChartDetail
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Save
+// @Title 保存标的
+// @Description 保存标的
+// @Param	request	body aiPredictModel.AiPredictModelIndexSaveReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /index/save [post]
+func (this *AiPredictModelIndexController) Save() {
+	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 aiPredictModel.AiPredictModelIndexSaveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.IndexId < 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("标的ID有误, IndexId: %d", req.IndexId)
+		return
+	}
+
+	indexOb := new(aiPredictModel.AiPredictModelIndex)
+	indexItem, e := indexOb.GetItemById(req.IndexId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "标的已被删除,请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
+		return
+	}
+
+	var extraConfig aiPredictModel.AiPredictModelIndexExtraConfig
+	if indexItem.ExtraConfig != "" {
+		if e = json.Unmarshal([]byte(indexItem.ExtraConfig), &extraConfig); e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("标的配置解析失败, %v", e)
+			return
+		}
+	}
+	if req.MonthlyChart != nil {
+		extraConfig.MonthlyChart.LeftMin = req.MonthlyChart.LeftMin
+		extraConfig.MonthlyChart.LeftMax = req.MonthlyChart.LeftMax
+		extraConfig.MonthlyChart.Unit = req.MonthlyChart.Unit
+	}
+	if req.DailyChart != nil {
+		extraConfig.DailyChart.LeftMin = req.DailyChart.LeftMin
+		extraConfig.DailyChart.LeftMax = req.DailyChart.LeftMax
+		extraConfig.DailyChart.Unit = req.DailyChart.Unit
+	}
+
+	configByte, _ := json.Marshal(extraConfig)
+	indexItem.ExtraConfig = string(configByte)
+	indexItem.ModifyTime = time.Now()
+	updateCols := []string{indexOb.Cols().ExtraConfig, indexOb.Cols().ModifyTime}
+	if e = indexItem.Update(updateCols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("保存标的失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "操作成功"
+	br.Success = true
+}
+
+// DashboardSave
+// @Title 保存看板
+// @Description 保存看板
+// @Param	request	body aiPredictModel.AiPredictModelDashboardSaveReq true "type json string"
+// @Success 200 Ret=200 新增成功
+// @router /index/dashboard/save [post]
+func (this *AiPredictModelIndexController) DashboardSave() {
+	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 aiPredictModel.AiPredictModelDashboardSaveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.IndexId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, %d", req.IndexId)
+		return
+	}
+	req.DashboardName = strings.TrimSpace(req.DashboardName)
+
+	indexOb := new(aiPredictModel.AiPredictModelIndex)
+	_, e := indexOb.GetItemById(req.IndexId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "标的已被删除,请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
+		return
+	}
+
+	// 获取看板
+	var isUpdate bool
+	var updateCols []string
+	dashboardItem := new(aiPredictModel.AiPredictModelDashboard)
+	if req.IndexId > 0 {
+		cond := fmt.Sprintf(" AND %s = ?", dashboardItem.Cols().AiPredictModelIndexId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.IndexId)
+		item, e := dashboardItem.GetItemByCondition(cond, pars, "")
+		if e != nil && !utils.IsErrNoRow(e) {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取标的看板失败, %v", e)
+			return
+		}
+		if item != nil && item.AiPredictModelIndexId > 0 {
+			isUpdate = true
+			dashboardItem = item
+			dashboardItem.DashboardName = req.DashboardName
+			dashboardItem.ModifyTime = time.Now()
+			updateCols = append(updateCols, dashboardItem.Cols().DashboardName, dashboardItem.Cols().ModifyTime)
+		}
+	}
+	if !isUpdate {
+		dashboardItem.AiPredictModelIndexId = req.IndexId
+		dashboardItem.DashboardName = req.DashboardName
+		dashboardItem.SysUserId = sysUser.AdminId
+		dashboardItem.SysUserRealName = sysUser.RealName
+		dashboardItem.CreateTime = time.Now()
+		dashboardItem.ModifyTime = time.Now()
+	}
+
+	// 详情
+	dashboardDetails := make([]*aiPredictModel.AiPredictModelDashboardDetail, 0)
+	for i, v := range req.List {
+		t := &aiPredictModel.AiPredictModelDashboardDetail{
+			Type:       v.Type,
+			UniqueCode: v.UniqueCode,
+			Sort:       i + 1,
+			CreateTime: time.Now(),
+			ModifyTime: time.Now(),
+		}
+		dashboardDetails = append(dashboardDetails, t)
+	}
+
+	// 保存
+	if e := dashboardItem.SaveIndexDashboard(dashboardItem, dashboardDetails, isUpdate, updateCols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("保存标的看板失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// DashboardDetail
+// @Title 看板详情
+// @Description 看板详情
+// @Param   IndexId   query   int   true   "标的ID"
+// @Success 200 {object} aiPredictModel.AiPredictModelDashboardDetailResp
+// @router /index/dashboard/detail [get]
+func (this *AiPredictModelIndexController) DashboardDetail() {
+	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
+	}
+	indexId, _ := this.GetInt("IndexId")
+	resp := new(aiPredictModel.AiPredictModelDashboardDetailResp)
+
+	indexOb := new(aiPredictModel.AiPredictModelIndex)
+	indexItem, e := indexOb.GetItemById(indexId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "标的已被删除,请刷新页面"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
+		return
+	}
+	resp.CreateUserId = indexItem.SysUserId
+	resp.CreateUserRealName = indexItem.SysUserRealName
+
+	// 获取标的看板
+	dashboardOb := new(aiPredictModel.AiPredictModelDashboard)
+	dashboardItem := new(aiPredictModel.AiPredictModelDashboardItem)
+	{
+		cond := fmt.Sprintf(" AND %s = ?", dashboardOb.Cols().AiPredictModelIndexId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, indexId)
+		item, e := dashboardOb.GetItemByCondition(cond, pars, "")
+		if e != nil && !utils.IsErrNoRow(e) {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取标的看板失败, %v", e)
+			return
+		}
+		if item != nil {
+			dashboardItem = item.Format2Item()
+		}
+	}
+
+	// 获取看板详情
+	dashboardDetails := make([]*aiPredictModel.AiPredictModelDashboardDetailItem, 0)
+	if dashboardItem.DashboardId > 0 {
+		detailOb := new(aiPredictModel.AiPredictModelDashboardDetail)
+		cond := fmt.Sprintf(" AND %s = ?", detailOb.Cols().AiPredictModelDashboardId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, dashboardItem.DashboardId)
+		list, e := detailOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", detailOb.Cols().Sort))
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取看板详情失败, %v", e)
+			return
+		}
+		for _, v := range list {
+			dashboardDetails = append(dashboardDetails, v.Format2Item())
+		}
+	}
+
+	resp.AiPredictModelDashboardItem = dashboardItem
+	resp.List = dashboardDetails
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 5 - 5
controllers/data_manage/baiinfo_data.go

@@ -36,14 +36,14 @@ func (this *EdbInfoController) BaiinfoClassify() {
 	}
 
 	rootList, err := data_manage.GetBaseFromBaiinfoClassifyByParentId(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromBaiinfoClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -52,7 +52,7 @@ func (this *EdbInfoController) BaiinfoClassify() {
 	baseFromBaiinfoIndexMap := make(map[int][]*data_manage.BaseFromBaiinfoClassifyItems)
 
 	allBaseFromBaiinfoIndex, err := data_manage.GetBaiinfoIndexAll()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 		return
@@ -144,14 +144,14 @@ func (this *EdbInfoController) BaiinfoClassifyName() {
 	}
 
 	rootList, err := data_manage.GetBaseFromBaiinfoClassifyByParentId(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromBaiinfoClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return

+ 3 - 2
controllers/data_manage/base_from_ly_index_controller.go

@@ -114,8 +114,9 @@ func (this *BaseFromLyIndexController) LyIndexDataList() {
 	if currentIndex <= 0 {
 		currentIndex = 1
 	}
+	startSize := utils.StartIndex(currentIndex, pageSize)
 
-	indexDataList, err := data.GetIndexDataPage(indexId, currentIndex, pageSize)
+	indexDataList, err := data.GetIndexDataPage(indexId, startSize, pageSize)
 	if err != nil {
 		br.Msg = "获取指标数据列表失败"
 		br.ErrMsg = "获取指标数据列表失败,Err:" + err.Error()
@@ -459,7 +460,7 @@ func (this *BaseFromLyIndexController) LyIndexDataExport() {
 
 			var lyDataList []*data_manage.BaseFromLyData
 			lyDataList, err = data_manage.GetBaseFromLyDataByIndexCode(v.IndexCode)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.ErrMsg = "GetBaseFromLyDataByIndexCode,Err:" + err.Error()
 				br.Msg = "获取数据失败"
 				return

+ 1152 - 0
controllers/data_manage/base_from_radish_research.go

@@ -0,0 +1,1152 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	dataSourceModel "eta/eta_api/models/data_source"
+	"eta/eta_api/models/system"
+	"eta/eta_api/services/data"
+	"eta/eta_api/services/elastic"
+	etaTrialService "eta/eta_api/services/eta_trial"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// BaseFromRadishResearchController 萝卜投研
+type BaseFromRadishResearchController struct {
+	controllers.BaseAuthController
+}
+
+// IndexPageList
+// @Title 指标列表-分页
+// @Description 指标列表-分页
+// @Success 200 {object} data_manage.RadishResearchIndexPageListResp
+// @router /radish_research/index/page_list [get]
+func (this *BaseFromRadishResearchController) IndexPageList() {
+	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 params data_manage.RadishResearchIndexListForm
+	if e := this.ParseForm(&params); e != nil {
+		br.Msg = "参数解析失败"
+		br.ErrMsg = fmt.Sprintf("参数解析失败, err: %v", e)
+		return
+	}
+	resp := new(data_manage.RadishResearchIndexPageListResp)
+	resp.List = make([]*data_manage.BaseFromRadishResearchIndexItem, 0)
+	classifyId, _ := this.GetInt("ClassifyId", -1)
+
+	// 分页查询
+	var startSize int
+	if params.PageSize <= 0 {
+		params.PageSize = utils.PageSize20
+	}
+	if params.CurrentIndex <= 0 {
+		params.CurrentIndex = 1
+	}
+	startSize = utils.StartIndex(params.CurrentIndex, params.PageSize)
+
+	// 筛选项
+	indexOb := new(data_manage.BaseFromRadishResearchIndex)
+	var (
+		cond        string
+		pars        []interface{}
+		classifyIds []int
+	)
+	// 未分类
+	if classifyId == 0 {
+		cond += fmt.Sprintf(` AND %s = ?`, indexOb.Cols().ClassifyId)
+		pars = append(pars, classifyId)
+	}
+	// 包含所有子分类的指标
+	if classifyId > 0 {
+		classifyOb := new(data_manage.BaseFromRadishResearchClassify)
+		classifies, e := classifyOb.GetItemsByCondition(fmt.Sprintf(" AND FIND_IN_SET(%d, %s)", classifyId, classifyOb.Cols().LevelPath), make([]interface{}, 0), []string{classifyOb.Cols().PrimaryId}, fmt.Sprintf("%s ASC, %s ASC", classifyOb.Cols().ParentId, classifyOb.Cols().Sort))
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取子分类IDs失败, %v", e)
+			return
+		}
+		for _, v := range classifies {
+			if v.BaseFromRadishResearchClassifyId <= 0 {
+				continue
+			}
+			classifyIds = append(classifyIds, v.BaseFromRadishResearchClassifyId)
+		}
+		if len(classifyIds) > 0 {
+			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().ClassifyId)
+			pars = append(pars, classifyIds)
+		}
+	}
+	// 分类多选
+	params.ClassifyIds = strings.TrimSpace(params.ClassifyIds)
+	if params.ClassifyIds != "" {
+		idsArr := strings.Split(params.ClassifyIds, ",")
+		for _, v := range idsArr {
+			id, _ := strconv.Atoi(v)
+			if id > 0 {
+				classifyIds = append(classifyIds, id)
+			}
+		}
+		if len(classifyIds) > 0 {
+			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().ClassifyId)
+			pars = append(pars, classifyIds)
+		}
+	}
+	// 频度多选
+	params.Frequencies = strings.TrimSpace(params.Frequencies)
+	if params.Frequencies != "" {
+		freArr := strings.Split(params.Frequencies, ",")
+		if len(freArr) > 0 {
+			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().Frequency)
+			pars = append(pars, freArr)
+		}
+	}
+	// 关键词
+	params.Keyword = strings.TrimSpace(params.Keyword)
+	if params.Keyword != "" {
+		kw := fmt.Sprint("%", params.Keyword, "%")
+		cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, indexOb.Cols().IndexName, indexOb.Cols().IndexCode)
+		pars = append(pars, kw, kw)
+	}
+	// 是否忽略已加入指标库的
+	if params.IgnoreEdbExist {
+		cond += fmt.Sprintf(` AND %s = 0`, indexOb.Cols().EdbExist)
+	}
+
+	// 列表合计
+	total, e := indexOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取指标总数失败, %v", e)
+		return
+	}
+	if total <= 0 {
+		page := paging.GetPaging(params.CurrentIndex, params.PageSize, 0)
+		resp.Paging = page
+		br.Data = resp
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+
+	items, e := indexOb.GetPageItemsByCondition(cond, pars, []string{}, "", startSize, params.PageSize)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取指标列表失败, %v", e)
+		return
+	}
+	for _, v := range items {
+		t := v.Format2Item()
+		resp.List = append(resp.List, t)
+	}
+
+	page := paging.GetPaging(params.CurrentIndex, params.PageSize, total)
+	resp.Paging = page
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// IndexDetail
+// @Title 指标详情
+// @Description 指标详情
+// @Param   IndexId  query  string  true  "指标ID"
+// @Success 200 {object} data_manage.BaseFromRadishResearchIndexDetail
+// @router /radish_research/index/detail [get]
+func (this *BaseFromRadishResearchController) IndexDetail() {
+	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
+	}
+	indexId, _ := this.GetInt("IndexId")
+	if indexId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", indexId)
+		return
+	}
+	resp := new(data_manage.BaseFromRadishResearchIndexDetail)
+
+	indexOb := new(data_manage.BaseFromRadishResearchIndex)
+	item, e := indexOb.GetItemById(indexId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "指标不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取指标失败, %v", e)
+		return
+	}
+	if item != nil && item.BaseFromRadishResearchIndexId <= 0 {
+		br.Msg = "指标不存在, 请刷新页面"
+		return
+	}
+	resp.BaseFromRadishResearchIndexItem = item.Format2Item()
+	resp.DataList = make([]*data_manage.BaseFromRadishResearchDataItem, 0)
+
+	dataOb := new(data_manage.BaseFromRadishResearchData)
+	cond := fmt.Sprintf(` AND %s = ?`, dataOb.Cols().IndexCode)
+	pars := make([]interface{}, 0)
+	pars = append(pars, item.IndexCode)
+	dataList, e := dataOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s DESC", dataOb.Cols().DataTime))
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取指标数据失败, %v", e)
+		return
+	}
+	for _, v := range dataList {
+		resp.DataList = append(resp.DataList, v.Format2Item())
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// IndexEdit
+// @Title 编辑指标
+// @Description 编辑指标
+// @Success 200 {object} data_manage.RadishResearchIndexEditReq
+// @router /radish_research/index/edit [post]
+func (this *BaseFromRadishResearchController) IndexEdit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req data_manage.RadishResearchIndexEditReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.IndexId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", req.IndexId)
+		return
+	}
+
+	indexOb := new(data_manage.BaseFromRadishResearchIndex)
+	item, e := indexOb.GetItemById(req.IndexId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "指标不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取指标失败, %v", e)
+		return
+	}
+	if item != nil && item.BaseFromRadishResearchIndexId <= 0 {
+		br.Msg = "指标不存在, 请刷新页面"
+		return
+	}
+
+	// 更新指标(这里不多限制,允许移到未分类)
+	item.ClassifyId = req.ClassifyId
+	item.ModifyTime = time.Now().Local()
+	updateCols := []string{indexOb.Cols().ClassifyId, indexOb.Cols().ModifyTime}
+	if e = item.Update(updateCols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新指标分类失败, %v", e)
+		return
+	}
+
+	// 更新ES
+	go func() {
+		indexItem := new(dataSourceModel.SearchDataSource)
+		indexItem.PrimaryId = item.BaseFromRadishResearchIndexId
+		indexItem.IndexCode = item.IndexCode
+		indexItem.IndexName = item.IndexName
+		indexItem.ClassifyId = item.ClassifyId
+		indexItem.Unit = item.Unit
+		indexItem.Frequency = item.Frequency
+		indexItem.StartDate = item.StartDate.Format(utils.FormatDate)
+		indexItem.EndDate = item.EndDate.Format(utils.FormatDate)
+		indexItem.LatestValue = fmt.Sprint(item.LatestValue)
+		indexItem.Source = utils.DATA_SOURCE_RADISH_RESEARCH
+		indexItem.SourceName = utils.DATA_SOURCE_NAME_RADISH_RESEARCH
+		indexItem.IsDeleted = 0
+		indexItem.CreateTime = item.CreateTime.Format(utils.FormatDateTime)
+		indexItem.ModifyTime = item.ModifyTime.Format(utils.FormatDateTime)
+
+		docId := fmt.Sprintf("%d-%d", utils.DATA_SOURCE_RADISH_RESEARCH, item.BaseFromRadishResearchIndexId)
+		if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
+			utils.FileLog.Warning("RadishResearch-写入指标ES失败, %v", e)
+			return
+		}
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// IndexRemove
+// @Title 删除指标
+// @Description 删除指标
+// @Success 200 {object} data_manage.RadishResearchIndexRemoveReq
+// @router /radish_research/index/remove [post]
+func (this *BaseFromRadishResearchController) IndexRemove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req data_manage.RadishResearchIndexRemoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if req.IndexId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", req.IndexId)
+		return
+	}
+
+	indexOb := new(data_manage.BaseFromRadishResearchIndex)
+	item, e := indexOb.GetItemById(req.IndexId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "指标不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取指标失败, %v", e)
+		return
+	}
+	if item != nil && item.BaseFromRadishResearchIndexId <= 0 {
+		br.Msg = "指标不存在, 请刷新页面"
+		return
+	}
+	if item.EdbExist == 1 {
+		br.Msg = "指标已被引用, 不允许删除"
+		return
+	}
+	if e = indexOb.RemoveIndexAndData(item.IndexCode); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("删除指标和数据失败, %v", e)
+		return
+	}
+
+	// 更新ES
+	go func() {
+		indexItem := new(dataSourceModel.SearchDataSource)
+		indexItem.PrimaryId = item.BaseFromRadishResearchIndexId
+		indexItem.IndexCode = item.IndexCode
+		indexItem.IndexName = item.IndexName
+		indexItem.ClassifyId = item.ClassifyId
+		indexItem.Unit = item.Unit
+		indexItem.Frequency = item.Frequency
+		indexItem.StartDate = item.StartDate.Format(utils.FormatDate)
+		indexItem.EndDate = item.EndDate.Format(utils.FormatDate)
+		indexItem.LatestValue = fmt.Sprint(item.LatestValue)
+		indexItem.Source = utils.DATA_SOURCE_RADISH_RESEARCH
+		indexItem.SourceName = utils.DATA_SOURCE_NAME_RADISH_RESEARCH
+		indexItem.IsDeleted = 1 // 标记已删除
+		indexItem.CreateTime = item.CreateTime.Format(utils.FormatDateTime)
+		indexItem.ModifyTime = item.ModifyTime.Format(utils.FormatDateTime)
+
+		docId := fmt.Sprintf("%d-%d", utils.DATA_SOURCE_RADISH_RESEARCH, item.BaseFromRadishResearchIndexId)
+		if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
+			utils.FileLog.Warning("RadishResearch-写入指标ES失败, %v", e)
+			return
+		}
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// IndexExport
+// @Title 导出指标数据
+// @Description 导出指标数据
+// @Param   ClassifyId  query  int  false  "分类Id"
+// @Success 200  导出成功
+// @router /radish_research/index/export [get]
+func (this *BaseFromRadishResearchController) IndexExport() {
+	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
+	}
+	classifyId, _ := this.GetInt("ClassifyId", -1)
+
+	var (
+		cond        string
+		pars        []interface{}
+		classifyIds []int
+	)
+	// 未分类
+	indexOb := new(data_manage.BaseFromRadishResearchIndex)
+	if classifyId == 0 {
+		cond += fmt.Sprintf(` AND %s = ?`, indexOb.Cols().ClassifyId)
+		pars = append(pars, classifyId)
+	}
+	// 包含所有子分类的指标
+	if classifyId > 0 {
+		classifyOb := new(data_manage.BaseFromRadishResearchClassify)
+		classifies, e := classifyOb.GetItemsByCondition(fmt.Sprintf(" AND FIND_IN_SET(%d, %s)", classifyId, classifyOb.Cols().LevelPath), make([]interface{}, 0), []string{classifyOb.Cols().PrimaryId}, fmt.Sprintf("%s ASC, %s ASC", classifyOb.Cols().ParentId, classifyOb.Cols().Sort))
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取子分类IDs失败, %v", e)
+			return
+		}
+		for _, v := range classifies {
+			if v.BaseFromRadishResearchClassifyId <= 0 {
+				continue
+			}
+			classifyIds = append(classifyIds, v.BaseFromRadishResearchClassifyId)
+		}
+		if len(classifyIds) > 0 {
+			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().ClassifyId)
+			pars = append(pars, classifyIds)
+		}
+	}
+
+	dir, _ := os.Executable()
+	exPath := filepath.Dir(dir)
+	downFile := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
+	xlsxFile := xlsx.NewFile()
+
+	// 获取指标数据
+	indexes, e := indexOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC, %s ASC", indexOb.Cols().Sort, indexOb.Cols().PrimaryId))
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取指标失败, %v", e)
+		return
+	}
+	if len(indexes) == 0 {
+		// 无数据返回空文件
+		if e := xlsxFile.Save(downFile); e != nil {
+			sheet, e := xlsxFile.AddSheet("无数据")
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("新增Sheet失败, %v", e)
+				return
+			}
+			rowSecName := sheet.AddRow()
+			celSecName := rowSecName.AddCell()
+			celSecName.SetValue("")
+			if e = xlsxFile.Save(downFile); e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("保存文件失败, %v", e)
+				return
+			}
+		}
+		fileName := fmt.Sprintf("%s%s%s", utils.DATA_SOURCE_NAME_RADISH_RESEARCH, time.Now().Format("06.01.02"), ".xlsx")
+		this.Ctx.Output.Download(downFile, fileName)
+		defer func() {
+			_ = os.Remove(downFile)
+		}()
+		return
+	}
+
+	// 划分指标频度
+	frequencyIndex := make(map[string][]*data_manage.BaseFromRadishResearchIndex)
+	frequencyIndexIds := make(map[string][]int)
+	for _, v := range indexes {
+		if frequencyIndex[v.Frequency] == nil {
+			frequencyIndex[v.Frequency] = make([]*data_manage.BaseFromRadishResearchIndex, 0)
+		}
+		if frequencyIndexIds[v.Frequency] == nil {
+			frequencyIndexIds[v.Frequency] = make([]int, 0)
+		}
+		frequencyIndexIds[v.Frequency] = append(frequencyIndexIds[v.Frequency], v.BaseFromRadishResearchIndexId)
+		frequencyIndex[v.Frequency] = append(frequencyIndex[v.Frequency], v)
+	}
+
+	frequencyArr := []string{"日度", "周度", "旬度", "月度", "季度", "半年度", "年度"}
+	//frequencyMap := map[string]string{
+	//	"日度":  "Daily",
+	//	"周度":  "Weekly",
+	//	"旬度":  "ten-day",
+	//	"月度":  "Monthly",
+	//	"季度":  "Quarterly",
+	//	"半年度": "Semi-annual",
+	//	"年度":  "Annual",
+	//}
+	dataOb := new(data_manage.BaseFromRadishResearchData)
+	for _, frequency := range frequencyArr {
+		// 获取对应频度指标
+		secNameList := frequencyIndex[frequency]
+		if len(secNameList) == 0 {
+			continue
+		}
+
+		//sheetName := fmt.Sprintf("%s(%s)", frequency, frequencyMap[frequency])
+		sheetNew, e := xlsxFile.AddSheet(frequency)
+		if e != nil {
+			utils.FileLog.Warning(fmt.Sprintf("萝卜投研导出-AddSheet err: %v", e))
+			continue
+		}
+		secNameRow := sheetNew.AddRow()
+		frequencyRow := sheetNew.AddRow()
+		unitRow := sheetNew.AddRow()
+		updateTimeRow := sheetNew.AddRow()
+
+		// 指标日期序列
+		indexIds := frequencyIndexIds[frequency]
+		dataTimeList, e := dataOb.GetDataTimeByIndexIds(indexIds)
+		if e != nil {
+			utils.FileLog.Warning(fmt.Sprintf("萝卜投研导出-GetDataTimeByIndexIds err: %v", e))
+			continue
+		}
+
+		// 添加excel左侧指标日期
+		setRowIndex := 4
+		for rk, dv := range dataTimeList {
+			rowIndex := setRowIndex + rk
+			row := sheetNew.Row(rowIndex)
+			displayDate, _ := time.Parse(utils.FormatDate, dv)
+			displayDateCell := row.AddCell()
+			style := new(xlsx.Style)
+			style.ApplyAlignment = true
+			style.Alignment.WrapText = true
+			displayDateCell.SetStyle(style)
+			displayDateCell.SetDate(displayDate)
+		}
+		for k, sv := range secNameList {
+			// 获取数据
+			dataCond := fmt.Sprintf(` AND %s = ?`, dataOb.Cols().IndexCode)
+			dataPars := make([]interface{}, 0)
+			dataPars = append(dataPars, sv.IndexCode)
+			dataList, e := dataOb.GetItemsByCondition(dataCond, dataPars, []string{}, fmt.Sprintf("%s DESC", dataOb.Cols().DataTime))
+			if e != nil {
+				utils.FileLog.Warning(fmt.Sprintf("萝卜投研导出-GetIndexDataByCondition err: %v", e))
+				continue
+			}
+
+			if k == 0 {
+				secNameRow.AddCell().SetValue("指标名称")
+				frequencyRow.AddCell().SetValue("频度")
+				unitRow.AddCell().SetValue("单位")
+				updateTimeRow.AddCell().SetValue("更新时间")
+				minCol := k * 3
+				sheetNew.SetColWidth(minCol, minCol, 15)
+			}
+			if len(dataList) == 0 {
+				continue
+			}
+			secNameRow.AddCell().SetValue(sv.IndexName)
+			frequencyRow.AddCell().SetValue(sv.Frequency)
+			unitRow.AddCell().SetValue(sv.Unit)
+
+			updateTimeRow.AddCell().SetValue(sv.ModifyTime)
+			dataInfoMap := make(map[string]*data_manage.BaseFromRadishResearchData)
+			for _, v := range dataList {
+				dt := v.DataTime.Format(utils.FormatDate)
+				dataInfoMap[dt] = v
+			}
+
+			for rk, dtv := range dataTimeList {
+				rowIndex := setRowIndex + rk
+				row := sheetNew.Row(rowIndex)
+				displayDateCell := row.AddCell()
+				tmpData, ok := dataInfoMap[dtv]
+				if ok {
+					displayDateCell.SetValue(tmpData.Value)
+				}
+			}
+		}
+	}
+
+	// 保存文件出错返回空文件
+	if e := xlsxFile.Save(downFile); e != nil {
+		sheet, e := xlsxFile.AddSheet("无数据")
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("新增Sheet失败, %v", e)
+			return
+		}
+		rowSecName := sheet.AddRow()
+		celSecName := rowSecName.AddCell()
+		celSecName.SetValue("")
+		if e = xlsxFile.Save(downFile); e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("保存文件失败, %v", e)
+			return
+		}
+	}
+	fileName := fmt.Sprintf("%s%s%s", utils.DATA_SOURCE_NAME_RADISH_RESEARCH, time.Now().Format("06.01.02"), ".xlsx")
+	this.Ctx.Output.Download(downFile, fileName)
+	defer func() {
+		_ = os.Remove(downFile)
+	}()
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "success"
+
+}
+
+// IndexSelect
+// @Title 批量加入指标库-选择指标
+// @Description 批量加入指标库-选择指标
+// @Success 200 {object} data_manage.BaseFromRadishResearchIndexItem
+// @router /radish_research/index/select [post]
+func (this *BaseFromRadishResearchController) IndexSelect() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req data_manage.RadishResearchIndexSelectReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	resp := make([]*data_manage.BaseFromRadishResearchIndexItem, 0)
+
+	indexOb := new(data_manage.BaseFromRadishResearchIndex)
+	var (
+		cond string
+		pars []interface{}
+	)
+	// 忽略已加入指标库的
+	cond += fmt.Sprintf(` AND %s = 0`, indexOb.Cols().EdbExist)
+	if len(req.ClassifyIds) > 0 {
+		cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().ClassifyId)
+		pars = append(pars, req.ClassifyIds)
+	}
+	if len(req.Frequencies) > 0 {
+		cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().Frequency)
+		pars = append(pars, req.Frequencies)
+	}
+	req.Keyword = strings.TrimSpace(req.Keyword)
+	if req.Keyword != "" {
+		kw := fmt.Sprint("%", req.Keyword, "%")
+		cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, indexOb.Cols().IndexName, indexOb.Cols().IndexCode)
+		pars = append(pars, kw, kw)
+	}
+	// 列表全选-SelectAll-true: IndexCodes为排除的指标, SelectAll-false: IndexCodes为选择的指标
+	if len(req.IndexCodes) > 0 {
+		if req.SelectAll {
+			cond += fmt.Sprintf(` AND %s NOT IN ?`, indexOb.Cols().IndexCode)
+		} else {
+			cond += fmt.Sprintf(` AND %s IN ?`, indexOb.Cols().IndexCode)
+		}
+		pars = append(pars, req.IndexCodes)
+	}
+
+	items, e := indexOb.GetItemsByCondition(cond, pars, []string{}, "")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取指标列表失败, %v", e)
+		return
+	}
+	if len(items) > 30 {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+	for _, v := range items {
+		t := v.Format2Item()
+		resp = append(resp, t)
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// EdbAdd
+// @Title 加入指标库
+// @Description 加入指标库
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /radish_research/edb/add [post]
+func (this *BaseFromRadishResearchController) EdbAdd() {
+	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
+	}
+	deleteCache := true
+	cacheKey := fmt.Sprintf("CACHE_EDB_INFO_ADD_%d_%d", utils.DATA_SOURCE_RADISH_RESEARCH, sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			_ = utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试"
+		return
+	}
+	var req data_manage.AddEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析失败, %v", e)
+		return
+	}
+	req.EdbCode = strings.TrimSpace(req.EdbCode)
+	req.EdbName = strings.TrimSpace(req.EdbName)
+	if req.EdbCode == "" {
+		br.Msg = "指标编码不能为空"
+		return
+	}
+	if req.EdbName == "" {
+		br.Msg = "指标名称不能为空"
+		return
+	}
+	if req.Frequency == "" {
+		br.Msg = "频率不能为空"
+		return
+	}
+	if req.Unit == "" {
+		br.Msg = "单位不能为空"
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	// 是否加入过指标库
+	exist, e := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_RADISH_RESEARCH, req.EdbCode)
+	if e != nil && !utils.IsErrNoRow(e) {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("校验是否加入过指标库失败, %v", e)
+		return
+	}
+	if exist != nil && exist.EdbInfoId > 0 {
+		br.Msg = "指标库已存在,请刷新页面"
+		return
+	}
+
+	// 指标入库
+	edbInfo, err, errMsg, isSendEmail := data.EdbInfoAdd(utils.DATA_SOURCE_RADISH_RESEARCH, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, req.StartDate, req.EndDate, sysUser.AdminId, sysUser.RealName, this.Lang)
+	if err != nil {
+		br.Msg = "保存失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+
+	// 刷新指标数据
+	refreshRes, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, "")
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("刷新指标数据失败, %v", e)
+		return
+	}
+	if refreshRes != nil && refreshRes.Ret != 200 {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("刷新指标数据失败, Ret: %d, Msg: %s, ErrMsg: %s", refreshRes.Ret, refreshRes.Msg, refreshRes.ErrMsg)
+		return
+	}
+
+	// 更新指标EdbExist
+	indexOb := new(data_manage.BaseFromRadishResearchIndex)
+	if e := indexOb.UpdateEdbExists(1, []string{req.EdbCode}); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新数据源EdbExist失败, %v", e)
+		return
+	}
+
+	//新增操作日志
+	{
+		edbLog := new(data_manage.EdbInfoLog)
+		edbLog.EdbInfoId = edbInfo.EdbInfoId
+		edbLog.SourceName = edbInfo.SourceName
+		edbLog.Source = edbInfo.Source
+		edbLog.EdbCode = edbInfo.EdbCode
+		edbLog.EdbName = edbInfo.EdbName
+		edbLog.ClassifyId = edbInfo.ClassifyId
+		edbLog.SysUserId = sysUser.AdminId
+		edbLog.SysUserRealName = sysUser.RealName
+		edbLog.CreateTime = time.Now()
+		edbLog.Content = string(this.Ctx.Input.RequestBody)
+		edbLog.Status = "新增指标"
+		edbLog.Method = this.Ctx.Input.URI()
+		go data_manage.AddEdbInfoLog(edbLog)
+	}
+
+	// 更新es
+	go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+
+	// 试用平台更新用户累计新增指标数
+	if utils.BusinessCode == utils.BusinessCodeSandbox {
+		go func() {
+			adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+			if e != nil {
+				return
+			}
+			if adminItem != nil && adminItem.AdminId <= 0 {
+				return
+			}
+			if adminItem.DepartmentName != "ETA试用客户" {
+				return
+			}
+
+			var r etaTrialService.EtaTrialUserReq
+			r.Mobile = adminItem.Mobile
+			_, _ = etaTrialService.UpdateUserIndexNum(r)
+		}()
+	}
+
+	resp := new(data_manage.AddEdbInfoResp)
+	resp.EdbInfoId = edbInfo.EdbInfoId
+	resp.UniqueCode = edbInfo.UniqueCode
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+	br.IsAddLog = true
+}
+
+// EdbNameCheck
+// @Title 批量加入指标库-重名校验
+// @Description 批量加入指标库-重名校验
+// @Success 200 {object} data_manage.EdbNameCheckResult
+// @router /radish_research/edb/name_check [post]
+func (this *BaseFromRadishResearchController) EdbNameCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req []*data_manage.NameCheckEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	codeMaxT := 30
+	codeLen := len(req)
+	if codeLen > codeMaxT {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+
+	indexNames := make([]string, 0)
+	resp := make([]*data_manage.EdbNameCheckResult, 0)
+	nameCount := make(map[string]int)
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		nameCount[v.EdbName] += 1
+
+		indexNames = append(indexNames, v.EdbName)
+		resp = append(resp, &data_manage.EdbNameCheckResult{
+			EdbCode: v.EdbCode,
+			EdbName: v.EdbName,
+		})
+	}
+	// 本次提交的名称中也不允许重复
+	for _, v := range resp {
+		if nameCount[v.EdbName] > 1 {
+			v.Exist = true
+		}
+	}
+
+	// 重名校验
+	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames, utils.EDB_INFO_TYPE)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取重名指标失败, Err: " + e.Error()
+		return
+	}
+	nameExists := make(map[string]bool)
+	for _, v := range edbList {
+		nameExists[v.EdbName] = true
+	}
+	if len(nameExists) > 0 {
+		for _, v := range resp {
+			v.Exist = nameExists[v.EdbName]
+		}
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// EdbMultiAdd
+// @Title 批量加入指标库
+// @Description 批量加入指标库
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /radish_research/edb/multi_add [post]
+func (this *BaseFromRadishResearchController) EdbMultiAdd() {
+	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
+	}
+	deleteCache := true
+	cacheKey := fmt.Sprintf("CACHE_EDB_INFO_BATCH_ADD_%d_%d", utils.DATA_SOURCE_RADISH_RESEARCH, sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			_ = utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req []*data_manage.AddEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if len(req) > 30 {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		v.Frequency = strings.TrimSpace(v.Frequency)
+		if v.Frequency == "" {
+			br.Msg = "请选择频度"
+			return
+		}
+		v.Unit = strings.TrimSpace(v.Unit)
+		if v.Unit == "" {
+			br.Msg = "请输入单位"
+			return
+		}
+		if v.ClassifyId <= 0 {
+			br.Msg = "请选择分类"
+			return
+		}
+	}
+
+	// 限定同一时间最多批量新增30个指标
+	var successCodes []string
+	for _, v := range req {
+		// 是否加入过指标库
+		exist, e := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_RADISH_RESEARCH, v.EdbCode)
+		if e != nil && !utils.IsErrNoRow(e) {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("校验是否加入过指标库失败, %v", e)
+			return
+		}
+		if exist != nil && exist.EdbInfoId > 0 {
+			// 加入过指标库这里直接忽略掉
+			continue
+		}
+
+		// 指标入库
+		edbInfo, err, errMsg, isSendEmail := data.EdbInfoAdd(utils.DATA_SOURCE_RADISH_RESEARCH, utils.DATA_SUB_SOURCE_EDB, v.ClassifyId, v.EdbCode, v.EdbName, v.Frequency, v.Unit, v.StartDate, v.EndDate, sysUser.AdminId, sysUser.RealName, this.Lang)
+		if err != nil {
+			br.Msg = "保存失败"
+			if errMsg != `` {
+				br.Msg = errMsg
+			}
+			br.ErrMsg = err.Error()
+			br.IsSendEmail = isSendEmail
+			return
+		}
+		successCodes = append(successCodes, v.EdbCode)
+
+		// 刷新指标数据
+		refreshRes, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, "")
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("刷新指标数据失败, %v", e)
+			return
+		}
+		if refreshRes != nil && refreshRes.Ret != 200 {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("刷新指标数据失败, Ret: %d, Msg: %s, ErrMsg: %s", refreshRes.Ret, refreshRes.Msg, refreshRes.ErrMsg)
+			return
+		}
+
+		// 试用平台更新用户累计新增指标数
+		if utils.BusinessCode == utils.BusinessCodeSandbox {
+			go func() {
+				adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+				if e != nil {
+					tips := fmt.Sprintf("试用平台更新用户累计新增指标数-获取用户失败, Err: " + e.Error())
+					utils.FileLog.Info(tips)
+					return
+				}
+				if adminItem.DepartmentName != "ETA试用客户" {
+					return
+				}
+				var ur etaTrialService.EtaTrialUserReq
+				ur.Mobile = adminItem.Mobile
+				_, _ = etaTrialService.UpdateUserIndexNum(ur)
+			}()
+		}
+
+		// 新增操作日志
+		{
+			edbLog := new(data_manage.EdbInfoLog)
+			edbLog.EdbInfoId = edbInfo.EdbInfoId
+			edbLog.SourceName = edbInfo.SourceName
+			edbLog.Source = edbInfo.Source
+			edbLog.EdbCode = edbInfo.EdbCode
+			edbLog.EdbName = edbInfo.EdbName
+			edbLog.ClassifyId = edbInfo.ClassifyId
+			edbLog.SysUserId = sysUser.AdminId
+			edbLog.SysUserRealName = sysUser.RealName
+			edbLog.CreateTime = time.Now()
+			edbLog.Content = string(this.Ctx.Input.RequestBody)
+			edbLog.Status = "新增指标"
+			edbLog.Method = this.Ctx.Input.URI()
+			go data_manage.AddEdbInfoLog(edbLog)
+		}
+
+		// 更新es
+		go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+	}
+
+	// 更新指标EdbExist
+	if len(successCodes) > 0 {
+		indexOb := new(data_manage.BaseFromRadishResearchIndex)
+		if e := indexOb.UpdateEdbExists(1, successCodes); e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("更新数据源EdbExist失败, %v", e)
+			return
+		}
+	}
+
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+}

+ 518 - 0
controllers/data_manage/base_from_radish_research_classify.go

@@ -0,0 +1,518 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/services/data"
+	"eta/eta_api/utils"
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// ClassifyList
+// @Title 分类列表-含指标
+// @Description 分类列表-含指标
+// @Param   ParentId  query  int  false  "父级ID"
+// @Success 200 {object} data_manage.RadishResearchSearchEdbResp
+// @router /radish_research/classify/list [get]
+func (this *BaseFromRadishResearchController) ClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	parentId, _ := this.GetInt("ParentId", -1)
+
+	resp := make([]*data_manage.BaseFromRadishResearchClassifyListItem, 0)
+
+	// 默认查询未分类及一级分类
+	var classifyId int
+	if parentId == -1 {
+		resp = append(resp, &data_manage.BaseFromRadishResearchClassifyListItem{
+			ClassifyName: "未分类",
+			Level:        1,
+			Sort:         -100,
+			UniqueCode:   "unclassified",
+		})
+	}
+	// 查询未分类下的指标
+	if parentId == 0 {
+		classifyId = -1
+	}
+	if parentId > 0 {
+		classifyId = parentId
+	}
+
+	// 查询分类
+	classifyOb := new(data_manage.BaseFromRadishResearchClassify)
+	{
+		cond := fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ParentId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, classifyId)
+		list, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", classifyOb.Cols().Sort))
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取子分类失败, %v", e)
+			return
+		}
+		for _, v := range list {
+			resp = append(resp, &data_manage.BaseFromRadishResearchClassifyListItem{
+				ClassifyId:   v.BaseFromRadishResearchClassifyId,
+				ClassifyName: v.ClassifyName,
+				ParentId:     v.ParentId,
+				Level:        v.Level,
+				Sort:         v.Sort,
+				UniqueCode:   v.UniqueCode,
+			})
+		}
+	}
+
+	// 查询指标
+	if parentId > -1 {
+		indexOb := new(data_manage.BaseFromRadishResearchIndex)
+		{
+			cond := fmt.Sprintf(" AND %s = ?", indexOb.Cols().ClassifyId)
+			pars := make([]interface{}, 0)
+			pars = append(pars, parentId)
+			list, e := indexOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", indexOb.Cols().Sort))
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("获取分类下指标失败, %v", e)
+				return
+			}
+			for _, v := range list {
+				resp = append(resp, &data_manage.BaseFromRadishResearchClassifyListItem{
+					NodeType:   1,
+					IndexId:    v.BaseFromRadishResearchIndexId,
+					IndexCode:  v.IndexCode,
+					IndexName:  v.IndexName,
+					ParentId:   parentId,
+					Sort:       v.Sort,
+					UniqueCode: v.IndexCode,
+				})
+			}
+		}
+	}
+	sort.Slice(resp, func(i, j int) bool {
+		return resp[i].Sort < resp[j].Sort
+	})
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// ClassifyTree
+// @Title 分类树
+// @Description 分类树
+// @Success 200 {object} data_manage.RadishResearchSearchEdbResp
+// @router /radish_research/classify/tree [get]
+func (this *BaseFromRadishResearchController) ClassifyTree() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	// 获取所有分类
+	classifyOb := new(data_manage.BaseFromRadishResearchClassify)
+	list, e := classifyOb.GetItemsByCondition(``, make([]interface{}, 0), []string{}, fmt.Sprintf("%s ASC, %s ASC", classifyOb.Cols().ParentId, classifyOb.Cols().Sort))
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取分类列表失败, %v", e)
+		return
+	}
+	items := make([]*data_manage.BaseFromRadishResearchClassifyItem, 0)
+	for _, v := range list {
+		items = append(items, v.Format2Item())
+	}
+	tree := data.GetRadishResearchClassifyTreeRecursive(items, 0)
+
+	// 未分类置顶
+	resp := make([]*data_manage.BaseFromRadishResearchClassifyItem, 0)
+	resp = append(resp, &data_manage.BaseFromRadishResearchClassifyItem{
+		ClassifyName: "未分类",
+		Level:        1,
+		Sort:         -100,
+		UniqueCode:   "unclassified",
+	})
+	resp = append(resp, tree...)
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// ClassifyAdd
+// @Title 新增分类
+// @Description 新增分类
+// @Param	request	body data_manage.RadishResearchClassifyAddReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /radish_research/classify/add [post]
+func (this *BaseFromRadishResearchController) ClassifyAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req data_manage.RadishResearchClassifyAddReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	req.ClassifyName = strings.TrimSpace(req.ClassifyName)
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+	if req.ParentId < 0 {
+		br.Msg = "请选择上级分类"
+		return
+	}
+	if req.Level > 6 {
+		br.Msg = "目前只支持6级目录"
+		return
+	}
+
+	// 校验分类名称
+	classifyOb := new(data_manage.BaseFromRadishResearchClassify)
+	{
+		cond := fmt.Sprintf(" AND %s = ? AND %s = ?", classifyOb.Cols().ParentId, classifyOb.Cols().ClassifyName)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.ParentId, req.ClassifyName)
+		count, e := classifyOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取分类名称重复数失败, %v", e)
+			return
+		}
+		if count > 0 {
+			br.Msg = "分类名称已存在"
+			return
+		}
+	}
+
+	// 层级路径
+	var levelPath string
+	var rootId int
+	if req.ParentId > 0 {
+		parent, e := classifyOb.GetItemById(req.ParentId)
+		if e != nil {
+			br.Msg = "上级分类有误"
+			br.ErrMsg = fmt.Sprintf("获取上级分类失败, %v", e)
+			return
+		}
+		levelPath = parent.LevelPath
+		rootId = parent.RootId
+	}
+
+	sortMax, e := classifyOb.GetSortMax(req.ParentId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类最大排序失败, %v", e)
+		return
+	}
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	classifyOb.ParentId = req.ParentId
+	classifyOb.ClassifyName = req.ClassifyName
+	classifyOb.Level = req.Level + 1
+	classifyOb.Sort = sortMax + 1
+	classifyOb.SysUserId = sysUser.AdminId
+	classifyOb.SysUserRealName = sysUser.RealName
+	classifyOb.UniqueCode = utils.MD5(classifyOb.TableName() + "_" + timestamp)
+	classifyOb.CreateTime = time.Now().Local()
+	classifyOb.ModifyTime = time.Now().Local()
+	if e = classifyOb.Create(); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("新增分类失败, %v", e)
+		return
+	}
+	if req.ParentId > 0 {
+		// 用英文逗号拼接方便查询
+		classifyOb.LevelPath = fmt.Sprintf("%s,%d", levelPath, classifyOb.BaseFromRadishResearchClassifyId)
+		classifyOb.RootId = rootId
+	} else {
+		classifyOb.LevelPath = fmt.Sprint(classifyOb.BaseFromRadishResearchClassifyId)
+		classifyOb.RootId = classifyOb.BaseFromRadishResearchClassifyId
+	}
+	if e = classifyOb.Update([]string{classifyOb.Cols().LevelPath, classifyOb.Cols().RootId}); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
+		return
+	}
+
+	br.Data = classifyOb.BaseFromRadishResearchClassifyId
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// ClassifyEdit
+// @Title 编辑分类
+// @Description 编辑分类
+// @Param	request	body data_manage.RadishResearchClassifyEditReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /radish_research/classify/edit [post]
+func (this *BaseFromRadishResearchController) ClassifyEdit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req data_manage.RadishResearchClassifyEditReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.ClassifyId < 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+	req.ClassifyName = strings.TrimSpace(req.ClassifyName)
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+
+	classifyOb := new(data_manage.BaseFromRadishResearchClassify)
+	classifyItem, e := classifyOb.GetItemById(req.ClassifyId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Msg = "分类不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
+		return
+	}
+	if classifyItem != nil && classifyItem.BaseFromRadishResearchClassifyId <= 0 {
+		br.Msg = "分类不存在, 请刷新页面"
+		return
+	}
+
+	// 校验分类名称
+	{
+		cond := fmt.Sprintf(" AND %s <> ? AND %s = ?", classifyOb.Cols().PrimaryId, classifyOb.Cols().ClassifyName)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.ClassifyId, req.ClassifyName)
+		count, e := classifyOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取分类名称重复数失败, %v", e)
+			return
+		}
+		if count > 0 {
+			br.Msg = "分类名称已存在"
+			return
+		}
+	}
+	classifyItem.ClassifyName = req.ClassifyName
+	classifyItem.ModifyTime = time.Now().Local()
+	updateCols := []string{classifyOb.Cols().ClassifyName, classifyOb.Cols().ModifyTime}
+	if e = classifyItem.Update(updateCols); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("更新分类失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// ClassifyRemove
+// @Title 删除分类
+// @Description 删除分类
+// @Param	request	body data_manage.RadishResearchClassifyRemoveReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /radish_research/classify/remove [post]
+func (this *BaseFromRadishResearchController) ClassifyRemove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req data_manage.RadishResearchClassifyRemoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.ClassifyId < 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	classifyOb := new(data_manage.BaseFromRadishResearchClassify)
+	classifyItem, e := classifyOb.GetItemById(req.ClassifyId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "操作成功"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
+		return
+	}
+	if classifyItem != nil && classifyItem.BaseFromRadishResearchClassifyId <= 0 {
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "操作成功"
+		return
+	}
+
+	// 查询子分类
+	{
+		cond := fmt.Sprintf(" AND %s = ?", classifyOb.Cols().ParentId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.ClassifyId)
+		count, e := classifyOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取子分类数失败, %v", e)
+			return
+		}
+		if count > 0 {
+			br.Msg = "该分类下含有子分类, 不允许删除"
+			return
+		}
+	}
+
+	// 查询指标
+	indexOb := new(data_manage.BaseFromRadishResearchIndex)
+	{
+		cond := fmt.Sprintf(" AND %s = ?", indexOb.Cols().ClassifyId)
+		pars := make([]interface{}, 0)
+		pars = append(pars, req.ClassifyId)
+		count, e := indexOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("获取分类下指标数失败, %v", e)
+			return
+		}
+		if count > 0 {
+			br.Msg = "该分类下含有指标, 不允许删除"
+			return
+		}
+	}
+
+	if e := classifyItem.Remove(); e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("删除分类失败, %v", e)
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// ClassifyMove
+// @Title 移动分类
+// @Description 移动分类
+// @Param	request	body data_manage.BaseFromRadishResearchClassifyMoveReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /radish_research/classify/move [post]
+func (this *BaseFromRadishResearchController) ClassifyMove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req data_manage.BaseFromRadishResearchClassifyMoveReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析异常, %v", e)
+		return
+	}
+	if req.ClassifyId <= 0 && req.ItemId <= 0 {
+		br.Msg = "请选择分类或指标"
+		return
+	}
+
+	err, errMsg := data.RadishResearchMoveClassify(req, sysUser)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 1 - 1
controllers/data_manage/base_from_rzd_index_controller.go

@@ -580,7 +580,7 @@ func (this *BaseFromRzdIndexController) RzdIndexDataExport() {
 
 			var dataList []*data_manage.BaseFromRzdData
 			dataList, err = data_manage.GetBaseFormRzdDataByIndexCode(v.IndexCode)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.ErrMsg = "GetBaseFormRzdDataByIndexCode,Err:" + err.Error()
 				br.Msg = "获取数据失败"
 				return

+ 105 - 75
controllers/data_manage/base_from_ths_hf.go

@@ -5,8 +5,10 @@ import (
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
+	dataSourceModel "eta/eta_api/models/data_source"
 	"eta/eta_api/models/mgo"
 	"eta/eta_api/services/data"
+	"eta/eta_api/services/elastic"
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
@@ -296,6 +298,7 @@ func (this *BaseFromThsHfController) List() {
 		br.ErrMsg = fmt.Sprintf("参数有误, SortType: %d", params.SortType)
 		return
 	}
+	params.Keywords = strings.TrimSpace(params.Keywords)
 	resp := new(data_manage.ThsHfIndexPageListResp)
 	resp.List = make([]*data_manage.BaseFromThsHfIndexItem, 0)
 
@@ -316,18 +319,30 @@ func (this *BaseFromThsHfController) List() {
 		//classifies = list
 	}
 
+	// 分页查询
+	var startSize int
+	if params.PageSize <= 0 {
+		params.PageSize = utils.PageSize20
+	}
+	if params.CurrentIndex <= 0 {
+		params.CurrentIndex = 1
+	}
+	startSize = utils.StartIndex(params.CurrentIndex, params.PageSize)
+
 	// 筛选项
 	var (
-		cond      string
-		pars      []interface{}
-		listOrder string
+		cond         string
+		pars         []interface{}
+		listOrder    string
+		classifyIds  []int
+		adminIds     []int
+		frequencyArr []string
 	)
 	indexOb := new(data_manage.BaseFromThsHfIndex)
 	{
 		// 分类
 		if params.ClassifyId != "" {
 			classifyIdArr := strings.Split(params.ClassifyId, ",")
-			classifyIds := make([]int, 0)
 			for _, v := range classifyIdArr {
 				t, _ := strconv.Atoi(v)
 				if t > 0 {
@@ -344,65 +359,23 @@ func (this *BaseFromThsHfController) List() {
 			}
 			cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().BaseFromThsHfClassifyId, utils.GetOrmInReplace(len(classifyIds)))
 			pars = append(pars, classifyIds)
-
-			//// 不包含子分类
-			//if len(classifyIds) > 0 && !params.IncludeChild {
-			//	cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().BaseFromThsHfClassifyId, utils.GetOrmInReplace(len(classifyIds)))
-			//	pars = append(pars, classifyIds)
-			//}
-			//
-			//// 包含子分类
-			//if len(classifyIds) > 0 && params.IncludeChild {
-			//	queryClassifyIds := make([]int, 0)
-			//	queryClassifyExist := make(map[int]bool)
-			//
-			//	for _, v := range classifyIds {
-			//		// 遍历所有分类从LevelPath中找含有查询分类ID的...=_=!
-			//		for _, cv := range classifies {
-			//			if queryClassifyExist[cv.BaseFromThsHfClassifyId] {
-			//				continue
-			//			}
-			//			if cv.LevelPath == "" {
-			//				continue
-			//			}
-			//			strArr := strings.Split(cv.LevelPath, ",")
-			//			if len(strArr) == 0 {
-			//				continue
-			//			}
-			//			for _, sv := range strArr {
-			//				tv, _ := strconv.Atoi(sv)
-			//				if tv == v {
-			//					queryClassifyIds = append(queryClassifyIds, cv.BaseFromThsHfClassifyId)
-			//					queryClassifyExist[cv.BaseFromThsHfClassifyId] = true
-			//					break
-			//				}
-			//			}
-			//		}
-			//	}
-			//
-			//	if len(queryClassifyIds) == 0 {
-			//		page := paging.GetPaging(params.CurrentIndex, params.PageSize, 0)
-			//		resp.Paging = page
-			//		br.Ret = 200
-			//		br.Success = true
-			//		br.Msg = "获取成功"
-			//		return
-			//	}
-			//	cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().BaseFromThsHfClassifyId, utils.GetOrmInReplace(len(queryClassifyIds)))
-			//	pars = append(pars, queryClassifyIds)
-			//}
 		}
 
 		if params.Frequency != "" {
-			frequencyArr := strings.Split(params.Frequency, ",")
-			if len(frequencyArr) > 0 {
-				cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().Frequency, utils.GetOrmInReplace(len(frequencyArr)))
-				pars = append(pars, frequencyArr)
+			frequencyArr = strings.Split(params.Frequency, ",")
+			if len(frequencyArr) == 0 {
+				page := paging.GetPaging(params.CurrentIndex, params.PageSize, 0)
+				resp.Paging = page
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
 			}
+			cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().Frequency, utils.GetOrmInReplace(len(frequencyArr)))
+			pars = append(pars, frequencyArr)
 		}
 		if params.SysAdminId != "" {
 			adminIdArr := strings.Split(params.SysAdminId, ",")
-			adminIds := make([]int, 0)
 			for _, v := range adminIdArr {
 				t, _ := strconv.Atoi(v)
 				if t > 0 {
@@ -410,15 +383,60 @@ func (this *BaseFromThsHfController) List() {
 				}
 			}
 			if len(adminIds) > 0 {
-				cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().SysUserId, utils.GetOrmInReplace(len(adminIds)))
-				pars = append(pars, adminIds)
+				page := paging.GetPaging(params.CurrentIndex, params.PageSize, 0)
+				resp.Paging = page
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
 			}
+			cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().SysUserId, utils.GetOrmInReplace(len(adminIds)))
+			pars = append(pars, adminIds)
 		}
-		params.Keywords = strings.TrimSpace(params.Keywords)
+
+		// 关键词空格拆分
 		if params.Keywords != "" {
-			cond += fmt.Sprintf(" AND (%s LIKE ? OR %s LIKE ?)", indexOb.Cols().IndexCode, indexOb.Cols().IndexName)
-			kw := fmt.Sprint("%", params.Keywords, "%")
-			pars = append(pars, kw, kw)
+			indexCodeCol := indexOb.Cols().IndexCode
+			indexNameCol := indexOb.Cols().IndexName
+			keywordArr := strings.Split(params.Keywords, " ")
+			if len(keywordArr) > 1 {
+				sliceArr := make([]string, 0)
+				sliceArr = append(sliceArr, fmt.Sprintf(` %s LIKE ? OR %s LIKE ? `, indexCodeCol, indexNameCol))
+				pars = utils.GetLikeKeywordPars(pars, params.Keywords, 2)
+				for _, v := range keywordArr {
+					if v == ` ` || v == `` {
+						continue
+					}
+					sliceArr = append(sliceArr, fmt.Sprintf(` %s LIKE ? OR %s LIKE ? `, indexCodeCol, indexNameCol))
+					pars = utils.GetLikeKeywordPars(pars, v, 2)
+				}
+				cond += ` AND (` + strings.Join(sliceArr, " OR ") + `)`
+			} else {
+				cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, indexCodeCol, indexNameCol)
+				pars = utils.GetLikeKeywordPars(pars, params.Keywords, 2)
+			}
+
+			// ES关键词搜索
+			//_, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, params.Keywords, utils.DATA_SOURCE_THS, utils.DATA_SUB_SOURCE_HIGH_FREQUENCY, []int{}, []int{}, []string{}, startSize, params.PageSize)
+			//if e != nil {
+			//	br.Msg = "获取失败"
+			//	br.ErrMsg = fmt.Sprintf("ES-搜索高频数据指标失败, %v", e)
+			//	return
+			//}
+			//if len(list) == 0 {
+			//	page := paging.GetPaging(params.CurrentIndex, params.PageSize, 0)
+			//	resp.Paging = page
+			//	br.Ret = 200
+			//	br.Success = true
+			//	br.Msg = "获取成功"
+			//	return
+			//}
+			//var indexIds []int
+			//for _, v := range list {
+			//	indexIds = append(indexIds, v.PrimaryId)
+			//}
+			//cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().PrimaryId, utils.GetOrmInReplace(len(indexIds)))
+			//pars = append(pars, indexIds)
 		}
 
 		// 排序
@@ -446,15 +464,6 @@ func (this *BaseFromThsHfController) List() {
 		return
 	}
 
-	// 分页查询
-	var startSize int
-	if params.PageSize <= 0 {
-		params.PageSize = utils.PageSize20
-	}
-	if params.CurrentIndex <= 0 {
-		params.CurrentIndex = 1
-	}
-	startSize = utils.StartIndex(params.CurrentIndex, params.PageSize)
 	items, e := indexOb.GetPageItemsByCondition(cond, pars, []string{}, listOrder, startSize, params.PageSize)
 	if e != nil {
 		br.Msg = "获取失败"
@@ -719,7 +728,7 @@ func (this *BaseFromThsHfController) Edit() {
 	indexOb := new(data_manage.BaseFromThsHfIndex)
 	item, e := indexOb.GetItemById(params.IndexId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "指标不存在, 请刷新页面"
 			return
 		}
@@ -810,7 +819,7 @@ func (this *BaseFromThsHfController) Detail() {
 	indexOb := new(data_manage.BaseFromThsHfIndex)
 	item, e := indexOb.GetItemById(indexId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "指标不存在, 请刷新页面"
 			return
 		}
@@ -890,7 +899,7 @@ func (this *BaseFromThsHfController) Refresh() {
 	indexOb := new(data_manage.BaseFromThsHfIndex)
 	_, e := indexOb.GetItemById(params.IndexId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "指标不存在, 请刷新页面"
 			return
 		}
@@ -950,7 +959,7 @@ func (this *BaseFromThsHfController) Remove() {
 	indexOb := new(data_manage.BaseFromThsHfIndex)
 	item, e := indexOb.GetItemById(params.IndexId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Ret = 200
 			br.Success = true
 			br.Msg = "操作成功"
@@ -1004,6 +1013,27 @@ func (this *BaseFromThsHfController) Remove() {
 		}
 	}
 
+	// ES标记删除
+	go func() {
+		indexItem := new(dataSourceModel.SearchDataSource)
+		indexItem.PrimaryId = item.BaseFromThsHfIndexId
+		indexItem.IndexName = item.IndexName
+		indexItem.IndexCode = item.IndexCode
+		indexItem.ClassifyId = item.BaseFromThsHfClassifyId
+		indexItem.Source = utils.DATA_SOURCE_THS
+		indexItem.SubSource = utils.DATA_SUB_SOURCE_HIGH_FREQUENCY
+		indexItem.SourceName = "同花顺高频"
+		indexItem.IsDeleted = 1
+		indexItem.CreateTime = utils.TimeTransferString(utils.FormatDateTime, item.CreateTime)
+		indexItem.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, item.ModifyTime)
+
+		docId := fmt.Sprintf("%d-%d", indexItem.Source, indexItem.PrimaryId)
+		if e := elastic.EsAddOrEditDataSourceIndex(utils.EsDataSourceIndexName, docId, indexItem); e != nil {
+			utils.FileLog.Info("同花顺高频-标记删除es失败, %v", e)
+			return
+		}
+	}()
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "操作成功"

+ 2 - 2
controllers/data_manage/base_from_ths_hf_classify.go

@@ -301,7 +301,7 @@ func (this *BaseFromThsHfController) ClassifyEdit() {
 	classifyOb := new(data_manage.BaseFromThsHfClassify)
 	classifyItem, e := classifyOb.GetItemById(req.ClassifyId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "分类不存在, 请刷新页面"
 			return
 		}
@@ -382,7 +382,7 @@ func (this *BaseFromThsHfController) ClassifyRemove() {
 	classifyOb := new(data_manage.BaseFromThsHfClassify)
 	classifyItem, e := classifyOb.GetItemById(req.ClassifyId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Ret = 200
 			br.Success = true
 			br.Msg = "获取成功"

+ 78 - 15
controllers/data_manage/bloomberg_data.go

@@ -57,16 +57,70 @@ func (this *BloombergDataController) List() {
 		return
 	}
 
+	var startSize int
+	if params.PageSize <= 0 {
+		params.PageSize = utils.PageSize20
+	}
+	if params.CurrentIndex <= 0 {
+		params.CurrentIndex = 1
+	}
+	startSize = utils.StartIndex(params.CurrentIndex, params.PageSize)
+	dataResp := new(data_manage.BloombergSourceListResp)
+
 	cond := ``
 	pars := make([]interface{}, 0)
 	// 筛选项
 	{
 		params.Keywords = strings.TrimSpace(params.Keywords)
 		if params.Keywords != "" {
-			cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, data_manage.BaseFromBloombergIndexCols.IndexCode, data_manage.BaseFromBloombergIndexCols.IndexName)
-			kw := fmt.Sprint("%", params.Keywords, "%")
-			pars = append(pars, kw, kw)
+			// 空格分词搜
+			indexCodeCol := data_manage.BaseFromBloombergIndexCols.IndexCode
+			indexNameCol := data_manage.BaseFromBloombergIndexCols.IndexName
+			//keywordArr := strings.Split(params.Keywords, " ")
+			//if len(keywordArr) > 1 {
+			//	sliceArr := make([]string, 0)
+			//	sliceArr = append(sliceArr, fmt.Sprintf(` %s LIKE ? OR %s LIKE ? `, indexCodeCol, indexNameCol))
+			//	pars = utils.GetLikeKeywordPars(pars, params.Keywords, 2)
+			//
+			//	for _, v := range keywordArr {
+			//		if v == ` ` || v == `` {
+			//			continue
+			//		}
+			//		sliceArr = append(sliceArr, fmt.Sprintf(` %s LIKE ? OR %s LIKE ? `, indexCodeCol, indexNameCol))
+			//		pars = utils.GetLikeKeywordPars(pars, v, 2)
+			//	}
+			//	cond += ` AND (` + strings.Join(sliceArr, " OR ") + `)`
+			//} else {
+			//	cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, indexCodeCol, indexNameCol)
+			//	pars = utils.GetLikeKeywordPars(pars, params.Keywords, 2)
+			//}
+			cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, indexCodeCol, indexNameCol)
+			pars = utils.GetLikeKeywordPars(pars, params.Keywords, 2)
+
+			// ES搜
+			//_, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, params.Keywords, utils.DATA_SOURCE_BLOOMBERG, 0, []int{}, []int{}, []string{}, startSize, params.PageSize)
+			//if e != nil {
+			//	br.Msg = "获取失败"
+			//	br.ErrMsg = fmt.Sprintf("ES-搜索Bloomberg指标失败, %v", e)
+			//	return
+			//}
+			//if len(list) == 0 {
+			//	dataResp.Paging = paging.GetPaging(params.CurrentIndex, params.PageSize, 0)
+			//	dataResp.List = make([]*data_manage.BaseFromBloombergIndexItem, 0)
+			//	br.Data = dataResp
+			//	br.Ret = 200
+			//	br.Success = true
+			//	br.Msg = "获取成功"
+			//	return
+			//}
+			//var indexIds []int
+			//for _, v := range list {
+			//	indexIds = append(indexIds, v.PrimaryId)
+			//}
+			//cond += fmt.Sprintf(" AND %s IN (%s)", data_manage.BaseFromBloombergIndexCols.BaseFromBloombergIndexId, utils.GetOrmInReplace(len(indexIds)))
+			//pars = append(pars, indexIds)
 		}
+
 		if params.Frequency != "" {
 			cond += fmt.Sprintf(` AND %s = ?`, data_manage.BaseFromBloombergIndexCols.Frequency)
 			pars = append(pars, params.Frequency)
@@ -81,14 +135,6 @@ func (this *BloombergDataController) List() {
 		br.ErrMsg = "获取Bloomberg原始指标列表总数失败, Err: " + e.Error()
 		return
 	}
-	var startSize int
-	if params.PageSize <= 0 {
-		params.PageSize = utils.PageSize20
-	}
-	if params.CurrentIndex <= 0 {
-		params.CurrentIndex = 1
-	}
-	startSize = utils.StartIndex(params.CurrentIndex, params.PageSize)
 
 	// 排序, 默认创建时间倒序
 	orderFields := map[int]string{
@@ -143,7 +189,6 @@ func (this *BloombergDataController) List() {
 		respList = append(respList, t)
 	}
 	page := paging.GetPaging(params.CurrentIndex, params.PageSize, total)
-	dataResp := new(data_manage.BloombergSourceListResp)
 	dataResp.Paging = page
 	dataResp.List = respList
 
@@ -479,9 +524,27 @@ func (this *BloombergDataController) AddCheck() {
 	// 筛选项
 	req.Keywords = strings.TrimSpace(req.Keywords)
 	if req.Keywords != "" {
-		cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, data_manage.BaseFromBloombergIndexCols.IndexCode, data_manage.BaseFromBloombergIndexCols.IndexName)
-		kw := fmt.Sprint("%", req.Keywords, "%")
-		pars = append(pars, kw, kw)
+		// 空格分词搜
+		indexCodeCol := data_manage.BaseFromBloombergIndexCols.IndexCode
+		indexNameCol := data_manage.BaseFromBloombergIndexCols.IndexName
+		keywordArr := strings.Split(req.Keywords, " ")
+		if len(keywordArr) > 1 {
+			sliceArr := make([]string, 0)
+			sliceArr = append(sliceArr, fmt.Sprintf(` %s LIKE ? OR %s LIKE ? `, indexCodeCol, indexNameCol))
+			pars = utils.GetLikeKeywordPars(pars, req.Keywords, 2)
+
+			for _, v := range keywordArr {
+				if v == ` ` || v == `` {
+					continue
+				}
+				sliceArr = append(sliceArr, fmt.Sprintf(` %s LIKE ? OR %s LIKE ? `, indexCodeCol, indexNameCol))
+				pars = utils.GetLikeKeywordPars(pars, v, 2)
+			}
+			cond += ` AND (` + strings.Join(sliceArr, " OR ") + `)`
+		} else {
+			cond += fmt.Sprintf(` AND (%s LIKE ? OR %s LIKE ?)`, indexCodeCol, indexNameCol)
+			pars = utils.GetLikeKeywordPars(pars, req.Keywords, 2)
+		}
 	}
 	if req.Frequency != "" {
 		cond += fmt.Sprintf(` AND %s = ?`, data_manage.BaseFromBloombergIndexCols.Frequency)

+ 45 - 19
controllers/data_manage/business_data.go

@@ -8,6 +8,7 @@ import (
 	"eta/eta_api/models/data_manage/request"
 	"eta/eta_api/models/system"
 	"eta/eta_api/services/data"
+	"eta/eta_api/services/elastic"
 	etaTrialService "eta/eta_api/services/eta_trial"
 	"eta/eta_api/utils"
 	"fmt"
@@ -37,7 +38,7 @@ func (c *EdbBusinessController) SourceList() {
 
 	obj := data_manage.EdbBusinessSource{}
 	list, err := obj.GetAllList()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -90,26 +91,51 @@ func (c *EdbBusinessController) List() {
 	var condition string
 	var pars []interface{}
 
+	keywords = strings.TrimSpace(keywords)
 	if keywords != "" {
-		keywordSlice := strings.Split(keywords, " ")
-		if len(keywordSlice) > 0 {
-			tmpConditionSlice := make([]string, 0)
-			tmpConditionSlice = append(tmpConditionSlice, ` a.index_name like ? or a.index_code like ? `)
-			pars = utils.GetLikeKeywordPars(pars, keywords, 2)
-
-			for _, v := range keywordSlice {
-				if v == ` ` || v == `` {
-					continue
-				}
-				tmpConditionSlice = append(tmpConditionSlice, ` a.index_name like ? or a.index_code like ? `)
-				pars = utils.GetLikeKeywordPars(pars, v, 2)
+		//keywordSlice := strings.Split(keywords, " ")
+		//if len(keywordSlice) > 0 {
+		//	tmpConditionSlice := make([]string, 0)
+		//	tmpConditionSlice = append(tmpConditionSlice, ` a.index_name like ? or a.index_code like ? `)
+		//	pars = utils.GetLikeKeywordPars(pars, keywords, 2)
+		//
+		//	for _, v := range keywordSlice {
+		//		if v == ` ` || v == `` {
+		//			continue
+		//		}
+		//		tmpConditionSlice = append(tmpConditionSlice, ` a.index_name like ? or a.index_code like ? `)
+		//		pars = utils.GetLikeKeywordPars(pars, v, 2)
+		//	}
+		//	condition += ` AND (` + strings.Join(tmpConditionSlice, " or ") + `)`
+		//
+		//} else {
+		//	condition += ` a.index_name like ? or a.index_code like ? `
+		//	pars = utils.GetLikeKeywordPars(pars, keywords, 2)
+		//}
+
+		// ES搜
+		_, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keywords, utils.DATA_SOURCE_BUSINESS, 0, []int{}, []int{}, []string{}, startSize, req.PageSize)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("ES-搜索自有数据指标失败, %v", e)
+			return
+		}
+		if len(list) == 0 {
+			br.Data = data_manage.BusinessIndexListResp{
+				List:   make([]*data_manage.BaseFromBusinessIndexItem, 0),
+				Paging: paging.GetPaging(req.CurrentIndex, req.PageSize, 0),
 			}
-			condition += ` AND (` + strings.Join(tmpConditionSlice, " or ") + `)`
-
-		} else {
-			condition += ` a.index_name like ? or a.index_code like ? `
-			pars = utils.GetLikeKeywordPars(pars, keywords, 2)
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "获取成功"
+			return
+		}
+		var indexIds []int
+		for _, v := range list {
+			indexIds = append(indexIds, v.PrimaryId)
 		}
+		condition += fmt.Sprintf(" AND a.base_from_business_index_id IN (%s)", utils.GetOrmInReplace(len(indexIds)))
+		pars = append(pars, indexIds)
 	}
 
 	if frequency != "" {
@@ -574,7 +600,7 @@ func (c *EdbBusinessController) DataList() {
 
 	// 获取分页数据
 	dataCount, dataList, err := data.GetPageBaseBusinessIndexData(req.IndexCode, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return

+ 11 - 3
controllers/data_manage/ccf_data.go

@@ -327,9 +327,17 @@ func (this *EdbInfoController) CCFSingleData() {
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
+	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_CCF, indexCode)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取指标库信息失败"
+		br.ErrMsg = "获取数据源失败,Err:" + err.Error()
+		return
+	}
 	var ret data_manage.CCFSingleDataResp
 	var dataList []*data_manage.CCFSingleData
-
+	if edbInfo != nil {
+		ret.EdbInfoId = edbInfo.EdbInfoId
+	}
 	ret.ClassifyId = indexInfo.ClassifyId
 	ret.BaseFromCcfIndexId = indexInfo.BaseFromCcfIndexId
 	ret.IndexCode = indexInfo.IndexCode
@@ -751,7 +759,7 @@ func (this *EdbInfoController) CCFStockTable() {
 	// 若无tableDate默认取最近的有数据的表格
 	item, e := excelOb.GetItemByCondition(cond, pars, fmt.Sprintf("%s DESC", excelOb.Cols().ExcelDate))
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Ret = 200
 			br.Success = true
 			br.Msg = "该日期暂无数据"
@@ -1075,7 +1083,7 @@ func (this *EdbInfoController) CCFIndexNameCheck() {
 			EdbName: v.EdbName,
 		})
 		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_CCF, 0, utils.EDB_DATA_LIMIT)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
 			return

+ 429 - 177
controllers/data_manage/chart_classify.go

@@ -8,11 +8,18 @@ import (
 	"eta/eta_api/models/system"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
+	"eta/eta_api/services/eta_forum"
 	"eta/eta_api/utils"
 	"fmt"
 	"time"
 )
 
+const (
+	CHART_CLASSIFY_ADD_OR_EDIT = "chartLib:classifyOpt:add"
+	CHART_CLASSIFY_DELETE      = "chartLib:classifyOpt:delete"
+	CHART_CLASSIFY_MOVE        = "chartLib:classifyOpt:move"
+)
+
 // 数据管理-分类模块
 type ChartClassifyController struct {
 	controllers.BaseAuthController
@@ -76,7 +83,7 @@ func (this *ChartClassifyController) ChartClassifyListV2() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -129,21 +136,21 @@ func (this *ChartClassifyController) ChartClassifyListV2() {
 	}
 
 	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	allChartInfo, err := data_manage.GetChartInfoAll([]int{utils.CHART_SOURCE_DEFAULT})
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
@@ -202,19 +209,19 @@ 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)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	allChartInfo, err := data_manage.GetChartInfoByAdminId([]int{utils.CHART_SOURCE_DEFAULT}, adminInfo.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
@@ -375,7 +382,7 @@ func (this *ChartClassifyController) AddChartClassify() {
 	}
 
 	// 新增图表分类
-	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_DEFAULT, this.Lang, this.SysUser)
+	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_DEFAULT, req.IsSelected, this.Lang, this.SysUser)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = "添加分类失败,Err:" + err.Error()
@@ -420,18 +427,35 @@ func (this *ChartClassifyController) EditChartClassify() {
 	}
 
 	// 编辑图表分类
-	_, err, errMsg, isSendEmail := data.EditChartClassifyV2(req.ChartClassifyId, req.ParentId, utils.CHART_SOURCE_DEFAULT, req.ChartClassifyName, this.Lang)
+	classifyInfo, isDeleteForumChart, tipCode, err, errMsg, isSendEmail := data.EditChartClassifyV2(req.ChartClassifyId, req.ParentId, utils.CHART_SOURCE_DEFAULT, req.ChartClassifyName, req.IsSelected, this.Lang)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = "保存分类失败,Err:" + err.Error()
 		br.IsSendEmail = isSendEmail
 		return
 	}
+	var ret data_manage.EditChartClassifyResp
+	if tipCode != "" {
+		br.Ret = 200
+		br.Msg = "该分类下存在已上架的图表,请先将图表从资源库下架,再关闭该精选资源分类。"
+		ret.TipCode = tipCode
+		ret.TipMsg = "该分类下存在已上架的图表,请先将图表从资源库下架,再关闭该精选资源分类。"
+		br.IsSendEmail = false
+		br.Success = true
+		br.Data = ret
+		return
+	}
+
+	// 移除精选后,删除所有的图表
+	if isDeleteForumChart {
+		go eta_forum.ChartInfoDeleteBatch(classifyInfo, this.SysUser)
+	}
 
 	br.Ret = 200
 	br.Msg = "保存成功"
 	br.Success = true
 	br.IsAddLog = true
+	br.Data = ret
 }
 
 // @Title 删除图表检测接口
@@ -503,7 +527,7 @@ func (this *ChartClassifyController) DeleteChartClassifyCheck() {
 
 	if deleteStatus != 1 && req.ChartInfoId == 0 {
 		classifyCount, err := data_manage.GetChartClassifyCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
 			return
@@ -517,6 +541,24 @@ func (this *ChartClassifyController) DeleteChartClassifyCheck() {
 		tipsMsg = "可删除,进行删除操作"
 	}
 
+	if req.ChartInfoId > 0 {
+		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				br.Msg = "图表已删除,请刷新页面"
+				br.ErrMsg = "指标不存在,Err:" + err.Error()
+				return
+			}
+			br.Msg = "删除失败"
+			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+			return
+		}
+		if chartInfo.ForumChartInfoId > 0 {
+			deleteStatus = 3
+			tipsMsg = "删除后,该图表将从ETA投研资源库同步删除,影响客户的查看权限,是否确认删除?"
+		}
+	}
+
 	resp := new(data_manage.ChartClassifyDeleteCheckResp)
 	resp.DeleteStatus = deleteStatus
 	resp.TipsMsg = tipsMsg
@@ -590,7 +632,7 @@ func (this *ChartClassifyController) DeleteChartClassify() {
 
 		//判断是否含有指标
 		count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -608,13 +650,15 @@ func (this *ChartClassifyController) DeleteChartClassify() {
 			br.ErrMsg = "删除失败,Err:" + err.Error()
 			return
 		}
+
+		go eta_forum.ChartClassifySaveBatch(item.Source)
 	}
 	resp := new(data_manage.AddChartInfoResp)
 	//删除图表
 	if req.ChartInfoId > 0 {
 		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -693,6 +737,10 @@ func (this *ChartClassifyController) DeleteChartClassify() {
 			// 删除MY ETA 图表 es数据
 			//go data.EsDeleteMyChartInfoByChartInfoId(req.ChartInfoId)
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)
+			
+			if chartInfo.ForumChartInfoId > 0 {
+				go eta_forum.DeleteChartByForumChartInfoId(chartInfo.ForumChartInfoId)
+			}
 		}
 
 		var condition string
@@ -704,7 +752,7 @@ func (this *ChartClassifyController) DeleteChartClassify() {
 		pars = append(pars, req.ChartInfoId)
 
 		nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 			return
@@ -724,14 +772,14 @@ func (this *ChartClassifyController) DeleteChartClassify() {
 			pars = append(pars, chartInfo.ChartClassifyId)
 
 			classifyItem, err := data_manage.GetChartClassifyByCondition(condition, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
 				return
 			}
 			if classifyItem != nil {
 				nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 					return
@@ -789,7 +837,6 @@ func (this *ChartClassifyController) ChartClassifyMove() {
 		br.Ret = 408
 		return
 	}
-
 	var req data_manage.MoveChartClassifyReq
 	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
 	if err != nil {
@@ -797,141 +844,197 @@ func (this *ChartClassifyController) ChartClassifyMove() {
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
 		return
 	}
-
-	if req.ClassifyId <= 0 {
+	if req.ClassifyId <= 0 && req.ChartInfoId <= 0 {
 		br.Msg = "参数错误"
-		br.ErrMsg = "分类id小于等于0"
-		return
-	}
-	//判断分类是否存在
-	chartClassifyInfo, err := data_manage.GetChartClassifyById(req.ClassifyId)
-	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
-			br.Msg = "分类不存在,请刷新页面"
-			return
-		}
-		br.Msg = "移动失败"
-		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+		br.ErrMsg = "请选择拖动目标,分类目录或者指标"
 		return
 	}
 
-	// 校验移动的父级目录下是否有重名分类
-	exists, e := data_manage.GetChartClassifyByParentIdAndName(req.ParentClassifyId, chartClassifyInfo.ChartClassifyName, req.ClassifyId)
-	if e != nil && e.Error() != utils.ErrNoRow() {
-		br.Msg = "移动失败"
-		br.ErrMsg = "获取父级目录下的同名分类失败, Err: " + e.Error()
-		return
-	}
-	if exists != nil {
-		br.Msg = "移动失败,分类名称已存在"
-		return
-	}
-	// 已授权分类id
-	permissionClassifyIdList, err := data_manage_permission.GetUserChartClassifyPermissionList(this.SysUser.AdminId, chartClassifyInfo.ChartClassifyId)
-	if err != nil {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取已授权分类id数据失败,Err:" + err.Error()
-		return
-	}
-	// 权限校验
-	{
-		haveOperaAuth := data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(chartClassifyInfo.IsJoinPermission, chartClassifyInfo.ChartClassifyId, permissionClassifyIdList)
-
-		button := data.GetChartClassifyOpButton(this.SysUser, chartClassifyInfo.SysUserId, haveOperaAuth)
-		if !button.OpButton {
-			br.Msg = "无操作权限"
+	err, errMsg := data.MoveChartClassify(req, sysUser, utils.CHART_SOURCE_DEFAULT)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
 			br.IsSendEmail = false
-			return
 		}
-	}
-
-	if chartClassifyInfo.Source != utils.CHART_SOURCE_DEFAULT {
-		br.Msg = "分类异常"
-		br.ErrMsg = "分类异常,不是ETA图库的分类"
 		return
 	}
-	updateCol := make([]string, 0)
-
-	//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
-	if chartClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId != 0 {
-		parentChartClassifyInfo, err := data_manage.GetChartClassifyById(req.ParentClassifyId)
-		if err != nil {
-			br.Msg = "移动失败"
-			br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
-			return
-		}
-		chartClassifyInfo.ParentId = parentChartClassifyInfo.ChartClassifyId
-		chartClassifyInfo.Level = parentChartClassifyInfo.Level + 1
-		chartClassifyInfo.ModifyTime = time.Now()
-		updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
-	}
-
-	//如果有传入 上一个兄弟节点分类id
-	if req.PrevClassifyId > 0 {
-		//上一个兄弟节点
-		prevClassify, err := data_manage.GetChartClassifyById(req.PrevClassifyId)
-		if err != nil {
-			br.Msg = "移动失败"
-			br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
-			return
-		}
-
-		//如果是移动在两个兄弟节点之间
-		if req.NextClassifyId > 0 {
-			//下一个兄弟节点
-			nextClassify, err := data_manage.GetChartClassifyById(req.NextClassifyId)
-			if err != nil {
-				br.Msg = "移动失败"
-				br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
-				return
-			}
-			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
-			if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == chartClassifyInfo.Sort {
-				//变更兄弟节点的排序
-				updateSortStr := `sort + 2`
-				_ = data_manage.UpdateChartClassifySortByParentId(prevClassify.ParentId, prevClassify.ChartClassifyId, prevClassify.Sort, updateSortStr)
-			} else {
-				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
-				if nextClassify.Sort-prevClassify.Sort == 1 {
-					//变更兄弟节点的排序
-					updateSortStr := `sort + 1`
-					_ = data_manage.UpdateChartClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
-				}
-			}
-		}
-
-		chartClassifyInfo.Sort = prevClassify.Sort + 1
-		chartClassifyInfo.ModifyTime = time.Now()
-		updateCol = append(updateCol, "Sort", "ModifyTime")
-
-	} else {
-		firstClassify, err := data_manage.GetFirstChartClassifyByParentId(chartClassifyInfo.ParentId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
-			br.Msg = "移动失败"
-			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
-			return
-		}
-
-		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
-		if firstClassify != nil && firstClassify.Sort == 0 {
-			updateSortStr := ` sort + 1 `
-			_ = data_manage.UpdateChartClassifySortByParentId(firstClassify.ParentId, firstClassify.ChartClassifyId-1, 0, updateSortStr)
-		}
-
-		chartClassifyInfo.Sort = 0 //那就是排在第一位
-		chartClassifyInfo.ModifyTime = time.Now()
-		updateCol = append(updateCol, "Sort", "ModifyTime")
-	}
-
-	//更新
-	if len(updateCol) > 0 {
-		err = chartClassifyInfo.Update(updateCol)
-		if err != nil {
-			br.Msg = "移动失败"
-			br.ErrMsg = "修改失败,Err:" + err.Error()
-			return
-		}
-	}
+	// var req data_manage.MoveChartClassifyReq
+	// err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	// if err != nil {
+	// 	br.Msg = "参数解析异常!"
+	// 	br.ErrMsg = "参数解析失败,Err:" + err.Error()
+	// 	return
+	// }
+
+	// if req.ClassifyId <= 0 {
+	// 	br.Msg = "参数错误"
+	// 	br.ErrMsg = "分类id小于等于0"
+	// 	return
+	// }
+	// //判断分类是否存在
+	// chartClassifyInfo, err := data_manage.GetChartClassifyById(req.ClassifyId)
+	// if err != nil {
+	// 	if utils.IsErrNoRow(err) {
+	// 		br.Msg = "分类不存在,请刷新页面"
+	// 		return
+	// 	}
+	// 	br.Msg = "移动失败"
+	// 	br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+	// 	return
+	// }
+	// oldParentId := chartClassifyInfo.ParentId
+	// oldLevelPath := chartClassifyInfo.LevelPath
+	// oldSelected := chartClassifyInfo.IsSelected
+
+	// // 校验移动的父级目录下是否有重名分类
+	// exists, e := data_manage.GetChartClassifyByParentIdAndName(req.ParentClassifyId, chartClassifyInfo.ChartClassifyName, req.ClassifyId)
+	// if e != nil && !utils.IsErrNoRow(e) {
+	// 	br.Msg = "移动失败"
+	// 	br.ErrMsg = "获取父级目录下的同名分类失败, Err: " + e.Error()
+	// 	return
+	// }
+	// if exists != nil && exists.ChartClassifyId > 0 {
+	// 	br.Msg = "移动失败,分类名称已存在"
+	// 	return
+	// }
+	// // 已授权分类id
+	// permissionClassifyIdList, err := data_manage_permission.GetUserChartClassifyPermissionList(this.SysUser.AdminId, chartClassifyInfo.ChartClassifyId)
+	// if err != nil {
+	// 	br.Msg = "获取失败"
+	// 	br.ErrMsg = "获取已授权分类id数据失败,Err:" + err.Error()
+	// 	return
+	// }
+	// // 权限校验
+	// {
+	// 	haveOperaAuth := data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(chartClassifyInfo.IsJoinPermission, chartClassifyInfo.ChartClassifyId, permissionClassifyIdList)
+
+	// 	button := data.GetChartClassifyOpButton(this.SysUser, chartClassifyInfo.SysUserId, haveOperaAuth)
+	// 	if !button.OpButton {
+	// 		br.Msg = "无操作权限"
+	// 		br.IsSendEmail = false
+	// 		return
+	// 	}
+	// }
+
+	// if chartClassifyInfo.Source != utils.CHART_SOURCE_DEFAULT {
+	// 	br.Msg = "分类异常"
+	// 	br.ErrMsg = "分类异常,不是ETA图库的分类"
+	// 	return
+	// }
+	// updateCol := make([]string, 0)
+
+	// var parentChartClassifyInfo *data_manage.ChartClassify
+	// if req.ParentClassifyId > 0 {
+	// 	parentChartClassifyInfo, err = data_manage.GetChartClassifyById(req.ParentClassifyId)
+	// 	if err != nil {
+	// 		br.Msg = "移动失败"
+	// 		br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
+	// 		return
+	// 	}
+	// }
+	// //判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	// if chartClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId != 0 {
+	// 	if chartClassifyInfo.Level != parentChartClassifyInfo.Level+1 { //禁止层级调整
+	// 		br.Msg = "移动失败"
+	// 		br.ErrMsg = "不支持目录层级变更"
+	// 		return
+	// 	}
+	// 	chartClassifyInfo.ParentId = parentChartClassifyInfo.ChartClassifyId
+	// 	chartClassifyInfo.Level = parentChartClassifyInfo.Level + 1
+	// 	chartClassifyInfo.ModifyTime = time.Now()
+	// 	updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
+	// }else if chartClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId == 0 {
+	// 	br.Msg = "移动失败"
+	// 	br.ErrMsg = "不支持目录层级变更"
+	// 	return
+	// }
+
+	// //如果有传入 上一个兄弟节点分类id
+	// if req.PrevClassifyId > 0 {
+	// 	//上一个兄弟节点
+	// 	prevClassify, err := data_manage.GetChartClassifyById(req.PrevClassifyId)
+	// 	if err != nil {
+	// 		br.Msg = "移动失败"
+	// 		br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
+	// 		return
+	// 	}
+
+	// 	//如果是移动在两个兄弟节点之间
+	// 	if req.NextClassifyId > 0 {
+	// 		//下一个兄弟节点
+	// 		nextClassify, err := data_manage.GetChartClassifyById(req.NextClassifyId)
+	// 		if err != nil {
+	// 			br.Msg = "移动失败"
+	// 			br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
+	// 			return
+	// 		}
+	// 		//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+	// 		if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == chartClassifyInfo.Sort {
+	// 			//变更兄弟节点的排序
+	// 			updateSortStr := `sort + 2`
+	// 			_ = data_manage.UpdateChartClassifySortByParentId(prevClassify.ParentId, prevClassify.ChartClassifyId, prevClassify.Sort, updateSortStr)
+	// 		} else {
+	// 			//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+	// 			if nextClassify.Sort-prevClassify.Sort == 1 {
+	// 				//变更兄弟节点的排序
+	// 				updateSortStr := `sort + 1`
+	// 				_ = data_manage.UpdateChartClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
+	// 			}
+	// 		}
+	// 	}
+
+	// 	chartClassifyInfo.Sort = prevClassify.Sort + 1
+	// 	chartClassifyInfo.ModifyTime = time.Now()
+	// 	updateCol = append(updateCol, "Sort", "ModifyTime")
+
+	// } else {
+	// 	firstClassify, err := data_manage.GetFirstChartClassifyByParentId(chartClassifyInfo.ParentId)
+	// 	if err != nil && !utils.IsErrNoRow(err) {
+	// 		br.Msg = "移动失败"
+	// 		br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
+	// 		return
+	// 	}
+
+	// 	//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+	// 	if firstClassify != nil && firstClassify.Sort == 0 {
+	// 		updateSortStr := ` sort + 1 `
+	// 		_ = data_manage.UpdateChartClassifySortByParentId(firstClassify.ParentId, firstClassify.ChartClassifyId-1, 0, updateSortStr)
+	// 	}
+
+	// 	chartClassifyInfo.Sort = 0 //那就是排在第一位
+	// 	chartClassifyInfo.ModifyTime = time.Now()
+	// 	updateCol = append(updateCol, "Sort", "ModifyTime")
+	// }
+
+	// //更新
+	// if len(updateCol) > 0 {
+	// 	err = chartClassifyInfo.Update(updateCol)
+	// 	if err != nil {
+	// 		br.Msg = "移动失败"
+	// 		br.ErrMsg = "修改失败,Err:" + err.Error()
+	// 		return
+	// 	}
+	// }
+	// if oldParentId != req.ParentClassifyId {
+	// 	if err = data.UpdateChartClassifyLevelPathWithChildren(chartClassifyInfo, parentChartClassifyInfo, oldParentId, oldLevelPath); err != nil {
+	// 		br.Msg = "修改分类失败"
+	// 		br.ErrMsg = "更新分类level_path失败,Err:" + err.Error()
+	// 		return
+	// 	}
+	// }
+	// // 如果是精选目录,则需要同步到ETA资源库
+	// if chartClassifyInfo.Source == utils.CHART_SOURCE_DEFAULT {
+	// 	// 如果当前目录的精选标识发生变化,需要同步更新子目录的精选标识
+	// 	if err = data.UpdateChildClassifySelection(chartClassifyInfo, parentChartClassifyInfo, oldSelected); err != nil {
+	// 		br.Msg = "修改分类失败"
+	// 		br.ErrMsg = "更新子目录精选标识失败,Err:" + err.Error()
+	// 		return
+	// 	}
+	// 	go eta_forum.ChartClassifySaveBatch(chartClassifyInfo.Source)
+	// }
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "移动成功"
@@ -940,13 +1043,13 @@ func (this *ChartClassifyController) ChartClassifyMove() {
 // getChartClassifyListForMe 获取我创建的图表分类
 func getChartClassifyListForMeV2(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
 	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
@@ -1005,7 +1108,7 @@ func (this *ChartClassifyController) ChartClassifyChartListV2() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1018,7 +1121,7 @@ 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 && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取全部数据失败,Err:" + err.Error()
 			return
@@ -1036,7 +1139,7 @@ func (this *ChartClassifyController) ChartClassifyChartListV2() {
 	}
 
 	allChartInfo, err := data_manage.GetChartInfoAllByClassifyId(utils.CHART_SOURCE_DEFAULT, chartClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
@@ -1089,13 +1192,13 @@ func (this *ChartClassifyController) ChartClassifyChartListV3() {
 		br.Msg = "参数错误"
 		return
 	}
-
+	
 	// 获取当前账号的不可见指标
 	noPermissionChartIdMap := make(map[int]bool)
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1104,51 +1207,83 @@ func (this *ChartClassifyController) ChartClassifyChartListV3() {
 			noPermissionChartIdMap[v.ChartInfoId] = true
 		}
 	}
-
+	var allNodes []*data_manage.ChartClassifyItems
+	// 获取是否精选资源标识
+	isSelected, _ := this.GetInt("IsSelected")
+	if chartClassifyId > 0 {
+		chartClassifyInfo, err := data_manage.GetChartClassifyById(chartClassifyId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+			return
+		}
+		isSelected = chartClassifyInfo.IsSelected
+	}
 	isShowMe, _ := this.GetBool("IsShowMe")
 	if isShowMe {
-		allChartInfo, err := data_manage.GetChartClassifyAndInfoByParentIdForMe(chartClassifyId, sysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		allChartInfo, err := data_manage.GetChartClassifyAndInfoByParentIdForMe(chartClassifyId, sysUser.AdminId, isSelected)
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
 		}
 		// 移除没有权限的图表
-		allNodes := data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap, this.SysUser.AdminId)
+		allNodes = data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap, this.SysUser.AdminId)
 		allNodes, err = data.GetChartClassifyByIsMe(sysUser.AdminId, chartClassifyId, utils.CHART_SOURCE_DEFAULT, allNodes)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
 		}
-		resp.AllNodes = allNodes
-
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "获取成功"
-		br.Data = resp
-		fmt.Println("source my classify")
-		return
+		//resp.AllNodes = allNodes
+		//
+		//br.Ret = 200
+		//br.Success = true
+		//br.Msg = "获取成功"
+		//br.Data = resp
+		//fmt.Println("source my classify")
+		//return
+	} else {
+		allChartInfo, err := data_manage.GetChartClassifyAndInfoByParentId(chartClassifyId, isSelected)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取数据失败,Err:" + err.Error()
+			return
+		}
+		//allChartInfo, err := data_manage.GetChartInfoAllByClassifyId(utils.CHART_SOURCE_DEFAULT, chartClassifyId)
+		//if err != nil && err.Error() != utils.ErrNoRow() {
+		//	br.Msg = "获取失败"
+		//	br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		//	return
+		//}
+		// 移除没有权限的图表
+		allNodes = data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap, this.SysUser.AdminId)
 	}
-
-	allChartInfo, err := data_manage.GetChartClassifyAndInfoByParentId(chartClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	menulist, e := system.GetMenuButtonsByRoleId(this.SysUser.RoleId)
+	if e != nil {
 		br.Msg = "获取失败"
-		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		br.ErrMsg = "获取角色按钮权限失败, Err: " + e.Error()
 		return
 	}
-
-	//allChartInfo, err := data_manage.GetChartInfoAllByClassifyId(utils.CHART_SOURCE_DEFAULT, chartClassifyId)
-	//if err != nil && err.Error() != utils.ErrNoRow() {
-	//	br.Msg = "获取失败"
-	//	br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
-	//	return
-	//}
-	// 移除没有权限的图表
-	allNodes := data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap, this.SysUser.AdminId)
-
+	buttonList := make(map[string]int, 0)
+	for _, item := range menulist {
+		if item.MenuType == 1 {
+			buttonList[item.ButtonCode] = 1
+		}
+	}
+	var addOrEditRight, deleteRight, moveRight bool
+	if _, ok := buttonList[CHART_CLASSIFY_ADD_OR_EDIT]; ok {
+		addOrEditRight = true
+	}
+	if _, ok := buttonList[CHART_CLASSIFY_DELETE]; ok {
+		deleteRight = true
+	}
+	if _, ok := buttonList[CHART_CLASSIFY_MOVE]; ok {
+		moveRight = true
+	}
 	for k, item := range allNodes {
-		item.Button = data.GetChartOpButton(this.SysUser, item.SysUserId, item.HaveOperaAuth)
+		//item.Button = data.GetChartOpButton(this.SysUser, item.SysUserId, item.HaveOperaAuth)
+		item.Button = data.GetChartOpButtonV2(item.HaveOperaAuth, addOrEditRight, deleteRight, moveRight)
 		if item.ChartInfoId > 0 {
 			item.Button.AddButton = false
 			item.Button.OpButton = false
@@ -1167,3 +1302,120 @@ func (this *ChartClassifyController) ChartClassifyChartListV3() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+// SetChartClassifyResourceStatus
+// @Title 一键从资源库上架/下架
+// @Description 一键从资源库上架/下架
+// @Param   ChartClassifyId   query   bool  true       "图片分类id"
+// @Param   ResourceStatus   query   bool  true       "资源状态"
+// @Success 200 {object} models.BaseResponse
+// @router /chart_classify/resource_status [post]
+func (this *ChartClassifyController) SetChartClassifyResourceStatus() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req data_manage.SetChartClassifyResourceStatusReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	chartClassifyId := req.ChartClassifyId	
+	if chartClassifyId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	resourceStatus := req.ResourceStatus
+	if resourceStatus <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+
+	chartClassifyInfo, err := data_manage.GetChartClassifyById(chartClassifyId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+		return
+	}
+	if resourceStatus == utils.ChartClassifyResourceStatusDown {
+		errMsg, err := eta_forum.SetChartClassifyResourceStatusDown(chartClassifyInfo, this.SysUser)
+		if err != nil {
+			if errMsg != "" {
+				br.Msg = errMsg
+				br.ErrMsg = err.Error()
+				return
+			}
+			br.Msg = "操作失败"
+			br.ErrMsg = err.Error()
+			return
+		}
+	} else if resourceStatus == utils.ChartClassifyResourceStatusUp {
+		errMsg, err := eta_forum.SetChartClassifyResourceStatusUp(chartClassifyInfo, this.SysUser)
+		if err != nil {
+			if errMsg != "" {
+				br.Msg = errMsg
+				br.ErrMsg = err.Error()
+				return
+			}
+			br.Msg = "操作失败"
+			br.ErrMsg = err.Error()
+			return
+		}
+	}
+	
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+
+// 一键更新至资源库
+// @Title 一键更新至资源库
+// @Description 一键更新至资源库
+// @Param   ChartClassifyId   query   bool  true       "图片分类id"
+// @Success 200 {object} models.BaseResponse
+// @router /chart_classify/forum_chart/update [post]
+func (this *ChartClassifyController) UpdateChartClassifyResource() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req data_manage.ChartClassifyResourceUpdate
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	
+	chartClassifyInfo, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+		return
+	}
+	if chartClassifyInfo.Source != utils.CHART_SOURCE_DEFAULT {
+		br.Msg = "分类来源错误"
+		return
+	}
+	if chartClassifyInfo.IsSelected != utils.ChartClassifyIsSelected {
+		br.Msg = "该分类不是精选分类"
+		return
+	}
+
+	err = eta_forum.ChartBatchUpdateAndUpload(chartClassifyInfo, this.SysUser)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = err.Error()
+		return
+	}
+	
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 61 - 1
controllers/data_manage/chart_common.go

@@ -11,6 +11,7 @@ import (
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services"
 	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/excel"
@@ -54,7 +55,7 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	status := true
 	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			status = false
 		} else {
 			br.Msg = "获取失败"
@@ -351,3 +352,62 @@ func getBalanceChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoVie
 
 	return
 }
+
+// GeneralChartToken
+// @Title 根据图表唯一code生成token
+// @Description 根据编码获取图表详情接口
+// @Param   UniqueCode   query   string  true       "图表/表格唯一编码"
+// @Param   Source   query   string  true       "来源,枚举值:chart、table"
+// @Success 200 {object} data_manage.ChartInfoDetailFromUniqueCodeResp
+// @router /chart_info/common/general_token [get]
+func (this *ChartInfoController) GeneralChartToken() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	uniqueCode := this.GetString("UniqueCode")
+	if uniqueCode == "" {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误,uniqueCode is empty"
+		return
+	}
+	source := this.GetString("Source", "chart")
+
+	businessConf, err := models.GetBusinessConfByKey(models.BusinessConfIsOpenChartExpired)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取配置失败,Err:" + err.Error()
+		return
+	}
+
+	var token string
+	if businessConf.ConfVal == `true` {
+		// 缓存key
+		sourceType := source
+		if source == `table` {
+			sourceType = source
+		}
+		token, err = services.GeneralChartToken(sourceType, uniqueCode)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败"
+			return
+		}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = token
+
+	return
+}

+ 2 - 2
controllers/data_manage/chart_edb_config.go

@@ -148,7 +148,7 @@ func (this *EdbInfoController) ModifyNoPermissionAdmin() {
 	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
 	if err != nil {
 		br.Msg = "修改失败"
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "找不到该指标"
 			br.IsSendEmail = false
 		}
@@ -208,7 +208,7 @@ func (this *EdbInfoController) DelNoPermissionAdmin() {
 	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
 	if err != nil {
 		br.Msg = "删除失败"
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "找不到该指标"
 			br.IsSendEmail = false
 		}

+ 38 - 16
controllers/data_manage/chart_framework.go

@@ -9,6 +9,7 @@ import (
 	"eta/eta_api/services/data"
 	"eta/eta_api/utils"
 	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"strings"
 	"time"
 )
@@ -43,6 +44,9 @@ func (this *ChartFrameworkController) List() {
 		return
 	}
 
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
 	adminId, _ := this.GetInt("AdminId")
 	visibility, _ := this.GetInt("Visibility")
 	if visibility == 1 && adminId <= 0 {
@@ -68,19 +72,37 @@ func (this *ChartFrameworkController) List() {
 		pars = append(pars, visibilityArr[visibility])
 	}
 
+	var total, startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize15
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	t, e := frameworkOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取框架列表总数失败, Err: " + e.Error()
+		return
+	}
+	total = t
 	orderRule := `sort ASC, create_time DESC`
-	list, e := frameworkOb.GetItemsByCondition(cond, pars, []string{}, orderRule)
+	list, e := frameworkOb.GetPageItemsByCondition(cond, pars, []string{}, orderRule, startSize, pageSize)
 	if e != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取框架列表失败, Err: " + e.Error()
 		return
 	}
-	resp := make([]*data_manage.ChartFrameworkItem, 0)
+	resp := new(data_manage.ChartFrameworkListResp)
+	resp.List = make([]*data_manage.ChartFrameworkItem, 0)
 	for _, v := range list {
 		t := data_manage.FormatChartFramework2Item(v, make([]*data_manage.ChartFrameworkNodeItem, 0))
-		resp = append(resp, t)
+		resp.List = append(resp.List, t)
 	}
 
+	resp.Paging = paging.GetPaging(currentIndex, pageSize, total)
 	br.Data = resp
 	br.Ret = 200
 	br.Success = true
@@ -205,12 +227,12 @@ func (this *ChartFrameworkController) Add() {
 		pars := make([]interface{}, 0)
 		pars = append(pars, req.FrameworkName, sysUser.AdminId)
 		exist, e := ob.GetItemByCondition(cond, pars)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "操作失败"
 			br.ErrMsg = "获取重名框架失败, Err: " + e.Error()
 			return
 		}
-		if exist != nil {
+		if exist != nil && exist.ChartFrameworkId > 0 {
 			br.Msg = "框架名称已存在"
 			return
 		}
@@ -315,7 +337,7 @@ func (this *ChartFrameworkController) Edit() {
 	frameworkOb := new(data_manage.ChartFramework)
 	item, e := frameworkOb.GetItemById(req.ChartFrameworkId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "框架不存在, 请刷新页面"
 			return
 		}
@@ -331,12 +353,12 @@ func (this *ChartFrameworkController) Edit() {
 		pars := make([]interface{}, 0)
 		pars = append(pars, req.ChartFrameworkId, req.FrameworkName, sysUser.AdminId)
 		exist, e := ob.GetItemByCondition(cond, pars)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "操作失败"
 			br.ErrMsg = "获取重名框架失败, Err: " + e.Error()
 			return
 		}
-		if exist != nil {
+		if exist != nil && exist.ChartFrameworkId > 0 {
 			br.Msg = "框架名称已存在"
 			return
 		}
@@ -429,7 +451,7 @@ func (this *ChartFrameworkController) Remove() {
 	ob := new(data_manage.ChartFramework)
 	item, e := ob.GetItemById(req.ChartFrameworkId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Ret = 200
 			br.Success = true
 			br.Msg = "操作成功"
@@ -499,7 +521,7 @@ func (this *ChartFrameworkController) Rename() {
 	frameworkOb := new(data_manage.ChartFramework)
 	item, e := frameworkOb.GetItemById(req.ChartFrameworkId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "框架不存在, 请刷新页面"
 			return
 		}
@@ -515,12 +537,12 @@ func (this *ChartFrameworkController) Rename() {
 		pars := make([]interface{}, 0)
 		pars = append(pars, req.ChartFrameworkId, req.FrameworkName, sysUser.AdminId)
 		exist, e := ob.GetItemByCondition(cond, pars)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "操作失败"
 			br.ErrMsg = "获取重名框架失败, Err: " + e.Error()
 			return
 		}
-		if exist != nil {
+		if exist != nil && exist.ChartFrameworkId > 0 {
 			br.Msg = "框架名称已存在"
 			return
 		}
@@ -584,7 +606,7 @@ func (this *ChartFrameworkController) EditPublic() {
 	frameworkOb := new(data_manage.ChartFramework)
 	item, e := frameworkOb.GetItemById(req.ChartFrameworkId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "框架不存在, 请刷新页面"
 			return
 		}
@@ -651,7 +673,7 @@ func (this *ChartFrameworkController) Move() {
 	frameworkOb := new(data_manage.ChartFramework)
 	item, e := frameworkOb.GetItemById(req.ChartFrameworkId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "框架不存在, 请刷新页面"
 			return
 		}
@@ -698,7 +720,7 @@ func (this *ChartFrameworkController) Move() {
 		updateCols = append(updateCols, "Sort", "ModifyTime")
 	} else {
 		first, err := data_manage.GetFirstChartFramework(sysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "操作失败"
 			br.ErrMsg = "获取我的图库框架排首位的数据失败, Err:" + err.Error()
 			return
@@ -759,7 +781,7 @@ func (this *ChartFrameworkController) Detail() {
 	frameworkOb := new(data_manage.ChartFramework)
 	item, e := frameworkOb.GetItemById(frameworkId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "框架不存在, 请刷新页面"
 			return
 		}

+ 316 - 62
controllers/data_manage/chart_info.go

@@ -2,6 +2,7 @@ package data_manage
 
 import (
 	"encoding/json"
+	"errors"
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
@@ -10,6 +11,7 @@ import (
 	"eta/eta_api/services"
 	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
+	"eta/eta_api/services/data/area_graph"
 	"eta/eta_api/services/data/data_manage_permission"
 	"eta/eta_api/services/data/excel"
 	"eta/eta_api/services/eta_forum"
@@ -66,7 +68,7 @@ func (this *ChartInfoController) ChartInfoSave() {
 
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面!"
 			br.ErrMsg = "图表已被删除,请刷新页面,ChartInfoId:" + strconv.Itoa(req.ChartInfoId)
 			return
@@ -334,7 +336,7 @@ func (this *ChartInfoController) ChartEnInfoEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -357,7 +359,7 @@ func (this *ChartInfoController) ChartEnInfoEdit() {
 		edbInfoId := v.EdbInfoId
 		edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表不存在!"
 				br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId)
 				return
@@ -367,7 +369,7 @@ func (this *ChartInfoController) ChartEnInfoEdit() {
 				return
 			}
 		}
-		if edbInfo == nil {
+		if edbInfo == nil || edbInfo.EdbInfoId <= 0 {
 			br.Msg = "指标不存在!"
 			br.ErrMsg = "指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId)
 			return
@@ -389,7 +391,7 @@ func (this *ChartInfoController) ChartEnInfoEdit() {
 
 			edbExist, err := data_manage.GetEdbInfoByCondition(edbCondition, edbPars)
 			if err != nil {
-				if err.Error() != utils.ErrNoRow() {
+				if !utils.IsErrNoRow(err) {
 					br.Msg = "判断英文指标名称是否存在失败"
 					br.ErrMsg = "判断英文指标名称是否存在失败,Err:" + err.Error()
 					return
@@ -418,7 +420,7 @@ func (this *ChartInfoController) ChartEnInfoEdit() {
 
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return
@@ -447,7 +449,7 @@ func (this *ChartInfoController) ChartEnInfoEdit() {
 		edbInfoId := v.EdbInfoId
 		edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表不存在!"
 				br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId)
 				return
@@ -457,7 +459,7 @@ func (this *ChartInfoController) ChartEnInfoEdit() {
 				return
 			}
 		}
-		if edbInfo != nil {
+		if edbInfo != nil && edbInfo.EdbInfoId > 0 {
 			go data.AddOrEditEdbInfoToEs(edbInfoId)
 		}
 	}
@@ -526,7 +528,7 @@ func (this *ChartInfoController) ChartInfoBaseEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -549,7 +551,7 @@ func (this *ChartInfoController) ChartInfoBaseEdit() {
 		edbInfoId := v.EdbInfoId
 		edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表不存在!"
 				br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId)
 				return
@@ -584,7 +586,7 @@ func (this *ChartInfoController) ChartInfoBaseEdit() {
 
 			edbExist, err := data_manage.GetEdbInfoByCondition(edbCondition, edbPars)
 			if err != nil {
-				if err.Error() != utils.ErrNoRow() {
+				if !utils.IsErrNoRow(err) {
 					br.Msg = "判断英文指标名称是否存在失败"
 					br.ErrMsg = "判断英文指标名称是否存在失败,Err:" + err.Error()
 					return
@@ -616,7 +618,7 @@ func (this *ChartInfoController) ChartInfoBaseEdit() {
 
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return
@@ -645,7 +647,7 @@ func (this *ChartInfoController) ChartInfoBaseEdit() {
 		edbInfoId := v.EdbInfoId
 		edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表不存在!"
 				br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId)
 				return
@@ -655,7 +657,7 @@ func (this *ChartInfoController) ChartInfoBaseEdit() {
 				return
 			}
 		}
-		if edbInfo != nil {
+		if edbInfo != nil && edbInfo.EdbInfoId > 0 {
 			go data.AddOrEditEdbInfoToEs(edbInfoId)
 		}
 	}
@@ -698,7 +700,7 @@ func (this *ChartInfoController) ChartInfoNewest() {
 		this.ServeJSON()
 	}()
 	item, err := data_manage.GetChartInfoByNewest(1)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取最新图表失败"
 		br.ErrMsg = "获取最新图表失败,Err:" + err.Error()
 		return
@@ -781,17 +783,17 @@ func (this *ChartInfoController) ChartInfoMove() {
 			return
 		}
 	}
-
+	oldClassifyId := chartInfo.ChartClassifyId
 	//如果改变了分类,那么移动该图表数据
 	if chartInfo.ChartClassifyId != req.ChartClassifyId {
 		//查询需要修改的分类下是否存在同一个图表名称
 		tmpChartInfo, tmpErr := data_manage.GetChartInfoByClassifyIdAndName(req.ChartClassifyId, chartInfo.ChartName)
-		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "移动失败,Err:" + tmpErr.Error()
 			return
 		}
-		if tmpChartInfo != nil {
+		if tmpChartInfo != nil && tmpChartInfo.ChartInfoId > 0 {
 			br.Msg = "移动失败,同一个分类下图表名称不允许重复"
 			br.ErrMsg = "移动失败,同一个分类下图表名称不允许重复"
 			return
@@ -845,14 +847,14 @@ func (this *ChartInfoController) ChartInfoMove() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartInfoByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return
 		}
 
 		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
-		if firstClassify != nil && firstClassify.Sort == 0 {
+		if firstClassify != nil && firstClassify.ChartClassifyId > 0 && firstClassify.Sort == 0 {
 			updateSortStr := ` sort + 1 `
 			_ = data_manage.UpdateChartInfoSortByClassifyId(firstClassify.ChartClassifyId, 0, firstClassify.ChartInfoId-1, []int{chartInfo.Source}, updateSortStr)
 		}
@@ -872,6 +874,20 @@ func (this *ChartInfoController) ChartInfoMove() {
 		}
 		//添加es数据
 		go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+
+		// 判断是否为精选目录
+			// 如果该目录不是精选目录,且该图表已经上架,则需撤回该图表
+			if oldClassifyId != req.ChartClassifyId {
+				parentChartClassifyInfo, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
+				if err != nil {
+					br.Msg = "移动失败"
+					br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
+					return
+				}
+				if parentChartClassifyInfo.IsSelected == 0 && chartInfo.ForumChartInfoId > 0 {
+					go eta_forum.DeleteChart(chartInfo.ChartInfoId)
+				}
+			}
 	}
 
 	if err != nil {
@@ -959,7 +975,7 @@ func (this *ChartInfoController) ChartInfoDetail() {
 	if chartInfoId > 0 {
 		chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "该图表已删除,自动查看下一图表"
 				br.ErrMsg = "该图表已删除,自动查看下一图表,Err:" + err.Error()
 				br.Ret = 406
@@ -1028,7 +1044,7 @@ func (this *ChartInfoController) ChartInfoDetail() {
 	extraConfigStr := chartInfo.ExtraConfig
 	// 柱方图的一些配置
 	var barConfig data_manage.BarChartInfoReq
-	if chartInfo != nil && chartInfo.ChartType == 7 {
+	if chartInfo != nil && chartInfo.ChartInfoId > 0 && chartInfo.ChartType == 7 {
 		if chartInfo.BarConfig == `` {
 			br.Msg = "柱方图未配置"
 			br.ErrMsg = "柱方图未配置"
@@ -1058,6 +1074,10 @@ func (this *ChartInfoController) ChartInfoDetail() {
 			}
 		}
 	}
+	if chartType == utils.CHART_TYPE_SEASON && dateType == utils.DateTypeNYears {
+		// 季度图,的至今N年,需要特殊处理,将日期范围扩大到下一年
+		dateMax = time.Date(dateMax.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+	}
 	// 开始/结束日期
 	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, dateMax)
 
@@ -1124,7 +1144,7 @@ func (this *ChartInfoController) ChartInfoDetail() {
 		if len(warnEdbList) > 0 {
 			chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
 		}
-		if chartInfoId > 0 && chartInfo != nil {
+		if chartInfoId > 0 && chartInfo != nil && chartInfo.ChartInfoId > 0 {
 			//判断是否加入我的图库
 			{
 				var myChartCondition string
@@ -1135,7 +1155,7 @@ func (this *ChartInfoController) ChartInfoDetail() {
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "获取失败"
 					br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -1327,6 +1347,11 @@ func (this *ChartInfoController) PreviewChartInfoDetail() {
 		mappingList[k] = v
 	}
 
+	if req.ChartType == utils.CHART_TYPE_SEASON && req.DateType == utils.DateTypeNYears {
+		// 季节性图表,要特殊处理起始日期, 最近N年
+		dateMax = time.Date(dateMax.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+	}
+
 	// 开始/结束日期
 	startDate, endDate := utils.GetDateByDateTypeV2(req.DateType, req.StartDate, req.EndDate, req.StartYear, dateMax)
 	if startDate == "" {
@@ -1350,7 +1375,7 @@ func (this *ChartInfoController) PreviewChartInfoDetail() {
 	extraConfigStr := chartInfo.ExtraConfig
 	// 柱方图的一些配置
 	var barConfig data_manage.BarChartInfoReq
-	if chartInfo != nil && chartInfo.ChartType == 7 {
+	if chartInfo != nil && chartInfo.ChartInfoId > 0 && chartInfo.ChartType == 7 {
 		if chartInfo.BarConfig == `` {
 			br.Msg = "柱方图未配置"
 			br.ErrMsg = "柱方图未配置"
@@ -1363,7 +1388,9 @@ func (this *ChartInfoController) PreviewChartInfoDetail() {
 			return
 		}
 		extraConfigStr = chartInfo.BarConfig
-	} else if chartInfo != nil && chartInfo.ChartType == utils.CHART_TYPE_SECTION_COMBINE {
+	} else if chartInfo != nil && chartInfo.ChartInfoId > 0 && chartInfo.ChartType == utils.CHART_TYPE_SECTION_COMBINE {
+		extraConfigStr = req.ExtraConfig
+	} else if chartInfo != nil && chartInfo.ChartInfoId > 0 && chartInfo.ChartType == utils.CHART_TYPE_AREA {
 		extraConfigStr = req.ExtraConfig
 	}
 
@@ -1392,6 +1419,16 @@ func (this *ChartInfoController) PreviewChartInfoDetail() {
 		chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
 	}
 
+	// 面积图 面积堆积 数据处理
+	if req.ChartType == utils.CHART_TYPE_AREA {
+		err, errMsg = fillAreaGraphData(extraConfigStr, edbList)
+		if err != nil {
+			br.Msg = "面积图处理失败"
+			br.ErrMsg = errMsg
+			return
+		}
+	}
+
 	//图表操作权限
 	chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId, true)
 	//判断是否需要展示英文标识
@@ -1484,6 +1521,60 @@ func (this *ChartInfoController) PreviewChartInfoDetail() {
 	br.Data = resp
 }
 
+func fillAreaGraphData(extraConfigStr string, edbDataList []*data_manage.ChartEdbInfoMapping) (err error, errMsg string) {
+
+	var tmpConfig data_manage.AreaExtraConf
+	if extraConfigStr != `` {
+		err = json.Unmarshal([]byte(extraConfigStr), &tmpConfig)
+		if err != nil {
+			errMsg = "面积图配置异常"
+			err = errors.New(errMsg)
+			return
+		}
+		if tmpConfig.StandardEdbInfoId <= 0 {
+			utils.FileLog.Info("面积图未开启面积堆积")
+			return
+		}
+	}
+	if tmpConfig.IsHeap == 1 {
+		standardIndexMap := make(map[string]*data_manage.EdbDataList)
+		var startDate, endDate string
+		for _, v := range edbDataList {
+			// 判断是否为基准指标
+			if v.EdbInfoId == tmpConfig.StandardEdbInfoId {
+				if dataList, ok := v.DataList.([]*data_manage.EdbDataList); ok {
+					startDate = dataList[0].DataTime
+					endDate = dataList[len(dataList)-1].DataTime
+					for _, dataObject := range dataList {
+						standardIndexMap[dataObject.DataTime] = dataObject
+					}
+				}
+				break
+			}
+		}
+		strategy, err := area_graph.CreateStrategy(tmpConfig.NullDealWay)
+		if err != nil {
+			return err, "创建空值处理器失败"
+		}
+		err = strategy.Deal(tmpConfig, edbDataList, standardIndexMap, startDate, endDate)
+		if err != nil {
+			return err, err.Error()
+		}
+
+		// 时间戳处理
+		for _, mapping := range edbDataList {
+			if dataList, ok := mapping.DataList.([]*data_manage.EdbDataList); ok {
+				for _, dataInfo := range dataList {
+					toFormatTime := utils.StringToFormatTime(dataInfo.DataTime, utils.FormatDate)
+					dataInfo.DataTimestamp = toFormatTime.UnixMilli()
+				}
+			}
+		}
+	}
+
+	return nil, ""
+}
+
 // ChartInfoDetailV2
 // @Title 获取图表详情
 // @Description 获取图表详情接口
@@ -1512,7 +1603,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 	}
 	chartInfo, err := data_manage.GetChartInfoViewById(chartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "该图表已删除,自动查看下一图表"
 			br.ErrMsg = "该图表已删除,自动查看下一图表,Err:" + err.Error()
 			br.Ret = 406
@@ -1524,6 +1615,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 	}
 
 	resp := new(data_manage.ChartInfoDetailResp)
+	isSelected := 0
 	// 图表数据权限
 	{
 		// 图表分类
@@ -1533,7 +1625,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 			br.ErrMsg = "获取图表分类信息失败,Err:" + err.Error()
 			return
 		}
-
+		isSelected = chartClassify.IsSelected
 		// 已授权分类id
 		permissionChartIdList, permissionClassifyIdList, err := data_manage_permission.GetUserChartAndClassifyPermissionList(this.SysUser.AdminId, chartInfo.ChartInfoId, chartInfo.ChartClassifyId)
 		if err != nil {
@@ -1597,7 +1689,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 	var dateMax time.Time
 	if dateType == utils.DateTypeNYears {
 		for _, v := range mappingList {
-			if v.LatestDate != "" {
+			if v.LatestDate != "" && v.LatestDate != "0000-00-00" {
 				lastDateT, tErr := time.Parse(utils.FormatDate, v.LatestDate)
 				if tErr != nil {
 					br.Msg = "获取失败"
@@ -1610,6 +1702,9 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 			}
 		}
 	}
+	if dateType == utils.DateTypeNYears && chartInfo.ChartType == utils.CHART_TYPE_SEASON {
+		dateMax = time.Date(dateMax.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+	}
 	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, dateMax)
 
 	if chartInfo.ChartType == 2 {
@@ -1620,7 +1715,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 	extraConfigStr := chartInfo.ExtraConfig
 	// 柱方图的一些配置
 	var barConfig data_manage.BarChartInfoReq
-	if chartInfo != nil && chartInfo.ChartType == 7 {
+	if chartInfo != nil && chartInfo.ChartInfoId > 0 && chartInfo.ChartType == 7 {
 		if chartInfo.BarConfig == `` {
 			br.Msg = "柱方图未配置"
 			br.ErrMsg = "柱方图未配置"
@@ -1660,7 +1755,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 		if len(warnEdbList) > 0 {
 			chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
 		}
-		if chartInfoId > 0 && chartInfo != nil {
+		if chartInfoId > 0 && chartInfo != nil && chartInfo.ChartInfoId > 0 {
 			//判断是否加入我的图库
 			{
 				var myChartCondition string
@@ -1671,7 +1766,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "获取失败"
 					br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -1738,6 +1833,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 	}
 
 	// 图表当前分类的分类树
+	
 	classifyLevels := make([]string, 0)
 	{
 		list, e := data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_DEFAULT)
@@ -1756,6 +1852,7 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 	}
 
 	resp.ClassifyLevels = classifyLevels
+	resp.IsSelected = isSelected
 
 	//图表操作权限
 	chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId, chartInfo.HaveOperaAuth)
@@ -2104,7 +2201,7 @@ func (this *ChartInfoController) ChartInfoSearch() {
 	for _, v := range keyWordArr {
 		v = strings.Replace(v, " ", "%", -1)
 		newSearchList, err := data_manage.ChartInfoSearchByKeyWord(v, showSysId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -2215,7 +2312,7 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 		showSysId = sysUser.AdminId
 	}
 
-	var searchList []*data_manage.ChartInfo
+	var searchList []*data_manage.ChartInfoMore
 	var total int64
 	var err error
 
@@ -2224,7 +2321,7 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -2241,7 +2338,7 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 		isEs = true
 	} else {
 		total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, []int{utils.CHART_SOURCE_DEFAULT}, noPermissionChartIdList, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -2278,7 +2375,7 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 		}
 		// 当前列表中的分类map
 		chartClassifyMap := make(map[int]*data_manage.ChartClassify)
-
+		isSelectClassifyMap := make(map[int]bool)
 		// 图表分类
 		{
 			chartClassifyList, err := data_manage.GetChartClassifyByIdList(classifyIdList)
@@ -2289,6 +2386,9 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 			}
 			for _, v := range chartClassifyList {
 				chartClassifyMap[v.ChartClassifyId] = v
+				if v.IsSelected == 1 {
+					isSelectClassifyMap[v.ChartClassifyId] = true
+				}
 			}
 		}
 		// 图表
@@ -2324,7 +2424,7 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 
 		for _, v := range searchList {
 			tmp := new(data_manage.ChartInfoMore)
-			tmp.ChartInfo = *v
+			tmp.ChartInfo = v.ChartInfo
 			//判断是否需要展示英文标识
 			if edbTmpList, ok := chartEdbMap[v.ChartInfoId]; ok {
 				tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, edbTmpList, v.Source, v.ChartType)
@@ -2334,7 +2434,13 @@ func (this *ChartInfoController) ChartInfoSearchByEs() {
 			if currClassify, ok := chartClassifyMap[v.ChartClassifyId]; ok {
 				tmp.HaveOperaAuth = data_manage_permission.CheckChartPermissionByPermissionIdList(v.IsJoinPermission, currClassify.IsJoinPermission, v.ChartInfoId, v.ChartClassifyId, permissionChartIdList, permissionClassifyIdList)
 			}
-
+			tmp.SearchText = v.SearchText
+			if tmp.SearchText == "" {
+				tmp.SearchText = v.ChartName
+			}
+			if _, ok := isSelectClassifyMap[v.ChartClassifyId]; ok {
+				tmp.IsSelected = 1
+			}
 			finalList = append(finalList, tmp)
 		}
 	}
@@ -2392,7 +2498,7 @@ func (this *EdbInfoController) ChartInfoRefresh() {
 		chartInfo, err = data_manage.GetChartInfoByUniqueCode(uniqueCode)
 	}
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,无需刷新"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -2511,7 +2617,7 @@ func (this *ChartInfoController) ChartInfoDetailFromUniqueCode() {
 	status := true
 	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			status = false
 		} else {
 			br.Msg = "获取失败"
@@ -2581,7 +2687,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					msg = "获取失败"
 					errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -2750,12 +2856,16 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			}
 		}
 	}
+	if chartInfo.ChartType == utils.CHART_TYPE_SEASON && dateType == utils.DateTypeNYears {
+		// 季度图,的至今N年,需要特殊处理,将日期范围扩大到下一年
+		dateMax = time.Date(dateMax.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+	}
 	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, dateMax)
 
 	extraConfigStr := chartInfo.ExtraConfig //图表额外数据参数
 	var barConfig data_manage.BarChartInfoReq
 	// 柱方图的一些配置
-	if chartInfo != nil && chartInfo.ChartType == 7 {
+	if chartInfo != nil && chartInfo.ChartInfoId > 0 && chartInfo.ChartType == 7 {
 		if chartInfo.BarConfig == `` {
 			msg = "柱方图未配置"
 			errMsg = "柱方图未配置"
@@ -2801,11 +2911,22 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 	*/
 
 	chartViewClassify, _ := data_manage.GetChartClassifyViewById(chartInfo.ChartClassifyId)
-	if chartViewClassify != nil {
+	if chartViewClassify != nil && chartViewClassify.ChartClassifyId > 0 {
 		chartClassifyParent, _ := data_manage.GetChartClassifyViewById(chartClassify.ParentId)
 		chartInfo.ChartClassify = append(chartInfo.ChartClassify, chartClassifyParent)
 	}
 	chartInfo.ChartClassify = append(chartInfo.ChartClassify, chartViewClassify)
+
+	// 面积图 面积堆积 数据处理
+	if chartType == utils.CHART_TYPE_AREA {
+		err, errMsg = fillAreaGraphData(extraConfigStr, edbList)
+		if err != nil {
+			msg = "获取失败"
+			errMsg = "获取面积图数据失败,Err:" + err.Error()
+			return
+		}
+	}
+
 	resp.EdbInfoList = edbList
 	//判断是否需要展示英文标识
 	chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList, chartInfo.Source, chartInfo.ChartType)
@@ -3090,7 +3211,7 @@ func (this *ChartInfoController) CopyChartInfo() {
 	}
 	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			br.ErrMsg = "分类不存在"
 			return
@@ -3198,7 +3319,10 @@ func (this *ChartInfoController) CopyChartInfo() {
 	{
 		mapList := make([]*data_manage.ChartEdbMapping, 0)
 		for _, v := range edbMappingList {
+			// windows server环境这里得加个延时,不然生成时间戳都是一样的
+			time.Sleep(100 * time.Millisecond)
 			timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+			//utils.FileLog.Info("IndexCode: %s, UniqueCode: %s", v.EdbInfoId, utils.MD5(utils.CHART_PREFIX+"_"+timestamp))
 			mapItem := &data_manage.ChartEdbMapping{
 				//ChartEdbMappingId: 0,
 				ChartInfoId:   chartInfo.ChartInfoId,
@@ -3216,7 +3340,7 @@ func (this *ChartInfoController) CopyChartInfo() {
 				ChartStyle:    v.ChartStyle,
 				ChartColor:    v.ChartColor,
 				ChartWidth:    v.ChartWidth,
-				Source:        v.Source,
+				Source:        oldChartInfo.Source,
 				EdbAliasName:  v.EdbAliasName,
 				IsConvert:     v.IsConvert,
 				ConvertType:   v.ConvertType,
@@ -3753,10 +3877,6 @@ func (this *EdbInfoController) GetBatchChartRefreshResult() {
 //	fmt.Println("end")
 //}
 
-//func init() {
-//	data.AddAllChartInfo()
-//}
-
 // 截面散点示例数据
 //func init() {
 //
@@ -4062,7 +4182,7 @@ func (this *ChartInfoController) ChartInfoConvertDetail() {
 	if chartInfoId > 0 {
 		chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "该图表已删除,自动查看下一图表"
 				br.ErrMsg = "该图表已删除,自动查看下一图表,Err:" + err.Error()
 				br.Ret = 406
@@ -4150,7 +4270,7 @@ func (this *ChartInfoController) ChartInfoConvertDetail() {
 		extraConfigStr := chartInfo.ExtraConfig
 		// 柱方图的一些配置
 		var barConfig data_manage.BarChartInfoReq
-		if chartInfo != nil && chartInfo.ChartType == 7 {
+		if chartInfo != nil && chartInfo.ChartInfoId > 0 && chartInfo.ChartType == 7 {
 			if chartInfo.BarConfig == `` {
 				br.Msg = "柱方图未配置"
 				br.ErrMsg = "柱方图未配置"
@@ -4180,6 +4300,10 @@ func (this *ChartInfoController) ChartInfoConvertDetail() {
 				}
 			}
 		}
+		if chartType == utils.CHART_TYPE_SEASON && dateType == utils.DateTypeNYears {
+			// 季节性图,最近N年需要特殊处理
+			dateMax = time.Date(dateMax.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+		}
 		// 开始/结束日期
 		startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, dateMax)
 
@@ -4207,7 +4331,7 @@ func (this *ChartInfoController) ChartInfoConvertDetail() {
 		if len(warnEdbList) > 0 {
 			chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
 		}
-		if chartInfoId > 0 && chartInfo != nil {
+		if chartInfoId > 0 && chartInfo != nil && chartInfo.ChartInfoId > 0 {
 			//判断是否加入我的图库
 			{
 				var myChartCondition string
@@ -4218,7 +4342,7 @@ func (this *ChartInfoController) ChartInfoConvertDetail() {
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "获取失败"
 					br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -4348,6 +4472,9 @@ func (this *ChartInfoController) UpdateToForum() {
 		return
 	}
 
+	// 更新指标数据
+	utils.Rc.LPush(utils.CACHE_KEY_EDB_DATA_UPDATE_LOG, []byte("1"))
+	
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "保存成功"
@@ -4620,7 +4747,7 @@ func (this *ChartInfoController) ChartList() {
 	if len(chartClassifyIdsStr) > 0 {
 		if !subClassify {
 			chartClassifyId, err := data_manage.GetChartClassifyByIdsNoSubClassify(chartClassifyIds)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取图表信息失败"
 				br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 				return
@@ -4657,7 +4784,12 @@ func (this *ChartInfoController) ChartList() {
 		}
 	}
 	if keyWord != "" {
-		condition += ` AND  ( chart_name LIKE '%` + keyWord + `%' OR chart_name_en LIKE '%` + keyWord + `%' )`
+		keyWordArr := strings.Split(keyWord, " ")
+		if len(keyWordArr) > 0 {
+			for _, v := range keyWordArr {
+				condition += ` AND CONCAT(chart_name,chart_name_en) LIKE '%` + v + `%'`
+			}
+		}
 	}
 	if sysUserIds != "" {
 		adminIds := strings.Split(sysUserIds, ",")
@@ -4695,7 +4827,7 @@ func (this *ChartInfoController) ChartList() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -4713,7 +4845,7 @@ func (this *ChartInfoController) ChartList() {
 
 	//获取图表信息
 	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -4721,7 +4853,7 @@ func (this *ChartInfoController) ChartList() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -4813,7 +4945,7 @@ func (this *ChartInfoController) ChartList() {
 	}
 
 	resp := new(data_manage.ChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.Paging = page
 		resp.List = items
@@ -4824,7 +4956,7 @@ func (this *ChartInfoController) ChartList() {
 	}
 
 	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -4892,7 +5024,7 @@ func (this *ChartInfoController) ModifyChartList() {
 		if len(chartClassifyIds) > 0 {
 			if !req.SubClassify {
 				chartClassifyId, err := data_manage.GetChartClassifyByIdsNoSubClassify(chartClassifyIds)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "获取图表信息失败"
 					br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 					return
@@ -5009,8 +5141,130 @@ func (this *ChartInfoController) ModifyChartList() {
 		br.ErrMsg = "更新图表分类失败,Err:" + err.Error()
 		return
 	}
+	
+	go eta_forum.ChartInfoDeleteBatchByChartInfoIds(chartIds, req.ChartClassifyId)
 
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "操作成功"
 }
+
+// 查询图表简介列表
+// @Title 查询图表简介列表
+// @Description 查询图表简介列表
+// @Param   ChartInfoId   query   int  true       "图表id"
+// @Success 200 {object} models.ChartDescriptionListResponse
+// @router /chart_info/description/list [get]
+func (this *ChartInfoController) GetChartDescriptionList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	chartInfoId, _ := this.GetInt("ChartInfoId")
+	if chartInfoId <= 0 {
+		br.Msg = "请选择图表"
+		return
+	}
+
+	chartDescriptionList, err := data_manage.GetChartDescriptionByChartInfoId(chartInfoId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表简介失败,Err:" + err.Error()
+		return
+	}
+	list := make([]*data_manage.ChartDescriptionList, 0)
+	response := new(data_manage.ChartDescriptionListResponse)
+	for _, v := range chartDescriptionList {
+		list = append(list, &data_manage.ChartDescriptionList{
+			Id:               v.Id,
+			Description:      v.Description,
+			ChartInfoId:      v.ChartInfoId,
+			SysUserId:        v.SysUserId,
+			SysUserRealName:  v.SysUserRealName,
+			CreateTime:       v.CreateTime.Format(utils.FormatDateTime),
+		})
+	}
+	response.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = response
+}
+
+// 添加图表简介
+// @Title 添加图表简介
+// @Description 添加图表简介
+// @Param   ChartInfoId   query   int  true       "图表id"
+// @Success 200 {object} models.ChartDescriptionListResponse
+// @router /chart_info/description/add [post]
+func (this *ChartInfoController) AddChartDescription() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}	
+
+	var req data_manage.ChartDescriptionAddReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartInfoId <= 0 {
+		br.Msg = "请选择图表"
+		return
+	}
+	if req.Description == "" {
+		br.Msg = "请输入简介"
+		return
+	}
+	// 判断图表是否存在
+	_, err = data_manage.GetChartInfoById(req.ChartInfoId)
+	if err != nil {
+		if !utils.IsErrNoRow(err) {
+			br.Msg = "图表不存在"
+			return
+		}
+		br.Msg = "获取图表信息失败"
+		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		return
+	}
+	item := &data_manage.ChartDescription{
+		ChartInfoId: req.ChartInfoId,
+		Description: req.Description,
+		SysUserId: sysUser.AdminId,
+		SysUserRealName: sysUser.RealName,
+		ModifyTime: time.Now(),
+		CreateTime: time.Now(),
+	}
+	err = data_manage.AddChartDescription(item)
+	if err != nil {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加图表简介失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "添加成功"
+}
+

+ 10 - 4
controllers/data_manage/chart_theme.go

@@ -207,6 +207,9 @@ func (c *ChartThemeController) GetThemePreviewData() {
 		chartInfo.LeftMax = "4000"
 		extraConfigStr = `{"DateConfList":[],"IsHeap":0,"XDataList":[{"Name":"内销"},{"Name":"出口"},{"Name":"销量"},{"Name":"产量"}],"UnitList":{"LeftName":"万台","RightName":"%","RightTwoName":""},"BaseChartSeriesName":"增量","SortType":0,"SeriesList":[{"ChartSeriesId":0,"SeriesName":"增量","ChartStyle":"column","ChartColor":"rgba(0, 0, 255, 1)","ChartWidth":1,"IsPoint":0,"IsNumber":0,"IsAxis":1,"EdbInfoList":[{"ChartSeriesEdbMappingId":0,"ChartSeriesId":0,"EdbInfoId":19,"DateConfName":"","DateConfType":0,"DateConf":{"MoveForward":0,"DateChange":[]}},{"ChartSeriesEdbMappingId":0,"ChartSeriesId":0,"EdbInfoId":20,"DateConfName":"","DateConfType":0,"DateConf":{"MoveForward":0,"DateChange":[]}},{"ChartSeriesEdbMappingId":0,"ChartSeriesId":0,"EdbInfoId":21,"DateConfName":"","DateConfType":0,"DateConf":{"MoveForward":0,"DateChange":[]}},{"ChartSeriesEdbMappingId":0,"ChartSeriesId":0,"EdbInfoId":22,"DateConfName":"","DateConfType":0,"DateConf":{"MoveForward":0,"DateChange":[]}}]},{"ChartSeriesId":0,"SeriesName":"增速","ChartStyle":"spline","ChartColor":"rgba(255, 0, 200, 1)","ChartWidth":1,"IsPoint":0,"IsNumber":0,"IsAxis":0,"EdbInfoList":[{"ChartSeriesEdbMappingId":0,"ChartSeriesId":0,"EdbInfoId":23,"DateConfName":"","DateConfType":0,"DateConf":{"MoveForward":0,"DateChange":[]}},{"ChartSeriesEdbMappingId":0,"ChartSeriesId":0,"EdbInfoId":24,"DateConfName":"","DateConfType":0,"DateConf":{"MoveForward":0,"DateChange":[]}},{"ChartSeriesEdbMappingId":0,"ChartSeriesId":0,"EdbInfoId":25,"DateConfName":"","DateConfType":0,"DateConf":{"MoveForward":0,"DateChange":[]}},{"ChartSeriesEdbMappingId":0,"ChartSeriesId":0,"EdbInfoId":26,"DateConfName":"","DateConfType":0,"DateConf":{"MoveForward":0,"DateChange":[]}}]}]}`
 		chartInfo.ChartName = "图表标题"
+	case utils.CHART_TYPE_AREA: // 曲线图
+		edbInfoIdList = []int{25, 26}
+		chartInfo.ChartName = "面积图"
 	default:
 		br.Msg = "暂不支持该类型"
 		br.IsSendEmail = false
@@ -247,6 +250,9 @@ func (c *ChartThemeController) GetThemePreviewData() {
 			}
 		}
 	}
+	if chartType == utils.CHART_TYPE_SEASON && dateType == utils.DateTypeNYears {
+		dateMax = time.Date(dateMax.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+	}
 	// 开始/结束日期
 	startDate, endDate := utils.GetDateByDateTypeV2(dateType, tmpStartDate, tmpEndDate, startYear, dateMax)
 
@@ -398,7 +404,7 @@ func (c *ChartThemeController) Edit() {
 	// 获取配置
 	chartTheme, err := chart_theme.GetChartThemeId(req.ChartThemeId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "主题不存在或已删除"
 			br.ErrMsg = "主题不存在或已删除"
 			br.IsSendEmail = false
@@ -468,7 +474,7 @@ func (c *ChartThemeController) Delete() {
 	// 获取配置
 	chartTheme, err := chart_theme.GetChartThemeId(req.ChartThemeId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "主题不存在或已删除"
 			br.ErrMsg = "主题不存在或已删除"
 			br.IsSendEmail = false
@@ -556,7 +562,7 @@ func (c *ChartThemeController) SetDefaultTheme() {
 	// 获取图表配置
 	chartTheme, err := chart_theme.GetChartThemeId(req.ChartThemeId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "主题不存在或已删除"
 			br.ErrMsg = "主题不存在或已删除"
 			br.IsSendEmail = false
@@ -570,7 +576,7 @@ func (c *ChartThemeController) SetDefaultTheme() {
 	// 获取图表类型
 	chartThemeType, err := chart_theme.GetChartThemeTypeById(req.ChartThemeTypeId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "获取图表类型不存在或已删除"
 			br.ErrMsg = "获取图表类型不存在或已删除"
 			br.IsSendEmail = false

+ 1653 - 0
controllers/data_manage/clarksons_data.go

@@ -0,0 +1,1653 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/data_manage/request"
+	"eta/eta_api/models/data_manage/response"
+	"eta/eta_api/models/system"
+	"eta/eta_api/services/data"
+	etaTrialService "eta/eta_api/services/eta_trial"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/tealeg/xlsx"
+)
+
+type ClarksonsDataController struct {
+	controllers.BaseAuthController
+}
+
+// @Title 克拉克森数据分类
+// @Description 克拉克森数据分类接口
+// @Success 200 {object} data_manage.SciClassify
+// @router /clarksons/classify [get]
+func (this *ClarksonsDataController) Classify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	classifyList, err := data_manage.GetClarksonsClassifyAll()
+	if err != nil {
+		br.Msg = "查询失败"
+		br.ErrMsg = "查询失败, Err:" + err.Error()
+		return
+	}
+
+	initClassify := &data_manage.BaseFromClarksonsClassifyItem{
+		BaseFromClassifyId: 0,
+		ClassifyName:       "未分类",
+		ClassifyNameEn:     "Unclassified",
+		UniqueCode:         "0",
+		ParentId:           0,
+		Level:              1,
+		Sort:               0,
+		Children:           nil,
+	}
+	finalList := make([]*data_manage.BaseFromClarksonsClassifyItem, 0)
+	classifyTree := getClarksonsClassifyTree(classifyList, 0)
+	finalList = append(finalList, initClassify)
+	finalList = append(finalList, classifyTree...)
+
+	br.Msg = "查询成功"
+	br.Data = finalList
+	br.Success = true
+	br.Ret = 200
+}
+
+// AddSciClassify
+// @Title 新增分类
+// @Description 新增分类接口
+// @Param	request	body data_manage.AddBaseFromSciClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /clarksons/classify/add [post]
+func (this *ClarksonsDataController) AddClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.AddBaseFromClarksonsClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+	if req.ParentId < 0 {
+		br.Msg = "操作异常"
+		return
+	}
+	ok, msg, err := data.AddClarksonsClassify(req.ClassifyName, req.ParentId)
+	if err != nil {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+	if !ok {
+		if msg != "" {
+			br.Msg = msg
+			return
+		}
+		br.Msg = "添加失败"
+		return
+	}
+	br.Msg = "添加成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// DelClassify
+// @Title 新增分类
+// @Description 新增分类接口
+// @Param	request	body data_manage.AddBaseFromSciClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /clarksons/classify/del [post]
+func (this *ClarksonsDataController) DelClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.DelBaseFromClarksonsClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromClassifyId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	err = data.DelClarksonsClassify(req.BaseFromClassifyId)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// EditClassify
+// @Title 修改分类
+// @Description 修改分类接口
+// @Param	request	body data_manage.EditBaseFromMysteelChemicalClassifyReq true "type json string"
+// @Success 200 Ret=200 修改成功
+// @router /clarksons/classify/edit [post]
+func (this *ClarksonsDataController) EditClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.EditBaseFromClarksonsClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BaseFromClassifyId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+	classify, err := data_manage.GetClarksonsClassifyById(req.BaseFromClassifyId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			br.Msg = "分类不存在"
+			return
+		}
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类失败,Err:" + err.Error()
+		return
+	}
+
+	if classify.ClassifyName != req.ClassifyName {
+		count, err := data_manage.GetClarksonsClassifyCountByName(req.ClassifyName)
+		if err != nil {
+			br.Msg = "编辑失败"
+			br.ErrMsg = "获取分类失败,Err:" + err.Error()
+			return
+		}
+		if count > 0 {
+			br.Msg = "分类名称已存在"
+			return
+		}
+		classify.ClassifyName = req.ClassifyName
+		classify.ModifyTime = time.Now()
+		err = classify.Update([]string{"classify_name", "modify_time"})
+		if err != nil {
+			br.Msg = "编辑失败"
+			br.ErrMsg = "编辑失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	br.Msg = "编辑成功"
+	br.Success = true
+	br.Ret = 200
+	br.IsAddLog = true
+}
+
+// MoveClassify
+// @Title 分类移动接口
+// @Description 分类移动接口
+// @Success 200 {object} data_manage.MoveBaseFromMysteelChemicalClassifyReq
+// @router /clarksons/classify/move [post]
+func (this *ClarksonsDataController) MoveClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.MoveBaseFromClarksonsClassifyReq
+	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BaseFromClassifyId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "分类id小于等于0"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.MoveClarksonsClassify(req.BaseFromClassifyId, req.ParentClassifyId, req.PrevClassifyId, req.NextClassifyId)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "移动成功"
+}
+
+// IndexList
+// @Title 克拉克森指标列表
+// @Description 克拉克森数据指标列表接口
+// @Param   BaseFromClassifyId   query   int  true       "分类id"
+// @Success 200 {object} data_manage.BaseFromMysteelChemicalIndexResp
+// @router /clarksons/index/list [get]
+func (this *ClarksonsDataController) IndexList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	classifyId, _ := this.GetInt("BaseFromClassifyId", 0)
+	indexList, err := data_manage.GetClarksonsIndexBaseInfoByClassifyId(classifyId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = indexList
+}
+
+// GetClarksonsIndexInfo
+// @Title 添加指标-根据条件获取指标信息
+// @Description 添加指标-根据条件获取指标信息
+// @Param   KeyWord   query   string  false       "关键字"
+// @Param   ClassifyIds   query   string  false       "分类id"
+// @Param   Frequencies   query   string  false       "频率"
+// @Param   PageSize   query   int  false       "每页数据条数"
+// @Param   CurrentIndex   query   int  false       "当前页页码,从1开始"
+// @Success 200 {object} data_manage.BaseFromRzdIndexPage
+// @router /clarksons/get/index/info [post]
+func (this *ClarksonsDataController) GetClarksonsIndexInfo() {
+	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.ClarksonsDataBatchListReq
+	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	keyWord := req.KeyWord
+	classifyIds := req.ClassifyIds
+	frequencies := req.Frequencies
+
+	pageSize := req.PageSize
+	currentIndex := req.CurrentIndex
+	var startSize int
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	var classifyIdList []string
+	var frequencyList []string
+	if classifyIds != "" {
+		classifyIdList = strings.Split(classifyIds, ",")
+	}
+	if frequencies != "" {
+		frequencyList = strings.Split(frequencies, ",")
+	}
+	indexInfoPage, err := data.GetClarksonsIndexInfo(keyWord, classifyIdList, frequencyList, currentIndex, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = indexInfoPage
+}
+
+// SearchList
+// @Title 克拉克森模糊搜索
+// @Description 克拉克森模糊搜索
+// @Param   Keyword   query   string  true       "关键字搜索"
+// @Success 200 {object} models.BaseResponse
+// @router /clarksons/search_list [get]
+func (this *ClarksonsDataController) SearchList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	//关键字
+	keyword := this.GetString("Keyword")
+	var condition string
+	var pars []interface{}
+	if keyword != "" {
+		condition += ` AND (index_code LIKE ? OR index_name LIKE ?)`
+		pars = utils.GetLikeKeywordPars(pars, keyword, 2)
+	} else {
+		br.Msg = "请输入指标ID/指标名称"
+		return
+	}
+
+	list, err := data_manage.GetClarksonsIndexBaseInfoByCondition(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// SingleData
+// @Title 获取克拉克森据
+// @Description 获取克拉克森单条数据接口
+// @Param   BaseFromClarksonsIndexId   query   string  true       "指标唯一编码"
+// @Success 200 {object} models.BaseResponse
+// @router /clarksons/single_data [get]
+func (this *ClarksonsDataController) SingleData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	baseFromClarksonsIndexId, _ := this.GetInt("BaseFromClarksonsIndexId")
+	indexInfo, err := data_manage.GetClarksonsIndexByIndexId(baseFromClarksonsIndexId)
+	if err != nil {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_CLARKSONS, indexInfo.IndexCode)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取指标数据失败"
+		br.ErrMsg = "获取指标库数据失败,Err:" + err.Error()
+		return
+	}
+	var edbInfoId int
+	if edbInfo != nil {
+		edbInfoId = edbInfo.EdbInfoId
+	}
+	dataList, err := data_manage.GetClarksonsDataByIndexId(baseFromClarksonsIndexId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	var ret response.ClarksonsSingleDataResp
+	ret.ClassifyId = indexInfo.ClassifyId
+	ret.BaseFromClarksonsIndexId = indexInfo.BaseFromClarksonsIndexId
+	ret.IndexCode = indexInfo.IndexCode
+	ret.EdbInfoId = edbInfoId
+	ret.IndexName = indexInfo.IndexName
+	ret.Frequency = indexInfo.Frequency
+	ret.CreateTime = indexInfo.CreateTime.Format(utils.FormatDateTime)
+	ret.ModifyTime = indexInfo.ModifyTime.Format(utils.FormatDateTime)
+	ret.Unit = indexInfo.Unit
+	ret.Data = dataList
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = ret
+}
+
+// MoveClarksonsData
+// @Title 克拉克森指标移动接口
+// @Description 克拉克森指标移动接口
+// @Success 200 {object} request.MoveBaseFromClarksonsReq
+// @router /clarksons/move [post]
+func (this *ClarksonsDataController) MoveClarksonsData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req request.MoveBaseFromClarksonsReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromClarksonsIndexId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "指标id小于等于0"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.BaseFromClassifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.MoveClarksonsData(req.BaseFromClarksonsIndexId, req.BaseFromClassifyId, req.PrevBaseFromClarksonsIndexId, req.NextBaseFromClarksonsIndexId)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "移动成功"
+}
+
+// ResetClarksonsIndex
+// @Title 指标数据清除分类
+// @Description 指标数据清除分类
+// @Param	request	body data_manage.DelBaseFromSciReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /clarksons/reset [post]
+//func (this *ClarksonsDataController) ResetClarksonsIndex() {
+//	br := new(models.BaseResponse).Init()
+//	defer func() {
+//		this.Data["json"] = br
+//		this.ServeJSON()
+//	}()
+//	var req request.ResetBaseFromClarksonsReq
+//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+//	if err != nil {
+//		br.Msg = "参数解析异常!"
+//		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+//		return
+//	}
+//
+//	if req.BaseFromClarksonsIndexId < 0 {
+//		br.Msg = "参数错误"
+//		br.IsSendEmail = false
+//		return
+//	}
+//
+//	err = data.ResetClarksonsIndex(req.BaseFromClarksonsIndexId)
+//	if err != nil {
+//		br.Msg = "移动失败"
+//		br.ErrMsg = "移动失败,Err:" + err.Error()
+//		return
+//	}
+//
+//	br.Ret = 200
+//	br.Msg = "操作成功"
+//	br.Success = true
+//	br.IsAddLog = true
+//}
+
+// AddEdbInfo
+// @Title 新增指标接口
+// @Description 新增指标接口
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /clarksons/edb_info/add [post]
+//func (this *ClarksonsDataController) AddEdbInfo() {
+//	br := new(models.BaseResponse).Init()
+//	defer func() {
+//		this.Data["json"] = br
+//		this.ServeJSON()
+//	}()
+//
+//	sysUser := this.SysUser
+//	if sysUser == nil {
+//		br.Msg = "请登录"
+//		br.ErrMsg = "请登录,SysUser Is Empty"
+//		br.Ret = 408
+//		return
+//	}
+//	deleteCache := true
+//	cacheKey := "CACHE_EDB_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
+//	defer func() {
+//		if deleteCache {
+//			utils.Rc.Delete(cacheKey)
+//		}
+//	}()
+//	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+//		deleteCache = false
+//		br.Msg = "系统处理中,请稍后重试!"
+//		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+//		return
+//	}
+//	var req data_manage.AddEdbInfoReq
+//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+//	if err != nil {
+//		br.Msg = "参数解析异常!"
+//		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+//		return
+//	}
+//
+//	req.EdbName = strings.Trim(req.EdbName, " ")
+//	req.EdbCode = strings.Trim(req.EdbCode, " ")
+//
+//	if req.EdbCode == "" {
+//		br.Msg = "指标ID不能为空"
+//		return
+//	}
+//
+//	if req.EdbName == "" {
+//		br.Msg = "指标名称不能为空"
+//		return
+//	}
+//
+//	if req.Frequency == "" {
+//		br.Msg = "频率不能为空"
+//		return
+//	}
+//
+//	if req.Unit == "" {
+//		br.Msg = "单位不能为空"
+//		return
+//	}
+//
+//	if req.ClassifyId <= 0 {
+//		br.Msg = "请选择分类"
+//		return
+//	}
+//
+//	_, err = data_manage.GetClarksonsIndexByIndexCode(req.EdbCode)
+//	if err != nil {
+//		if utils.IsErrNoRow(err) {
+//			br.Msg = "指标不存在"
+//			return
+//		}
+//		br.Msg = "获取失败"
+//		br.ErrMsg = "获取失败,Err:" + err.Error()
+//		return
+//	}
+//	source := utils.DATA_SOURCE_CLARKSONS
+//	// 指标入库
+//	edbInfo, err, errMsg, isSendEmail := data.EdbInfoAdd(source, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, req.StartDate, req.EndDate, sysUser.AdminId, sysUser.RealName, this.Lang)
+//	if err != nil {
+//		br.Msg = "保存失败"
+//		if errMsg != `` {
+//			br.Msg = errMsg
+//		}
+//		br.ErrMsg = err.Error()
+//		br.IsSendEmail = isSendEmail
+//		return
+//	}
+//
+//	// 试用平台更新用户累计新增指标数
+//	adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+//	if e != nil {
+//		br.Msg = "操作失败"
+//		br.ErrMsg = "获取系统用户数据失败,Err:" + e.Error()
+//		return
+//	}
+//	if utils.BusinessCode == utils.BusinessCodeSandbox && adminItem.DepartmentName == "ETA试用客户" {
+//		go func() {
+//			var r etaTrialService.EtaTrialUserReq
+//			r.Mobile = adminItem.Mobile
+//			_, _ = etaTrialService.UpdateUserIndexNum(r)
+//		}()
+//	}
+//
+//	//新增操作日志
+//	{
+//		// 添加钢联指标更新日志
+//		if edbInfo.Source == utils.DATA_SOURCE_MYSTEEL_CHEMICAL {
+//			go data_stat.AddEdbInfoUpdateLog(edbInfo.EdbInfoId, 1, "", sysUser, 2)
+//		}
+//
+//		edbLog := new(data_manage.EdbInfoLog)
+//		edbLog.EdbInfoId = edbInfo.EdbInfoId
+//		edbLog.SourceName = edbInfo.SourceName
+//		edbLog.Source = edbInfo.Source
+//		edbLog.EdbCode = edbInfo.EdbCode
+//		edbLog.EdbName = edbInfo.EdbName
+//		edbLog.ClassifyId = edbInfo.ClassifyId
+//		edbLog.SysUserId = sysUser.AdminId
+//		edbLog.SysUserRealName = sysUser.RealName
+//		edbLog.CreateTime = time.Now()
+//		edbLog.Content = string(this.Ctx.Input.RequestBody)
+//		edbLog.Status = "新增指标"
+//		edbLog.Method = this.Ctx.Input.URI()
+//		go data_manage.AddEdbInfoLog(edbLog)
+//	}
+//
+//	// 更新es
+//	go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+//
+//	resp := new(data_manage.AddEdbInfoResp)
+//	resp.EdbInfoId = edbInfo.EdbInfoId
+//	resp.UniqueCode = edbInfo.UniqueCode
+//	br.Ret = 200
+//	br.Success = true
+//	br.Msg = "保存成功"
+//	br.Data = resp
+//	br.IsAddLog = true
+//}
+
+// AddCheck
+// @Title 新增校验
+// @Description 新增校验
+// @Param	request	body request.BusinessDataBatchAddCheckReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /clarksons/edb_info/add_check [post]
+func (this *ClarksonsDataController) AddCheck() {
+	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.ClarksonsDataBatchAddCheckReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	codeMax := 30
+	codeLen := len(req.IndexCodes)
+	if len(req.IndexCodes) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+
+	if codeLen > codeMax {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
+		return
+	}
+	// 获取指标库已有指标
+	existsEdb, e := data_manage.GetEdbCodesBySource(utils.DATA_SOURCE_CLARKSONS)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取自有数据已添加的指标失败, Err: " + e.Error()
+		return
+	}
+	existMap := make(map[string]*data_manage.EdbInfo)
+	for _, v := range existsEdb {
+		existMap[v.EdbCode] = v
+	}
+
+	// 查询选中的指标
+	cond := fmt.Sprintf(` AND index_code IN (%s)`, utils.GetOrmInReplace(codeLen))
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.IndexCodes)
+	list, err := data_manage.GetClarksonsIndexAndEdbInfoByCondition(cond, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取克拉克森原始指标列表失败, Err: " + err.Error()
+		return
+	}
+
+	resp := make([]*data_manage.BaseFromClarksonsIndexView, 0)
+	for _, v := range list {
+		if v.EdbInfoId > 0 {
+			v.EdbExist = 1
+		}
+		resp = append(resp, v)
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// NameCheck
+// @Title 重名校验
+// @Description 批量新增
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /clarksons/edb_info/name_check [post]
+func (c *ClarksonsDataController) NameCheck() {
+	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
+	}
+	var req []*data_manage.NameCheckEdbInfoReq
+	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	codeMax := 30
+	codeLen := len(req)
+	if codeLen > codeMax {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
+		return
+	}
+
+	type NameCheckResult struct {
+		EdbCode string
+		EdbName string
+		Exist   bool
+	}
+	indexNames := make([]string, 0)
+	resp := make([]*NameCheckResult, 0)
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		indexNames = append(indexNames, v.EdbName)
+		resp = append(resp, &NameCheckResult{
+			EdbCode: v.EdbCode,
+			EdbName: v.EdbName,
+		})
+		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_CLARKSONS, 0, utils.EDB_DATA_LIMIT)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取克拉克森已存在信息失败,Err:" + err.Error()
+			return
+		}
+		if len(dataItems) <= 0 {
+			respItem, err := data.AddEdbData(utils.DATA_SOURCE_CLARKSONS, v.EdbCode, v.Frequency)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				return
+			}
+			if respItem.Ret != 200 {
+				br.Msg = "未搜索到该指标"
+				br.ErrMsg = respItem.ErrMsg + ";EdbCode:" + v.EdbCode
+				return
+			}
+		}
+	}
+
+	// 重名校验
+	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames, utils.EDB_INFO_TYPE)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取重名指标失败, Err: " + e.Error()
+		return
+	}
+	nameExists := make(map[string]bool)
+	for _, v := range edbList {
+		nameExists[v.EdbName] = true
+	}
+	if len(nameExists) > 0 {
+		for _, v := range resp {
+			v.Exist = nameExists[v.EdbName]
+		}
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// BatchAdd
+// @Title 批量新增
+// @Description 批量新增
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /clarksons/edb_info/batch_add [post]
+func (this *ClarksonsDataController) BatchAdd() {
+	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
+	}
+
+	deleteCache := true
+	cacheKey := "CACHE_EDB_INFO_BATCH_ADD_CLARKSONS_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			_ = utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req []*data_manage.AddEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if len(req) > 30 {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		v.Frequency = strings.TrimSpace(v.Frequency)
+		if v.Frequency == "" {
+			br.Msg = "请选择频度"
+			return
+		}
+		v.Unit = strings.TrimSpace(v.Unit)
+		if v.Unit == "" {
+			br.Msg = "请输入单位"
+			return
+		}
+		if v.ClassifyId <= 0 {
+			br.Msg = "请选择分类"
+			return
+		}
+	}
+
+	// 限定同一时间最多批量新增30个指标
+	for _, v := range req {
+		var r data.ClarksonsIndexSource2EdbReq
+		r.EdbCode = v.EdbCode
+		r.EdbName = v.EdbName
+		r.Frequency = v.Frequency
+		r.Unit = v.Unit
+		r.ClassifyId = v.ClassifyId
+		r.AdminId = sysUser.AdminId
+		r.AdminRealName = sysUser.RealName
+
+		edbInfo, errMsg, skip, e := data.ClarksonsIndexSource2Edb(r, this.Lang)
+		if e != nil {
+			br.Msg = "操作失败"
+			if errMsg != "" {
+				br.Msg = errMsg
+			}
+			br.ErrMsg = e.Error()
+			return
+		}
+		if skip {
+			continue
+		}
+
+		// 试用平台更新用户累计新增指标数
+		if utils.BusinessCode == utils.BusinessCodeSandbox {
+			go func() {
+				adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+				if e != nil {
+					tips := fmt.Sprintf("试用平台更新用户累计新增指标数-获取用户失败, Err: " + e.Error())
+					utils.FileLog.Info(tips)
+					return
+				}
+				if adminItem.DepartmentName != "ETA试用客户" {
+					return
+				}
+				var ur etaTrialService.EtaTrialUserReq
+				ur.Mobile = adminItem.Mobile
+				_, _ = etaTrialService.UpdateUserIndexNum(ur)
+			}()
+		}
+
+		// 新增操作日志
+		{
+			edbLog := new(data_manage.EdbInfoLog)
+			edbLog.EdbInfoId = edbInfo.EdbInfoId
+			edbLog.SourceName = edbInfo.SourceName
+			edbLog.Source = edbInfo.Source
+			edbLog.EdbCode = edbInfo.EdbCode
+			edbLog.EdbName = edbInfo.EdbName
+			edbLog.ClassifyId = edbInfo.ClassifyId
+			edbLog.SysUserId = sysUser.AdminId
+			edbLog.SysUserRealName = sysUser.RealName
+			edbLog.CreateTime = time.Now()
+			edbLog.Content = string(this.Ctx.Input.RequestBody)
+			edbLog.Status = "新增指标"
+			edbLog.Method = this.Ctx.Input.URI()
+			go data_manage.AddEdbInfoLog(edbLog)
+		}
+
+		// 更新es
+		go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+	}
+
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// BatchDelete
+// @Title 批量删除
+// @Description 批量删除
+// @Param	request	body []*request.DelBaseFromClarksonsReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /clarksons/edb_info/batch_delete [post]
+func (this *ClarksonsDataController) BatchDelete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req []*request.DelBaseFromClarksonsReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if len(req) > 30 {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+	var deleteIds []int
+	for _, v := range req {
+		if v.BaseFromClarksonsIndexId <= 0 {
+			continue
+		}
+		deleteIds = append(deleteIds, v.BaseFromClarksonsIndexId)
+	}
+	existList, err := data.BatchDelClarksonsData(deleteIds)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	br.Data = existList
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// BatchEdit
+// @Title 批量编辑
+// @Description 批量编辑
+// @Param	request	body []*request.DelBaseFromClarksonsReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /clarksons/edb_info/batch_edit [post]
+func (this *ClarksonsDataController) BatchEdit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req []*request.EditBaseFromClarksonsReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+
+	indexIds := make([]int, 0)
+	classifyIds := make([]int, 0)
+	indexIdToclassifyId := make(map[int]int)
+	for _, v := range req {
+		if v.BaseFromClarksonsIndexId <= 0 {
+			continue
+		}
+		if v.BaseFromClassifyId <= 0 {
+			continue
+		}
+		indexIds = append(indexIds, v.BaseFromClarksonsIndexId)
+		classifyIds = append(classifyIds, v.BaseFromClassifyId)
+		indexIdToclassifyId[v.BaseFromClarksonsIndexId] = v.BaseFromClassifyId
+	}
+	if len(indexIds) == 0 {
+		br.Msg = "请选择指标或指定正确的分类"
+		return
+	}
+	indexList, err := data_manage.GetClarksonsIndexListByIndexIds(indexIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取指标失败,Err:" + err.Error()
+		return
+	}
+	classifySort, err := data_manage.GetClarksonsClassifyMaxSortByClassifyIds(classifyIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类最大排序失败,Err:" + err.Error()
+		return
+	}
+	classifySortMap := make(map[int]int)
+	for _, v := range classifySort {
+		classifySortMap[v.BaseFromClassifyId] = v.MaxSort
+	}
+	classifyList, err := data_manage.GetClarksonsClassifyListByIds(classifyIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类失败,Err:" + err.Error()
+		return
+	}
+	existClassifyList := make(map[int]struct{})
+	for _, v := range classifyList {
+		existClassifyList[v.BaseFromClassifyId] = struct{}{}
+	}
+	//编辑指标
+	updateIndexList := make([]*data_manage.BaseFromClarksonsIndex, 0)
+	for _, v := range indexList {
+		tmpClassifyId := indexIdToclassifyId[v.BaseFromClarksonsIndexId]
+		if _, ok := existClassifyList[tmpClassifyId]; ok {
+			v.ClassifyId = tmpClassifyId
+			v.Sort = classifySortMap[tmpClassifyId] + 1
+			classifySortMap[tmpClassifyId] += 1
+			updateIndexList = append(updateIndexList, v)
+		}
+	}
+	err = data_manage.BatchModifyClarksonsIndexClassify(updateIndexList)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑指标失败,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+
+}
+
+// EditClarksons
+// @Title 编辑克拉克森指标
+// @Description 编辑克拉克森指标接口
+// @Param	request	body data_manage.AddEdbClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /clarksons/edit [post]
+func (this *ClarksonsDataController) EditClarksons() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.EditBaseFromClarksonsReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BaseFromClarksonsIndexId <= 0 {
+		br.Msg = "请选择指标"
+		br.IsSendEmail = false
+		return
+	}
+	if req.BaseFromClassifyId < 0 {
+		br.Msg = "请选择分类"
+		br.IsSendEmail = false
+		return
+	}
+
+	//编辑指标
+	sciIndexInfo, errMsg, err := data.EditClarksonsIndex(req.BaseFromClarksonsIndexId, req.BaseFromClassifyId)
+	if errMsg != `` {
+		br.Msg = errMsg
+		return
+	}
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑指标失败,Err:" + err.Error()
+		return
+	}
+
+	resp := response.EditClarksonsIndexInfoResp{
+		BaseFromClarksonsIndexId: sciIndexInfo.BaseFromClarksonsIndexId,
+		IndexCode:                sciIndexInfo.IndexCode,
+	}
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "保存成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// DeleteClarksonsData
+// @Title 删除指标
+// @Description 删除指标接口
+// @Param	request	body data_manage.DelBaseFromSciReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /clarksons/del [post]
+func (this *ClarksonsDataController) DeleteClarksonsData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.DelBaseFromClarksonsReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromClarksonsIndexId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.DelClarksonsData(req.BaseFromClarksonsIndexId)
+	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
+}
+
+// ExportClarksonsList
+// @Title 导出Sci数据
+// @Description 导出Sci数据
+// @Param   BaseFromClassifyId   query   int  true       "关键字搜索"
+// @Param   IndexCode   query   string  true       "指标编码"
+// @Success 200  导出成功
+// @router /export/clarksonsList [get]
+func (this *ClarksonsDataController) ExportClarksonsList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请重新登录"
+		return
+	}
+
+	classifyId, _ := this.GetInt("BaseFromClassifyId")
+	indexCode := this.GetString("IndexCode")
+	if classifyId < 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+	secNameList := make([]*data_manage.BaseFromClarksonsIndex, 0)
+	dir, _ := os.Executable()
+	exPath := filepath.Dir(dir)
+	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
+	xlsxFile := xlsx.NewFile()
+
+	var condition string
+	var pars []interface{}
+	if classifyId > 0 {
+		childClassify, err := data_manage.GetChildClarksonsClassifyListById(classifyId)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取分类失败,Err:" + err.Error()
+			return
+		}
+		if len(childClassify) > 0 {
+			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
+			for _, child := range childClassify {
+				pars = append(pars, child.BaseFromClassifyId)
+			}
+		} else {
+			condition += ` AND classify_id=?`
+			pars = append(pars, classifyId)
+		}
+	} else {
+		condition += ` AND classify_id=?`
+		pars = append(pars, classifyId)
+	}
+	if indexCode != "" {
+		condition += ` AND index_code=? `
+		pars = append(pars, indexCode)
+	}
+	frequencies, err := data_manage.GetClarksonsFrequencyByCondition(condition, pars)
+	if err != nil {
+		fmt.Println("GetSciFrequency err:", err.Error())
+		utils.FileLog.Info("GetSciFrequency err:" + err.Error())
+		return
+	}
+	for _, frequency := range frequencies {
+		//获取指标
+		secNameList, err = data_manage.GetClarksonsIndexByConditionAndFrequency(condition, *frequency, pars)
+		if err != nil {
+			fmt.Println("获取数据失败,Err:" + err.Error())
+			return
+		}
+		if len(secNameList) <= 0 {
+			fmt.Println("secNameList长度为0")
+			return
+		}
+		sheetNew, err := xlsxFile.AddSheet(*frequency)
+		if err != nil {
+			fmt.Println("新增Sheet失败", err.Error())
+			return
+		}
+		secNameRow := sheetNew.AddRow()
+		frequencyRow := sheetNew.AddRow()
+		unitRow := sheetNew.AddRow()
+		lastModifyDateRow := sheetNew.AddRow()
+
+		var indexIdList []int
+		for _, sv := range secNameList {
+			indexIdList = append(indexIdList, sv.BaseFromClarksonsIndexId)
+		}
+		dataTimeList, err := data_manage.GetClarksonsDataDataTimeByIndexId(indexIdList)
+		if err != nil {
+			fmt.Println("获取数据时间失败", err.Error())
+			return
+		}
+
+		// 添加excel左侧指标日期
+		setRowIndex := 4
+		for rk, dv := range dataTimeList {
+			rowIndex := setRowIndex + rk
+			row := sheetNew.Row(rowIndex)
+			displayDate, _ := time.Parse(utils.FormatDate, dv)
+			displayDateCell := row.AddCell()
+			style := new(xlsx.Style)
+			style.ApplyAlignment = true
+			style.Alignment.WrapText = true
+			displayDateCell.SetStyle(style)
+			displayDateCell.SetDate(displayDate)
+
+		}
+		for k, sv := range secNameList {
+			//获取数据
+			dataList, err := data_manage.GetClarksonsIndexDataByCode(sv.IndexCode)
+			if err != nil {
+				br.Msg = "获取数据失败"
+				br.ErrMsg = "获取数据失败,Err:" + err.Error()
+				return
+			}
+			if k == 0 {
+				secNameRow.AddCell().SetValue("指标名称")
+				frequencyRow.AddCell().SetValue("频率")
+				unitRow.AddCell().SetValue("单位")
+				lastModifyDateRow.AddCell().SetValue("更新时间")
+				min := k * 3
+				sheetNew.SetColWidth(min, min, 15)
+			}
+			if len(dataList) == 0 {
+				continue
+			}
+			secNameRow.AddCell().SetValue(sv.IndexName)
+			frequencyRow.AddCell().SetValue(sv.Frequency)
+			unitRow.AddCell().SetValue(sv.Unit)
+
+			lastModifyDateRow.AddCell().SetValue(sv.ModifyTime.Format(utils.FormatDate))
+			dataInfoMap := make(map[string]*data_manage.BaseFromClarksonsData)
+			for _, v := range dataList {
+				dataInfoMap[v.DataTime] = v
+			}
+
+			for rk, dtv := range dataTimeList {
+				rowIndex := setRowIndex + rk
+				row := sheetNew.Row(rowIndex)
+				displayDateCell := row.AddCell()
+				tmpData, ok := dataInfoMap[dtv]
+				if ok {
+					displayDateCell.SetValue(tmpData.Value)
+				}
+			}
+		}
+	}
+
+	err = xlsxFile.Save(downLoadnFilePath)
+	if err != nil {
+		//有指标无数据时先导出一遍空表
+		sheet, err := xlsxFile.AddSheet("无数据")
+		if err != nil {
+			br.Msg = "新增Sheet失败"
+			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
+			return
+		}
+		rowSecName := sheet.AddRow()
+		celSecName := rowSecName.AddCell()
+		celSecName.SetValue("")
+		err = xlsxFile.Save(downLoadnFilePath)
+		if err != nil {
+			br.Msg = "保存文件失败"
+			br.ErrMsg = "保存文件失败"
+			return
+		}
+	}
+	fileName := `克拉克森`
+	if indexCode != "" && len(secNameList) == 1 {
+		fileName = secNameList[0].IndexName
+	}
+	fileName += time.Now().Format("2006.01.02") + `.xlsx` //文件名称
+	this.Ctx.Output.Download(downLoadnFilePath, fileName)
+	defer func() {
+		os.Remove(downLoadnFilePath)
+	}()
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "success"
+}
+
+// getClarksonsClassifyTree 返回卓创红旗的树形结构
+func getClarksonsClassifyTree(items []*data_manage.BaseFromClarksonsClassifyItem, parentId int) []*data_manage.BaseFromClarksonsClassifyItem {
+	res := make([]*data_manage.BaseFromClarksonsClassifyItem, 0)
+	for _, item := range items {
+		if item.ParentId == parentId {
+			t := new(data_manage.BaseFromClarksonsClassifyItem)
+			t.BaseFromClassifyId = item.BaseFromClassifyId
+			t.ClassifyName = item.ClassifyName
+			t.ParentId = item.ParentId
+			t.Level = item.Level
+			t.Sort = item.Sort
+			t.ModifyTime = item.ModifyTime
+			t.CreateTime = item.CreateTime
+			t.ClassifyNameEn = item.ClassifyNameEn
+			if item.UniqueCode == "" {
+				t.UniqueCode = strconv.Itoa(item.BaseFromClassifyId)
+			}
+			t.Children = getClarksonsClassifyTree(items, item.BaseFromClassifyId)
+			res = append(res, t)
+		}
+	}
+	return res
+}
+
+// @Title 获取克拉克森数据
+// @Description 获取克拉克森数据接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   BaseFromSci99ClassifyId   query   int  true       "分类id"
+// @Param   KeyWord   query   string  true       "关键词"
+// @Success 200 {object} data_source.BaseFromSci99IndexView
+// @router /clarksons/index/data [get]
+func (this *ClarksonsDataController) ClarksonsData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	baseFromClarksonsClassifyId, _ := this.GetInt("BaseFromClarksonsClassifyId")
+	if baseFromClarksonsClassifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		return
+	}
+
+	keyword := this.GetString("KeyWord")
+
+	//获取指标
+	var condition string
+	var pars []interface{}
+
+	if baseFromClarksonsClassifyId > 0 {
+		condition += ` AND classify_id=? `
+		pars = append(pars, baseFromClarksonsClassifyId)
+	}
+
+	if keyword != "" {
+		condition += ` AND (index_code =? OR index_name LIKE ?)  `
+		pars = append(pars, keyword)
+		pars = append(pars, "%"+keyword+"%")
+	}
+
+	sci99List, err := data_manage.GetClarksonsIndex(condition, pars)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resultList := make([]*data_manage.BaseFromClarksonsIndexList, 0)
+	for _, v := range sci99List {
+		product := new(data_manage.BaseFromClarksonsIndexList)
+		product.BaseFromClarksonsIndexId = v.BaseFromClarksonsIndexId
+		product.ClassifyId = v.ClassifyId
+		product.IndexCode = v.IndexCode
+		product.IndexName = v.IndexName
+		product.Frequency = v.Frequency
+		product.Unit = v.Unit
+		product.ModifyTime = v.ModifyTime
+
+		modifyTime, err := data_manage.GetClarksonsIndexLatestDate(v.IndexCode)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "获取更新时间失败"
+			br.ErrMsg = "获取更新时间失败,Err:" + err.Error()
+			return
+		}
+		product.ModifyTime = modifyTime
+
+		total, err := data_manage.GetClarksonsIndexDataCount(v.IndexCode)
+		page := paging.GetPaging(currentIndex, pageSize, total)
+		dataList, err := data_manage.GetClarksonsIndexData(v.IndexCode, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+		if dataList == nil {
+			dataList = make([]*data_manage.BaseFromClarksonsData, 0)
+		}
+		product.DataList = dataList
+		product.Paging = page
+		resultList = append(resultList, product)
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resultList
+}
+
+// IndexPageList
+// @Title 克拉克森指标列表
+// @Description 克拉克森数据指标列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyId   query   int  true       "分类id"
+// @Param   IsListAll   query   int  true       "是否展示全部"
+// @Success 200 {object} data_manage.BaseFromMysteelChemicalIndexResp
+// @router /clarksons/index/page/list [get]
+func (this *ClarksonsDataController) IndexPageList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	classifyId, _ := this.GetInt("ClassifyId", 0)
+	pageSize, _ := this.GetInt("PageSize")
+	currrentIndex, _ := this.GetInt("CurrentIndex")
+	isListAll, _ := this.GetBool("IsListAll")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currrentIndex <= 0 {
+		currrentIndex = 1
+	}
+	startSize = utils.StartIndex(currrentIndex, pageSize)
+	var total int
+	var indexList []*data_manage.BaseFromClarksonsIndexView
+	if isListAll {
+		tmpTotal, err := data_manage.GetClarksonsIndexCount()
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+		tmpIndexList, err := data_manage.GetClarksonsIndexByPage(startSize, pageSize)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		indexList = tmpIndexList
+	} else {
+		var classifyIds []int
+		if classifyId > 0 {
+			tmpClassifyIds, err := data_manage.GetClarksonsChildClassifyIdsById(classifyId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+				return
+			}
+			if len(tmpClassifyIds) > 0 {
+				classifyIds = append(classifyIds, tmpClassifyIds...)
+			}
+		}
+		classifyIds = append(classifyIds, classifyId)
+		tmpTotal, err := data_manage.GetClarksonsIndexCountByClassifyId(classifyIds)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+		tmpIndexList, err := data_manage.GetClarksonsIndexByClassifyId(classifyIds, startSize, pageSize)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		indexList = tmpIndexList
+	}
+
+	page := paging.GetPaging(currrentIndex, pageSize, total)
+	resp := new(response.ClarksonsIndexPageListResp)
+	resp.List = indexList
+	resp.Paging = page
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 5 - 5
controllers/data_manage/com_trade.go

@@ -29,7 +29,7 @@ func (this *EdbInfoController) ComTradeCountryList() {
 	}
 
 	list, err := data_manage.GetComTradeCountryItemAll()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -161,14 +161,14 @@ func (this *EdbInfoController) ComTradeDataList() {
 	sortStr = fmt.Sprintf("%s %s,modify_time desc ", sortParam, sortType)
 
 	total, err := data_manage.GetComTradeListCount(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	list, err := data_manage.GetComTradeList(condition, pars, startSize, pageSize, sortStr)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -178,7 +178,7 @@ func (this *EdbInfoController) ComTradeDataList() {
 	lastUpdateTimeStr := ``
 	// 获取用到的指标信息
 	comTradeList, err := data_manage.GetAllComTradeIndexList()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -247,7 +247,7 @@ func (this *EdbInfoController) ComTradeList() {
 	}
 
 	list, err := data_manage.GetComTradeIndexList(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return

+ 29 - 31
controllers/data_manage/correlation/correlation_chart_classify.go

@@ -62,7 +62,7 @@ func (this *CorrelationChartClassifyController) ChartClassifyList() {
 	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
 	// 查询分类节点
 	rootList, err := data_manage.GetChartClassifyByParentId(parentId, utils.CHART_SOURCE_CORRELATION)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -155,19 +155,19 @@ func (this *CorrelationChartClassifyController) ChartClassifyList() {
 // getChartClassifyListForMe 获取我创建的图表
 func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
 	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_CORRELATION)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_CORRELATION)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	allChartInfo, err := data_manage.GetChartInfoByAdminId([]int{utils.CHART_SOURCE_CORRELATION, utils.CHART_SOURCE_CORRELATION}, adminInfo.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
@@ -263,7 +263,7 @@ func (this *CorrelationChartClassifyController) AddChartClassify() {
 	}
 
 	// 新增图表分类
-	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_CORRELATION, this.Lang, this.SysUser)
+	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_CORRELATION, 0,this.Lang, this.SysUser)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = "添加分类失败,Err:" + err.Error()
@@ -367,7 +367,7 @@ func (this *CorrelationChartClassifyController) DeleteChartClassifyCheck() {
 
 	if deleteStatus != 1 && req.ChartInfoId == 0 {
 		classifyCount, err := data_manage.GetChartClassifyCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
 			return
@@ -429,7 +429,7 @@ func (this *CorrelationChartClassifyController) DeleteChartClassify() {
 	if req.ChartClassifyId > 0 && req.ChartInfoId == 0 {
 		//判断是否含有指标
 		count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -449,11 +449,12 @@ func (this *CorrelationChartClassifyController) DeleteChartClassify() {
 		}
 	}
 	resp := new(data_manage.AddChartInfoResp)
+
 	//删除图表
 	if req.ChartInfoId > 0 {
 		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -492,13 +493,23 @@ func (this *CorrelationChartClassifyController) DeleteChartClassify() {
 		}
 
 		source := chartInfo.Source // 相关性图表(滚动相关性)
-		//删除图表及关联指标
+
+		// 删除图表及关联指标
 		err = data_manage.DeleteChartInfoAndData(chartInfo.ChartInfoId)
 		if err != nil {
 			br.Msg = "删除失败"
 			br.ErrMsg = "删除失败,Err:" + err.Error()
 			return
 		}
+
+		// 删除图表关联
+		e = correlationServ.RemoveCorrelationRelate(chartInfo.ChartInfoId)
+		if e != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = fmt.Sprintf("删除相关性图表关联失败, %v", e)
+			return
+		}
+
 		//删除ES
 		{
 			go data.EsDeleteChartInfo(chartInfo.ChartInfoId)
@@ -507,16 +518,14 @@ func (this *CorrelationChartClassifyController) DeleteChartClassify() {
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)
 		}
 
+		// 删除后定位至其他图(不知道原需求具体定位到哪张...修复的时候只是多加上了个source条件)
 		var condition string
 		var pars []interface{}
-		condition += " AND chart_classify_id=? AND source = ? "
-		pars = append(pars, chartInfo.ChartClassifyId, source)
-
-		condition += " AND chart_info_id>? ORDER BY create_time ASC LIMIT 1 "
-		pars = append(pars, req.ChartInfoId)
+		condition += ` AND chart_classify_id = ? AND source = ? AND chart_info_id > ? ORDER BY create_time ASC LIMIT 1`
+		pars = append(pars, chartInfo.ChartClassifyId, source, req.ChartInfoId)
 
 		nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 			return
@@ -529,21 +538,18 @@ func (this *CorrelationChartClassifyController) DeleteChartClassify() {
 			var condition string
 			var pars []interface{}
 
-			condition += " AND level=1 "
-			//pars = append(pars, chartInfo.ChartClassifyId)
-
-			condition += " AND chart_classify_id>? ORDER BY chart_classify_id ASC LIMIT 1 "
-			pars = append(pars, chartInfo.ChartClassifyId)
+			condition += ` AND level = 1 AND chart_classify_id > ? AND source = ? ORDER BY chart_classify_id ASC LIMIT 1`
+			pars = append(pars, chartInfo.ChartClassifyId, source)
 
 			classifyItem, err := data_manage.GetChartClassifyByCondition(condition, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
 				return
 			}
 			if classifyItem != nil {
-				nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				nextItem, err = data_manage.GetNextChartByClassifyIdAndSource(chartInfo.ChartClassifyId, source)
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 					return
@@ -555,14 +561,6 @@ func (this *CorrelationChartClassifyController) DeleteChartClassify() {
 			}
 		}
 
-		// 删除图表关联
-		e = correlationServ.RemoveCorrelationRelate(chartInfo.ChartInfoId)
-		if e != nil {
-			br.Msg = "删除失败"
-			br.ErrMsg = fmt.Sprintf("删除相关性图表关联失败, %v", e)
-			return
-		}
-
 		//新增操作日志
 		{
 			chartLog := new(data_manage.ChartInfoLog)

+ 34 - 30
controllers/data_manage/correlation/correlation_chart_info.go

@@ -335,7 +335,7 @@ func (this *CorrelationChartInfoController) Move() {
 	if chartInfo.ChartClassifyId != req.ChartClassifyId {
 		//查询需要修改的分类下是否存在同一个图表名称
 		tmpChartInfo, tmpErr := data_manage.GetChartInfoByClassifyIdAndName(req.ChartClassifyId, chartInfo.ChartName)
-		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "移动失败,Err:" + tmpErr.Error()
 			return
@@ -394,7 +394,7 @@ func (this *CorrelationChartInfoController) Move() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartInfoByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return
@@ -510,7 +510,7 @@ func (this *CorrelationChartInfoController) List() {
 
 	if chartClassifyId > 0 {
 		chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取图表信息失败"
 			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 			return
@@ -550,7 +550,7 @@ func (this *CorrelationChartInfoController) List() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -568,7 +568,7 @@ func (this *CorrelationChartInfoController) List() {
 
 	//获取图表信息
 	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -576,7 +576,7 @@ func (this *CorrelationChartInfoController) List() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -620,7 +620,7 @@ func (this *CorrelationChartInfoController) List() {
 	}
 
 	resp := new(data_manage.ChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.Paging = page
 		resp.List = items
@@ -631,7 +631,7 @@ func (this *CorrelationChartInfoController) List() {
 	}
 
 	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -682,7 +682,7 @@ func (this *CorrelationChartInfoController) Detail() {
 	chartInfo := new(data_manage.ChartInfoView)
 	chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图被删除,请刷新页面"
 			br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error()
 			return
@@ -807,7 +807,7 @@ func (this *CorrelationChartInfoController) Detail() {
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -963,7 +963,7 @@ func (this *CorrelationChartInfoController) DetailFromUniqueCode() {
 	status := true
 	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			status = false
 		} else {
 			br.Msg = "获取失败"
@@ -1001,7 +1001,7 @@ func (this *CorrelationChartInfoController) DetailFromUniqueCode() {
 					myCond += ` AND a.chart_info_id=? `
 					myPars = append(myPars, chartInfo.ChartInfoId)
 					myList, err := data_manage.GetMyChartByCondition(myCond, myPars)
-					if err != nil && err.Error() != utils.ErrNoRow() {
+					if err != nil && !utils.IsErrNoRow(err) {
 						br.Msg = "获取失败"
 						br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 						return
@@ -1072,7 +1072,7 @@ func (this *CorrelationChartInfoController) Refresh() {
 		chartInfo, err = data_manage.GetChartInfoByUniqueCode(uniqueCode)
 	}
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,无需刷新"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -1191,7 +1191,7 @@ func (this *CorrelationChartInfoController) Copy() {
 
 		_, e = data_manage.GetChartClassifyById(req.ChartClassifyId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "分类不存在"
 				return
 			}
@@ -1204,7 +1204,7 @@ func (this *CorrelationChartInfoController) Copy() {
 	// 图表信息
 	originChart, e := data_manage.GetChartInfoById(req.ChartInfoId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "原图表不存在"
 			return
 		}
@@ -1221,7 +1221,7 @@ func (this *CorrelationChartInfoController) Copy() {
 	// 相关性图
 	originCorrelate := new(data_manage.ChartInfoCorrelation)
 	if e = originCorrelate.GetItemById(req.ChartInfoId); e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "原相关性图表不存在"
 			return
 		}
@@ -1234,7 +1234,7 @@ func (this *CorrelationChartInfoController) Copy() {
 	chartInfo := new(data_manage.ChartInfo)
 	if originCorrelate.AnalysisMode != 1 {
 		multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByChartId(req.ChartInfoId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = `保存失败`
 			br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
 			return
@@ -1503,7 +1503,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					msg = "获取失败"
 					errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -1724,7 +1724,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				msg = "获取失败"
 				errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -1840,7 +1840,7 @@ func (this *CorrelationChartInfoController) EnInfoEdit() {
 	pars = append(pars, req.ChartInfoId, req.ChartNameEn, utils.CHART_SOURCE_CORRELATION)
 	existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "判断英文图表名称是否存在失败"
 			br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 			return
@@ -1944,7 +1944,7 @@ func (this *CorrelationChartInfoController) SearchByEs() {
 		sourceList = append(sourceList, source)
 	}
 
-	var searchList []*data_manage.ChartInfo
+	var searchList []*data_manage.ChartInfoMore
 	var total int64
 	var err error
 
@@ -1953,7 +1953,7 @@ func (this *CorrelationChartInfoController) SearchByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1967,7 +1967,7 @@ func (this *CorrelationChartInfoController) SearchByEs() {
 		searchList, total, err = data.EsSearchChartInfo(keyword, showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
 	} else {
 		total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -1997,13 +1997,17 @@ func (this *CorrelationChartInfoController) SearchByEs() {
 
 		for _, v := range searchList {
 			tmp := new(data_manage.ChartInfoMore)
-			tmp.ChartInfo = *v
+			tmp.ChartInfo = v.ChartInfo
 			// 图表数据权限
 			tmp.HaveOperaAuth = true
 			//判断是否需要展示英文标识
 			if edbTmpList, ok := chartEdbMap[v.ChartInfoId]; ok {
 				tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, edbTmpList, v.Source, v.ChartType)
 			}
+			tmp.SearchText = v.SearchText
+			if tmp.SearchText == "" {
+				tmp.SearchText = v.ChartName
+			}
 			finalList = append(finalList, tmp)
 		}
 	}
@@ -2038,7 +2042,7 @@ func (this *CorrelationChartInfoController) Newest() {
 		this.ServeJSON()
 	}()
 	item, err := data_manage.GetChartInfoByNewest(utils.CHART_SOURCE_CORRELATION)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取最新图表失败"
 		br.ErrMsg = "获取最新图表失败,Err:" + err.Error()
 		return
@@ -2111,7 +2115,7 @@ func (this *CorrelationChartInfoController) BaseInfoEdit() {
 	pars = append(pars, req.ChartName)
 	existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "判断英文图表名称是否存在失败"
 			br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 			return
@@ -2303,7 +2307,7 @@ func (this *CorrelationChartInfoController) MultiFactorAdd() {
 
 		_, e = data_manage.GetChartClassifyById(req.ClassifyId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "分类不存在"
 				return
 			}
@@ -2659,7 +2663,7 @@ func (this *CorrelationChartInfoController) MultiFactorEdit() {
 
 	chartInfo, e := data_manage.GetChartInfoById(req.ChartInfoId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "图表已被删除, 请刷新页面"
 			return
 		}
@@ -2711,7 +2715,7 @@ func (this *CorrelationChartInfoController) MultiFactorEdit() {
 
 		_, e = data_manage.GetChartClassifyById(req.ClassifyId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "分类不存在"
 				return
 			}
@@ -2912,7 +2916,7 @@ func (this *CorrelationChartInfoController) MultiFactorDetail() {
 
 	chartInfo, e := data_manage.GetChartInfoByUniqueCode(uniqueCode)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "图表已被删除, 请刷新页面"
 			return
 		}

+ 30 - 25
controllers/data_manage/cross_variety/chart_info.go

@@ -84,7 +84,7 @@ func (c *ChartInfoController) List() {
 
 	if chartClassifyId > 0 {
 		chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取图表信息失败"
 			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 			return
@@ -105,7 +105,8 @@ func (c *ChartInfoController) List() {
 			for _, v := range keyWordArr {
 				if v != "" {
 					condition += ` chart_name LIKE '%` + v + `%' OR chart_name_en LIKE '%` + v + `%' OR`
-				}			}
+				}
+			}
 		}
 		condition = strings.TrimRight(condition, "OR")
 		condition += " ) "
@@ -123,7 +124,7 @@ func (c *ChartInfoController) List() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(c.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -141,7 +142,7 @@ func (c *ChartInfoController) List() {
 
 	//获取图表信息
 	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -149,7 +150,7 @@ func (c *ChartInfoController) List() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -193,7 +194,7 @@ func (c *ChartInfoController) List() {
 	}
 
 	resp := new(data_manage.ChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.Paging = page
 		resp.List = items
@@ -204,7 +205,7 @@ func (c *ChartInfoController) List() {
 	}
 
 	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -490,7 +491,7 @@ func (c *ChartInfoController) Detail() {
 	chartInfo := new(data_manage.ChartInfoView)
 	chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图被删除,请刷新页面"
 			br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error()
 			return
@@ -583,7 +584,7 @@ func (c *ChartInfoController) Detail() {
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -702,7 +703,7 @@ func (c *ChartInfoController) Relation() {
 	chartInfo := new(data_manage.ChartInfoView)
 	chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图被删除,请刷新页面"
 			br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error()
 			return
@@ -972,7 +973,7 @@ func (c *ChartInfoController) Move() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartInfoByClassifyId(chartInfo.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return
@@ -1074,7 +1075,7 @@ func (c *ChartInfoController) Refresh() {
 		chartInfo, err = data_manage.GetChartInfoByUniqueCode(uniqueCode)
 	}
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,无需刷新"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -1159,7 +1160,7 @@ func (c *ChartInfoController) EnInfoEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -1278,7 +1279,7 @@ func (c *ChartInfoController) DeleteChart() {
 	//删除图表
 	chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已删除,请刷新页面"
 			br.ErrMsg = "指标不存在,Err:" + err.Error()
 			return
@@ -1341,7 +1342,7 @@ func (c *ChartInfoController) DeleteChart() {
 	pars = append(pars, req.ChartInfoId)
 
 	nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "删除失败"
 		br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 		return
@@ -1361,14 +1362,14 @@ func (c *ChartInfoController) DeleteChart() {
 		tmpPars = append(tmpPars, chartInfo.ChartClassifyId)
 
 		classifyItem, err := data_manage.GetChartClassifyByCondition(tmpCondition, tmpPars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
 			return
 		}
 		if classifyItem != nil {
 			nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 				return
@@ -1450,7 +1451,7 @@ func (c *ChartInfoController) SearchByEs() {
 
 	sourceList := []int{utils.CHART_SOURCE_CROSS_HEDGING}
 
-	var searchList []*data_manage.ChartInfo
+	var searchList []*data_manage.ChartInfoMore
 	var total int64
 	var err error
 
@@ -1459,7 +1460,7 @@ func (c *ChartInfoController) SearchByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(c.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1473,7 +1474,7 @@ func (c *ChartInfoController) SearchByEs() {
 		searchList, total, err = data.EsSearchChartInfo(keyword, showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
 	} else {
 		total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -1503,13 +1504,17 @@ func (c *ChartInfoController) SearchByEs() {
 
 		for _, v := range searchList {
 			tmp := new(data_manage.ChartInfoMore)
-			tmp.ChartInfo = *v
+			tmp.ChartInfo = v.ChartInfo
 			// 图表数据权限
 			tmp.HaveOperaAuth = true
 			//判断是否需要展示英文标识
 			if _, ok := chartEdbMap[v.ChartInfoId]; ok {
 				tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, []*data_manage.ChartEdbInfoMapping{}, v.Source, v.ChartType)
 			}
+			tmp.SearchText = v.SearchText
+			if tmp.SearchText == "" {
+				tmp.SearchText = v.ChartName
+			}
 			finalList = append(finalList, tmp)
 		}
 	}
@@ -1553,7 +1558,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					msg = "获取失败"
 					errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -1696,7 +1701,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				msg = "获取失败"
 				errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -1791,7 +1796,7 @@ func (c *ChartInfoController) Save() {
 
 	chartItem, e := data_manage.GetChartInfoById(req.ChartInfoId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "图表已被删除, 请刷新页面"
 			return
 		}
@@ -1878,7 +1883,7 @@ func (c *ChartInfoController) BaseInfoEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return

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

@@ -36,7 +36,7 @@ func (c *ClassifyController) List() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(c.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -54,14 +54,14 @@ func (c *ClassifyController) List() {
 	}
 
 	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_CROSS_HEDGING)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	allChartInfo, err := data_manage.GetChartInfoAll([]int{source})
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
@@ -195,7 +195,7 @@ func (c *ClassifyController) DeleteChartClassifyCheck() {
 
 	if deleteStatus != 1 && req.ChartInfoId == 0 {
 		classifyCount, err := data_manage.GetChartClassifyCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
 			return
@@ -257,7 +257,7 @@ func (c *ClassifyController) DeleteChartClassify() {
 	if req.ChartClassifyId > 0 && req.ChartInfoId == 0 {
 		//判断是否含有指标
 		count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -281,7 +281,7 @@ func (c *ClassifyController) DeleteChartClassify() {
 	if req.ChartInfoId > 0 {
 		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -344,7 +344,7 @@ func (c *ClassifyController) DeleteChartClassify() {
 		pars = append(pars, req.ChartInfoId)
 
 		nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 			return
@@ -364,14 +364,14 @@ func (c *ClassifyController) DeleteChartClassify() {
 			pars = append(pars, chartInfo.ChartClassifyId)
 
 			classifyItem, err := data_manage.GetChartClassifyByCondition(condition, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
 				return
 			}
 			if classifyItem != nil {
 				nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 					return
@@ -497,7 +497,7 @@ func (c *ClassifyController) ChartClassifyMove() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartClassifyByParentIdAndSource(chartClassifyInfo.ParentId, chartClassifyInfo.Source)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取跨品种分析图表分类排序第一条的分类信息失败,Err:" + err.Error()
 			return

+ 5 - 5
controllers/data_manage/cross_variety/tag.go

@@ -45,12 +45,12 @@ func (c *TagController) Add() {
 	}
 	TagName := utils.TrimStr(req.TagName)
 	item, err := cross_variety.GetTagByName(TagName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "添加失败"
 		br.ErrMsg = "添加失败,Err:" + err.Error()
 		return
 	}
-	if item != nil {
+	if item != nil && item.ChartTagId > 0 {
 		br.Msg = "添加失败,标签名称不能重复"
 		br.IsSendEmail = false
 		return
@@ -110,12 +110,12 @@ func (c *TagController) Edit() {
 	TagName := utils.TrimStr(req.TagName)
 
 	item, err := cross_variety.GetTagByName(TagName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "添加失败"
 		br.ErrMsg = "添加失败,Err:" + err.Error()
 		return
 	}
-	if item != nil && item.ChartTagId != req.ChartTagId {
+	if item != nil && item.ChartTagId != req.ChartTagId && item.ChartTagId > 0 {
 		br.Msg = "添加失败,标签名称不能重复"
 		br.IsSendEmail = false
 		return
@@ -248,7 +248,7 @@ func (c *TagController) Delete() {
 
 	varietyInfo, err := cross_variety.GetTagById(req.ChartTagId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "该标签不存在或已删除"
 			br.IsSendEmail = false
 		} else {

+ 5 - 5
controllers/data_manage/cross_variety/variety.go

@@ -44,12 +44,12 @@ func (c *VarietyController) Add() {
 	}
 	varietyName := utils.TrimStr(req.VarietyName)
 	item, err := cross_variety.GetVarietyByName(varietyName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "添加失败"
 		br.ErrMsg = "添加失败,Err:" + err.Error()
 		return
 	}
-	if item != nil {
+	if item != nil && item.ChartVarietyId > 0 {
 		br.Msg = "添加失败,品种名称不能重复"
 		br.IsSendEmail = false
 		return
@@ -109,12 +109,12 @@ func (c *VarietyController) Edit() {
 	varietyName := utils.TrimStr(req.VarietyName)
 
 	item, err := cross_variety.GetVarietyByName(varietyName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "添加失败"
 		br.ErrMsg = "添加失败,Err:" + err.Error()
 		return
 	}
-	if item != nil && item.ChartVarietyId != req.ChartVarietyId {
+	if item != nil && item.ChartVarietyId != req.ChartVarietyId && item.ChartVarietyId > 0 {
 		br.Msg = "添加失败,品种名称不能重复"
 		br.IsSendEmail = false
 		return
@@ -246,7 +246,7 @@ func (c *VarietyController) Delete() {
 
 	varietyInfo, err := cross_variety.GetVarietyById(req.ChartVarietyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "该品种不存在或已删除"
 			br.IsSendEmail = false
 		} else {

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

@@ -129,7 +129,7 @@ func (c *DataMangePermissionController) MessageRead() {
 	messageOb := new(data_manage_permission.DataPermissionMessage)
 	messageItem, e := messageOb.GetItemById(req.MessageId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "消息不存在, 请刷新页面"
 			return
 		}
@@ -221,7 +221,7 @@ func (c *DataMangePermissionController) MessageDetail() {
 	messageOb := new(data_manage_permission.DataPermissionMessage)
 	messageItem, e := messageOb.GetItemById(messageId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "消息不存在, 请刷新页面"
 			return
 		}

+ 175 - 17
controllers/data_manage/edb_classify.go

@@ -9,7 +9,10 @@ import (
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
 	"eta/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"sort"
+	"strconv"
+	"strings"
 )
 
 // EdbClassifyController 数据管理-分类模块
@@ -29,13 +32,13 @@ func (this *EdbClassifyController) ListV2() {
 		this.ServeJSON()
 	}()
 	rootList, err := data_manage.GetEdbClassifyByParentId(0, 0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 	classifyAll, err := data_manage.GetEdbClassifyAll()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -57,7 +60,7 @@ func (this *EdbClassifyController) ListV2() {
 	// 获取当前账号的不可见指标
 	obj := data_manage.EdbInfoNoPermissionAdmin{}
 	confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 		return
@@ -67,7 +70,7 @@ func (this *EdbClassifyController) ListV2() {
 		noPermissionEdbInfoIdMap[v.EdbInfoId] = true
 	}
 	allEdbInfo, err := data_manage.GetEdbInfoAll(utils.EDB_INFO_TYPE)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -288,7 +291,7 @@ func (this *EdbClassifyController) EditEdbClassify() {
 		return
 	}
 
-	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ClassifyName, this.Lang, this.SysUser)
+	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ParentId, req.ClassifyName, this.Lang, this.SysUser)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -650,13 +653,13 @@ func (this *EdbClassifyController) ItemsV2() {
 		this.ServeJSON()
 	}()
 	rootList, err := data_manage.GetEdbClassifyByParentId(0, 0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 	classifyAll, err := data_manage.GetEdbClassifyAll()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -775,7 +778,7 @@ func (this *EdbClassifyController) ClassifyEdbInfoList() {
 	// 获取当前账号的不可见指标
 	obj := data_manage.EdbInfoNoPermissionAdmin{}
 	confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 		return
@@ -786,7 +789,7 @@ func (this *EdbClassifyController) ClassifyEdbInfoList() {
 	}
 
 	allEdbInfo, err := data_manage.GetEdbInfoByClassifyId(classifyId, 0, 0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -836,19 +839,19 @@ func (this *EdbClassifyController) ItemsV3() {
 		this.ServeJSON()
 	}()
 	rootList, err := data_manage.GetEdbClassifyByParentId(0, 0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 	rootTwoList, err := data_manage.GetEdbClassifyByParentIdTwo(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 	classifyAll, err := data_manage.GetEdbClassifyAllV2(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -974,7 +977,7 @@ func (this *EdbClassifyController) SimpleList() {
 		sysUserId = this.SysUser.AdminId
 	}
 	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, 0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -987,7 +990,7 @@ func (this *EdbClassifyController) SimpleList() {
 		// 获取当前账号的不可见指标
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1109,9 +1112,9 @@ func (this *EdbClassifyController) ClassifyTree() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-
+	level, _ := this.GetInt(`Level`)
 	allList, err := data_manage.GetNormalEdbClassifyAll()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -1135,7 +1138,7 @@ func (this *EdbClassifyController) ClassifyTree() {
 			button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
 			allList[k].Button = button
 		}
-		nodeAll = data.GetClassifyTreeRecursive(allList, 0)
+		nodeAll = data.GetClassifyTreeRecursive(allList, 0, level)
 		//根据sort值排序
 		sortList = nodeAll
 		sort.Sort(sortList)
@@ -1221,3 +1224,158 @@ func (this *EdbClassifyController) ClassifyTree() {
 //	br.Success = true
 //	br.Msg = "移动成功"
 //}
+
+// EdbInfoList
+// @Title 批量编辑指标列表接口
+// @Description 批量编辑指标列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   EdbInfoId   query   int  true       "指标id"
+// @Param   KeyWord   query   string  false       "搜索关键词:指标ID/指标名称"
+// @Success 200 {object} data_manage.EdbInfoListResp
+// @router /classify/edb/list [get]
+func (this *EdbInfoController) ClassifyEdbInfoList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	subClassify, _ := this.GetBool("SubClassify")
+	sources := this.GetString("Sources")
+	keyWord := this.GetString("KeyWord")
+	sysUserIds := this.GetString("SysUserIds")
+	classifyIdsStr := this.GetString("ClassifyIds")
+	classifyIds := strings.Split(classifyIdsStr, ",")
+
+	var condition string
+	var pars []interface{}
+
+	// 已授权分类id
+	//permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(this.SysUser.AdminId, 0)
+	//if err != nil {
+	//	br.Msg = "获取失败"
+	//	br.ErrMsg = "获取已授权分类id数据失败,Err:" + err.Error()
+	//	return
+	//}
+	classifyIdsArr := make([]int, 0)
+	for _, v := range classifyIds {
+		if v != `` {
+			id, _ := strconv.Atoi(v)
+			classifyIdsArr = append(classifyIdsArr, id)
+		}
+	}
+
+	//if len(permissionClassifyIdList) > 0 {
+	//	classifyIdsArr = utils.IntersectInt(permissionClassifyIdList, classifyIdsArr)
+	//}
+
+	condition += " AND edb_info_type = 0 "
+	if len(classifyIdsArr) > 0 {
+		if !subClassify {
+			condition += " AND classify_id IN(" + utils.GetOrmInReplace(len(classifyIdsArr)) + ") "
+			pars = append(pars, classifyIdsArr)
+		} else {
+			classifyAll, err := data_manage.GetNormalEdbClassifyAll()
+			if err != nil && !utils.IsErrNoRow(err) {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取数据失败,Err:" + err.Error()
+				return
+			}
+			finalClassifyIds := make([]int, 0)
+			parents := data.GetEdbClassifyChildrenRecursiveByParentIds(classifyAll, classifyIds)
+			sort.Slice(parents, func(i, j int) bool {
+				return parents[i].Level < parents[i].Level
+			})
+			for _, v := range parents {
+				finalClassifyIds = append(finalClassifyIds, v.ClassifyId)
+			}
+
+			condition += " AND classify_id IN(" + utils.GetOrmInReplace(len(finalClassifyIds)) + ") "
+			pars = append(pars, finalClassifyIds)
+		}
+	}
+
+	if keyWord != "" {
+		keyWordArr := strings.Split(keyWord, " ")
+		if len(keyWordArr) > 0 {
+			for _, v := range keyWordArr {
+				condition += ` AND edb_name LIKE '%` + v + `%' `
+			}
+		}
+	}
+	if sources != "" {
+		condition += " AND source IN(" + utils.GetOrmInReplace(len(strings.Split(sources, ","))) + ") "
+		pars = append(pars, strings.Split(sources, ","))
+	}
+	if sysUserIds != "" {
+		adminIds := strings.Split(sysUserIds, ",")
+		if len(adminIds) == 0 {
+			br.Msg = "请选择正确的创建人"
+			return
+		}
+		adminIdsSlice := make([]int, 0)
+		for _, adminId := range adminIds {
+			adminIdInt, e := strconv.Atoi(adminId)
+			if e != nil {
+				br.Msg = "请选择正确的创建人"
+				return
+			}
+			adminIdsSlice = append(adminIdsSlice, adminIdInt)
+		}
+		condition += "  AND sys_user_id in (" + utils.GetOrmInReplace(len(adminIds)) + ") "
+		pars = append(pars, adminIdsSlice)
+	}
+
+	// 获取当前账号的不可见指标
+	obj := data_manage.EdbInfoNoPermissionAdmin{}
+	confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+		return
+	}
+	noPermissionEdbInfoIds := make([]int, 0)
+	for _, v := range confList {
+		noPermissionEdbInfoIds = append(noPermissionEdbInfoIds, v.EdbInfoId)
+	}
+	if len(noPermissionEdbInfoIds) > 0 {
+		condition += " AND edb_info_id NOT IN(" + utils.GetOrmInReplace(len(noPermissionEdbInfoIds)) + ") "
+		pars = append(pars, noPermissionEdbInfoIds)
+	}
+
+	count, err := data_manage.GetEdbInfoByConditionCount(condition, pars)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	page := paging.GetPaging(currentIndex, pageSize, count)
+
+	list, err := data_manage.GetEdbInfoListByCondition(condition, pars, startSize, pageSize, "")
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	resp := new(data_manage.EdbInfoFilterDataResp)
+	resp.List = list
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

File diff ditekan karena terlalu besar
+ 144 - 108
controllers/data_manage/edb_info.go


+ 12 - 7
controllers/data_manage/edb_info_calculate.go

@@ -764,7 +764,7 @@ func (this *ChartInfoController) CalculateBatchEdit() {
 
 	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "指标已被删除,请刷新页面"
 			br.ErrMsg = "指标已被删除,请刷新页面:Err:" + err.Error()
 			return
@@ -933,7 +933,7 @@ func (this *ChartInfoController) CalculateBatchReset() {
 
 	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "指标已被删除,请刷新页面"
 			br.ErrMsg = "指标已删除,请刷新页面:Err:" + err.Error()
 			return
@@ -968,7 +968,7 @@ func (this *ChartInfoController) CalculateBatchReset() {
 	//	for _, v := range fromEdbInfoList {
 	//		edbInfo, err := data_manage.GetEdbInfoById(v.FromEdbInfoId)
 	//		if err != nil {
-	//			if err.Error() == utils.ErrNoRow() {
+	//			if utils.IsErrNoRow(err) {
 	//				br.Msg = "重新计算失败"
 	//				br.Msg = "指标 " + strconv.Itoa(v.FromEdbInfoId) + " 不存在"
 	//				return
@@ -1347,7 +1347,7 @@ func (this *ChartInfoController) EditPythonEdb() {
 	//获取指标信息
 	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "指标已被删除,请刷新页面"
 			br.ErrMsg = "指标已被删除,请刷新页面:Err:" + err.Error()
 			return
@@ -1476,7 +1476,12 @@ func (this *EdbInfoController) QueryEdbDataTable() {
 	if edbInfo.Source == utils.DATA_SOURCE_BUSINESS && utils.UseMongo {
 		templateStr = fmt.Sprintf("# 查询条件\nquery = {\"edb_code\": \"%s\"}\n# 排序\nsort = [(\"data_time\", -1)]  # -1 表示降序排列,对应 SQL 的 DESC\nprojection = {\"data_time\": 1, \"value\": 1, \"_id\": 0}  # 只选择data_time和value字段,忽略_id字段\n# 使用 find() 方法获取数据,然后使用 aggregate() 转换为列表\nraw_data = list(collection.find(query, projection).sort(sort))\n# 将结果转换为 DataFrame\nraw = pd.DataFrame(raw_data)\n# 转换data_time字段为本地时区时间\nraw['data_time'] = raw['data_time'].apply(lambda x: x.replace(tzinfo=utc_tz)).dt.tz_convert(local_tz).dt.strftime('%s')", edbInfo.EdbCode, "%Y-%m-%d")
 	} else {
-		templateStr = fmt.Sprintf("sql1 = f\"\"\"SELECT data_time,`value` FROM %s WHERE edb_code = '%s' ORDER BY data_time DESC;\"\"\"\nraw = pandas_fetch_all(sql1, db)", tableName, edbInfo.EdbCode)
+		switch utils.DbDriverName {
+		case `dm`:
+			templateStr = fmt.Sprintf("sql1 = f\"\"\"SELECT data_time,\"value\" FROM %s WHERE edb_code = '%s' ORDER BY data_time DESC;\"\"\"\nraw = pandas_fetch_all(sql1, db)", tableName, edbInfo.EdbCode)
+		default:
+			templateStr = fmt.Sprintf("sql1 = f\"\"\"SELECT data_time,`value` FROM %s WHERE edb_code = '%s' ORDER BY data_time DESC;\"\"\"\nraw = pandas_fetch_all(sql1, db)", tableName, edbInfo.EdbCode)
+		}
 	}
 	info := data_manage.TableInfoResp{
 		ColumnList:  columnList,
@@ -2252,7 +2257,7 @@ func (this *ChartInfoController) CalculateMultiChoice() {
 	}
 
 	list, err := data_manage.GetEdbInfoByIdList(edbIdArr)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标列表失败"
 		br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
 		return
@@ -2445,7 +2450,7 @@ func (this *ChartInfoController) CalculateMultiSearch() {
 		}
 
 		list, err := data_manage.GetEdbInfoByIdList(edbIdArr)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取指标列表失败"
 			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
 			return

+ 22 - 13
controllers/data_manage/edb_info_refresh.go

@@ -97,14 +97,14 @@ func (c *EdbInfoController) RefreshClassifyList() {
 	switch source {
 	case utils.DATA_SOURCE_MYSTEEL_CHEMICAL: // 钢联
 		rootList, err := data_manage.GetBaseFromMysteelChemicalClassifyByParentId(0)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
 		}
 
 		classifyAll, err := data_manage.GetAllBaseFromMysteelChemicalClassify()
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
@@ -161,14 +161,14 @@ func (c *EdbInfoController) RefreshClassifyList() {
 			Children:     nil,
 		})
 		rootList, err := data_manage.GetBaseFromSmmClassifyByParentId(0)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
 		}
 
 		classifyAll, err := data_manage.GetAllBaseFromSmmClassify()
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
@@ -204,7 +204,7 @@ func (c *EdbInfoController) RefreshClassifyList() {
 
 	default:
 		tmpList, err := data_manage.GetAllEdbClassify()
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
@@ -262,11 +262,20 @@ func buildTree(items []*edb_refresh.BaseClassifyItems, parentId int) []*edb_refr
 // @router /edb_info/refresh/edb_list [get]
 func (c *EdbInfoController) RefreshEdbList() {
 	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
+	}
 
 	source, _ := c.GetInt("Source")
 	subSource, _ := c.GetInt("SubSource")
@@ -304,7 +313,7 @@ func (c *EdbInfoController) RefreshEdbList() {
 	startSize = utils.StartIndex(currentIndex, pageSize)
 
 	total, list, err := data.GetList(source, subSource, classifyId, terminalCode, sysUserId, frequency, keyword, status, startSize, pageSize, sortParam, sortType)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -359,7 +368,7 @@ func (c *EdbInfoController) GetEdbRefreshDefaultConfig() {
 	}
 
 	// 非有色的来源,频度不能为空
-	if source != utils.DATA_SOURCE_YS && frequency == `` {
+	if source != utils.DATA_SOURCE_YS && source != utils.DATA_SOURCE_RADISH_RESEARCH && frequency == `` {
 		br.Msg = "频度不能为空"
 		br.IsSendEmail = false
 		return
@@ -481,7 +490,7 @@ func (c *EdbInfoController) SaveEdbRefreshStatus() {
 	if req.IsSelectAll {
 		// 如果是列表全选
 		_, edbList, err := data.GetList(req.Source, req.SubSource, req.ClassifyId, req.TerminalCode, req.SysUserId, req.Frequency, req.Keyword, req.Status, 0, 100000, "", "")
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
@@ -529,7 +538,7 @@ func (c *EdbInfoController) SaveEdbRefreshStatus() {
 	if isStop == 1 {
 		fromEdbIdList := make([]int, 0)
 		edbList, e := data_manage.GetEdbInfoByIdList(edbIdList)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + e.Error()
 			return
@@ -598,7 +607,7 @@ func (c *EdbInfoController) SaveEdbRefreshStatusSingle() {
 	// 查询指标
 	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "指标不存在"
 			return
 		}
@@ -685,7 +694,7 @@ func (c *EdbInfoController) SaveRelationEdbRefreshStatus() {
 	if req.IsSelectAll {
 		// 如果是列表全选
 		_, edbList, err := data.GetEdbRelationList(req.Source, edbType, req.ClassifyId, req.SysUserId, req.Frequency, req.Keyword, req.Status, 0, 100000, "", "")
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
@@ -718,7 +727,7 @@ func (c *EdbInfoController) SaveRelationEdbRefreshStatus() {
 	}
 	//查询指标信息
 	edbList, e := data_manage.GetEdbInfoByIdList(edbIdList)
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + e.Error()
 		return

+ 42 - 14
controllers/data_manage/edb_info_relation.go

@@ -80,7 +80,7 @@ func (c *EdbInfoRelationController) RelationEdbList() {
 	startSize = utils.StartIndex(currentIndex, pageSize)
 
 	total, list, err := data.GetEdbRelationList(source, edbType, classifyId, sysUserId, frequency, keyword, status, startSize, pageSize, sortParam, sortType)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -127,7 +127,7 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 	startSize = utils.StartIndex(currentIndex, pageSize)
 
 	total, relationList, err := data_manage.GetEdbInfoRelationDetailList(edbInfoId, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -144,6 +144,9 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 	// 查询事件日历
 	eventInfoIds := make([]int, 0)
 
+	// 预测指标
+	predictEdbIds := make([]int, 0)
+
 	for _, v := range relationList {
 		switch v.ReferObjectType {
 		case utils.EDB_RELATION_SANDBOX:
@@ -154,18 +157,21 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 			chartInfoIds = append(chartInfoIds, v.ReferObjectId)
 		case utils.EDB_RELATION_TABLE:
 			tableInfoIds = append(tableInfoIds, v.ReferObjectId)
+		case utils.EDB_RELATION_PREDICT_EDB:
+			predictEdbIds = append(predictEdbIds, v.ReferObjectId)
 		}
 	}
-	objectNameMap := make(map[int]string)
+	objectNameMap := make(map[string]string)
 	if len(sandboxIds) > 0 {
 		sandboxList, err := sandbox.GetSandboxNameByIds(sandboxIds)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
 		}
 		for _, v := range sandboxList {
-			objectNameMap[v.SandboxId] = v.Name
+			name := fmt.Sprintf("%d_%d", utils.EDB_RELATION_SANDBOX, v.SandboxId)
+			objectNameMap[name] = v.Name
 		}
 	}
 
@@ -176,26 +182,28 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 		pars := make([]interface{}, 0)
 		pars = append(pars, eventInfoIds)
 		eventList, err := matterOb.GetItemsByCondition(cond, pars, []string{}, "")
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取事件日历数据失败,Err:" + err.Error()
 			return
 		}
 		for _, v := range eventList {
-			objectNameMap[v.FeCalendarMatterId] = fmt.Sprintf("%s, %s", v.MatterDate, v.ChartPermissionName)
+			name := fmt.Sprintf("%d_%d", utils.EDB_RELATION_CALENDAR, v.FeCalendarMatterId)
+			objectNameMap[name] = fmt.Sprintf("%s, %s", v.MatterDate, v.ChartPermissionName)
 		}
 	}
 
 	// 查询图表
 	if len(chartInfoIds) > 0 {
 		chartList, err := data_manage.GetChartInfoByIdList(chartInfoIds)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表数据失败,Err:" + err.Error()
 			return
 		}
 		for _, v := range chartList {
-			objectNameMap[v.ChartInfoId] = v.ChartName
+			name := fmt.Sprintf("%d_%d", utils.EDB_RELATION_CHART, v.ChartInfoId)
+			objectNameMap[name] = v.ChartName
 		}
 	}
 
@@ -205,7 +213,7 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 		pars := make([]interface{}, 0)
 		pars = append(pars, tableInfoIds)
 		tableList, err := excel.GetNoContentExcelInfoListByConditionNoPage(cond, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取表格数据失败,Err:" + err.Error()
 			return
@@ -223,7 +231,7 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 			pars = make([]interface{}, 0)
 			pars = append(pars, parentIds)
 			parentList, err := excel.GetNoContentExcelInfoListByConditionNoPage(cond, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取表格数据失败,Err:" + err.Error()
 				return
@@ -233,16 +241,32 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 			}
 		}
 		for _, v := range tableList {
+			name := fmt.Sprintf("%d_%d", utils.EDB_RELATION_TABLE, v.ExcelInfoId)
 			if v.ParentId > 0 {
 				parentName := excelParentName[v.ParentId]
-				objectNameMap[v.ExcelInfoId] = fmt.Sprintf("%s_%s", parentName, v.ExcelName)
+				objectNameMap[name] = fmt.Sprintf("%s_%s", parentName, v.ExcelName)
 			} else {
-				objectNameMap[v.ExcelInfoId] = v.ExcelName
+				objectNameMap[name] = v.ExcelName
 			}
 		}
 	}
+
+	// 查询预测指标名称
+	if len(predictEdbIds) > 0 {
+		predictList, err := data_manage.GetEdbInfoByIdList(predictEdbIds)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取预测指标信息失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range predictList {
+			name := fmt.Sprintf("%d_%d", utils.EDB_RELATION_PREDICT_EDB, v.EdbInfoId)
+			objectNameMap[name] = v.EdbName
+		}
+	}
 	for _, v := range relationList {
-		referObjectName, _ := objectNameMap[v.ReferObjectId]
+		name := fmt.Sprintf("%d_%d", v.ReferObjectType, v.ReferObjectId)
+		referObjectName, _ := objectNameMap[name]
 		tmp := &data_manage.EdbInfoRelationDetail{
 			EdbInfoRelationId:  v.EdbInfoRelationId,
 			EdbInfoId:          v.EdbInfoId,
@@ -271,6 +295,8 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 				tmp.ReferObjectTypeName = "跨品种分析"
 			case utils.CHART_SOURCE_FUTURE_GOOD, utils.CHART_SOURCE_FUTURE_GOOD_PROFIT:
 				tmp.ReferObjectTypeName = "商品价格曲线"
+			case utils.CHART_SOURCE_RANGE_ANALYSIS:
+				tmp.ReferObjectTypeName = "区间分析"
 			}
 		case utils.EDB_RELATION_TABLE:
 			switch v.ReferObjectSubType {
@@ -281,6 +307,8 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 			case utils.BALANCE_TABLE:
 				tmp.ReferObjectTypeName = "平衡表"
 			}
+		case utils.EDB_RELATION_PREDICT_EDB:
+			tmp.ReferObjectTypeName = "预测指标"
 		}
 		list = append(list, tmp)
 	}

+ 3 - 2
controllers/data_manage/eia_steo.go

@@ -47,6 +47,7 @@ func (this *EdbInfoController) EiaSteoClassify() {
 	childClassifyMap := make(map[int][]*data_manage.BaseFromEiaSteoClassifyView)
 	rootList := make([]*data_manage.BaseFromEiaSteoClassifyView, 0)
 	for _, v := range classifyList {
+		v.UniqueCode = strconv.Itoa(v.BaseFromEiaSteoClassifyId)
 		if v.Level == 1 {
 			rootList = append(rootList, v)
 		} else {
@@ -556,7 +557,7 @@ func (c *EdbInfoController) EiaSteoNameCheck() {
 			EdbName: v.EdbName,
 		})
 		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_EIA_STEO, 0, utils.EDB_DATA_LIMIT)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
 			return
@@ -814,7 +815,7 @@ func (this *EdbInfoController) EiaSteoAdd() {
 
 	tmpInfo, err := data_manage.GetBaseFromEiaSteoIndexByCode(req.EdbCode)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取失败,Err:" + err.Error()
 			return

+ 21 - 10
controllers/data_manage/excel/balance_table.go

@@ -17,13 +17,14 @@ import (
 	excel2 "eta/eta_api/services/excel"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/tealeg/xlsx"
 	"io/ioutil"
 	"os"
 	"sort"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/tealeg/xlsx"
 )
 
 // GetChildTable
@@ -505,7 +506,7 @@ func (c *ExcelInfoController) BalanceChartInfoAdd() {
 	adminItem, e := system.GetSysAdminById(sysUser.AdminId)
 	if e != nil {
 		br.Msg = "操作失败"
-		br.ErrMsg = "获取系统用户数据失败,Err:" + err.Error()
+		br.ErrMsg = "获取系统用户数据失败,Err:" + e.Error()
 		return
 	}
 	if utils.BusinessCode == utils.BusinessCodeSandbox && adminItem.DepartmentName == "ETA试用客户" {
@@ -712,7 +713,7 @@ func (c *ExcelInfoController) GetBalanceChartList() {
 	// 查询所有子表
 	excelInfo, err := excel.GetExcelInfoById(excelInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "表格不存在"
 			return
 		}
@@ -810,7 +811,7 @@ func (c *ExcelInfoController) DeleteBalanceChart() {
 	if req.ChartInfoId > 0 {
 		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -1146,6 +1147,11 @@ func (c *ExcelInfoController) AddStaticExcel() {
 	resp.ExcelInfoId = excelInfo.ExcelInfoId
 	resp.UniqueCode = excelInfo.UniqueCode
 
+	// 写入ES
+	go func() {
+		excel2.EsAddOrEditExcel(excelInfo.ExcelInfoId)
+	}()
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "保存成功"
@@ -1413,13 +1419,18 @@ func downloadBalanceTable(excelInfo *excel.ExcelInfo, lang string) (savePath, zi
 				errMsg = msg
 				return
 			}
-			tableData, er := excel2.GetTableDataByMixedTableData(newResult, false)
+			tableData, er := excel2.GetTableDataByMixedTableData(newResult, false, childExcelInfo.ExcelInfoId)
 			if er != nil {
 				errMsg = "获取失败"
 				err = fmt.Errorf("转换成table失败,Err:" + err.Error())
 				return
 			}
-
+			//tableData, err = excel2.HandleRuleToTableCell(childExcelInfo.ExcelInfoId, tableData)
+			//if err != nil {
+			//	errMsg = "获取失败"
+			//	err = fmt.Errorf("处理条件格式管理规则失败,Err:%w", err)
+			//	return
+			//}
 			// 将单个sheet的数据写入到excel
 			err = tableData.WriteExcelSheetData(xlsxFile, childExcelInfo.ExcelName)
 			if err != nil {
@@ -1590,7 +1601,7 @@ func (this *ExcelInfoController) BalanceChartInfoBaseEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -1613,7 +1624,7 @@ func (this *ExcelInfoController) BalanceChartInfoBaseEdit() {
 		edbInfoId := v.EdbInfoId
 		edbInfo, err := excel.GetExcelChartEdbById(edbInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表不存在!"
 				br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId)
 				return
@@ -1648,7 +1659,7 @@ func (this *ExcelInfoController) BalanceChartInfoBaseEdit() {
 
 			edbExist, err := excel.GetBalanceChartEdbByCondition(edbCondition, edbPars)
 			if err != nil {
-				if err.Error() != utils.ErrNoRow() {
+				if !utils.IsErrNoRow(err) {
 					br.Msg = "判断英文指标名称是否存在失败"
 					br.ErrMsg = "判断英文指标名称是否存在失败,Err:" + err.Error()
 					return
@@ -1680,7 +1691,7 @@ func (this *ExcelInfoController) BalanceChartInfoBaseEdit() {
 
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return

+ 20 - 9
controllers/data_manage/excel/custom_analysis.go

@@ -13,6 +13,7 @@ import (
 	"eta/eta_api/services/data/data_manage_permission"
 	"eta/eta_api/services/data/excel"
 	excel2 "eta/eta_api/services/data/excel"
+	excel3 "eta/eta_api/services/excel"
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
@@ -61,7 +62,7 @@ func (c *CustomAnalysisController) ExcelByName() {
 	// 获取数据详情
 	excelDetail, err := excelModel.GetNoContentExcelInfoByName(excelName, utils.CUSTOM_ANALYSIS_TABLE, sysUser.AdminId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Ret = 200
 			br.Success = true
 			br.Msg = "获取成功"
@@ -224,6 +225,11 @@ func (c *CustomAnalysisController) Add() {
 	// 生成excel文件
 	go excel.UpdateExcelInfoFileUrl(excelInfo)
 
+	// 写入ES
+	go func() {
+		excel3.EsAddOrEditExcel(excelInfo.ExcelInfoId)
+	}()
+
 	//新增操作日志
 	//{
 	//	excelLog := &data_manage.ExcelInfoLog{
@@ -344,6 +350,11 @@ func (c *CustomAnalysisController) Save() {
 	// 生成excel文件
 	go excel.UpdateExcelInfoFileUrl(excelInfo)
 
+	// 写入ES
+	go func() {
+		excel3.EsAddOrEditExcel(excelInfo.ExcelInfoId)
+	}()
+
 	//新增操作日志
 	//{
 	//	excelLog := &data_manage.ExcelInfoLog{
@@ -402,7 +413,7 @@ func (c *CustomAnalysisController) BaseExcelDetail() {
 	// 获取数据详情
 	excelDetail, err := excelModel.GetNoContentExcelInfoByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Ret = 200
 			br.Success = true
 			br.Msg = "获取成功"
@@ -560,7 +571,7 @@ func (c *CustomAnalysisController) ExcelDataList() {
 	// 获取数据详情
 	excelDetail, err := excelModel.GetNoContentExcelInfoByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Ret = 200
 			br.Success = true
 			br.Msg = "获取成功"
@@ -785,7 +796,7 @@ func (c *CustomAnalysisController) ClassifyList() {
 		classifyMap[v.ExcelClassifyId] = v
 	}
 	allExcelInfo, err := excelModel.GetNoContentExcelInfoAll(source, sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取表格信息失败,Err:" + err.Error()
 		return
@@ -948,14 +959,14 @@ func (c *CustomAnalysisController) List() {
 	// 筛选分类
 	if !isShare && excelClassifyId > 0 {
 		_, err := excelModel.GetExcelClassifyById(excelClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取表格信息失败"
 			br.ErrMsg = "获取信息失败,GetExcelClassify,Err:" + err.Error()
 			return
 		}
 
 		childClassify, e, _ := excel2.GetChildClassifyByClassifyId(excelClassifyId, source)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
 			return
@@ -989,7 +1000,7 @@ func (c *CustomAnalysisController) List() {
 	}
 	startSize = paging.StartIndex(currentIndex, pageSize)
 	list, err := excelModel.GetNoContentExcelListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取表格信息失败"
 		br.ErrMsg = "获取表格信息失败,Err:" + err.Error()
@@ -1002,7 +1013,7 @@ func (c *CustomAnalysisController) List() {
 
 	// 总数据量
 	dataCount, err := excelModel.GetExcelListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取表格列表信息失败"
 		br.ErrMsg = "获取表格列表数据总数失败,Err:" + err.Error()
 		return
@@ -1055,7 +1066,7 @@ func (c *CustomAnalysisController) Share() {
 
 	excelInfo, e := excelModel.GetExcelInfoById(req.ExcelInfoId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "表格不存在, 请刷新页面"
 			return
 		}

+ 1 - 1
controllers/data_manage/excel/custom_analysis_edb.go

@@ -312,7 +312,7 @@ func (c *CustomAnalysisController) EditEdb() {
 
 	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "指标已被删除,请刷新页面"
 			br.ErrMsg = "指标已被删除,请刷新页面:Err:" + err.Error()
 			return

+ 15 - 15
controllers/data_manage/excel/excel_classify.go

@@ -87,14 +87,14 @@ func (this *ExcelClassifyController) List() {
 		}
 
 		allExcelInfo, err = excel.GetBalanceNoContentExcelInfoAll(source, excelIds, showUserId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取表格信息失败,Err:" + err.Error()
 			return
 		}
 	} else {
 		allExcelInfo, err = excel.GetNoContentExcelInfoAll(source, showUserId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取表格信息失败,Err:" + err.Error()
 			return
@@ -196,7 +196,7 @@ func AnalysisClassifyList(this *ExcelClassifyController) (br *models.BaseRespons
 	// 获取三级分类
 	// 根据来源获取所有excel表格(无内容)
 	allExcelInfo, err := excel.GetNoContentExcelInfoAll(source, showUserId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取表格信息失败,Err:" + err.Error()
 		return
@@ -432,7 +432,7 @@ func (this *ExcelClassifyController) AddExcelClassify() {
 		var parent *excel.ExcelClassify
 		parent, err = excel.GetExcelClassifyById(req.ParentId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "父级分类不存在"
 				return
 			}
@@ -577,7 +577,7 @@ func (this *ExcelClassifyController) DeleteExcelClassifyCheck() {
 	// 校验是否存在该分类
 	ExcelClassifyInfo, err := excel.GetExcelClassifyById(req.ExcelClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "该分类不存在"
 			br.ErrMsg = "该分类不存在"
 			return
@@ -607,7 +607,7 @@ func (this *ExcelClassifyController) DeleteExcelClassifyCheck() {
 			tipsMsg = "该分类下关联表格不可删除"
 		} else {
 			childClassify, e := excel.GetChildClassifyById(req.ExcelClassifyId)
-			if e != nil && e.Error() != utils.ErrNoRow() {
+			if e != nil && !utils.IsErrNoRow(e) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
 				return
@@ -621,7 +621,7 @@ func (this *ExcelClassifyController) DeleteExcelClassifyCheck() {
 				var pars []interface{}
 				pars = append(pars, classifyIds)
 				childCount, err := excel.GetExcelInfoCountByCondition(condition, pars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "查询分类下表格数量失败,Err:" + err.Error()
 					return
@@ -701,7 +701,7 @@ func (this *ExcelClassifyController) DeleteExcelClassify() {
 	if req.ExcelClassifyId > 0 && req.ExcelInfoId == 0 {
 		//判断是否含有指标
 		count, err := excel.GetExcelInfoCountByClassifyId(req.ExcelClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -713,7 +713,7 @@ func (this *ExcelClassifyController) DeleteExcelClassify() {
 			return
 		} else {
 			childClassify, e := excel.GetChildClassifyById(req.ExcelClassifyId)
-			if e != nil && e.Error() != utils.ErrNoRow() {
+			if e != nil && !utils.IsErrNoRow(e) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
 				return
@@ -727,7 +727,7 @@ func (this *ExcelClassifyController) DeleteExcelClassify() {
 				var pars []interface{}
 				pars = append(pars, classifyIds)
 				childCount, err := excel.GetExcelInfoCountByCondition(condition, pars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "查询分类下表格数量失败,Err:" + err.Error()
 					return
@@ -744,7 +744,7 @@ func (this *ExcelClassifyController) DeleteExcelClassify() {
 		if err != nil {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取分类失败,Err:" + err.Error()
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "分类不存在"
 				br.ErrMsg = "分类不存在"
 			}
@@ -764,7 +764,7 @@ func (this *ExcelClassifyController) DeleteExcelClassify() {
 	if req.ExcelInfoId > 0 {
 		excelInfo, err := excel.GetExcelInfoById(req.ExcelInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "表格已删除,请刷新页面"
 				br.ErrMsg = "表格已删除,请刷新页面"
 				return
@@ -808,7 +808,7 @@ func (this *ExcelClassifyController) DeleteExcelClassify() {
 			pars = append(pars, excelInfo.Sort, excelInfo.Sort, excelInfo.ExcelInfoId)
 
 			nextItem, err = excel.GetNextExcelInfoByCondition(condition, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级表格信息失败,Err:" + err.Error()
 				return
@@ -817,14 +817,14 @@ func (this *ExcelClassifyController) DeleteExcelClassify() {
 			// 如果没找到,那么查找下一个分类的第一个表格
 			if nextItem == nil {
 				currClassifyInfo, err := excel.GetExcelClassifyById(excelInfo.ExcelClassifyId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取当前表格分类信息失败,Err:" + err.Error()
 					return
 				}
 
 				nextItem, err = excel.GetNextExcelInfo(excelInfo.ExcelClassifyId, currClassifyInfo.Sort, currClassifyInfo.Source)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取下一级表格信息失败,Err:" + err.Error()
 					return

+ 463 - 38
controllers/data_manage/excel/excel_info.go

@@ -6,6 +6,7 @@ import (
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
+	excelPermissionModel "eta/eta_api/models/data_manage/data_manage_permission"
 	excel3 "eta/eta_api/models/data_manage/excel"
 	"eta/eta_api/models/data_manage/excel/request"
 	"eta/eta_api/models/data_manage/excel/response"
@@ -13,6 +14,7 @@ import (
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
 	excel2 "eta/eta_api/services/data/excel"
+	"eta/eta_api/services/elastic"
 	"eta/eta_api/services/excel"
 	"eta/eta_api/utils"
 	"fmt"
@@ -89,7 +91,7 @@ func (c *ExcelInfoController) Add() {
 	if req.ExcelClassifyId > 0 {
 		excelClassify, e := excel3.GetExcelClassifyById(req.ExcelClassifyId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "分类不存在"
 				br.ErrMsg = "分类不存在"
 				br.IsSendEmail = false
@@ -110,7 +112,7 @@ func (c *ExcelInfoController) Add() {
 	if req.ParentId > 0 {
 		parentExcelInfo, e := excel3.GetExcelInfoById(req.ParentId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "父级ETA表格被删除,请刷新页面"
 				return
 			}
@@ -121,6 +123,18 @@ func (c *ExcelInfoController) Add() {
 		req.ExcelClassifyId = parentExcelInfo.ExcelClassifyId
 	}
 
+	// 额外配置(表格冻结行列等)
+	var extraConfig string
+	if req.ExtraConfig != nil {
+		b, e := json.Marshal(req.ExtraConfig)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("操作失败, %v", e)
+			return
+		}
+		extraConfig = string(b)
+	}
+
 	var condition string
 	var pars []interface{}
 	condition += " AND excel_classify_id=? AND parent_id=?"
@@ -257,6 +271,7 @@ func (c *ExcelInfoController) Add() {
 		UpdateUserId:       sysUser.AdminId,
 		UpdateUserRealName: sysUser.RealName,
 		SourcesFrom:        req.SourcesFrom,
+		ExtraConfig:        extraConfig,
 	}
 
 	excelEdbMappingList := make([]*excel3.ExcelEdbMapping, 0)
@@ -293,6 +308,7 @@ func (c *ExcelInfoController) Add() {
 			//ParentId:           req.ParentId,
 			UpdateUserId:       sysUser.AdminId,
 			UpdateUserRealName: sysUser.RealName,
+			ExtraConfig:        extraConfig,
 		}
 	}
 	err = excel3.AddExcelInfo(excelInfo, excelEdbMappingList, childExcel)
@@ -336,6 +352,15 @@ func (c *ExcelInfoController) Add() {
 	//	go data_manage.AddExcelInfoLog(excelLog)
 	//}
 
+	// 写入ES
+	go func() {
+		excel.EsAddOrEditExcel(excelInfo.ExcelInfoId)
+
+		if childExcel != nil && childExcel.ExcelInfoId > 0 {
+			excel.EsAddOrEditExcel(childExcel.ExcelInfoId)
+		}
+	}()
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "保存成功"
@@ -411,14 +436,14 @@ func (c *ExcelInfoController) List() {
 	// 筛选分类
 	if excelClassifyId > 0 {
 		_, err := excel3.GetExcelClassifyById(excelClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取表格信息失败"
 			br.ErrMsg = "获取信息失败,GetExcelClassify,Err:" + err.Error()
 			return
 		}
 
 		childClassify, e, _ := excel2.GetChildClassifyByClassifyId(excelClassifyId, source)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
 			return
@@ -496,7 +521,7 @@ func (c *ExcelInfoController) List() {
 
 			//获取表格信息
 			tmpList, e := excel3.GetNoContentExcelListByConditionNoPage(newCondition, newPars)
-			if e != nil && e.Error() != utils.ErrNoRow() {
+			if e != nil && !utils.IsErrNoRow(e) {
 				br.Success = true
 				br.Msg = "获取表格信息失败"
 				br.ErrMsg = "获取表格信息失败,Err:" + e.Error()
@@ -554,7 +579,7 @@ func (c *ExcelInfoController) List() {
 	}
 	//获取表格信息
 	list, err := excel3.GetNoContentExcelListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取表格信息失败"
 		br.ErrMsg = "获取表格信息失败,Err:" + err.Error()
@@ -562,7 +587,7 @@ func (c *ExcelInfoController) List() {
 	}
 
 	lenList := len(list)
-	if list == nil || lenList <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || lenList <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		list = make([]*excel3.MyExcelInfoList, 0)
 	}
 
@@ -613,13 +638,17 @@ func (c *ExcelInfoController) List() {
 				// excel表格按钮权限
 				list[k].Button = excel2.GetBalanceExcelInfoOpButton(sysUser.AdminId, v.SysUserId, v.HaveOperaAuth, v.ExcelInfoId)
 			}
+			// 持仓分析表格
+			if v.Source == utils.TRADE_ANALYSIS_TABLE || v.Source == utils.TRADE_ANALYSIS_CORRELATION_TABLE {
+				list[k].Button = services.GetTradeAnalysisTableOpButton(v.SysUserId, sysUser.AdminId, sysUser.RoleTypeCode, v.HaveOperaAuth)
+			}
 		}
 
 	}
 
 	// 总数据量
 	dataCount, err := excel3.GetExcelListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取表格列表信息失败"
 		br.ErrMsg = "获取表格列表数据总数失败,Err:" + err.Error()
 		return
@@ -870,7 +899,7 @@ func (c *ExcelInfoController) Edit() {
 	if req.ExcelClassifyId > 0 {
 		excelClassify, e := excel3.GetExcelClassifyById(req.ExcelClassifyId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "分类不存在"
 				br.ErrMsg = "分类不存在"
 				br.IsSendEmail = false
@@ -890,7 +919,7 @@ func (c *ExcelInfoController) Edit() {
 	if excelInfo.ParentId > 0 {
 		parentExcelInfo, e := excel3.GetExcelInfoById(excelInfo.ParentId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "父级ETA表格被删除,请刷新页面"
 				return
 			}
@@ -1042,6 +1071,18 @@ func (c *ExcelInfoController) Edit() {
 		updateExcelInfoParams = []string{"ModifyTime", "ExcelName", "ExcelType", "ExcelClassifyId", "Content", "SourcesFrom"}
 	}
 
+	// 额外配置(表格冻结行列等)
+	if req.ExtraConfig != nil {
+		b, e := json.Marshal(req.ExtraConfig)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("操作失败, %v", e)
+			return
+		}
+		excelInfo.ExtraConfig = string(b)
+		updateExcelInfoParams = append(updateExcelInfoParams, "ExtraConfig")
+	}
+
 	excelEdbMappingList := make([]*excel3.ExcelEdbMapping, 0)
 	if len(edbInfoIdList) > 0 {
 		for _, edbInfoId := range edbInfoIdList {
@@ -1091,6 +1132,16 @@ func (c *ExcelInfoController) Edit() {
 		err = excel3.AddExcelDraft(excelDraftInfo)
 	}
 
+	// 判断是否清除该表引用
+	if req.IsColChange {
+		err = excel3.DeleteReferencedExcelConfig(excelInfo.UniqueCode)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = err.Error()
+			return
+		}
+	}
+
 	resp := response.AddExcelInfoResp{
 		ExcelInfoId: excelInfo.ExcelInfoId,
 		UniqueCode:  excelInfo.UniqueCode,
@@ -1100,6 +1151,11 @@ func (c *ExcelInfoController) Edit() {
 	//删除公共图库那边的缓存
 	_ = utils.Rc.Delete(utils.HZ_CHART_LIB_EXCEL_TABLE_DETAIL + ":" + excelInfo.UniqueCode)
 
+	// 写入ES
+	go func() {
+		excel.EsAddOrEditExcel(excelInfo.ExcelInfoId)
+	}()
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "修改成功"
@@ -1155,7 +1211,7 @@ func (c *ExcelInfoController) Move() {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取分类信息失败" + err.Error()
 
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "分类已被删除,不可移动,请刷新页面"
 				br.ErrMsg = "分类已被删除,不可移动,请刷新页面"
 				br.IsSendEmail = false
@@ -1364,7 +1420,7 @@ func (c *ExcelInfoController) Delete() {
 		condition += " AND sort>=? "
 		pars = append(pars, excelInfo.Sort)
 		nextItem, err = excel3.GetNextExcelInfoByCondition(condition, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级表格信息失败,Err:" + err.Error()
 			return
@@ -1373,7 +1429,7 @@ func (c *ExcelInfoController) Delete() {
 		// 如果没找到,那么查找下一个分类的第一个表格
 		if nextItem == nil {
 			currClassifyInfo, err := excel3.GetExcelClassifyById(excelInfo.ExcelClassifyId)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取当前表格分类信息失败,Err:" + err.Error()
 				return
@@ -1402,7 +1458,7 @@ func (c *ExcelInfoController) Delete() {
 			//}
 
 			nextItem, err = excel3.GetNextExcelInfo(excelInfo.ExcelClassifyId, currClassifyInfo.Sort, currClassifyInfo.Source)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级表格信息失败,Err:" + err.Error()
 				return
@@ -1421,6 +1477,11 @@ func (c *ExcelInfoController) Delete() {
 	//删除公共图库那边的缓存
 	_ = utils.Rc.Delete(utils.HZ_CHART_LIB_EXCEL_TABLE_DETAIL)
 
+	// 写入ES
+	go func() {
+		excel.EsAddOrEditExcel(excelInfo.ExcelInfoId)
+	}()
+
 	br.Ret = 200
 	br.Success = true
 	br.IsAddLog = true
@@ -1472,7 +1533,7 @@ func (c *ExcelInfoController) AddDraft() {
 
 	excelClassify, err := excel3.GetExcelClassifyById(req.ExcelClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			br.ErrMsg = "分类不存在"
 			br.IsSendEmail = false
@@ -1556,6 +1617,8 @@ func (c *ExcelInfoController) GetExcelTableData() {
 	}
 	uniqueCode := c.GetString("UniqueCode")
 	fromScene, _ := c.GetInt("FromScene", 0)
+	referencedId, _ := c.GetInt("ReferencedId", 0)
+	uuid := c.GetString("Uuid")
 
 	var err error
 	if uniqueCode == `` {
@@ -1569,7 +1632,7 @@ func (c *ExcelInfoController) GetExcelTableData() {
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取ETA表格信息失败,Err:" + err.Error()
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "ETA表格被删除,请刷新页面"
 			br.ErrMsg = "ETA表格被删除,请刷新页面,Err:" + err.Error()
 			br.IsSendEmail = false
@@ -1621,7 +1684,7 @@ func (c *ExcelInfoController) GetExcelTableData() {
 		}
 		excelSource = strings.Join(sourceNameList, ",")
 		excelSourceEn = strings.Join(sourceNameEnList, ",")
-	case utils.MIXED_TABLE:
+	case utils.MIXED_TABLE, utils.BALANCE_TABLE:
 		var result request.MixedTableReq
 		err = json.Unmarshal([]byte(excelInfo.Content), &result)
 		if err != nil {
@@ -1638,7 +1701,7 @@ func (c *ExcelInfoController) GetExcelTableData() {
 			br.ErrMsg = "获取最新的数据失败,Err:" + err.Error()
 			return
 		}
-		tableData, err = excel.GetTableDataByMixedTableData(newResult, true)
+		tableData, err = excel.GetTableDataByMixedTableData(newResult, true, excelInfo.ExcelInfoId)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "转换成table失败,Err:" + err.Error()
@@ -1667,7 +1730,7 @@ func (c *ExcelInfoController) GetExcelTableData() {
 	}
 
 	tableData = excel.HandleTableCell(tableData)
-	tableData, err = excel.HandleRuleToTableCell(excelInfo.ExcelInfoId, tableData)
+	// tableData, err = excel.HandleRuleToTableCell(excelInfo.ExcelInfoId, tableData)
 	if err != nil {
 		utils.FileLog.Info("表格管理规则处理失败,HandleRuleToTableCell err:", err.Error())
 	}
@@ -1687,17 +1750,26 @@ func (c *ExcelInfoController) GetExcelTableData() {
 		}
 	}
 
+	// 获取表格引用
+	reference, err := excel3.GetReferencedExcelConfig(referencedId, fromScene, uniqueCode, uuid)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取表格引用失败,Err:" + err.Error()
+		return
+	}
+
 	resp := response.ExcelTableDetailResp{
-		UniqueCode:    excelInfo.UniqueCode,
-		ExcelImage:    excelInfo.ExcelImage,
-		ExcelName:     excelInfo.ExcelName,
-		TableInfo:     tableData,
-		Config:        config,
-		SourcesFrom:   excelInfo.SourcesFrom,
-		ExcelSource:   excelSource,
-		ExcelSourceEn: excelSourceEn,
-		ExcelInfoId:   excelInfo.ExcelInfoId,
-		Source:        excelInfo.Source,
+		UniqueCode:            excelInfo.UniqueCode,
+		ExcelImage:            excelInfo.ExcelImage,
+		ExcelName:             excelInfo.ExcelName,
+		TableInfo:             tableData,
+		Config:                config,
+		SourcesFrom:           excelInfo.SourcesFrom,
+		ExcelSource:           excelSource,
+		ExcelSourceEn:         excelSourceEn,
+		ExcelInfoId:           excelInfo.ExcelInfoId,
+		Source:                excelInfo.Source,
+		ReferencedExcelConfig: reference,
 	}
 	br.Ret = 200
 	br.Success = true
@@ -2592,7 +2664,7 @@ func (c *ExcelInfoController) Download() {
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取ETA表格信息失败,Err:" + err.Error()
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "ETA表格被删除,请刷新页面"
 			br.ErrMsg = "ETA表格被删除,请刷新页面,Err:" + err.Error()
 			br.IsSendEmail = false
@@ -2647,12 +2719,18 @@ func (c *ExcelInfoController) Download() {
 			br.ErrMsg = "获取最新的数据失败,Err:" + err.Error()
 			return
 		}
-		tableData, err = excel.GetTableDataByMixedTableData(newResult, false)
+		tableData, err = excel.GetTableDataByMixedTableData(newResult, false, excelInfo.ExcelInfoId)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "转换成table失败,Err:" + err.Error()
 			return
 		}
+		//tableData, err = excel.HandleRuleToTableCell(excelInfo.ExcelInfoId, tableData)
+		//if err != nil {
+		//	br.Msg = "获取失败"
+		//	br.ErrMsg = "处理条件格式管理规则失败,Err:" + err.Error()
+		//	return
+		//}
 	case utils.BALANCE_TABLE: // 混合表格
 		savePath, fileName, uploadDir, err, errMsg := downloadBalanceTable(excelInfo, c.Lang)
 		if err != nil {
@@ -3026,7 +3104,7 @@ func (c *ExcelInfoController) BatchRefresh() {
 	syncing, e := data.BatchRefreshEdbByEdbIds(edbIds, redisKey, refreshKeys)
 	if e != nil {
 		br.Msg = "刷新失败"
-		br.ErrMsg = "刷新表格关联指标信息失败,Err:" + err.Error()
+		br.ErrMsg = "刷新表格关联指标信息失败,Err:" + e.Error()
 		return
 	}
 
@@ -3229,12 +3307,10 @@ func (c *ExcelInfoController) EditExcelRule() {
 		br.Msg = "应用选区不能为空"
 		return
 	}
-	if req.FontColor == "" {
-		br.Msg = "字体颜色不能为空"
-		return
-	}
-	if req.BackgroundColor == "" {
-		br.Msg = "背景颜色不能为空"
+	req.BackgroundColor = strings.TrimSpace(req.BackgroundColor)
+	req.FontColor = strings.TrimSpace(req.FontColor)
+	if req.FontColor == "" && req.BackgroundColor == "" {
+		br.Msg = "字体颜色或背景颜色不能同时为空"
 		return
 	}
 	if req.RuleType == 3 && req.RightValue == "" {
@@ -3372,3 +3448,352 @@ func (c *ExcelInfoController) GetExcelRuleDetail() {
 	br.Ret = 200
 	br.Success = true
 }
+
+// SearchByEs
+// @Title ES搜索
+// @Description ES搜索
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   Keyword   query   string  true       "搜索关键词"
+// @Param   Source   query   int  true       "格来源,1:excel插件的表格,2:自定义表格,3:混合表格,默认:1"
+// @Param   IsShowMe   query   bool  false       "是否只看我的,true、false"
+// @Param   IsShare   query   bool  false       "是否只看我的,true、false"
+// @Success 200 {object} response.ExcelListResp
+// @router /excel_info/search_by_es [get]
+func (c *ExcelInfoController) SearchByEs() {
+	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")
+	source, _ := c.GetInt("Source")
+	if source <= 0 {
+		source = utils.EXCEL_DEFAULT
+	}
+	isShowMe, _ := c.GetBool("IsShowMe")
+	isShare, _ := c.GetBool("IsShare")
+	keyword := c.GetString("KeyWord")
+	if keyword == `` {
+		keyword = c.GetString("Keyword")
+	}
+
+	var total, startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize15
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+
+	// 平衡表的查询条件
+	var condBalance string
+	var parsBalance []interface{}
+	if source == utils.BALANCE_TABLE {
+		condBalance += ` AND source = ? AND parent_id = 0 AND balance_type = 0` // 只显示动态表的一级表(不显示子表和静态表)
+		parsBalance = append(parsBalance, source)
+	}
+
+	// 可见性过滤
+	var queryIds, exceptIds []int
+	{
+		unauthorized, e := excelPermissionModel.GetExcelInfoDataNoPermissionByUserId(sysUser.AdminId, source)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取无权限表格失败, %v", e)
+			return
+		}
+		if len(unauthorized) > 0 {
+			for _, v := range unauthorized {
+				id, _ := strconv.Atoi(v.DataId)
+				if id == 0 {
+					continue
+				}
+				exceptIds = append(exceptIds, id)
+			}
+		}
+	}
+
+	// 自定义分析表
+	var queryAdminId int
+	if source == utils.CUSTOM_ANALYSIS_TABLE {
+		// 自定义分析共享表格
+		if isShare {
+			var kw string
+			if keyword != "" {
+				kw = fmt.Sprint("%", kw, "%")
+			}
+			// 查询我分享的/分享给我的表格
+			excels, e := excelPermissionModel.GetAdminAuthExcelInfoPermission(source, sysUser.AdminId, kw)
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("获取我分享的/分享给我的表格失败, %v", e)
+				return
+			}
+			var excelIds []int
+			for _, v := range excels {
+				id := int(v.ExcelInfoId)
+				if !utils.InArrayByInt(excelIds, id) {
+					excelIds = append(excelIds, id)
+					continue
+				}
+			}
+			if len(excelIds) == 0 {
+				list := make([]*excel3.SearchExcelInfo, 0)
+				resp := response.SearchExcelListResp{
+					Paging: page,
+					List:   list,
+				}
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				br.Data = resp
+				return
+			}
+			queryIds = excelIds
+		} else {
+			// 非共享只看我的
+			isShowMe = true
+		}
+	}
+
+	// 获取所有有权限的指标和分类
+	permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserExcelAndClassifyPermissionList(c.SysUser.AdminId, 0, 0)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error()
+		return
+	}
+	hasCheck := make(map[int]bool)
+	if isShowMe {
+		// 平衡表查询有权限的表格IDs
+		if source == utils.BALANCE_TABLE {
+			excelIds, e := services.GetBalanceExcelIdsByAdminId(sysUser.AdminId, condBalance, parsBalance, permissionEdbIdList, permissionClassifyIdList)
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("获取平衡表有权限的表格IDs失败, %v", e)
+				return
+			}
+			if len(excelIds) == 0 {
+				list := make([]*excel3.SearchExcelInfo, 0)
+				resp := response.SearchExcelListResp{
+					Paging: page,
+					List:   list,
+				}
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				br.Data = resp
+				return
+			}
+			queryIds = excelIds
+		} else {
+			queryAdminId = sysUser.AdminId
+		}
+	}
+
+	// es搜索表格
+	t, list, e := elastic.SearchExcelInfoData(utils.EsExcelIndexName, keyword, source, queryAdminId, queryIds, exceptIds, startSize, pageSize)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("搜索表格失败, %v", e)
+		return
+	}
+	total = int(t)
+
+	if len(list) > 0 {
+		classifyIdList := make([]int, 0)
+		for _, v := range list {
+			classifyIdList = append(classifyIdList, v.ExcelClassifyId)
+
+		}
+		classifyMap := make(map[int]*excel3.ExcelClassify)
+
+		// 分类信息
+		{
+			classifyList, err := excel3.GetClassifyByIdList(classifyIdList)
+			if err != nil {
+				br.Msg = "获取表格列表信息失败"
+				br.ErrMsg = "获取表格分类列表数据失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range classifyList {
+				classifyMap[v.ExcelClassifyId] = v
+			}
+		}
+
+		for k, v := range list {
+			// 数据权限
+			if authCheck, ok1 := hasCheck[v.ExcelInfoId]; ok1 {
+				v.HaveOperaAuth = authCheck
+			} else {
+				if classifyInfo, ok := classifyMap[v.ExcelClassifyId]; ok {
+					v.HaveOperaAuth = data_manage_permission.CheckExcelPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.ExcelInfoId, v.ExcelClassifyId, permissionEdbIdList, permissionClassifyIdList)
+				}
+			}
+			if v.Source == utils.BALANCE_TABLE {
+				// 处理按钮权限和编辑状态
+				markStatus, err := services.UpdateExcelEditMark(v.ExcelInfoId, sysUser.AdminId, 2, sysUser.RealName)
+				if err != nil {
+					br.Msg = "查询标记状态失败"
+					br.ErrMsg = "查询标记状态失败,Err:" + err.Error()
+					return
+				}
+				if markStatus.Status == 0 {
+					list[k].CanEdit = true
+				} else {
+					list[k].Editor = markStatus.Editor
+				}
+
+				// excel表格按钮权限
+				list[k].Button = excel2.GetBalanceExcelInfoOpButton(sysUser.AdminId, v.SysUserId, v.HaveOperaAuth, v.ExcelInfoId)
+			}
+		}
+	}
+
+	page = paging.GetPaging(currentIndex, pageSize, total)
+	resp := response.SearchExcelListResp{
+		Paging: page,
+		List:   list,
+	}
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// GetExcelReferenceDetail
+// @Title 表格引用配置详情
+// @Description 表格引用配置详情
+// @Param   ExcelInfoRuleMappingId   query   int  true       "id"
+// @Success Ret=200 获取成功
+// @router /excel_info/reference/detail [get]
+//func (c *ExcelInfoController) GetExcelReferenceDetail() {
+//	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
+//	}
+//	excelReferenceCode := c.GetString("ExcelReferenceCode")
+//
+//	item, err := excel3.GetReferencedExcelConfigByUniqueCode(excelReferenceCode)
+//	if err != nil && err.Error() != utils.ErrNoRow() {
+//		br.Msg = "获取规则"
+//		br.ErrMsg = "管理规则添加失败,Err:" + err.Error()
+//		return
+//	}
+//
+//	br.Data = item
+//	br.Msg = "获取成功"
+//	br.Ret = 200
+//	br.Success = true
+//}
+
+// GetExcelReferenceDetail
+// @Title 表格引用配置保存
+// @Description 表格引用配置保存
+// @Param   ExcelInfoRuleMappingId   query   int  true       "id"
+// @Success Ret=200 获取成功
+// @router /excel_info/reference/save [post]
+func (c *ExcelInfoController) SaveExcelReference() {
+	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 excel3.ExcelReferencesReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	addList := make([]*excel3.ReferencedExcelConfig, 0)
+
+	exist, e := excel3.GetReferencedExcelConfig(req.ReferencedId, req.FromScene, req.UniqueCode, req.Uuid)
+	if e != nil && !utils.IsErrNoRow(e) {
+		br.Msg = "查找引用失败"
+		br.ErrMsg = "查找引用失败,Err:" + e.Error()
+		return
+	}
+	if exist.ReferencedExcelConfigId == 0 {
+		item := excel3.ReferencedExcelConfig{
+			UniqueCode:   req.UniqueCode,
+			ReferencedId: req.ReferencedId,
+			FromScene:    req.FromScene,
+			Uuid:         req.Uuid,
+			WidthList:    req.WidthList,
+			HeightList:   req.HeightList,
+			OpUserId:     sysUser.AdminId,
+			OpUserName:   sysUser.RealName,
+			CreateTime:   time.Now(),
+			ModifyTime:   time.Now(),
+		}
+		addList = append(addList, &item)
+	} else {
+		exist.WidthList = req.WidthList
+		exist.HeightList = req.HeightList
+		exist.OpUserId = sysUser.AdminId
+		exist.OpUserName = sysUser.RealName
+		exist.ModifyTime = time.Now()
+		err = excel3.UpdateReferencedExcelConfig(&exist)
+		if err != nil {
+			br.Msg = "更新引用失败"
+			br.ErrMsg = "更新引用失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	if len(addList) > 0 {
+		err = excel3.AddReferencedExcelConfig(addList)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "添加引用失败"
+			br.ErrMsg = "添加引用失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	excelInfo, err := excel3.GetExcelInfoByUnicode(req.UniqueCode)
+	if err != nil {
+		br.Msg = "获取表格信息失败"
+		br.ErrMsg = "获取表格信息失败,Err:" + err.Error()
+		return
+	}
+	if excelInfo.ExcelInfoId > 0 {
+		//删除公共图库那边的缓存
+		_ = utils.Rc.Delete(utils.HZ_CHART_LIB_EXCEL_TABLE_DETAIL + ":" + excelInfo.UniqueCode)
+	}
+
+	br.Msg = "添加成功"
+	br.Ret = 200
+	br.Success = true
+}

+ 2 - 2
controllers/data_manage/factor_edb_series.go

@@ -328,7 +328,7 @@ func (this *FactorEdbSeriesController) Edit() {
 	seriesOb := new(data_manage.FactorEdbSeries)
 	seriesItem, e := seriesOb.GetItemById(req.SeriesId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "该因子指标系列不存在"
 			return
 		}
@@ -460,7 +460,7 @@ func (this *FactorEdbSeriesController) Detail() {
 	seriesOb := new(data_manage.FactorEdbSeries)
 	series, e := seriesOb.GetItemById(seriesId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "该因子指标系列不存在"
 			return
 		}

+ 52 - 29
controllers/data_manage/fenwei_data.go

@@ -173,36 +173,53 @@ func (this *EdbInfoController) FenweiIndexData() {
 	}
 
 	resultList := make([]*data_manage.BaseFromFenweiIndexList, 0)
-	for _, v := range indexes {
-		product := new(data_manage.BaseFromFenweiIndexList)
-		product.FenweiIndexId = v.FenweiIndexId
-		product.ClassifyId = v.ClassifyId
-		product.Unit = v.Unit
-		product.IndexCode = v.IndexCode
-		product.IndexName = v.IndexName
-		product.Frequency = v.Frequency
-		product.CreateTime = v.CreateTime
-		product.ModifyTime = v.ModifyTime
-
-		edbInfo := edbCodeMap[v.IndexCode]
-		if edbInfo != nil {
-			product.EdbInfoId = edbInfo.EdbInfoId
-		}
-
-		total := countMap[v.IndexCode]
-		page := paging.GetPaging(currentIndex, pageSize, total)
-		dataList, e := data_manage.GetFenweiIndexData(v.IndexCode, startSize, pageSize)
-		if e != nil {
-			br.Msg = "获取数据失败"
-			br.ErrMsg = "获取指标数据失败,Err:" + e.Error()
+	if indexes != nil {
+		// 获取指标数据最新更新时间
+		lastModifyTimeList, err := data_manage.GetFenWeiDataLastModifyTimeList(indexCodes)
+		if err != nil {
 			return
 		}
-		if dataList == nil {
-			dataList = make([]*data_manage.BaseFromFenweiData, 0)
+		lastModifyTimeMap := make(map[string]string)
+		for _, v := range lastModifyTimeList {
+			lastModifyTimeMap[v.IndexCode] = v.ModifyTime
+		}
+
+		for _, v := range indexes {
+			product := new(data_manage.BaseFromFenweiIndexList)
+			product.FenweiIndexId = v.FenweiIndexId
+			product.ClassifyId = v.ClassifyId
+			product.Unit = v.Unit
+			product.IndexCode = v.IndexCode
+			product.IndexName = v.IndexName
+			product.Frequency = v.Frequency
+			product.CreateTime = v.CreateTime
+
+			if lastModifyTimeMap[v.IndexCode] != "" {
+				product.ModifyTime = lastModifyTimeMap[v.IndexCode]
+			} else {
+				product.ModifyTime = ""
+			}
+
+			edbInfo := edbCodeMap[v.IndexCode]
+			if edbInfo != nil {
+				product.EdbInfoId = edbInfo.EdbInfoId
+			}
+
+			total := countMap[v.IndexCode]
+			page := paging.GetPaging(currentIndex, pageSize, total)
+			dataList, e := data_manage.GetFenweiIndexData(v.IndexCode, startSize, pageSize)
+			if e != nil {
+				br.Msg = "获取数据失败"
+				br.ErrMsg = "获取指标数据失败,Err:" + e.Error()
+				return
+			}
+			if dataList == nil {
+				dataList = make([]*data_manage.BaseFromFenweiData, 0)
+			}
+			product.DataList = dataList
+			product.Paging = page
+			resultList = append(resultList, product)
 		}
-		product.DataList = dataList
-		product.Paging = page
-		resultList = append(resultList, product)
 	}
 
 	br.Ret = 200
@@ -318,8 +335,14 @@ func (this *EdbInfoController) FenweiSingleData() {
 	ret.IndexName = indexInfo.IndexName
 	ret.Frequency = indexInfo.Frequency
 	ret.CreateTime = indexInfo.CreateTime.Format(utils.FormatDateTime)
-	ret.ModifyTime = indexInfo.ModifyTime.Format(utils.FormatDateTime)
 	ret.Unit = indexInfo.Unit
+	// 获取数据最新更新时间
+	lastModifyTimeList, err := data_manage.GetFenWeiDataLastModifyTimeList([]string{indexInfo.IndexCode})
+	if err != nil {
+		return
+	}
+	ret.ModifyTime = lastModifyTimeList[0].ModifyTime
+
 	for _, v := range dataTmpList {
 		tmp := &data_manage.FenweiSingleData{
 			Value:    v.Value,
@@ -921,7 +944,7 @@ func (this *EdbInfoController) FenWeiIndexDataExport() {
 
 			var dataList []*data_manage.BaseFromFenweiData
 			dataList, err = data_manage.GetBaseFromFenWeiDataByIndexCode(v.IndexCode)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.ErrMsg = "GetBaseFromFenWeiDataByIndexCode,Err:" + err.Error()
 				br.Msg = "获取数据失败"
 				return

+ 15 - 0
controllers/data_manage/fix.go

@@ -0,0 +1,15 @@
+package data_manage
+
+func init() {
+
+	// 刷新指标
+	//data.AddOrEditAllEdbInfoToEs()
+
+	// 修复ETA图库
+	//data.AddAllChartInfo()
+
+	// 修复我的图库
+	//data.AddAllMyChartInfo()
+	//
+	//fmt.Println("修复完成")
+}

+ 13 - 13
controllers/data_manage/future_good/future_good_chart_classify.go

@@ -36,7 +36,7 @@ func (this *FutureGoodChartClassifyController) ChartClassifyList() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -67,14 +67,14 @@ func (this *FutureGoodChartClassifyController) ChartClassifyList() {
 	}
 
 	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	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})
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
@@ -108,13 +108,13 @@ 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)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	allChartInfo, err := data_manage.GetChartInfoByAdminId([]int{utils.CHART_SOURCE_FUTURE_GOOD, utils.CHART_SOURCE_FUTURE_GOOD_PROFIT}, adminInfo.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
@@ -203,7 +203,7 @@ func (this *FutureGoodChartClassifyController) AddChartClassify() {
 	}
 
 	// 新增图表分类
-	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, 0, req.Level, utils.CHART_SOURCE_FUTURE_GOOD, this.Lang, this.SysUser)
+	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, 0, req.Level, utils.CHART_SOURCE_FUTURE_GOOD, 0, this.Lang, this.SysUser)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = "添加分类失败,Err:" + err.Error()
@@ -307,7 +307,7 @@ func (this *FutureGoodChartClassifyController) DeleteChartClassifyCheck() {
 
 	if deleteStatus != 1 && req.ChartInfoId == 0 {
 		classifyCount, err := data_manage.GetChartClassifyCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
 			return
@@ -369,7 +369,7 @@ func (this *FutureGoodChartClassifyController) DeleteChartClassify() {
 	if req.ChartClassifyId > 0 && req.ChartInfoId == 0 {
 		//判断是否含有指标
 		count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -393,7 +393,7 @@ func (this *FutureGoodChartClassifyController) DeleteChartClassify() {
 	if req.ChartInfoId > 0 {
 		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -455,7 +455,7 @@ func (this *FutureGoodChartClassifyController) DeleteChartClassify() {
 		pars = append(pars, req.ChartInfoId)
 
 		nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 			return
@@ -475,14 +475,14 @@ func (this *FutureGoodChartClassifyController) DeleteChartClassify() {
 			pars = append(pars, chartInfo.ChartClassifyId)
 
 			classifyItem, err := data_manage.GetChartClassifyByCondition(condition, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
 				return
 			}
 			if classifyItem != nil {
 				nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 					return
@@ -617,7 +617,7 @@ func (this *FutureGoodChartClassifyController) ChartClassifyMove() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartClassifyByParentId(chartClassifyInfo.ParentId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return

+ 46 - 41
controllers/data_manage/future_good/future_good_chart_info.go

@@ -82,7 +82,7 @@ func (this *FutureGoodChartInfoController) ChartList() {
 
 	if chartClassifyId > 0 {
 		chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取图表信息失败"
 			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 			return
@@ -104,7 +104,8 @@ func (this *FutureGoodChartInfoController) ChartList() {
 			for _, v := range keyWordArr {
 				if v != "" {
 					condition += ` chart_name LIKE '%` + v + `%' OR chart_name_en LIKE '%` + v + `%' OR`
-				}			}
+				}
+			}
 		}
 		condition = strings.TrimRight(condition, "OR")
 		condition += " ) "
@@ -122,7 +123,7 @@ func (this *FutureGoodChartInfoController) ChartList() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -140,7 +141,7 @@ func (this *FutureGoodChartInfoController) ChartList() {
 
 	//获取图表信息
 	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -148,7 +149,7 @@ func (this *FutureGoodChartInfoController) ChartList() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -192,7 +193,7 @@ func (this *FutureGoodChartInfoController) ChartList() {
 	}
 
 	resp := new(data_manage.ChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.Paging = page
 		resp.List = items
@@ -203,7 +204,7 @@ func (this *FutureGoodChartInfoController) ChartList() {
 	}
 
 	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -253,7 +254,7 @@ func (this *FutureGoodChartInfoController) ChartInfoSave() {
 
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面!"
 			br.ErrMsg = "图表已被删除,请刷新页面,ChartInfoId:" + strconv.Itoa(req.ChartInfoId)
 			return
@@ -362,7 +363,7 @@ func (this *FutureGoodChartInfoController) ChartInfoAdd() {
 
 	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			br.ErrMsg = "分类不存在"
 			return
@@ -404,7 +405,7 @@ func (this *FutureGoodChartInfoController) ChartInfoAdd() {
 		if v.Source == utils.CHART_SOURCE_DEFAULT { //ETA指标
 			edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					br.Msg = "指标不存在!"
 					br.ErrMsg = "指标不存在,edbInfoId:" + strconv.Itoa(edbInfoId)
 					return
@@ -432,7 +433,7 @@ func (this *FutureGoodChartInfoController) ChartInfoAdd() {
 		} else { // 商品指标
 			edbInfo, err := future_good.GetFutureGoodEdbInfo(edbInfoId)
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					br.Msg = "指标不存在!"
 					br.ErrMsg = "指标不存在,edbInfoId:" + strconv.Itoa(edbInfoId)
 					return
@@ -647,7 +648,7 @@ func (this *FutureGoodChartInfoController) ChartInfoEdit() {
 
 	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			br.ErrMsg = "分类不存在"
 			return
@@ -663,7 +664,7 @@ func (this *FutureGoodChartInfoController) ChartInfoEdit() {
 	}
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -725,7 +726,7 @@ func (this *FutureGoodChartInfoController) ChartInfoEdit() {
 		if v.Source == utils.CHART_SOURCE_DEFAULT { //ETA指标
 			edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					br.Msg = "图表不存在!"
 					br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId)
 					return
@@ -745,7 +746,7 @@ func (this *FutureGoodChartInfoController) ChartInfoEdit() {
 		} else { //商品指标
 			edbInfo, err := future_good.GetFutureGoodEdbInfo(edbInfoId)
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					br.Msg = "指标不存在!"
 					br.ErrMsg = "指标不存在,edbInfoId:" + strconv.Itoa(edbInfoId)
 					return
@@ -861,7 +862,7 @@ func (this *FutureGoodChartInfoController) ChartEnInfoEdit() {
 
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -895,7 +896,7 @@ func (this *FutureGoodChartInfoController) ChartEnInfoEdit() {
 	//校验指标信息是否存在
 	edbInfo, err := data_manage.GetEdbInfoById(edbInfoMapping.EdbInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表不存在!"
 			br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoMapping.EdbInfoId)
 			return
@@ -925,7 +926,7 @@ func (this *FutureGoodChartInfoController) ChartEnInfoEdit() {
 
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return
@@ -950,7 +951,7 @@ func (this *FutureGoodChartInfoController) ChartEnInfoEdit() {
 			}
 			futureGoodEdbInfo, err := future_good.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId)
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					br.Msg = "图表不存在!"
 					br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoMapping.EdbInfoId)
 					return
@@ -1039,7 +1040,7 @@ func (this *FutureGoodChartInfoController) ChartInfoNewest() {
 		this.ServeJSON()
 	}()
 	item, err := data_manage.GetChartInfoByNewest(2)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取最新图表失败"
 		br.ErrMsg = "获取最新图表失败,Err:" + err.Error()
 		return
@@ -1112,12 +1113,12 @@ func (this *FutureGoodChartInfoController) ChartInfoMove() {
 	if chartInfo.ChartClassifyId != req.ChartClassifyId {
 		//查询需要修改的分类下是否存在同一个图表名称
 		tmpChartInfo, tmpErr := data_manage.GetChartInfoByClassifyIdAndName(req.ChartClassifyId, chartInfo.ChartName)
-		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "移动失败,Err:" + tmpErr.Error()
 			return
 		}
-		if tmpChartInfo != nil {
+		if tmpChartInfo != nil && tmpChartInfo.ChartInfoId > 0 {
 			br.Msg = "移动失败,同一个分类下图表名称不允许重复"
 			br.ErrMsg = "移动失败,同一个分类下图表名称不允许重复"
 			return
@@ -1171,7 +1172,7 @@ func (this *FutureGoodChartInfoController) ChartInfoMove() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartInfoByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return
@@ -1283,7 +1284,7 @@ func (this *FutureGoodChartInfoController) ChartInfoDetail() {
 	if chartInfoId > 0 {
 		chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图被删除,请刷新页面"
 				br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error()
 				return
@@ -1327,7 +1328,7 @@ func getFutureGoodChartInfo(chartInfo *data_manage.ChartInfoView, chartType, dat
 	}
 	futureGoodEdbInfoMapping, err = data_manage.GetFutureGoodEdbChartEdbMapping(chartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "期货指标不存在"
 			return
 		}
@@ -1461,7 +1462,7 @@ func getFutureGoodChartInfo(chartInfo *data_manage.ChartInfoView, chartType, dat
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -1534,7 +1535,7 @@ func (this *FutureGoodChartInfoController) ChartInfoDetailFromUniqueCode() {
 	status := true
 	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			status = false
 		} else {
 			br.Msg = "获取失败"
@@ -1588,7 +1589,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					msg = "获取失败"
 					errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -1830,7 +1831,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				msg = "获取失败"
 				errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -2172,7 +2173,7 @@ func (this *FutureGoodChartInfoController) BaseChartInfoDetailFromUniqueCode() {
 	status := true
 	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			status = false
 		} else {
 			br.Msg = "获取失败"
@@ -2303,7 +2304,7 @@ func (this *FutureGoodChartInfoController) BaseChartInfoDetailFromUniqueCode() {
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -2390,7 +2391,7 @@ func (this *FutureGoodChartInfoController) ChartInfoSearchByEs() {
 		showSysId = sysUser.AdminId
 	}
 
-	var searchList []*data_manage.ChartInfo
+	var searchList []*data_manage.ChartInfoMore
 	var total int64
 	var err error
 
@@ -2399,7 +2400,7 @@ func (this *FutureGoodChartInfoController) ChartInfoSearchByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -2413,7 +2414,7 @@ func (this *FutureGoodChartInfoController) ChartInfoSearchByEs() {
 		searchList, total, err = data.EsSearchChartInfo(keyword, showSysId, []int{utils.CHART_SOURCE_FUTURE_GOOD, utils.CHART_SOURCE_FUTURE_GOOD_PROFIT}, noPermissionChartIdList, startSize, pageSize)
 	} else {
 		total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, []int{utils.CHART_SOURCE_FUTURE_GOOD, utils.CHART_SOURCE_FUTURE_GOOD_PROFIT}, noPermissionChartIdList, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -2443,13 +2444,17 @@ func (this *FutureGoodChartInfoController) ChartInfoSearchByEs() {
 
 		for _, v := range searchList {
 			tmp := new(data_manage.ChartInfoMore)
-			tmp.ChartInfo = *v
+			tmp.ChartInfo = v.ChartInfo
 			// 图表数据权限
 			tmp.HaveOperaAuth = true
 			//判断是否需要展示英文标识
 			if edbTmpList, ok := chartEdbMap[v.ChartInfoId]; ok {
 				tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, edbTmpList, v.Source, v.ChartType)
 			}
+			tmp.SearchText = v.SearchText
+			if tmp.SearchText == "" {
+				tmp.SearchText = v.ChartName
+			}
 			finalList = append(finalList, tmp)
 		}
 	}
@@ -2508,7 +2513,7 @@ func (this *FutureGoodChartInfoController) ChartInfoRefresh() {
 		chartInfo, err = data_manage.GetChartInfoByUniqueCode(uniqueCode)
 	}
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,无需刷新"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -2888,7 +2893,7 @@ func copyChartInfo(oldChartInfo *data_manage.ChartInfo, chartClassifyId int, cha
 	}
 	chartClassify, err := data_manage.GetChartClassifyById(chartClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			br.ErrMsg = "分类不存在"
 			return
@@ -3213,7 +3218,7 @@ func (this *FutureGoodChartInfoController) BaseInfoEdit() {
 
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -3250,7 +3255,7 @@ func (this *FutureGoodChartInfoController) BaseInfoEdit() {
 	//校验指标信息是否存在
 	edbInfoList, err := data_manage.GetEdbInfoByIdList(edbIds)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表不存在!"
 			br.ErrMsg = "图表指标不存在,ChartInfoId:" + strconv.Itoa(req.ChartInfoId)
 			return
@@ -3293,7 +3298,7 @@ func (this *FutureGoodChartInfoController) BaseInfoEdit() {
 
 			edbExist, e := data_manage.GetEdbInfoByCondition(edbCondition, edbPars)
 			if e != nil {
-				if e.Error() != utils.ErrNoRow() {
+				if !utils.IsErrNoRow(e) {
 					br.Msg = "判断英文指标名称是否存在失败"
 					br.ErrMsg = "判断英文指标名称是否存在失败,Err:" + e.Error()
 					return
@@ -3325,7 +3330,7 @@ func (this *FutureGoodChartInfoController) BaseInfoEdit() {
 
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return

+ 6 - 6
controllers/data_manage/future_good/future_good_edb_info.go

@@ -60,7 +60,7 @@ func (this *FutureGoodEdbInfoController) FutureGoodEdbInfoList() {
 	}
 
 	list, err := future_good2.GetFutureGoodEdbInfoList(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -141,14 +141,14 @@ func (this *FutureGoodEdbInfoController) FutureGoodEdbInfoDataList() {
 	}
 
 	total, err := future_good2.GetFutureGoodEdbDataListCount(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	list, err := future_good2.GetFutureGoodEdbDataList(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -156,7 +156,7 @@ func (this *FutureGoodEdbInfoController) FutureGoodEdbInfoDataList() {
 
 	// 获取用到的指标信息
 	futureGoodEdbInfoList, err := future_good2.GetAllFutureGoodEdbInfoList()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -219,7 +219,7 @@ func (this *FutureGoodEdbInfoController) FutureGoodEdbInfoGroupList() {
 	}
 
 	list, err := future_good2.GetFutureGoodEdbInfoGroupList(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -320,7 +320,7 @@ func (this *FutureGoodEdbInfoController) FutureGoodEdbExchangeList() {
 	}
 
 	list, err := future_good2.GetFutureGoodEdbExchangeList(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return

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

@@ -73,7 +73,7 @@ func (this *FutureGoodChartInfoController) ProfitChartInfoAdd() {
 
 	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			br.ErrMsg = "分类不存在"
 			return
@@ -165,7 +165,7 @@ func (this *FutureGoodChartInfoController) ProfitChartInfoAdd() {
 		edbInfoId := v.EdbInfoId
 		futureGoodEdbInfo, tmpErr := future_good.GetFutureGoodEdbInfo(edbInfoId)
 		if tmpErr != nil {
-			if tmpErr.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(tmpErr) {
 				br.Msg = "期货商品指标不存在!"
 				br.ErrMsg = "期货商品指标不存在,指标id:" + strconv.Itoa(edbInfoId)
 				return
@@ -397,7 +397,7 @@ func (this *FutureGoodChartInfoController) ProfitChartInfoEdit() {
 
 	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			br.ErrMsg = "分类不存在"
 			return
@@ -413,7 +413,7 @@ func (this *FutureGoodChartInfoController) ProfitChartInfoEdit() {
 	}
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -520,7 +520,7 @@ func (this *FutureGoodChartInfoController) ProfitChartInfoEdit() {
 		edbInfoId := v.EdbInfoId
 		futureGoodEdbInfo, tmpErr := future_good.GetFutureGoodEdbInfo(edbInfoId)
 		if tmpErr != nil {
-			if tmpErr.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(tmpErr) {
 				br.Msg = "期货商品指标不存在!"
 				br.ErrMsg = "期货商品指标不存在,指标id:" + strconv.Itoa(edbInfoId)
 				return
@@ -713,7 +713,7 @@ func copyProfitChartInfo(oldChartInfo *data_manage.ChartInfo, chartClassifyId in
 	}
 	chartClassify, err := data_manage.GetChartClassifyById(chartClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			br.ErrMsg = "分类不存在"
 			return
@@ -1124,7 +1124,7 @@ func getFutureGoodProfitChartInfo(chartInfo *data_manage.ChartInfoView, sysUser
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -1188,7 +1188,7 @@ func GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo *data_manage.Cha
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					msg = "获取失败"
 					errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -1387,7 +1387,7 @@ func GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo *data_manage.Cha
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				msg = "获取失败"
 				errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err: " + err.Error()
 				return

+ 59 - 10
controllers/data_manage/gl_data.go

@@ -1,12 +1,13 @@
 package data_manage
 
 import (
-	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
-	"github.com/tealeg/xlsx"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
+	"eta/eta_api/services/elastic"
 	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
 	"os"
 	"path/filepath"
 	"time"
@@ -174,30 +175,78 @@ func (this *EdbInfoController) GlData() {
 func (this *EdbInfoController) GlSearchList() {
 	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 = "请重新登录"
 		return
 	}
 
-	//关键字
-	keyword := this.GetString("Keyword")
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	keyword := this.GetString("KeyWord")
+	if keyword == `` {
+		keyword = this.GetString("Keyword")
+	}
 
-	list, err := data_manage.GetGlItemList(keyword)
-	if err != nil {
-		br.ErrMsg = "获取失败,Err:" + err.Error()
+	var total, startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize15
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	// es搜索
+	t, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keyword, utils.DATA_SOURCE_GL, 0, []int{}, []int{}, []string{}, startSize, pageSize)
+	if e != nil {
 		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("ES-搜索数据源列表失败, %v", e)
 		return
 	}
+	total = int(t)
+	resp := new(data_manage.GlDataPageListResp)
+	resp.Paging = paging.GetPaging(currentIndex, pageSize, total)
+	if len(list) == 0 {
+		resp.List = make([]*data_manage.GlSearchIndex, 0)
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = resp
+		return
+	}
+	highlightMap := make(map[int]string)
+	for _, v := range list {
+		highlightMap[v.PrimaryId] = v.SearchText
+	}
+
+	var ids []int
+	for _, v := range list {
+		ids = append(ids, v.PrimaryId)
+	}
+	items, e := data_manage.GetGlItemListByIds(ids)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取指标列表失败, %v", e)
+		return
+	}
+	for _, v := range items {
+		v.Source = utils.DATA_SOURCE_GL
+		v.SourceName = "钢联原始指标库"
+		v.SearchText = highlightMap[v.Id]
+	}
+	resp.List = items
 
+	br.Data = resp
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "获取成功"
-	br.Data = list
 }
 
 // GlSingleData

+ 1045 - 0
controllers/data_manage/gpr_risk_data.go

@@ -0,0 +1,1045 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/system"
+	"eta/eta_api/services/data"
+	etaTrialService "eta/eta_api/services/eta_trial"
+	"eta/eta_api/utils"
+	"fmt"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
+)
+
+type BaseFromGprRiskController struct {
+	controllers.BaseAuthController
+}
+
+// GprRiskClassify
+// @Title GPR地缘风险指数数据分类
+// @Description GPR地缘风险指数数据分类接口
+// @Success 200 {object} data_manage.BaseFromGprRiskClassify
+// @router /gpr_risk/classify [get]
+func (this *BaseFromGprRiskController) GprRiskClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	classifyAll, err := data_manage.GetAllBaseFromGprRiskClassify()
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	//组装一级分类
+	rootMap := make(map[int][]*data_manage.BaseFromGprRiskClassifyItems)
+	list := make([]*data_manage.BaseFromGprRiskClassifyItems, 0)
+	for _, classify := range classifyAll {
+		classify.UniqueCode = strconv.Itoa(classify.ClassifyId)
+		if classify.ParentId == 0 {
+			if _, ok := rootMap[classify.ClassifyId]; !ok {
+				rootMap[classify.ClassifyId] = make([]*data_manage.BaseFromGprRiskClassifyItems, 0)
+				list = append(list, classify)
+
+			}
+		} else {
+			child, ok := rootMap[classify.ParentId]
+			if ok {
+				child = append(child, classify)
+				rootMap[classify.ParentId] = child
+			}
+		}
+	}
+
+	for k, v := range list {
+		child, ok := rootMap[v.ClassifyId]
+		if ok {
+			list[k].Children = child
+		}
+	}
+	//组装二级分类
+	var ret data_manage.BaseFromGprRiskClassifyResp
+	ret.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = ret
+}
+
+// GprRiskIndexData
+// @Title 获取GPR地缘风险指数数据
+// @Description 获取GPR地缘风险指数数据接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyId   query   string  true       "分类id"
+// @Success 200 {object} data_manage.LzFrequency
+// @router /gpr_risk/index/data [get]
+func (this *BaseFromGprRiskController) GprRiskIndexData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		return
+	}
+	// 增加频度请求入参
+	frequency := this.GetString("Frequency")
+
+	//获取指标
+	var condition string
+	var pars []interface{}
+
+	if classifyId > 0 {
+		condition += ` AND classify_id=? `
+		pars = append(pars, classifyId)
+	}
+	if frequency != "" {
+		condition += ` AND frequency=? `
+		pars = append(pars, frequency)
+	}
+
+	GprRiskList, err := data_manage.GetGprRiskIndex(condition, pars)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	edbCodeList := make([]string, 0)
+	for _, v := range GprRiskList {
+		edbCodeList = append(edbCodeList, v.IndexCode)
+	}
+	edbInfoMap := make(map[string]*data_manage.EdbInfo)
+	dataMap := make(map[string][]*data_manage.BaseFromGprRiskData)
+	total := 0
+	if len(edbCodeList) > 0 {
+		edbInfoList, err := data_manage.GetEdbInfoByEdbCodeList(utils.DATA_SOURCE_GPR_RISK, edbCodeList)
+		if err != nil {
+			br.Msg = "获取数据源失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range edbInfoList {
+			edbInfoMap[v.EdbCode] = v
+		}
+		// 首先对分类下的指标按照日期进行分页,再针对日期,进行排序
+		dataTimes, err := data_manage.GetGprRiskIndexDataTimePageByCodes(edbCodeList, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取指标数据日期信息失败,Err:" + err.Error()
+			return
+		}
+		if len(dataTimes) > 0 {
+			startDate := utils.GormDateStrToDateStr(dataTimes[len(dataTimes)-1])
+			endDate := utils.GormDateStrToDateStr(dataTimes[0])
+			// 把截止日往后加1天
+			endDateT, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
+			endDate = endDateT.AddDate(0, 0, 1).Format(utils.FormatDate)
+			dataList, e := data_manage.GetGprRiskIndexDataByDataTime(edbCodeList, startDate, endDate)
+			if e != nil {
+				br.Msg = "获取数据失败"
+				br.ErrMsg = "获取指标数据失败,Err:" + e.Error()
+				return
+			}
+			//将数据按照指标进行分类
+			for _, v := range dataList {
+				dataMap[v.IndexCode] = append(dataMap[v.IndexCode], v)
+			}
+		}
+
+		total, err = data_manage.GetGprRiskIndexDataTimePageCount(edbCodeList)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+
+	resultList := make([]*data_manage.BaseFromGprRiskIndexList, 0)
+
+	for _, v := range GprRiskList {
+		product := new(data_manage.BaseFromGprRiskIndexList)
+		product.BaseFromGprRiskIndexId = v.BaseFromGprRiskIndexId
+		product.Unit = v.Unit
+		product.IndexCode = v.IndexCode
+		product.IndexName = v.IndexName
+		product.Frequency = v.Frequency
+		product.ModifyTime = v.ModifyTime
+		product.ClassifyId = v.ClassifyId
+		if edb, ok := edbInfoMap[v.IndexCode]; ok {
+			product.EdbInfoId = edb.EdbInfoId
+			product.EdbExist = 1
+		}
+
+		dataListTmp, ok := dataMap[v.IndexCode]
+		if !ok {
+			dataListTmp = make([]*data_manage.BaseFromGprRiskData, 0)
+		}
+		product.DataList = dataListTmp
+		product.Paging = page
+		resultList = append(resultList, product)
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resultList
+}
+
+// GprRiskSearchList
+// @Title GprRisk模糊搜索
+// @Description GprRisk模糊搜索
+// @Param   Keyword   query   string  ture       "关键字搜索"
+// @Success 200 {object} models.BaseResponse
+// @router /gpr_risk/search_list [get]
+func (this *BaseFromGprRiskController) GprRiskSearchList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请重新登录"
+		return
+	}
+
+	list := make([]*data_manage.BaseFromGprRiskIndexSearchItem, 0)
+	var err error
+	//关键字
+	keyword := this.GetString("Keyword")
+	if keyword != "" {
+		keyWordArr := strings.Split(keyword, " ")
+
+		if len(keyWordArr) > 0 {
+			condition := ""
+			for _, v := range keyWordArr {
+				condition += ` AND CONCAT(index_name,index_code) LIKE '%` + v + `%'`
+			}
+			list, err = data_manage.GetGprRiskItemList(condition)
+			if err != nil {
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				br.Msg = "获取失败"
+				return
+			}
+		}
+
+	} else {
+		list, err = data_manage.GetGprRiskItemList("")
+		if err != nil {
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			br.Msg = "获取失败"
+			return
+		}
+	}
+	classifyIds := make([]int, 0)
+	for _, v := range list {
+		classifyIds = append(classifyIds, v.ClassifyId)
+	}
+	classifyList, err := data_manage.GetBaseFromGprRiskClassifyByIds(classifyIds)
+	if err != nil {
+		br.Msg = "搜索失败"
+		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+		return
+	}
+	classifyMap := make(map[int]int)
+	for _, v := range classifyList {
+		classifyMap[v.ClassifyId] = v.ParentId
+	}
+	for _, v := range list {
+		v.ParentClassifyId = classifyMap[v.ClassifyId]
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// GprRiskSingleData
+// @Title 获取GprRisk数据
+// @Description 获取GprRisk单条数据接口
+// @Param   IndexCode   query   string  true       "指标唯一编码"
+// @Success 200 {object} models.BaseResponse
+// @router /gpr_risk/single_data [get]
+func (this *BaseFromGprRiskController) GprRiskSingleData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	indexCode := this.GetString("IndexCode")
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	var total int64
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	indexInfo, err := data_manage.GetBaseFromGprRiskIndexByIndexCode(indexCode)
+	if err != nil {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+	total, err = data_manage.GetGprRiskIndexDataTotalByCode(indexCode)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	page = paging.GetPaging(currentIndex, pageSize, int(total))
+	dataTmpList, err := data_manage.GetGprRiskIndexDataByCode(indexCode, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_GPR_RISK, indexCode)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取数据源失败"
+		br.ErrMsg = "获取数据源失败,Err:" + err.Error()
+		return
+	}
+
+	var ret data_manage.GprRiskSingleDataResp
+	var dataList []*data_manage.GprRiskSingleData
+
+	if edbInfo != nil {
+		ret.EdbInfoId = edbInfo.EdbInfoId
+		ret.EdbExist = 1
+	}
+	ret.ClassifyId = indexInfo.ClassifyId
+	ret.BaseFromGprRiskIndexId = indexInfo.BaseFromGprRiskIndexId
+	ret.IndexCode = indexInfo.IndexCode
+	ret.IndexName = indexInfo.IndexName
+	ret.Frequency = indexInfo.Frequency
+	ret.CreateTime = indexInfo.CreateTime.Format(utils.FormatDateTime)
+	ret.ModifyTime = indexInfo.ModifyTime.Format(utils.FormatDateTime)
+	ret.Unit = indexInfo.Unit
+	for _, v := range dataTmpList {
+		tmp := &data_manage.GprRiskSingleData{
+			Value:    v.Value,
+			DataTime: v.DataTime,
+		}
+		dataList = append(dataList, tmp)
+	}
+	ret.Data = dataList
+	ret.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = ret
+}
+
+// GprRiskIndexList
+// @Title GPR地缘风险指数指标列表
+// @Description GPR地缘风险指数指标列表
+// @Param   ClassifyId   query   int  true       "分类id"
+// @Success 200 {object} data_manage.BaseFromGprRiskClassifyResp
+// @router /gpr_risk/classify/index/list [get]
+func (this *BaseFromGprRiskController) GprRiskIndexList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	classifyId, _ := this.GetInt("ClassifyId", 0)
+	indexList, err := data_manage.GetGprRiskIndexByClassifyId(classifyId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	var ret data_manage.BaseFromGprRiskClassifyResp
+	list := make([]*data_manage.BaseFromGprRiskClassifyItems, 0)
+	for _, v := range indexList {
+		classify := new(data_manage.BaseFromGprRiskClassifyItems)
+		classify.ClassifyId = classifyId
+		classify.BaseFromGprRiskIndexId = v.BaseFromGprRiskIndexId
+		classify.IndexCode = v.IndexCode
+		classify.ClassifyName = v.IndexName
+		classify.UniqueCode = fmt.Sprintf("%d_%d", classifyId, v.BaseFromGprRiskIndexId)
+		list = append(list, classify)
+	}
+	ret.List = list
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = ret
+}
+
+// GprRiskNameCheck
+// @Title 加入指标库的重名检测
+// @Description 加入指标库的重名检测
+// @Param   ClassifyIds   query   string  true       "分类id, 多个分类用英文"
+// @Param   Keyword   query   string  true       "关键词, 指标ID/指标名称"
+// @Success 200 {object} NameCheckResult
+// @router /gpr_risk/edb_info/name_check [post]
+func (this *BaseFromGprRiskController) GprRiskNameCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req []*data_manage.NameCheckEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	codeMaxT := 30
+	codeLen := len(req)
+	if codeLen > codeMaxT {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+
+	indexNames := make([]string, 0)
+	resp := make([]*data_manage.EdbNameCheckResult, 0)
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		indexNames = append(indexNames, v.EdbName)
+		resp = append(resp, &data_manage.EdbNameCheckResult{
+			EdbCode: v.EdbCode,
+			EdbName: v.EdbName,
+		})
+		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_GPR_RISK, 0, utils.EDB_DATA_LIMIT)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
+			return
+		}
+		if len(dataItems) <= 0 {
+			respItem, err := data.AddEdbData(utils.DATA_SOURCE_GPR_RISK, v.EdbCode, v.Frequency)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				return
+			}
+			if respItem.Ret != 200 {
+				br.Msg = "未搜索到该指标"
+				br.ErrMsg = respItem.ErrMsg + ";EdbCode:" + v.EdbCode
+				return
+			}
+		}
+	}
+
+	// 重名校验
+	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames, utils.EDB_INFO_TYPE)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取重名指标失败, Err: " + e.Error()
+		return
+	}
+	nameExists := make(map[string]bool)
+	for _, v := range edbList {
+		nameExists[v.EdbName] = true
+	}
+	if len(nameExists) > 0 {
+		for _, v := range resp {
+			v.Exist = nameExists[v.EdbName]
+		}
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// GprRiskAddCheck
+// @Title 加入指标库指标Id检测
+// @Description 加入指标库指标Id检测
+// @Param	request	body request.BatchAddCheckReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /gpr_risk/edb_info/add_check [post]
+func (c *BaseFromGprRiskController) GprRiskAddCheck() {
+	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
+	}
+	var req data_manage.BatchAddCheckReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	codeMaxT := 30
+	codeLen := len(req.IndexCodes)
+
+	// 获取指标库已有指标
+	existsEdb, e := data_manage.GetEdbCodesBySource(utils.DATA_SOURCE_GPR_RISK)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取自有数据已添加的指标失败, Err: " + e.Error()
+		return
+	}
+	existMap := make(map[string]*data_manage.EdbInfo)
+	for _, v := range existsEdb {
+		existMap[v.EdbCode] = v
+	}
+
+	if codeLen == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if codeLen > codeMaxT {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMaxT)
+		return
+	}
+
+	// 查询选中的指标
+	cond := fmt.Sprintf(` AND index_code IN (%s)`, utils.GetOrmInReplace(codeLen))
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.IndexCodes)
+	list, err := data_manage.GetGprRiskIndex(cond, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
+		return
+	}
+
+	if len(list) > codeMaxT {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMaxT)
+		return
+	}
+
+	resp := make([]*data_manage.BaseFromGprRiskIndexList, 0)
+	for _, v := range list {
+		if edb, ok := existMap[v.IndexCode]; ok {
+			v.EdbInfoId = edb.EdbInfoId
+			v.EdbClassifyId = edb.ClassifyId
+			v.EdbUniqueCode = edb.UniqueCode
+			v.EdbExist = 1
+		}
+		resp = append(resp, v)
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// GprRiskEdbInfoAdd
+// @Title 新增指标接口
+// @Description 新增指标接口
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /gpr_risk/edb_info/add [post]
+func (this *BaseFromGprRiskController) GprRiskEdbInfoAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	deleteCache := true
+	cacheKey := "CACHE_EDB_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req data_manage.AddEdbInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	req.EdbName = strings.Trim(req.EdbName, " ")
+	req.EdbCode = strings.Trim(req.EdbCode, " ")
+
+	if req.EdbCode == "" {
+		br.Msg = "指标ID不能为空"
+		return
+	}
+
+	if req.EdbName == "" {
+		br.Msg = "指标名称不能为空"
+		return
+	}
+
+	if req.Frequency == "" {
+		br.Msg = "频率不能为空"
+		return
+	}
+
+	if req.Unit == "" {
+		br.Msg = "单位不能为空"
+		return
+	}
+
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	count, err := data_manage.GetGprRiskIndexDataCount(req.EdbCode)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if count == 0 {
+		br.Msg = "指标不存在"
+	}
+
+	// 指标入库
+	edbInfo, err, errMsg, isSendEmail := data.EdbInfoAdd(utils.DATA_SOURCE_GPR_RISK, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, req.StartDate, req.EndDate, sysUser.AdminId, sysUser.RealName, this.Lang)
+	if err != nil {
+		br.Msg = "保存失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+
+	// 试用平台更新用户累计新增指标数
+	adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取系统用户数据失败,Err:" + e.Error()
+		return
+	}
+	if utils.BusinessCode == utils.BusinessCodeSandbox && adminItem.DepartmentName == "ETA试用客户" {
+		go func() {
+			var r etaTrialService.EtaTrialUserReq
+			r.Mobile = adminItem.Mobile
+			_, _ = etaTrialService.UpdateUserIndexNum(r)
+		}()
+	}
+
+	//新增操作日志
+	{
+		edbLog := new(data_manage.EdbInfoLog)
+		edbLog.EdbInfoId = edbInfo.EdbInfoId
+		edbLog.SourceName = edbInfo.SourceName
+		edbLog.Source = edbInfo.Source
+		edbLog.EdbCode = edbInfo.EdbCode
+		edbLog.EdbName = edbInfo.EdbName
+		edbLog.ClassifyId = edbInfo.ClassifyId
+		edbLog.SysUserId = sysUser.AdminId
+		edbLog.SysUserRealName = sysUser.RealName
+		edbLog.CreateTime = time.Now()
+		edbLog.Content = string(this.Ctx.Input.RequestBody)
+		edbLog.Status = "新增指标"
+		edbLog.Method = this.Ctx.Input.URI()
+		go data_manage.AddEdbInfoLog(edbLog)
+	}
+
+	// 更新es
+	go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+
+	resp := new(data_manage.AddEdbInfoResp)
+	resp.EdbInfoId = edbInfo.EdbInfoId
+	resp.UniqueCode = edbInfo.UniqueCode
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+	br.IsAddLog = true
+}
+
+// ExportGprRiskList
+// @Title 导出GPR地缘风险指数数据
+// @Description 导出GPR地缘风险指数数据
+// @Param   ClassifyId   query   int  true       "关键字搜索"
+// @Param   IndexCode   query   string  true       "指标编码"
+// @Success 200  导出成功
+// @router /gpr_risk/export [get]
+func (this *BaseFromGprRiskController) ExportGprRiskList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请重新登录"
+		return
+	}
+
+	classifyId, _ := this.GetInt("ClassifyId")
+	indexCode := this.GetString("IndexCode")
+
+	if classifyId <= 0 && indexCode == "" {
+		br.Msg = "请选择分类或者指标"
+		return
+	}
+	dir, _ := os.Executable()
+	exPath := filepath.Dir(dir)
+	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
+	xlsxFile := xlsx.NewFile()
+
+	var condition string
+	var pars []interface{}
+	var classifyName string
+	if classifyId > 0 {
+		classifyInfo, err := data_manage.GetBaseFromGprRiskClassifyById(classifyId)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				br.Msg = "分类不存在"
+				return
+			}
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取分类失败,Err:" + err.Error()
+			return
+		}
+		classifyName = classifyInfo.ClassifyName
+		childClassify, err := data_manage.GetBaseFromGprRiskClassifyByParentId(classifyId)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取分类失败,Err:" + err.Error()
+			return
+		}
+
+		if len(childClassify) > 0 {
+			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
+			for _, child := range childClassify {
+				pars = append(pars, child.ClassifyId)
+			}
+		} else {
+			condition += ` AND classify_id=?`
+			pars = append(pars, classifyId)
+		}
+	}
+	if indexCode != "" {
+		condition += ` AND index_code=? `
+		pars = append(pars, indexCode)
+	}
+
+	indexList, err := data_manage.GetGprRiskIndex(condition, pars)
+	if err != nil {
+		br.Msg = "下载失败"
+		br.ErrMsg = "获取指标失败,Err:" + err.Error()
+		fmt.Println("获取数据失败,Err:" + err.Error())
+		return
+	}
+	if len(indexList) <= 0 {
+		fmt.Println("indexList 为空")
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "success"
+		return
+	}
+
+	codeList := make([]string, 0)
+	frequenciesMap := make(map[string][]*data_manage.BaseFromGprRiskIndexList)
+	for _, v := range indexList {
+		codeList = append(codeList, v.IndexCode)
+		frequenciesMap[v.Frequency] = append(frequenciesMap[v.Frequency], v)
+	}
+	dataListMap := make(map[string][]*data_manage.BaseFromGprRiskData)
+	if len(indexList) > 0 {
+		allDataList, e := data_manage.GetGprRiskIndexDataByCodes(codeList)
+		if e != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取数据失败,Err:" + e.Error()
+			return
+		}
+		for _, v := range allDataList {
+			dataListMap[v.IndexCode] = append(dataListMap[v.IndexCode], v)
+		}
+	}
+	// 按照频率分组排序
+	frequencies := []string{
+		"日度", "周度", "旬度", "月度", "季度", "半年度", "年度",
+	}
+	for _, frequency := range frequencies {
+		//获取指标
+		indexCodeList, ok := frequenciesMap[frequency]
+		if !ok {
+			continue
+		}
+		if len(indexCodeList) <= 0 {
+			fmt.Printf("sheet:%s, 不存在指标", frequency)
+			return
+		}
+		var sheetName string
+		switch frequency {
+		case "日度":
+			sheetName = "日度(Daily)"
+		case "周度":
+			sheetName = "周度(Weekly)"
+		case "旬度":
+			sheetName = "旬度(ten-day)"
+		case "月度":
+			sheetName = "月度(Monthly)"
+		case "季度":
+			sheetName = "季度(Quarterly)"
+		case "半年度":
+			sheetName = "半年度(Semi-annual)"
+		case "年度":
+			sheetName = "年度(Annual)"
+		default:
+			sheetName = "其他数据"
+		}
+		sheetNew, err := xlsxFile.AddSheet(sheetName)
+		if err != nil {
+			fmt.Println("新增Sheet失败", err.Error())
+			return
+		}
+		secNameRow := sheetNew.AddRow()
+		frequencyRow := sheetNew.AddRow()
+		unitRow := sheetNew.AddRow()
+		lastModifyDateRow := sheetNew.AddRow()
+
+		var indexIdList []int
+		for _, idx := range frequenciesMap[frequency] {
+			indexIdList = append(indexIdList, idx.BaseFromGprRiskIndexId)
+		}
+		dataTimeList, err := data_manage.GetGprRiskDataDataTimeByIndexId(indexIdList)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取数据时间失败,Err:" + err.Error()
+			fmt.Println("获取数据时间失败", err.Error())
+			return
+		}
+
+		// 添加excel左侧指标日期
+		setRowIndex := 4
+		for rk, dv := range dataTimeList {
+			rowIndex := setRowIndex + rk
+			row := sheetNew.Row(rowIndex)
+			displayDate, _ := time.Parse(utils.FormatDate, dv)
+			displayDateCell := row.AddCell()
+			style := new(xlsx.Style)
+			style.ApplyAlignment = true
+			style.Alignment.WrapText = true
+			displayDateCell.SetStyle(style)
+			displayDateCell.SetDate(displayDate)
+
+		}
+		for k, icl := range indexCodeList {
+			// 获取数据
+			dataList, ok := dataListMap[icl.IndexCode]
+			if !ok {
+				continue
+			}
+			if k == 0 {
+				secNameRow.AddCell().SetValue("指标名称/Metric Name")
+				frequencyRow.AddCell().SetValue("频度/Frequency")
+				unitRow.AddCell().SetValue("单位/Unit")
+				lastModifyDateRow.AddCell().SetValue("更新时间/Update Time")
+				min := k * 3
+				sheetNew.SetColWidth(min, min, 15)
+			}
+			if len(dataList) == 0 {
+				continue
+			}
+			secNameRow.AddCell().SetValue(icl.IndexName)
+			frequencyRow.AddCell().SetValue(icl.Frequency)
+			unitRow.AddCell().SetValue(icl.Unit)
+
+			timeDate, err := time.Parse(utils.FormatDateTime, dataList[0].ModifyTime)
+			if err != nil {
+				continue
+			}
+			lastModifyDateRow.AddCell().SetValue(timeDate.Format(utils.FormatDate))
+			dataInfoMap := make(map[string]*data_manage.BaseFromGprRiskData)
+			for _, v := range dataList {
+				dataInfoMap[v.DataTime] = v
+			}
+
+			for rk, dtv := range dataTimeList {
+				rowIndex := setRowIndex + rk
+				row := sheetNew.Row(rowIndex)
+				displayDateCell := row.AddCell()
+				tmpData, ok := dataInfoMap[dtv]
+				if ok {
+					displayDateCell.SetValue(tmpData.Value)
+				}
+			}
+		}
+	}
+
+	err = xlsxFile.Save(downLoadnFilePath)
+	if err != nil {
+		//有指标无数据时先导出一遍空表
+		sheet, err := xlsxFile.AddSheet("无数据")
+		if err != nil {
+			br.Msg = "新增Sheet失败"
+			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
+			return
+		}
+		rowSecName := sheet.AddRow()
+		celSecName := rowSecName.AddCell()
+		celSecName.SetValue("")
+		e := xlsxFile.Save(downLoadnFilePath)
+		if e != nil {
+			br.Msg = "保存文件失败"
+			br.ErrMsg = "保存文件失败"
+			return
+		}
+	}
+
+	fileName := classifyName
+	if indexCode != "" && len(indexList) == 1 {
+		fileName = indexList[0].IndexName
+	}
+	fileName = strings.Replace(fileName, ": ", "_", -1)
+	fileName = strings.Replace(fileName, ", ", "_", -1)
+	fileName = strings.Replace(fileName, " ", "_", -1)
+	fileName += time.Now().Format("06.01.02") + `.xlsx` //文件名称
+	fmt.Println(fileName)
+	this.Ctx.Output.Download(downLoadnFilePath, fileName)
+	defer func() {
+		os.Remove(downLoadnFilePath)
+	}()
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "success"
+}
+
+// GetFrequency
+// @Title GPR地缘风险指数数据频度
+// @Description GPR地缘风险指数数据频度接口
+// @Param   ClassifyId   query   string  true       "分类Id"
+// @Success 200 {object} data_manage.LzFrequency
+// @router /gpr_risk/frequency [get]
+func (this *BaseFromGprRiskController) GetFrequency() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		return
+	}
+
+	frequencyList, err := data_manage.GetGprRiskFrequencyByClassifyId(classifyId)
+	if err != nil {
+		br.Msg = "获取频度失败"
+		br.ErrMsg = "获取频度失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = frequencyList
+}

+ 22 - 0
controllers/data_manage/jiayue_edb_source.go

@@ -71,6 +71,15 @@ func (this *JiaYueEdbSourceController) FrequencyList() {
 		return
 	}
 
+	// 测试环境老在报错=_=!
+	if utils.RunMode == "debug" {
+		br.Data = make([]string, 0)
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+
 	frequencies, e := data.GetJiaYueFrequencyListFromBridge()
 	if e != nil {
 		br.Msg = "获取失败"
@@ -141,6 +150,19 @@ func (this *JiaYueEdbSourceController) IndexPageList() {
 		currentIndex = 1
 	}
 
+	// 测试环境老在报错=_=!
+	if utils.RunMode == "debug" {
+		page := paging.GetPaging(currentIndex, pageSize, 0)
+		resp := new(data_manage.JiaYueIndexPageListResp)
+		resp.Paging = page
+		resp.List = make([]*data_manage.DictIndexItem, 0)
+		br.Data = resp
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+
 	var params data_manage.BridgeJiaYuePageIndexReq
 	params.PageIndex = currentIndex
 	params.PageSize = pageSize

+ 13 - 13
controllers/data_manage/line_equation/line_chart_classify.go

@@ -36,7 +36,7 @@ func (this *LineEquationChartClassifyController) ChartClassifyList() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -64,14 +64,14 @@ func (this *LineEquationChartClassifyController) ChartClassifyList() {
 	source := utils.CHART_SOURCE_LINE_EQUATION
 
 	rootList, err := data_manage.GetChartClassifyByParentId(0, source)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	allChartInfo, err := data_manage.GetChartInfoAll([]int{source})
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
@@ -113,14 +113,14 @@ func (this *LineEquationChartClassifyController) ChartClassifyList() {
 func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
 	// 获取所有的分类
 	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_LINE_EQUATION)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	// /获取所有的图表
 	allChartInfo, err := data_manage.GetChartInfoByAdminId([]int{utils.CHART_SOURCE_LINE_EQUATION}, adminInfo.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
@@ -208,7 +208,7 @@ func (this *LineEquationChartClassifyController) AddChartClassify() {
 	}
 
 	// 新增图表分类
-	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_LINE_EQUATION, this.Lang, this.SysUser)
+	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_LINE_EQUATION, 0, this.Lang, this.SysUser)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = "添加分类失败,Err:" + err.Error()
@@ -312,7 +312,7 @@ func (this *LineEquationChartClassifyController) DeleteChartClassifyCheck() {
 
 	if deleteStatus != 1 && req.ChartInfoId == 0 {
 		classifyCount, err := data_manage.GetChartClassifyCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
 			return
@@ -374,7 +374,7 @@ func (this *LineEquationChartClassifyController) DeleteChartClassify() {
 	if req.ChartClassifyId > 0 && req.ChartInfoId == 0 {
 		//判断是否含有指标
 		count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -398,7 +398,7 @@ func (this *LineEquationChartClassifyController) DeleteChartClassify() {
 	if req.ChartInfoId > 0 {
 		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -461,7 +461,7 @@ func (this *LineEquationChartClassifyController) DeleteChartClassify() {
 		pars = append(pars, req.ChartInfoId)
 
 		nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 			return
@@ -481,14 +481,14 @@ func (this *LineEquationChartClassifyController) DeleteChartClassify() {
 			pars = append(pars, chartInfo.ChartClassifyId)
 
 			classifyItem, err := data_manage.GetChartClassifyByCondition(condition, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
 				return
 			}
 			if classifyItem != nil {
 				nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 					return
@@ -623,7 +623,7 @@ func (this *LineEquationChartClassifyController) ChartClassifyMove() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartClassifyByParentId(chartClassifyInfo.ParentId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return

+ 27 - 23
controllers/data_manage/line_equation/line_chart_info.go

@@ -413,7 +413,7 @@ func (this *LineEquationChartInfoController) Move() {
 	if chartInfo.ChartClassifyId != req.ChartClassifyId {
 		//查询需要修改的分类下是否存在同一个图表名称
 		tmpChartInfo, tmpErr := data_manage.GetChartInfoByClassifyIdAndName(req.ChartClassifyId, chartInfo.ChartName)
-		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "移动失败,Err:" + tmpErr.Error()
 			return
@@ -472,7 +472,7 @@ func (this *LineEquationChartInfoController) Move() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartInfoByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return
@@ -588,7 +588,7 @@ func (this *LineEquationChartInfoController) List() {
 
 	if chartClassifyId > 0 {
 		chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取图表信息失败"
 			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 			return
@@ -628,7 +628,7 @@ func (this *LineEquationChartInfoController) List() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -646,7 +646,7 @@ func (this *LineEquationChartInfoController) List() {
 
 	//获取图表信息
 	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -654,7 +654,7 @@ func (this *LineEquationChartInfoController) List() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -698,7 +698,7 @@ func (this *LineEquationChartInfoController) List() {
 	}
 
 	resp := new(data_manage.ChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.Paging = page
 		resp.List = items
@@ -709,7 +709,7 @@ func (this *LineEquationChartInfoController) List() {
 	}
 
 	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -760,7 +760,7 @@ func (this *LineEquationChartInfoController) Detail() {
 	chartInfo := new(data_manage.ChartInfoView)
 	chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图被删除,请刷新页面"
 			br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error()
 			return
@@ -834,7 +834,7 @@ func (this *LineEquationChartInfoController) Detail() {
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -962,7 +962,7 @@ func (this *LineEquationChartInfoController) DetailFromUniqueCode() {
 	status := true
 	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			status = false
 		} else {
 			br.Msg = "获取失败"
@@ -1000,7 +1000,7 @@ func (this *LineEquationChartInfoController) DetailFromUniqueCode() {
 					myCond += ` AND a.chart_info_id=? `
 					myPars = append(myPars, chartInfo.ChartInfoId)
 					myList, err := data_manage.GetMyChartByCondition(myCond, myPars)
-					if err != nil && err.Error() != utils.ErrNoRow() {
+					if err != nil && !utils.IsErrNoRow(err) {
 						br.Msg = "获取失败"
 						br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 						return
@@ -1076,7 +1076,7 @@ func (this *LineEquationChartInfoController) Refresh() {
 		chartInfo, err = data_manage.GetChartInfoByUniqueCode(uniqueCode)
 	}
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,无需刷新"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -1236,7 +1236,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					msg = "获取失败"
 					errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -1400,7 +1400,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				msg = "获取失败"
 				errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -1496,7 +1496,7 @@ func (this *LineEquationChartInfoController) EnInfoEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -1514,7 +1514,7 @@ func (this *LineEquationChartInfoController) EnInfoEdit() {
 		pars = append(pars, req.ChartInfoId, req.ChartNameEn, utils.CHART_SOURCE_LINE_EQUATION)
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return
@@ -1614,7 +1614,7 @@ func (this *LineEquationChartInfoController) SearchByEs() {
 
 	sourceList := []int{utils.CHART_SOURCE_LINE_EQUATION}
 
-	var searchList []*data_manage.ChartInfo
+	var searchList []*data_manage.ChartInfoMore
 	var total int64
 	var err error
 
@@ -1623,7 +1623,7 @@ func (this *LineEquationChartInfoController) SearchByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1637,7 +1637,7 @@ func (this *LineEquationChartInfoController) SearchByEs() {
 		searchList, total, err = data.EsSearchChartInfo(keyword, showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
 	} else {
 		total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -1667,13 +1667,17 @@ func (this *LineEquationChartInfoController) SearchByEs() {
 
 		for _, v := range searchList {
 			tmp := new(data_manage.ChartInfoMore)
-			tmp.ChartInfo = *v
+			tmp.ChartInfo = v.ChartInfo
 			// 图表数据权限
 			tmp.HaveOperaAuth = true
 			//判断是否需要展示英文标识
 			if _, ok := chartEdbMap[v.ChartInfoId]; ok {
 				tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, []*data_manage.ChartEdbInfoMapping{}, v.Source, v.ChartType)
 			}
+			tmp.SearchText = v.SearchText
+			if tmp.SearchText == "" {
+				tmp.SearchText = v.ChartName
+			}
 			finalList = append(finalList, tmp)
 		}
 	}
@@ -1735,7 +1739,7 @@ func (this *LineEquationChartInfoController) BaseInfoEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -1760,7 +1764,7 @@ func (this *LineEquationChartInfoController) BaseInfoEdit() {
 		pars = append(pars, req.ChartName)
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return

+ 61 - 41
controllers/data_manage/line_feature/chart_info.go

@@ -65,7 +65,7 @@ func (this *LineFeaturesChartInfoController) MultipleGraphConfigSave() {
 	if err != nil {
 		br.Msg = "指标A异常"
 		br.ErrMsg = "指标A异常,err:" + err.Error()
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = `指标A不存在`
 			br.IsSendEmail = false
 		}
@@ -226,7 +226,7 @@ func (this *LineFeaturesChartInfoController) MultipleGraphPreview() {
 	// 标准差图表信息
 	{
 		// 配置了数据才有返回
-		if req.StandardDeviation.CalculateValue > 0 {
+		if req.StandardDeviation.CalculateValue > 1 {
 			tmpChartInfo := *chartInfo
 			tmpChartInfo.ChartName = fmt.Sprintf("%s%d期滚动标准差", edbInfoMapping.EdbName, req.StandardDeviation.CalculateValue)
 
@@ -554,11 +554,15 @@ func (this *LineFeaturesChartInfoController) MultipleGraphConfigSaveChart() {
 	}
 
 	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
 		return
 	}
+	// 兼容gorm
+	if multipleGraphConfigChartMapping != nil && multipleGraphConfigChartMapping.Id <= 0 {
+		multipleGraphConfigChartMapping = nil
+	}
 
 	err = nil
 	var isAdd bool
@@ -567,13 +571,13 @@ func (this *LineFeaturesChartInfoController) MultipleGraphConfigSaveChart() {
 		isAdd = true
 	} else {
 		chartInfo, err := data_manage.GetChartInfoById(multipleGraphConfigChartMapping.ChartInfoId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = `保存失败`
 			br.ErrMsg = "获取图表信息失败,ERR:" + err.Error()
 			return
 		}
 		// 说明图还在,没有被删除
-		if chartInfo != nil {
+		if chartInfo != nil && chartInfo.ChartInfoId > 0 {
 			chartInfoId = multipleGraphConfigChartMapping.ChartInfoId
 			req.ChartName = chartInfo.ChartName
 			req.ClassifyId = chartInfo.ChartClassifyId
@@ -812,7 +816,7 @@ func (this *LineFeaturesChartInfoController) MultipleGraphConfigSaveChart() {
 			br.ErrMsg = "保存配置与图表的关联关系失败,ERR:" + err.Error()
 			return
 		}
-	} else if multipleGraphConfigChartMapping != nil {
+	} else if multipleGraphConfigChartMapping != nil && multipleGraphConfigChartMapping.MultipleGraphConfigId > 0 {
 		multipleGraphConfigChartMapping.ChartInfoId = chartInfo.ChartInfoId
 		multipleGraphConfigChartMapping.ModifyTime = time.Now()
 		err = multipleGraphConfigChartMapping.Update([]string{"ChartInfoId", "ModifyTime"})
@@ -866,7 +870,7 @@ func CopyMultipleGraphConfigSaveChart(req request.SaveMultipleGraphChartReq, thi
 	}
 
 	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
 		return
@@ -874,7 +878,7 @@ func CopyMultipleGraphConfigSaveChart(req request.SaveMultipleGraphChartReq, thi
 
 	// 原图
 	oldChartInfo, err := data_manage.GetChartInfoById(multipleGraphConfigChartMapping.ChartInfoId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取图表信息失败,ERR:" + err.Error()
 		return
@@ -1064,7 +1068,7 @@ func (this *LineFeaturesChartInfoController) MultipleGraphConfigSaveEdb() {
 	}
 
 	multipleGraphConfigEdbMapping, err := data_manage.GetMultipleGraphConfigEdbMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
 		return
@@ -1072,17 +1076,17 @@ func (this *LineFeaturesChartInfoController) MultipleGraphConfigSaveEdb() {
 	err = nil
 	var isAdd bool
 	var edbInfoId int
-	if multipleGraphConfigEdbMapping == nil {
+	if multipleGraphConfigEdbMapping == nil || multipleGraphConfigEdbMapping.MultipleGraphConfigId <= 0 {
 		isAdd = true
 	} else {
 		edbInfo, err := data_manage.GetEdbInfoById(multipleGraphConfigEdbMapping.EdbInfoId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = `保存失败`
 			br.ErrMsg = "获取图表信息失败,ERR:" + err.Error()
 			return
 		}
 		// 说明指标还在,没有被删除
-		if edbInfo != nil && !req.IsSaveAs {
+		if edbInfo != nil && edbInfo.EdbInfoId > 0 && !req.IsSaveAs {
 			edbInfoId = multipleGraphConfigEdbMapping.EdbInfoId
 			req.EdbName = edbInfo.EdbName
 			req.ClassifyId = edbInfo.ClassifyId
@@ -1463,12 +1467,12 @@ func (this *LineFeaturesChartInfoController) Move() {
 	if chartInfo.ChartClassifyId != req.ChartClassifyId {
 		//查询需要修改的分类下是否存在同一个图表名称
 		tmpChartInfo, tmpErr := data_manage.GetChartInfoByClassifyIdAndName(req.ChartClassifyId, chartInfo.ChartName)
-		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "移动失败,Err:" + tmpErr.Error()
 			return
 		}
-		if tmpChartInfo != nil {
+		if tmpChartInfo != nil && tmpChartInfo.ChartInfoId > 0 {
 			br.Msg = "移动失败,同一个分类下图表名称不允许重复"
 			br.ErrMsg = "移动失败,同一个分类下图表名称不允许重复"
 			return
@@ -1522,14 +1526,14 @@ func (this *LineFeaturesChartInfoController) Move() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartInfoByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return
 		}
 
 		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
-		if firstClassify != nil && firstClassify.Sort == 0 {
+		if firstClassify != nil && firstClassify.ChartClassifyId > 0 && firstClassify.Sort == 0 {
 			updateSortStr := ` sort + 1 `
 			_ = data_manage.UpdateChartInfoSortByClassifyId(firstClassify.ChartClassifyId, 0, firstClassify.ChartInfoId-1, []int{utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY}, updateSortStr)
 		}
@@ -1633,7 +1637,7 @@ func (this *LineFeaturesChartInfoController) List() {
 
 	if chartClassifyId > 0 {
 		chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取图表信息失败"
 			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 			return
@@ -1671,7 +1675,7 @@ func (this *LineFeaturesChartInfoController) List() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1689,7 +1693,7 @@ func (this *LineFeaturesChartInfoController) List() {
 
 	//获取图表信息
 	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -1697,7 +1701,7 @@ func (this *LineFeaturesChartInfoController) List() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -1741,7 +1745,7 @@ func (this *LineFeaturesChartInfoController) List() {
 	}
 
 	resp := new(data_manage.ChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.Paging = page
 		resp.List = items
@@ -1752,7 +1756,7 @@ func (this *LineFeaturesChartInfoController) List() {
 	}
 
 	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -1795,7 +1799,7 @@ func (this *LineFeaturesChartInfoController) Detail() {
 	chartInfo := new(data_manage.ChartInfoView)
 	chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图被删除,请刷新页面"
 			br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error()
 			return
@@ -1851,6 +1855,9 @@ func (this *LineFeaturesChartInfoController) Detail() {
 			latestDateT, _ := time.Parse(utils.FormatDate, edbMapping.LatestDate)
 			maxDate = latestDateT
 		}
+		if chartInfo.ChartType == utils.CHART_TYPE_SEASON && chartInfo.DateType == utils.DateTypeNYears {
+			maxDate = time.Date(maxDate.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+		}
 		startDate, endDate := utils.GetDateByDateTypeV2(chartInfo.DateType, chartInfo.StartDate, chartInfo.EndDate, chartInfo.StartYear, maxDate)
 		edbList, resultResp, err, errMsg = lineFeatureServ.GetStandardDeviationData(0, startDate, endDate, edbMapping, calculateValue)
 	case utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE:
@@ -1866,6 +1873,9 @@ func (this *LineFeaturesChartInfoController) Detail() {
 			latestDateT, _ := time.Parse(utils.FormatDate, edbMapping.LatestDate)
 			maxDate = latestDateT
 		}
+		if chartInfo.ChartType == utils.CHART_TYPE_SEASON && chartInfo.DateType == utils.DateTypeNYears {
+			maxDate = time.Date(maxDate.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+		}
 		startDate, endDate := utils.GetDateByDateTypeV2(chartInfo.DateType, chartInfo.StartDate, chartInfo.EndDate, chartInfo.StartYear, maxDate)
 		edbList, resultResp, err, errMsg = lineFeatureServ.GetPercentileData(0, startDate, endDate, edbMapping, percentileConfig.CalculateValue, percentileConfig.CalculateUnit, percentileConfig.PercentType)
 	case utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY:
@@ -1914,7 +1924,7 @@ func (this *LineFeaturesChartInfoController) Detail() {
 	}
 
 	// 判断是否加入我的图库
-	if chartInfoId > 0 && chartInfo != nil {
+	if chartInfoId > 0 && chartInfo != nil && chartInfo.ChartInfoId > 0 {
 		{
 			var myChartCondition string
 			var myChartPars []interface{}
@@ -1924,7 +1934,7 @@ func (this *LineFeaturesChartInfoController) Detail() {
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -2052,7 +2062,7 @@ func (this *LineFeaturesChartInfoController) DetailFromUniqueCode() {
 	status := true
 	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			status = false
 		} else {
 			br.Msg = "获取失败"
@@ -2090,7 +2100,7 @@ func (this *LineFeaturesChartInfoController) DetailFromUniqueCode() {
 					myCond += ` AND a.chart_info_id=? `
 					myPars = append(myPars, chartInfo.ChartInfoId)
 					myList, err := data_manage.GetMyChartByCondition(myCond, myPars)
-					if err != nil && err.Error() != utils.ErrNoRow() {
+					if err != nil && !utils.IsErrNoRow(err) {
 						br.Msg = "获取失败"
 						br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 						return
@@ -2166,7 +2176,7 @@ func (this *LineFeaturesChartInfoController) Refresh() {
 		chartInfo, err = data_manage.GetChartInfoByUniqueCode(uniqueCode)
 	}
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,无需刷新"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -2248,7 +2258,7 @@ func (this *LineFeaturesChartInfoController) Copy() {
 	}
 
 	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByChartId(oldChartInfo.ChartInfoId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
 		return
@@ -2332,7 +2342,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					msg = "获取失败"
 					errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -2408,7 +2418,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		if !isOk {
 			if errMsg != "" {
 				uniqueCode := ""
-				if chartInfo != nil {
+				if chartInfo != nil && chartInfo.ChartInfoId > 0 {
 					uniqueCode = chartInfo.UniqueCode
 				}
 				tmpTip := fmt.Sprintf("查询图表详情失败,line_feature.GetChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
@@ -2480,6 +2490,9 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			latestDateT, _ := time.Parse(utils.FormatDate, edbMapping.LatestDate)
 			maxDate = latestDateT
 		}
+		if chartInfo.ChartType == utils.CHART_TYPE_SEASON && chartInfo.DateType == utils.DateTypeNYears {
+			maxDate = time.Date(maxDate.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+		}
 		startDate, endDate := utils.GetDateByDateTypeV2(chartInfo.DateType, chartInfo.StartDate, chartInfo.EndDate, chartInfo.StartYear, maxDate)
 		edbList, resultResp, err, msg = lineFeatureServ.GetStandardDeviationData(0, startDate, endDate, edbMapping, calculateValue)
 	case utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE:
@@ -2495,6 +2508,9 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			latestDateT, _ := time.Parse(utils.FormatDate, edbMapping.LatestDate)
 			maxDate = latestDateT
 		}
+		if chartInfo.ChartType == utils.CHART_TYPE_SEASON && chartInfo.DateType == utils.DateTypeNYears {
+			maxDate = time.Date(maxDate.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+		}
 		startDate, endDate := utils.GetDateByDateTypeV2(chartInfo.DateType, chartInfo.StartDate, chartInfo.EndDate, chartInfo.StartYear, maxDate)
 		edbList, resultResp, err, msg = lineFeatureServ.GetPercentileData(0, startDate, endDate, edbMapping, percentileConfig.CalculateValue, percentileConfig.CalculateUnit, percentileConfig.PercentType)
 	case utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY:
@@ -2520,7 +2536,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		return
 	}
 
-	if chartInfo.ChartInfoId > 0 && chartInfo != nil {
+	if chartInfo != nil && chartInfo.ChartInfoId > 0 {
 		//判断是否加入我的图库
 		{
 			var myChartCondition string
@@ -2531,7 +2547,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				msg = "获取失败"
 				errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -2627,7 +2643,7 @@ func (this *LineFeaturesChartInfoController) EnInfoEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -2645,7 +2661,7 @@ func (this *LineFeaturesChartInfoController) EnInfoEdit() {
 		pars = append(pars, req.ChartInfoId, req.ChartNameEn, utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY)
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return
@@ -2745,7 +2761,7 @@ func (this *LineFeaturesChartInfoController) SearchByEs() {
 
 	sourceList := []int{utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY}
 
-	var searchList []*data_manage.ChartInfo
+	var searchList []*data_manage.ChartInfoMore
 	var total int64
 	var err error
 
@@ -2754,7 +2770,7 @@ func (this *LineFeaturesChartInfoController) SearchByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -2768,7 +2784,7 @@ func (this *LineFeaturesChartInfoController) SearchByEs() {
 		searchList, total, err = data.EsSearchChartInfo(keyword, showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
 	} else {
 		total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -2798,13 +2814,17 @@ func (this *LineFeaturesChartInfoController) SearchByEs() {
 
 		for _, v := range searchList {
 			tmp := new(data_manage.ChartInfoMore)
-			tmp.ChartInfo = *v
+			tmp.ChartInfo = v.ChartInfo
 			// 图表数据权限
 			tmp.HaveOperaAuth = true
 			//判断是否需要展示英文标识
 			if _, ok := chartEdbMap[v.ChartInfoId]; ok {
 				tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, []*data_manage.ChartEdbInfoMapping{}, v.Source, v.ChartType)
 			}
+			tmp.SearchText = v.SearchText
+			if tmp.SearchText == "" {
+				tmp.SearchText = v.ChartName
+			}
 			finalList = append(finalList, tmp)
 		}
 	}
@@ -2866,7 +2886,7 @@ func (this *LineFeaturesChartInfoController) BaseInfoEdit() {
 	//判断指标名称是否存在
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面"
 			br.ErrMsg = "图表已被删除,请刷新页面"
 			return
@@ -2892,7 +2912,7 @@ func (this *LineFeaturesChartInfoController) BaseInfoEdit() {
 		pars = append(pars, req.ChartName)
 		existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 		if err != nil {
-			if err.Error() != utils.ErrNoRow() {
+			if !utils.IsErrNoRow(err) {
 				br.Msg = "判断英文图表名称是否存在失败"
 				br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 				return

+ 13 - 13
controllers/data_manage/line_feature/classify.go

@@ -36,7 +36,7 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyList() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -64,14 +64,14 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyList() {
 	source := utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION
 
 	rootList, err := data_manage.GetChartClassifyByParentId(0, source)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	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})
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
@@ -113,14 +113,14 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyList() {
 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)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	// /获取所有的图表
 	allChartInfo, err := data_manage.GetChartInfoByAdminId([]int{utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY}, adminInfo.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
@@ -208,7 +208,7 @@ func (this *LineFeaturesChartClassifyController) AddChartClassify() {
 	}
 
 	// 新增图表分类
-	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, this.Lang, this.SysUser)
+	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, 0, this.Lang, this.SysUser)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = "添加分类失败,Err:" + err.Error()
@@ -312,7 +312,7 @@ func (this *LineFeaturesChartClassifyController) DeleteChartClassifyCheck() {
 
 	if deleteStatus != 1 && req.ChartInfoId == 0 {
 		classifyCount, err := data_manage.GetChartClassifyCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
 			return
@@ -374,7 +374,7 @@ func (this *LineFeaturesChartClassifyController) DeleteChartClassify() {
 	if req.ChartClassifyId > 0 && req.ChartInfoId == 0 {
 		//判断是否含有指标
 		count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -398,7 +398,7 @@ func (this *LineFeaturesChartClassifyController) DeleteChartClassify() {
 	if req.ChartInfoId > 0 {
 		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -461,7 +461,7 @@ func (this *LineFeaturesChartClassifyController) DeleteChartClassify() {
 		pars = append(pars, req.ChartInfoId)
 
 		nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 			return
@@ -481,14 +481,14 @@ func (this *LineFeaturesChartClassifyController) DeleteChartClassify() {
 			pars = append(pars, chartInfo.ChartClassifyId)
 
 			classifyItem, err := data_manage.GetChartClassifyByCondition(condition, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
 				return
 			}
 			if classifyItem != nil {
 				nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 					return
@@ -623,7 +623,7 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyMove() {
 
 	} else {
 		firstClassify, err := data_manage.GetFirstChartClassifyByParentId(chartClassifyInfo.ParentId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
 			return

+ 11 - 13
controllers/data_manage/manual.go

@@ -2,13 +2,13 @@ package data_manage
 
 import (
 	"encoding/json"
-	"fmt"
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/system"
 	"eta/eta_api/services/data"
 	"eta/eta_api/utils"
+	"fmt"
 	"strconv"
 	"strings"
 	"time"
@@ -224,12 +224,12 @@ func (this *ChartClassifyController) AddManualClassify() {
 	}
 
 	classifyItem, err := data_manage.GetManualClassifyByClassifyName(req.ClassifyName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "判断名称是否已存在失败"
 		br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 		return
 	}
-	if classifyItem != nil {
+	if classifyItem != nil && classifyItem.ClassifyId > 0 {
 		if classifyItem.IsShow == 1 {
 			br.Msg = "分类名称已存在,请重新输入"
 			br.IsSendEmail = false
@@ -243,7 +243,7 @@ func (this *ChartClassifyController) AddManualClassify() {
 				return
 			}
 			parentItem, _ := data_manage.GetManualClassifyById(req.ParentId)
-			if parentItem != nil && parentItem.IsShow == 0 {
+			if parentItem != nil && parentItem.ClassifyId > 0 && parentItem.IsShow == 0 {
 				err = data_manage.ModifyManualClassifyIsShow(1, parentItem.ClassifyId, req.ParentId)
 				if err != nil {
 					br.Msg = "保存失败"
@@ -315,17 +315,15 @@ func (this *ChartClassifyController) ManualClassifyEdit() {
 		return
 	}
 	classifyItem, err := data_manage.GetManualClassifyByClassifyName(req.ClassifyName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "修改失败"
 		br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 		return
 	}
 
-	if classifyItem != nil {
-		if item.ClassifyId != classifyItem.ClassifyId {
-			br.Msg = "名称已存在,请重新输入"
-			return
-		}
+	if classifyItem != nil && classifyItem.ClassifyId > 0 && item.ClassifyId != classifyItem.ClassifyId {
+		br.Msg = "名称已存在,请重新输入"
+		return
 	}
 
 	err = data_manage.ModifyManualClassifyName(req.ClassifyName, req.ClassifyId, req.ParentId)
@@ -364,7 +362,7 @@ func (this *ChartClassifyController) ManualClassifyDel() {
 		return
 	}
 	classifyItem, err := data_manage.GetManualClassifyById(req.ClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "查找分类失败"
 		br.ErrMsg = "查找分类失败,Err:" + err.Error()
 		return
@@ -377,7 +375,7 @@ func (this *ChartClassifyController) ManualClassifyDel() {
 
 	// 获取当前分类下是否存在子分类
 	count, err := data_manage.GetChildManualClassifyCount(req.ClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "删除失败"
 		br.ErrMsg = "根据分类id获取下面存在的子分类数量失败,Err:" + err.Error()
 		return
@@ -391,7 +389,7 @@ func (this *ChartClassifyController) ManualClassifyDel() {
 	if classifyItem.ParentId > 0 {
 		// 获取当前分类下的指标数
 		count, err = data_manage.GetManualEdbInfoCountByClassifyId(req.ClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "根据分类id获取下面存在的指标数量失败,Err:" + err.Error()
 			return

+ 45 - 11
controllers/data_manage/manual_edb.go

@@ -7,6 +7,7 @@ import (
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/system"
 	"eta/eta_api/services/data"
+	"eta/eta_api/services/elastic"
 	etaTrialService "eta/eta_api/services/eta_trial"
 	"eta/eta_api/utils"
 	"fmt"
@@ -274,19 +275,47 @@ func (c *ManualEdbController) EdbSearch() {
 
 	var startSize int
 	if pageSize <= 0 {
-		pageSize = utils.PageSize20
+		pageSize = utils.PageSize15
 	}
 	if currentIndex <= 0 {
 		currentIndex = 1
 	}
 	startSize = utils.StartIndex(currentIndex, pageSize)
+	resp := new(models.EdbListResp)
 
 	//关键字
 	keyword := c.GetString("Keyword")
+	keyword = strings.TrimSpace(keyword)
 
 	var condition string
 	var pars []interface{}
 
+	// es搜索
+	highlightMap := make(map[string]string)
+	if keyword != "" {
+		_, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keyword, utils.DATA_SOURCE_MANUAL, 0, []int{}, []int{}, []string{}, startSize, pageSize)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("ES-搜索手工指标列表失败, %v", e)
+			return
+		}
+		if len(list) == 0 {
+			resp.List = make([]*models.EdbInfoListItem, 0)
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "获取成功"
+			br.Data = resp
+			return
+		}
+		var codes []string
+		for _, v := range list {
+			codes = append(codes, v.IndexCode)
+			highlightMap[v.IndexCode] = v.SearchText
+		}
+		condition += fmt.Sprintf(` AND a.TRADE_CODE IN (%s)`, utils.GetOrmInReplace(len(list)))
+		pars = append(pars, codes)
+	}
+
 	//userId := sysUser.AdminId
 	//超管账号可以查看分类下的所有频度数据
 	if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
@@ -304,10 +333,10 @@ func (c *ManualEdbController) EdbSearch() {
 
 	}
 
-	if keyword != "" {
-		condition += ` AND (a.SEC_NAME like ?  or a.TRADE_CODE like ? )`
-		pars = utils.GetLikeKeywordPars(pars, keyword, 2)
-	}
+	//if keyword != "" {
+	//	condition += ` AND (a.SEC_NAME like ?  or a.TRADE_CODE like ? )`
+	//	pars = utils.GetLikeKeywordPars(pars, keyword, 2)
+	//}
 
 	total, err := models.GetCountEdbInfoList(condition, pars)
 	if err != nil {
@@ -315,22 +344,27 @@ func (c *ManualEdbController) EdbSearch() {
 		br.ErrMsg = "获取失败,Err:" + err.Error()
 		return
 	}
-
 	list, err := models.GetEdbInfoList(condition, pars, startSize, pageSize)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取失败,Err:" + err.Error()
 		return
 	}
-
 	for _, v := range list {
 		v.UniqueCode = utils.MD5(v.TradeCode)
+		// ES搜索信息
+		v.Source = utils.DATA_SOURCE_MANUAL
+		v.SourceName = "手工指标录入"
+		s := highlightMap[v.TradeCode]
+		if s == "" {
+			s = v.SecName
+		}
+		v.ClassifyUniqueCode = utils.MD5(strconv.Itoa(v.ClassifyId))
+		v.SearchText = s
 	}
 
-	resp := models.EdbListResp{
-		List:   list,
-		Paging: paging.GetPaging(currentIndex, pageSize, total),
-	}
+	resp.List = list
+	resp.Paging = paging.GetPaging(currentIndex, pageSize, total)
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "获取成功"

+ 17 - 10
controllers/data_manage/multiple_graph_config.go

@@ -61,7 +61,7 @@ func (this *ChartInfoController) MultipleGraphConfigSave() {
 	if err != nil {
 		br.Msg = "指标A异常"
 		br.ErrMsg = "指标A异常,err:" + err.Error()
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = `指标A不存在`
 			br.IsSendEmail = false
 		}
@@ -81,7 +81,7 @@ func (this *ChartInfoController) MultipleGraphConfigSave() {
 	if err != nil {
 		br.Msg = "指标B异常"
 		br.ErrMsg = "指标B异常,err:" + err.Error()
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = `指标B不存在`
 			br.IsSendEmail = false
 		}
@@ -676,11 +676,14 @@ func (this *ChartInfoController) MultipleGraphConfigSaveChart() {
 	}
 
 	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
 		return
 	}
+	if multipleGraphConfigChartMapping != nil && multipleGraphConfigChartMapping.Id <= 0 {
+		multipleGraphConfigChartMapping = nil
+	}
 
 	err = nil
 	var isAdd bool
@@ -689,13 +692,13 @@ func (this *ChartInfoController) MultipleGraphConfigSaveChart() {
 		isAdd = true
 	} else {
 		chartInfo, err := data_manage.GetChartInfoById(multipleGraphConfigChartMapping.ChartInfoId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = `保存失败`
 			br.ErrMsg = "获取图表信息失败,ERR:" + err.Error()
 			return
 		}
 		// 说明图还在,没有被删除
-		if chartInfo != nil {
+		if chartInfo != nil && chartInfo.ChartInfoId > 0 {
 			chartInfoId = multipleGraphConfigChartMapping.ChartInfoId
 			req.ChartName = chartInfo.ChartName
 			req.ClassifyId = chartInfo.ChartClassifyId
@@ -1018,7 +1021,7 @@ func CopyMultipleGraphConfigSaveChart(req request.SaveMultipleGraphChartReq, thi
 	}
 
 	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
 		return
@@ -1026,7 +1029,7 @@ func CopyMultipleGraphConfigSaveChart(req request.SaveMultipleGraphChartReq, thi
 
 	// 原图
 	oldChartInfo, err := data_manage.GetChartInfoById(multipleGraphConfigChartMapping.ChartInfoId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取图表信息失败,ERR:" + err.Error()
 		return
@@ -1275,11 +1278,15 @@ func (this *ChartInfoController) MultipleGraphConfigSaveEdb() {
 	}
 
 	multipleGraphConfigEdbMapping, err := data_manage.GetMultipleGraphConfigEdbMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = `保存失败`
 		br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
 		return
 	}
+	if multipleGraphConfigEdbMapping != nil && multipleGraphConfigEdbMapping.Id <= 0 {
+		multipleGraphConfigEdbMapping = nil
+	}
+
 	err = nil
 	var isAdd bool
 	var edbInfoId int
@@ -1287,13 +1294,13 @@ func (this *ChartInfoController) MultipleGraphConfigSaveEdb() {
 		isAdd = true
 	} else {
 		edbInfo, err := data_manage.GetEdbInfoById(multipleGraphConfigEdbMapping.EdbInfoId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = `保存失败`
 			br.ErrMsg = "获取图表信息失败,ERR:" + err.Error()
 			return
 		}
 		// 说明指标还在,没有被删除
-		if edbInfo != nil && !req.IsSaveAs {
+		if edbInfo != nil && edbInfo.EdbInfoId > 0 && !req.IsSaveAs {
 			edbInfoId = multipleGraphConfigEdbMapping.EdbInfoId
 			req.EdbName = edbInfo.EdbName
 			req.ClassifyId = edbInfo.ClassifyId

+ 76 - 59
controllers/data_manage/my_chart.go

@@ -70,30 +70,42 @@ func (this *MyChartController) ChartList() {
 	condition += ` AND source = ? `
 	pars = append(pars, utils.CHART_SOURCE_DEFAULT)
 
-	chartClassifyIds := make([]int, 0)
-	if chartClassifyId > 0 {
+	// 是否显示精选资源
+	isSelected, _ := this.GetInt("IsSelected", -1)
 
-		list, e := data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_DEFAULT)
-		if e != nil {
+	chartClassifyIds := make([]int, 0)
+	var classifyList []*data_manage.ChartClassifyItems
+	var err error
+	if isSelected >= 0 {
+		classifyList, err = data_manage.GetChartClassifyAllBySourceIsSelected(utils.CHART_SOURCE_DEFAULT, isSelected)
+		if err != nil {
 			br.Msg = "获取失败"
-			br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", e)
+			br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", err)
 			return
 		}
-		parents := data.GetChartClassifyChildrenRecursive(list, chartClassifyId)
+	} else {
+		classifyList, err = data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_DEFAULT)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", err)
+			return
+		}
+	}
+	if chartClassifyId > 0 {
+		parents := data.GetChartClassifyChildrenRecursive(classifyList, chartClassifyId)
 		sort.Slice(parents, func(i, j int) bool {
 			return parents[i].Level < parents[i].Level
 		})
 		for _, v := range parents {
 			chartClassifyIds = append(chartClassifyIds, v.ChartClassifyId)
 		}
-
-		//chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
-		//if err != nil && err.Error() != utils.ErrNoRow() {
-		//	br.Msg = "获取图表信息失败"
-		//	br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
-		//	return
-		//}
-		condition += " AND chart_classify_id IN(" + utils.GetOrmInReplace(len(chartClassifyIds)) + ") "
+		condition += " AND chart_classify_id IN (" + utils.GetOrmInReplace(len(chartClassifyIds)) + ") "
+		pars = append(pars, chartClassifyIds)
+	} else if isSelected >= 0 {
+		for _, v := range classifyList {
+			chartClassifyIds = append(chartClassifyIds, v.ChartClassifyId)
+		}
+		condition += " AND chart_classify_id IN (" + utils.GetOrmInReplace(len(chartClassifyIds)) + ") "
 		pars = append(pars, chartClassifyIds)
 	}
 
@@ -129,7 +141,7 @@ func (this *MyChartController) ChartList() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -147,7 +159,7 @@ func (this *MyChartController) ChartList() {
 
 	//获取图表信息
 	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -155,7 +167,7 @@ func (this *MyChartController) ChartList() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -232,7 +244,7 @@ func (this *MyChartController) ChartList() {
 	}
 
 	resp := new(data_manage.ChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.Paging = page
 		resp.List = items
@@ -243,7 +255,7 @@ func (this *MyChartController) ChartList() {
 	}
 
 	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -278,7 +290,7 @@ func (this *MyChartController) ClassifyList() {
 	}
 	//获取图表信息
 	list, err := data_manage.GetMyChartClassifyAll(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取分类信息失败"
 		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
@@ -286,7 +298,7 @@ func (this *MyChartController) ClassifyList() {
 	}
 
 	resp := new(data_manage.MyChartClassifyResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.MyChartClassifyItem, 0)
 		resp.List = items
 		br.Ret = 200
@@ -458,7 +470,7 @@ func (this *MyChartController) ClassifyEdit() {
 		return
 	}
 	item, err := data_manage.GetMyChartClassifyById(sysUser.AdminId, req.MyChartClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "保存失败"
 		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
 		return
@@ -546,7 +558,7 @@ func (this *MyChartController) ClassifyMove() {
 	}
 	//查询该分类存不存在
 	item, err := data_manage.GetMyChartClassifyById(sysUser.AdminId, req.MyChartClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "移动失败,找不到该分类"
 		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
 		return
@@ -596,14 +608,14 @@ func (this *MyChartController) ClassifyMove() {
 		updateCol = append(updateCol, "Sort", "ModifyTime")
 	} else {
 		firstClassify, err := data_manage.GetFirstMyChartClassifyByAdminId(sysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "移动失败"
 			br.ErrMsg = "获取获取当前账号下的排序第一条的分类信息失败,Err:" + err.Error()
 			return
 		}
 
 		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
-		if firstClassify != nil && firstClassify.Sort == 0 {
+		if firstClassify != nil && firstClassify.MyChartClassifyId > 0 && firstClassify.Sort == 0 {
 			updateSortStr := ` sort + 1 `
 			_ = data_manage.UpdateMyChartClassifySortByClassifyId(sysUser.AdminId, firstClassify.MyChartClassifyId-1, 0, updateSortStr)
 		}
@@ -670,7 +682,7 @@ func (this *MyChartController) ClassifyDelete() {
 	}
 
 	item, err := data_manage.GetMyChartClassifyById(sysUser.AdminId, req.MyChartClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "保存失败"
 		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
 		return
@@ -769,7 +781,7 @@ func (this *MyChartController) MyChartAdd() {
 	}
 
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败!"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
@@ -790,14 +802,14 @@ func (this *MyChartController) MyChartAdd() {
 	pars = append(pars, req.ChartInfoId)
 
 	existItem, err := data_manage.GetMyChartDetailByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "保存失败"
 		br.ErrMsg = "保存失败,校验名称是否存在失败,Err:" + err.Error()
 		return
 	}
 	resp := new(data_manage.MyChartAddResp)
 	var myChartClassifyId string
-	if existItem != nil { //修改
+	if existItem != nil && existItem.MyChartId > 0 { //修改
 		fmt.Println("modify")
 		for _, v := range req.MyChartClassifyId {
 			myChartClassifyId += strconv.Itoa(v) + ","
@@ -830,7 +842,7 @@ func (this *MyChartController) MyChartAdd() {
 			var sort float64
 			// 查找最小排序值
 			firstMapItem, _ := data_manage.GetMyChartSort(sysUser.AdminId, v, 0)
-			if firstMapItem != nil {
+			if firstMapItem != nil && firstMapItem.MyChartClassifyMappingId > 0 {
 				sort = firstMapItem.Sort
 			}
 			//获取最大的排序字段
@@ -910,7 +922,7 @@ func (this *MyChartController) MyChartAddToClassify() {
 	}
 
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败!"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
@@ -931,14 +943,14 @@ func (this *MyChartController) MyChartAddToClassify() {
 	pars = append(pars, req.ChartInfoId)
 
 	existItem, err := data_manage.GetMyChartDetailByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "保存失败"
 		br.ErrMsg = "保存失败,校验名称是否存在失败,Err:" + err.Error()
 		return
 	}
 	resp := new(data_manage.MyChartAddResp)
 	var myChartClassifyId string
-	if existItem != nil { //修改
+	if existItem != nil && existItem.MyChartId > 0 { //修改
 		fmt.Println("modify")
 		for _, v := range req.MyChartClassifyId {
 			myChartClassifyId += strconv.Itoa(v) + ","
@@ -1051,9 +1063,9 @@ func (this *MyChartController) GetMyChartClassifyIdList() {
 	pars = append(pars, sysUser.AdminId, chartInfoId)
 
 	existItem, _ := data_manage.GetMyChartDetailByCondition(condition, pars)
-	if existItem != nil {
+	if existItem != nil && existItem.MyChartId > 0 {
 		myChartClassifyList, err := data_manage.GetMyChartClassifyList(existItem.MyChartId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取图表信息失败!"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -1249,6 +1261,7 @@ func (this *MyChartController) MyChartList() {
 
 	myChartId, _ := this.GetInt("MyChartId")
 	isShared, _ := this.GetBool("IsShared")
+	keyword := this.GetString("Keyword")
 
 	var total int
 	page := paging.GetPaging(currentIndex, pageSize, total)
@@ -1274,7 +1287,7 @@ func (this *MyChartController) MyChartList() {
 		if isShared {
 			myClassify, e := data_manage.GetMyChartClassifyByClassifyId(myChartClassifyId)
 			if e != nil {
-				if e.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(e) {
 					br.Msg = "分类已被删除, 请刷新页面"
 					return
 				}
@@ -1285,6 +1298,14 @@ func (this *MyChartController) MyChartList() {
 			chartAdminId = myClassify.AdminId
 		}
 	}
+	if keyword != "" {
+		if this.Lang == utils.LANG_EN {
+			condition += " AND (b.chart_name_en like ?) "
+		} else {
+			condition += " AND (b.chart_name like ?) "
+		}
+		pars = append(pars, "%"+keyword+"%")
+	}
 
 	condition += " AND (a.admin_id = ? OR d.is_public = 1)"
 	pars = append(pars, chartAdminId)
@@ -1299,7 +1320,7 @@ func (this *MyChartController) MyChartList() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1317,14 +1338,14 @@ func (this *MyChartController) MyChartList() {
 
 	//获取图表信息
 	list, err := data_manage.GetMyChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 		return
 	}
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -1399,7 +1420,7 @@ func (this *MyChartController) MyChartList() {
 	}
 
 	resp := new(data_manage.MyChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.MyChartList, 0)
 		resp.Paging = page
 		resp.List = items
@@ -1409,7 +1430,7 @@ func (this *MyChartController) MyChartList() {
 		return
 	}
 	total, err = data_manage.GetMyChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取信息失败"
 		br.ErrMsg = "获取我的图表数据总数失败,Err:" + err.Error()
 		return
@@ -1590,7 +1611,7 @@ func (this *MyChartController) ChartRecommendList() {
 
 	//获取图表信息
 	list, err := data_manage.GetRecommendChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -1598,7 +1619,7 @@ func (this *MyChartController) ChartRecommendList() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -1649,7 +1670,7 @@ func (this *MyChartController) ChartRecommendList() {
 	}
 
 	resp := new(data_manage.ChartRecommendListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.List = items
 		br.Ret = 200
@@ -1698,7 +1719,7 @@ func (this *MyChartController) MyChartSearch() {
 
 	//获取图表信息
 	list, err := data_manage.GetMyChartSearchByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -1793,7 +1814,7 @@ func (this *MyChartController) MyChartSearchByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1910,7 +1931,7 @@ func (this *MyChartController) PublicClassifyList() {
 	}
 	//获取图表信息
 	list, err := data_manage.GetPublicChartClassifyAllExceptMy(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取公共分类信息失败"
 		br.ErrMsg = "获取公共分类信息失败,Err:" + err.Error()
@@ -1918,7 +1939,7 @@ func (this *MyChartController) PublicClassifyList() {
 	}
 
 	resp := new(data_manage.PublicChartClassifyResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		resp.List = make([]data_manage.PublicChartClassifyList, 0)
 		br.Ret = 200
 		br.Success = true
@@ -1980,11 +2001,11 @@ func (this *MyChartController) PublicClassifyList() {
 	// 指标显示的语言
 	{
 		configDetail, _ := system.GetConfigDetailByCode(this.SysUser.AdminId, system.ChartLanguageVar)
-		if configDetail != nil {
+		if configDetail != nil && configDetail.ConfigId > 0 {
 			language = configDetail.ConfigValue
 		} else {
 			configDetail, _ = system.GetDefaultConfigDetailByCode(system.ChartLanguageVar)
-			if configDetail != nil {
+			if configDetail != nil && configDetail.ConfigId > 0 {
 				language = configDetail.ConfigValue
 			}
 		}
@@ -2027,7 +2048,7 @@ func (this *MyChartController) ModifyClassifyPublicStatus() {
 	}
 	//查询该分类存不存在
 	item, err := data_manage.GetMyChartClassifyById(sysUser.AdminId, req.MyChartClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "修改失败,找不到该分类"
 		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
 		return
@@ -2099,7 +2120,7 @@ func (this *MyChartController) CopyClassifyAndChart() {
 	}
 	//查询该公共分类存不存在
 	item, err := data_manage.GetPublicMyChartClassifyById(req.MyChartClassifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "复制失败,找不到该分类"
 		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
 		return
@@ -2254,7 +2275,7 @@ func (this *MyChartController) CompanyPublicClassifyList() {
 		pars = append(pars, keyword)
 	}
 	list, err := data_manage.GetCompanyPublicClassifyList(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取用户可见分类列表失败"
 		br.ErrMsg = "获取用户可见分类列表失败, Err:" + err.Error()
@@ -2262,7 +2283,7 @@ func (this *MyChartController) CompanyPublicClassifyList() {
 	}
 
 	resp := new(data_manage.MyChartClassifyResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.MyChartClassifyItem, 0)
 		resp.List = items
 		br.Ret = 200
@@ -2284,10 +2305,6 @@ func (this *MyChartController) CompanyPublicClassifyList() {
 	br.Data = resp
 }
 
-//func init() {
-//	data.AddAllMyChartInfo()
-//}
-
 // ClassifyFrameworkNodeList
 // @Title 我的图表分类-关联的框架节点列表
 // @Description 我的图表分类-关联的框架节点列表
@@ -2319,7 +2336,7 @@ func (this *MyChartController) ClassifyFrameworkNodeList() {
 
 	_, e := data_manage.GetMyChartClassifyById(sysUser.AdminId, classifyId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "分类不存在, 请刷新页面"
 			return
 		}

+ 61 - 18
controllers/data_manage/mysteel_chemical_data.go

@@ -44,14 +44,14 @@ func (this *EdbInfoController) MysteelChemicalClassify() {
 	}
 
 	rootList, err := data_manage.GetBaseFromMysteelChemicalClassifyByParentId(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromMysteelChemicalClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -113,7 +113,7 @@ func (this *EdbInfoController) MysteelChemicalIndexList() {
 		return
 	}
 	allBaseFromMysteelChemicalIndex, err := data_manage.GetMysteelChemicalIndexByClassifyId(classifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 		return
@@ -594,7 +594,7 @@ func (this *EdbInfoController) MysteelChemicalData() {
 			dataList = make([]*data_manage.MysteelChemicalData, 0)
 		}
 		edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_MYSTEEL_CHEMICAL, v.IndexCode)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取数据失败"
 			br.ErrMsg = "获取指标库统计数据失败,Err:" + err.Error()
 			return
@@ -1327,7 +1327,7 @@ func (c *EdbInfoController) NameCheck() {
 			EdbName: v.EdbName,
 		})
 		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_MYSTEEL_CHEMICAL, 0, utils.EDB_DATA_LIMIT)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
 			return
@@ -1585,7 +1585,7 @@ func (this *EdbInfoController) Add() {
 
 	tmpInfo, err := data_manage.GetBaseFromMysteelChemicalIndexByCode(req.EdbCode)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取失败,Err:" + err.Error()
 			return
@@ -1745,7 +1745,7 @@ func (c *EdbInfoController) AddCheck() {
 	br.Success = true
 }
 
-// MysteelChemicalSearch
+// MysteelChemicalBatchSearch
 // @Title 钢联化工指标查询
 // @Description 钢联化工指标查询
 // @Param   BaseFromMysteelChemicalClassifyIds   query   string  true       "分类id"
@@ -1779,17 +1779,58 @@ func (this *EdbInfoController) MysteelChemicalBatchSearch() {
 		condition += " AND (index_name like ? OR index_code like ?) "
 		pars = utils.GetLikeKeywordPars(pars, keyword, 2)
 	}
+	// 频度(多选)
+	frequencies := this.GetString("Frequencies")
+	frequencies = strings.TrimSpace(frequencies)
+	if frequencies != "" {
+		freArr := strings.Split(frequencies, ",")
+		if len(freArr) > 0 {
+			condition += " AND frequency IN ?"
+			pars = append(pars, freArr)
+		}
+	}
+	resp := new(data_manage.MysteelChemicalPageListResp)
+	resp.List = make([]*data_manage.MysteelChemicalList, 0)
+
+	//if classifyIdStr == `` && keyword == `` {
+	//	var list = make([]*data_manage.MysteelChemicalList, 0)
+	//	br.Ret = 200
+	//	br.Success = true
+	//	br.Msg = "获取成功"
+	//	br.Data = list
+	//	return
+	//}
+
+	// 分页查询
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize10
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
 
-	if classifyIdStr == `` && keyword == `` {
-		var list = make([]*data_manage.MysteelChemicalList, 0)
+	// 获取未加入指标库的原始指标
+	total, e := data_manage.GetNoEdbMysteelChemicalIndexCount(condition, pars)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("获取未加入指标库的钢联指标数失败, %v", e)
+		return
+	}
+	if total <= 0 {
+		page := paging.GetPaging(currentIndex, pageSize, 0)
+		resp.Paging = page
+		br.Data = resp
 		br.Ret = 200
 		br.Success = true
 		br.Msg = "获取成功"
-		br.Data = list
 		return
 	}
 
-	list, err := data_manage.GetMysteelChemicalIndex(condition, pars)
+	list, err := data_manage.GetNoEdbMysteelChemicalIndexPageList(condition, pars, startSize, pageSize)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取失败,Err:" + err.Error()
@@ -1802,6 +1843,7 @@ func (this *EdbInfoController) MysteelChemicalBatchSearch() {
 			classifyIdInts = append(classifyIdInts, v.BaseFromMysteelChemicalClassifyId)
 		}
 	}
+	classifyListMap := make(map[int]int, 0)
 	if len(classifyIdInts) > 0 {
 		// 查询父级分类信息
 		classifyList, e := data_manage.GetBaseFromMysteelChemicalClassifyByIds(classifyIdInts)
@@ -1810,20 +1852,21 @@ func (this *EdbInfoController) MysteelChemicalBatchSearch() {
 			br.ErrMsg = "获取失获取目录信息失败,Err:" + e.Error()
 			return
 		}
-		classifyListMap := make(map[int]int, 0)
 		for _, v := range classifyList {
 			classifyListMap[v.BaseFromMysteelChemicalClassifyId] = v.ParentId
 		}
-		for _, v := range list {
-			v.UniqueCode = fmt.Sprint(v.BaseFromMysteelChemicalClassifyId, "_", v.Id)
-			if p, ok := classifyListMap[v.BaseFromMysteelChemicalClassifyId]; ok {
-				v.ParentClassifyId = p
-			}
+	}
+	for _, v := range list {
+		if p, ok := classifyListMap[v.BaseFromMysteelChemicalClassifyId]; ok {
+			v.ParentClassifyId = p
 		}
+		resp.List = append(resp.List, v)
 	}
 
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "获取成功"
-	br.Data = list
+	br.Data = resp
 }

+ 5 - 5
controllers/data_manage/predict_edb_classify.go

@@ -259,7 +259,7 @@ func (this *PredictEdbClassifyController) Edit() {
 		return
 	}
 
-	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ClassifyName, this.Lang, this.SysUser)
+	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ParentId, req.ClassifyName, this.Lang, this.SysUser)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -702,7 +702,7 @@ func (this *PredictEdbClassifyController) SimpleList() {
 	}
 
 	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, 1)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -715,7 +715,7 @@ func (this *PredictEdbClassifyController) SimpleList() {
 		// 获取当前账号的不可见指标
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -845,7 +845,7 @@ func (this *PredictEdbClassifyController) ClassifyTree() {
 	}()
 
 	allList, err := data_manage.GetPredictEdbClassifyAll()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -869,7 +869,7 @@ func (this *PredictEdbClassifyController) ClassifyTree() {
 			button := data.GetPredictEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
 			allList[k].Button = button
 		}
-		nodeAll = data.GetClassifyTreeRecursive(allList, 0)
+		nodeAll = data.GetClassifyTreeRecursive(allList, 0, 0)
 		//根据sort值排序
 		sortList = nodeAll
 		sort.Sort(sortList)

+ 205 - 89
controllers/data_manage/predict_edb_info.go

@@ -80,7 +80,7 @@ func (this *PredictEdbInfoController) EdbChartList() {
 	// 筛选分类
 	if classifyId > 0 {
 		childClassify, e, _ := data.GetChildClassifyByClassifyId(classifyId)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
 			return
@@ -104,7 +104,7 @@ func (this *PredictEdbInfoController) EdbChartList() {
 	// 获取当前账号的不可见指标
 	obj := data_manage.EdbInfoNoPermissionAdmin{}
 	confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 		return
@@ -120,14 +120,14 @@ func (this *PredictEdbInfoController) EdbChartList() {
 	}
 	//获取指标信息
 	dataCount, list, err := data_manage.GetEdbInfoFilterList(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取预测指标列表失败"
 		br.ErrMsg = "获取预测指标列表失败,Err:" + err.Error()
 		return
 	}
 
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		list = make([]*data_manage.EdbInfoList, 0)
 	} else {
 		classifyIdList := make([]int, 0)
@@ -245,14 +245,14 @@ func (this *PredictEdbInfoController) List() {
 	}
 	//获取指标信息
 	edbInfoItem, err := data_manage.GetEdbInfoByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 		return
 	}
 
-	if edbInfoItem == nil || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if edbInfoItem == nil || (err != nil && utils.IsErrNoRow(err)) {
 		item := new(data_manage.EdbInfoList)
 		resp.Paging = page
 		resp.Item = item
@@ -289,7 +289,7 @@ func (this *PredictEdbInfoController) List() {
 	//获取指标数据(实际已生成)
 	{
 		dataCount, dataList, err := data.GetPageData(edbInfoItem.EdbInfoId, edbInfoItem.Source, edbInfoItem.SubSource, edbInfoItem.LatestDate, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取指标信息失败"
 			br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 			return
@@ -427,31 +427,56 @@ func (this *PredictEdbInfoController) Add() {
 	ruleList := make([]request.RuleConfig, 0)
 	{
 		ruleMap := make(map[string]request.RuleConfig)
+		ruleEndNumSortMap := make(map[int]request.RuleConfig)
 		dateIntList := make([]int64, 0)
+		endNumList := make([]int, 0)
 		for _, v := range req.RuleList {
-			confEndDate, err := time.Parse(utils.FormatDate, v.EndDate)
-			if err != nil {
-				br.Msg = "配置项中时间异常,请重新选择"
-				br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error()
-				br.IsSendEmail = false
-				return
+			if req.EndDateType == 0 {
+				confEndDate, err := time.Parse(utils.FormatDate, v.EndDate)
+				if err != nil {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error()
+					br.IsSendEmail = false
+					return
+				}
+				dateIntList = append(dateIntList, confEndDate.Unix())
+				ruleMap[v.EndDate] = v
+			} else {
+				if _, ok := ruleEndNumSortMap[v.EndNum]; ok {
+					br.Msg = "所选期数不能和其他时间段相同"
+					return
+				}
+				endNumList = append(endNumList, v.EndNum)
+				ruleEndNumSortMap[v.EndNum] = v
 			}
-			dateIntList = append(dateIntList, confEndDate.Unix())
-			ruleMap[v.EndDate] = v
-		}
-		sort.Slice(dateIntList, func(i, j int) bool {
-			return dateIntList[i] < dateIntList[j]
-		})
-		for _, dateInt := range dateIntList {
-			currDateTime := time.Unix(dateInt, 0)
-			item, ok := ruleMap[currDateTime.Format(utils.FormatDate)]
-			if !ok {
-				br.Msg = "配置项中时间异常,请重新选择"
-				br.ErrMsg = "配置项中时间异常,请重新选择"
-				br.IsSendEmail = false
-				return
+		}
+		if req.EndDateType == 0 {
+			sort.Slice(dateIntList, func(i, j int) bool {
+				return dateIntList[i] < dateIntList[j]
+			})
+			for _, dateInt := range dateIntList {
+				currDateTime := time.Unix(dateInt, 0)
+				item, ok := ruleMap[currDateTime.Format(utils.FormatDate)]
+				if !ok {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择"
+					br.IsSendEmail = false
+					return
+				}
+				ruleList = append(ruleList, item)
+			}
+		} else {
+			sort.Ints(endNumList)
+			for _, endNum := range endNumList {
+				item, ok := ruleEndNumSortMap[endNum]
+				if !ok {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择"
+					br.IsSendEmail = false
+					return
+				}
+				ruleList = append(ruleList, item)
 			}
-			ruleList = append(ruleList, item)
 		}
 	}
 	req.RuleList = ruleList
@@ -479,6 +504,19 @@ func (this *PredictEdbInfoController) Add() {
 	}
 	resp := respItem.Data
 
+	edbInfoIdArr := make([]int, 0)
+	//查询相关的指标
+	edbMappingList, err := data_manage.GetAllCalculateByEdbInfoIdV2(resp.EdbInfoId)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取引用的指标信息失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range edbMappingList {
+		edbInfoIdArr = append(edbInfoIdArr, v.FromEdbInfoId)
+	}
+	// 添加指标引用记录
+	_ = data.SavePredictEdbInfoRelation(edbInfoIdArr, resp.EdbInfoId)
 	//添加es
 	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)
 
@@ -523,7 +561,7 @@ func (this *PredictEdbInfoController) ChartImageSet() {
 		if err != nil {
 			br.Msg = "保存失败"
 			br.ErrMsg = "保存失败,Err:" + err.Error()
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "找不到该指标"
 				br.ErrMsg = "找不到该指标"
 				br.IsSendEmail = false
@@ -603,31 +641,56 @@ func (this *PredictEdbInfoController) Edit() {
 	ruleList := make([]request.RuleConfig, 0)
 	{
 		ruleMap := make(map[string]request.RuleConfig)
+		ruleEndNumSortMap := make(map[int]request.RuleConfig)
 		dateIntList := make([]int64, 0)
+		endNumList := make([]int, 0)
 		for _, v := range req.RuleList {
-			confEndDate, err := time.Parse(utils.FormatDate, v.EndDate)
-			if err != nil {
-				br.Msg = "配置项中时间异常,请重新选择"
-				br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error()
-				br.IsSendEmail = false
-				return
+			if req.EndDateType == 0 {
+				confEndDate, err := time.Parse(utils.FormatDate, v.EndDate)
+				if err != nil {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error()
+					br.IsSendEmail = false
+					return
+				}
+				dateIntList = append(dateIntList, confEndDate.Unix())
+				ruleMap[v.EndDate] = v
+			} else {
+				if _, ok := ruleEndNumSortMap[v.EndNum]; ok {
+					br.Msg = "所选期数不能和其他时间段相同"
+					return
+				}
+				endNumList = append(endNumList, v.EndNum)
+				ruleEndNumSortMap[v.EndNum] = v
 			}
-			dateIntList = append(dateIntList, confEndDate.Unix())
-			ruleMap[v.EndDate] = v
-		}
-		sort.Slice(dateIntList, func(i, j int) bool {
-			return dateIntList[i] < dateIntList[j]
-		})
-		for _, dateInt := range dateIntList {
-			currDateTime := time.Unix(dateInt, 0)
-			item, ok := ruleMap[currDateTime.Format(utils.FormatDate)]
-			if !ok {
-				br.Msg = "配置项中时间异常,请重新选择"
-				br.ErrMsg = "配置项中时间异常,请重新选择"
-				br.IsSendEmail = false
-				return
+		}
+		if req.EndDateType == 0 {
+			sort.Slice(dateIntList, func(i, j int) bool {
+				return dateIntList[i] < dateIntList[j]
+			})
+			for _, dateInt := range dateIntList {
+				currDateTime := time.Unix(dateInt, 0)
+				item, ok := ruleMap[currDateTime.Format(utils.FormatDate)]
+				if !ok {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择"
+					br.IsSendEmail = false
+					return
+				}
+				ruleList = append(ruleList, item)
+			}
+		} else {
+			sort.Ints(endNumList)
+			for _, endNum := range endNumList {
+				item, ok := ruleEndNumSortMap[endNum]
+				if !ok {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择"
+					br.IsSendEmail = false
+					return
+				}
+				ruleList = append(ruleList, item)
 			}
-			ruleList = append(ruleList, item)
 		}
 	}
 	req.RuleList = ruleList
@@ -681,6 +744,19 @@ func (this *PredictEdbInfoController) Edit() {
 	}
 	resp := respItem.Data
 
+	edbInfoIdArr := make([]int, 0)
+	//查询相关的指标
+	edbMappingList, err := data_manage.GetAllCalculateByEdbInfoIdV2(resp.EdbInfoId)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取引用的指标信息失败,Err:" + err.Error()
+		return
+	}
+	for _, v := range edbMappingList {
+		edbInfoIdArr = append(edbInfoIdArr, v.FromEdbInfoId)
+	}
+	// 添加指标引用记录
+	_ = data.SavePredictEdbInfoRelation(edbInfoIdArr, resp.EdbInfoId)
 	//修改es
 	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)
 
@@ -850,7 +926,7 @@ func (this *PredictEdbInfoController) Detail() {
 	if edbInfo.EdbType == 1 {
 		// 获取所有的指标预测规则配置
 		tmpPredictEdbConfList, err := data_manage.GetPredictEdbConfListById(edbInfoId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取预测指标配置信息失败,Err:" + err.Error()
 			return
@@ -859,7 +935,7 @@ func (this *PredictEdbInfoController) Detail() {
 			var tmpPredictEdbConfCalculateMappingDetail []*data_manage.PredictEdbConfCalculateMappingDetail
 			if v.RuleType == 9 || v.RuleType == 14 {
 				tmpPredictEdbConfCalculateMappingDetail, err = data_manage.GetPredictEdbConfCalculateMappingDetailListByConfigId(v.PredictEdbInfoId, v.ConfigId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "获取失败"
 					br.ErrMsg = "获取预测指标配置与关联指标信息失败,Err:" + err.Error()
 					return
@@ -901,6 +977,7 @@ func (this *PredictEdbInfoController) Detail() {
 				ModifyTime:       v.ModifyTime,
 				CreateTime:       v.CreateTime,
 				CalculateList:    tmpPredictEdbConfCalculateMappingDetail,
+				EndNum:           v.EndNum,
 			}
 			predictEdbConfList = append(predictEdbConfList, tmp)
 		}
@@ -1100,7 +1177,7 @@ func (this *PredictEdbInfoController) FilterByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1176,6 +1253,15 @@ func (this *PredictEdbInfoController) FilterByEs() {
 	for i := 0; i < edbInfoListLen; i++ {
 		edbInfoList[i].EdbNameAlias = edbInfoList[i].EdbName
 		classifyIdList = append(classifyIdList, edbInfoList[i].ClassifyId)
+		// 如果没有关键词,那么搜索结果字段取指标名,前端已统一用该字段显示搜索的列表内容
+		if keyWord == "" {
+			if this.Lang == utils.ZhLangVersion {
+				edbInfoList[i].SearchText = edbInfoList[i].EdbName
+			}
+			if this.Lang == utils.EnLangVersion {
+				edbInfoList[i].SearchText = edbInfoList[i].EdbNameEn
+			}
+		}
 	}
 
 	// 当前列表中的分类map
@@ -1412,6 +1498,10 @@ func (this *PredictEdbInfoController) DataList() {
 		latestDateT, _ := time.Parse(utils.FormatDate, edbInfo.LatestDate)
 		maxDate = latestDateT
 	}
+	if chartType == utils.CHART_TYPE_SEASON && dateType == utils.DateTypeNYears {
+		// 季节性图需要特殊处理最近N年数据
+		maxDate = time.Date(maxDate.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+	}
 
 	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, maxDate)
 	if endDate == "" {
@@ -1519,31 +1609,56 @@ func (this *PredictEdbInfoController) ChartDataList() {
 	ruleList := make([]request.RuleConfig, 0)
 	{
 		ruleMap := make(map[string]request.RuleConfig)
+		ruleEndNumSortMap := make(map[int]request.RuleConfig)
 		dateIntList := make([]int64, 0)
+		endNumList := make([]int, 0)
 		for _, v := range req.RuleList {
-			confEndDate, err := time.Parse(utils.FormatDate, v.EndDate)
-			if err != nil {
-				br.Msg = "配置项中时间异常,请重新选择"
-				br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error()
-				br.IsSendEmail = false
-				return
+			if req.EndDateType == 0 {
+				confEndDate, err := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
+				if err != nil {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error()
+					br.IsSendEmail = false
+					return
+				}
+				dateIntList = append(dateIntList, confEndDate.Unix())
+				ruleMap[v.EndDate] = v
+			} else {
+				if _, ok := ruleEndNumSortMap[v.EndNum]; ok {
+					br.Msg = "所选期数不能和其他时间段相同"
+					return
+				}
+				endNumList = append(endNumList, v.EndNum)
+				ruleEndNumSortMap[v.EndNum] = v
 			}
-			dateIntList = append(dateIntList, confEndDate.Unix())
-			ruleMap[v.EndDate] = v
-		}
-		sort.Slice(dateIntList, func(i, j int) bool {
-			return dateIntList[i] < dateIntList[j]
-		})
-		for _, dateInt := range dateIntList {
-			currDateTime := time.Unix(dateInt, 0)
-			item, ok := ruleMap[currDateTime.Format(utils.FormatDate)]
-			if !ok {
-				br.Msg = "配置项中时间异常,请重新选择"
-				br.ErrMsg = "配置项中时间异常,请重新选择"
-				br.IsSendEmail = false
-				return
+		}
+		if req.EndDateType == 0 {
+			sort.Slice(dateIntList, func(i, j int) bool {
+				return dateIntList[i] < dateIntList[j]
+			})
+			for _, dateInt := range dateIntList {
+				currDateTime := time.Unix(dateInt, 0)
+				item, ok := ruleMap[currDateTime.Format(utils.FormatDate)]
+				if !ok {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择"
+					br.IsSendEmail = false
+					return
+				}
+				ruleList = append(ruleList, item)
+			}
+		} else {
+			sort.Ints(endNumList)
+			for _, endNum := range endNumList {
+				item, ok := ruleEndNumSortMap[endNum]
+				if !ok {
+					br.Msg = "配置项中时间异常,请重新选择"
+					br.ErrMsg = "配置项中时间异常,请重新选择"
+					br.IsSendEmail = false
+					return
+				}
+				ruleList = append(ruleList, item)
 			}
-			ruleList = append(ruleList, item)
 		}
 	}
 
@@ -1552,13 +1667,17 @@ func (this *PredictEdbInfoController) ChartDataList() {
 
 	endDateStr := `` //数据的结束日期
 	for _, v := range ruleList {
-		endDateStr = v.EndDate //预测指标的结束日期
-		confEndDate, err := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
-		if err != nil {
-			br.Msg = "配置项中时间异常,请重新选择"
-			br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error()
-			return
+		var confEndDate time.Time
+		if v.EndDate != "" {
+			endDateStr = v.EndDate //预测指标的结束日期
+			confEndDate, err = time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local)
+			if err != nil {
+				br.Msg = "配置项中时间异常,请重新选择"
+				br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error()
+				return
+			}
 		}
+
 		// 没有数据,自己瞎测试
 		//switch v.RuleType {
 		//case 3: //3:同比
@@ -1619,6 +1738,7 @@ func (this *PredictEdbInfoController) ChartDataList() {
 			FixedValue:       0,
 			Value:            v.Value,
 			EndDate:          confEndDate,
+			EndNum:           v.EndNum,
 			ModifyTime:       time.Now(),
 			CreateTime:       time.Now(),
 			DataList:         tmpDataList,
@@ -1631,7 +1751,7 @@ func (this *PredictEdbInfoController) ChartDataList() {
 	if err != nil {
 		br.Msg = "获取来源指标信息失败"
 		br.ErrMsg = "获取来源指标信息失败"
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.ErrMsg = "获取来源指标信息失败,Err:" + err.Error()
 		}
 		br.Success = true
@@ -1692,7 +1812,7 @@ func (this *PredictEdbInfoController) ChartDataList() {
 		// 获取预测数据
 		var predictMinValue, predictMaxValue float64
 
-		predictDataList, predictMinValue, predictMaxValue, err, errMsg := data.GetChartPredictEdbInfoDataListByConfList(predictEdbConfAndDataList, startDate, sourceEdbInfoItem.LatestDate, endDateStr, sourceEdbInfoItem.Frequency, req.DataDateType, allDataList)
+		predictDataList, predictMinValue, predictMaxValue, err, errMsg := data.GetChartPredictEdbInfoDataListByConfList(predictEdbConfAndDataList, startDate, sourceEdbInfoItem.LatestDate, endDateStr, req.EndDateType, sourceEdbInfoItem.Frequency, req.DataDateType, allDataList)
 		if err != nil {
 			br.Msg = "获取预测指标数据失败"
 			if errMsg != `` {
@@ -1930,10 +2050,6 @@ func (this *PredictEdbInfoController) Modify() {
 //
 //}
 
-//func init() {
-//	data.AddOrEditAllEdbInfoToEs()
-//}
-
 // ClassifyEdbInfoItems
 // @Title 获取分类下指标接口
 // @Description 获取分类下指标接口
@@ -1960,7 +2076,7 @@ func (this *PredictEdbInfoController) ClassifyEdbInfoItems() {
 	// 获取当前账号的不可见指标
 	obj := data_manage.EdbInfoNoPermissionAdmin{}
 	confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 		return
@@ -1977,7 +2093,7 @@ func (this *PredictEdbInfoController) ClassifyEdbInfoItems() {
 	}
 
 	allEdbInfo, err := data_manage.GetEdbInfoByClassifyId(classifyId, 1, sysUserId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -2093,7 +2209,7 @@ func (this *PredictEdbInfoController) ChartImageSetBySvg() {
 	if err != nil {
 		br.Msg = "保存失败"
 		br.ErrMsg = "保存失败,Err:" + err.Error()
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "找不到该指标"
 			br.ErrMsg = "找不到该指标"
 			br.IsSendEmail = false

+ 1045 - 0
controllers/data_manage/purang_data.go

@@ -0,0 +1,1045 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/system"
+	"eta/eta_api/services/data"
+	etaTrialService "eta/eta_api/services/eta_trial"
+	"eta/eta_api/utils"
+	"fmt"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
+)
+
+type BaseFromPurangController struct {
+	controllers.BaseAuthController
+}
+
+// PurangClassify
+// @Title Purang数据分类
+// @Description Purang数据分类接口
+// @Success 200 {object} data_manage.BaseFromPurangClassify
+// @router /purang/classify [get]
+func (this *BaseFromPurangController) PurangClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	classifyAll, err := data_manage.GetAllBaseFromPurangClassify()
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	//组装一级分类
+	rootMap := make(map[int][]*data_manage.BaseFromPurangClassifyItems)
+	list := make([]*data_manage.BaseFromPurangClassifyItems, 0)
+	for _, classify := range classifyAll {
+		classify.UniqueCode = strconv.Itoa(classify.ClassifyId)
+		if classify.ParentId == 0 {
+			if _, ok := rootMap[classify.ClassifyId]; !ok {
+				rootMap[classify.ClassifyId] = make([]*data_manage.BaseFromPurangClassifyItems, 0)
+				list = append(list, classify)
+
+			}
+		} else {
+			child, ok := rootMap[classify.ParentId]
+			if ok {
+				child = append(child, classify)
+				rootMap[classify.ParentId] = child
+			}
+		}
+	}
+
+	for k, v := range list {
+		child, ok := rootMap[v.ClassifyId]
+		if ok {
+			list[k].Children = child
+		}
+	}
+	//组装二级分类
+	var ret data_manage.BaseFromPurangClassifyResp
+	ret.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = ret
+}
+
+// PurangIndexData
+// @Title 获取Purang数据
+// @Description 获取Purang数据接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyId   query   string  true       "分类id"
+// @Success 200 {object} data_manage.LzFrequency
+// @router /purang/index/data [get]
+func (this *BaseFromPurangController) PurangIndexData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		return
+	}
+	// 增加频度请求入参
+	frequency := this.GetString("Frequency")
+
+	//获取指标
+	var condition string
+	var pars []interface{}
+
+	if classifyId > 0 {
+		condition += ` AND classify_id=? `
+		pars = append(pars, classifyId)
+	}
+	if frequency != "" {
+		condition += ` AND frequency=? `
+		pars = append(pars, frequency)
+	}
+
+	purangList, err := data_manage.GetPurangIndex(condition, pars)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	edbCodeList := make([]string, 0)
+	for _, v := range purangList {
+		edbCodeList = append(edbCodeList, v.IndexCode)
+	}
+	edbInfoMap := make(map[string]*data_manage.EdbInfo)
+	dataMap := make(map[string][]*data_manage.BaseFromPurangData)
+	total := 0
+	if len(edbCodeList) > 0 {
+		edbInfoList, err := data_manage.GetEdbInfoByEdbCodeList(utils.DATA_SOURCE_PURANG, edbCodeList)
+		if err != nil {
+			br.Msg = "获取数据源失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range edbInfoList {
+			edbInfoMap[v.EdbCode] = v
+		}
+		// 首先对分类下的指标按照日期进行分页,再针对日期,进行排序
+		dataTimes, err := data_manage.GetPurangIndexDataTimePageByCodes(edbCodeList, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取指标数据日期信息失败,Err:" + err.Error()
+			return
+		}
+		if len(dataTimes) > 0 {
+			startDate := utils.GormDateStrToDateStr(dataTimes[len(dataTimes)-1])
+			endDate := utils.GormDateStrToDateStr(dataTimes[0])
+			// 把截止日往后加1天
+			endDateT, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
+			endDate = endDateT.AddDate(0, 0, 1).Format(utils.FormatDate)
+			dataList, e := data_manage.GetPurangIndexDataByDataTime(edbCodeList, startDate, endDate)
+			if e != nil {
+				br.Msg = "获取数据失败"
+				br.ErrMsg = "获取指标数据失败,Err:" + e.Error()
+				return
+			}
+			//将数据按照指标进行分类
+			for _, v := range dataList {
+				dataMap[v.IndexCode] = append(dataMap[v.IndexCode], v)
+			}
+		}
+
+		total, err = data_manage.GetPurangIndexDataTimePageCount(edbCodeList)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+
+	resultList := make([]*data_manage.BaseFromPurangIndexList, 0)
+
+	for _, v := range purangList {
+		product := new(data_manage.BaseFromPurangIndexList)
+		product.BaseFromPurangIndexId = v.BaseFromPurangIndexId
+		product.Unit = v.Unit
+		product.IndexCode = v.IndexCode
+		product.IndexName = v.IndexName
+		product.Frequency = v.Frequency
+		product.ModifyTime = v.ModifyTime
+		product.ClassifyId = v.ClassifyId
+		if edb, ok := edbInfoMap[v.IndexCode]; ok {
+			product.EdbInfoId = edb.EdbInfoId
+			product.EdbExist = 1
+		}
+
+		dataListTmp, ok := dataMap[v.IndexCode]
+		if !ok {
+			dataListTmp = make([]*data_manage.BaseFromPurangData, 0)
+		}
+		product.DataList = dataListTmp
+		product.Paging = page
+		resultList = append(resultList, product)
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resultList
+}
+
+// PurangSearchList
+// @Title Purang模糊搜索
+// @Description Purang模糊搜索
+// @Param   Keyword   query   string  ture       "关键字搜索"
+// @Success 200 {object} models.BaseResponse
+// @router /purang/search_list [get]
+func (this *BaseFromPurangController) PurangSearchList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请重新登录"
+		return
+	}
+
+	list := make([]*data_manage.BaseFromPurangIndexSearchItem, 0)
+	var err error
+	//关键字
+	keyword := this.GetString("Keyword")
+	if keyword != "" {
+		keyWordArr := strings.Split(keyword, " ")
+
+		if len(keyWordArr) > 0 {
+			condition := ""
+			for _, v := range keyWordArr {
+				condition += ` AND CONCAT(index_name,index_code) LIKE '%` + v + `%'`
+			}
+			list, err = data_manage.GetPurangItemList(condition)
+			if err != nil {
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				br.Msg = "获取失败"
+				return
+			}
+		}
+
+	} else {
+		list, err = data_manage.GetPurangItemList("")
+		if err != nil {
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			br.Msg = "获取失败"
+			return
+		}
+	}
+	classifyIds := make([]int, 0)
+	for _, v := range list {
+		classifyIds = append(classifyIds, v.ClassifyId)
+	}
+	classifyList, err := data_manage.GetBaseFromPurangClassifyByIds(classifyIds)
+	if err != nil {
+		br.Msg = "搜索失败"
+		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+		return
+	}
+	classifyMap := make(map[int]int)
+	for _, v := range classifyList {
+		classifyMap[v.ClassifyId] = v.ParentId
+	}
+	for _, v := range list {
+		v.ParentClassifyId = classifyMap[v.ClassifyId]
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// PurangSingleData
+// @Title 获取Purang数据
+// @Description 获取Purang单条数据接口
+// @Param   IndexCode   query   string  true       "指标唯一编码"
+// @Success 200 {object} models.BaseResponse
+// @router /purang/single_data [get]
+func (this *BaseFromPurangController) PurangSingleData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	indexCode := this.GetString("IndexCode")
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	var total int64
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	indexInfo, err := data_manage.GetBaseFromPurangIndexByIndexCode(indexCode)
+	if err != nil {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+	total, err = data_manage.GetPurangIndexDataTotalByCode(indexCode)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	page = paging.GetPaging(currentIndex, pageSize, int(total))
+	dataTmpList, err := data_manage.GetPurangIndexDataByCode(indexCode, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_PURANG, indexCode)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取数据源失败"
+		br.ErrMsg = "获取数据源失败,Err:" + err.Error()
+		return
+	}
+
+	var ret data_manage.PurangSingleDataResp
+	var dataList []*data_manage.PurangSingleData
+
+	if edbInfo != nil {
+		ret.EdbInfoId = edbInfo.EdbInfoId
+		ret.EdbExist = 1
+	}
+	ret.ClassifyId = indexInfo.ClassifyId
+	ret.BaseFromPurangIndexId = indexInfo.BaseFromPurangIndexId
+	ret.IndexCode = indexInfo.IndexCode
+	ret.IndexName = indexInfo.IndexName
+	ret.Frequency = indexInfo.Frequency
+	ret.CreateTime = indexInfo.CreateTime.Format(utils.FormatDateTime)
+	ret.ModifyTime = indexInfo.ModifyTime.Format(utils.FormatDateTime)
+	ret.Unit = indexInfo.Unit
+	for _, v := range dataTmpList {
+		tmp := &data_manage.PurangSingleData{
+			Value:    v.Value,
+			DataTime: v.DataTime,
+		}
+		dataList = append(dataList, tmp)
+	}
+	ret.Data = dataList
+	ret.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = ret
+}
+
+// PurangIndexList
+// @Title Purang指标列表
+// @Description Purang指标列表
+// @Param   ClassifyId   query   int  true       "分类id"
+// @Success 200 {object} data_manage.BaseFromPurangClassifyResp
+// @router /purang/classify/index/list [get]
+func (this *BaseFromPurangController) PurangIndexList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	classifyId, _ := this.GetInt("ClassifyId", 0)
+	indexList, err := data_manage.GetPurangIndexByClassifyId(classifyId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	var ret data_manage.BaseFromPurangClassifyResp
+	list := make([]*data_manage.BaseFromPurangClassifyItems, 0)
+	for _, v := range indexList {
+		classify := new(data_manage.BaseFromPurangClassifyItems)
+		classify.ClassifyId = classifyId
+		classify.BaseFromPurangIndexId = v.BaseFromPurangIndexId
+		classify.IndexCode = v.IndexCode
+		classify.ClassifyName = v.IndexName
+		classify.UniqueCode = fmt.Sprintf("%d_%d", classifyId, v.BaseFromPurangIndexId)
+		list = append(list, classify)
+	}
+	ret.List = list
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = ret
+}
+
+// PurangNameCheck
+// @Title 加入指标库的重名检测
+// @Description 加入指标库的重名检测
+// @Param   ClassifyIds   query   string  true       "分类id, 多个分类用英文"
+// @Param   Keyword   query   string  true       "关键词, 指标ID/指标名称"
+// @Success 200 {object} NameCheckResult
+// @router /purang/edb_info/name_check [post]
+func (this *BaseFromPurangController) PurangNameCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req []*data_manage.NameCheckEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	codeMaxT := 30
+	codeLen := len(req)
+	if codeLen > codeMaxT {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+
+	indexNames := make([]string, 0)
+	resp := make([]*data_manage.EdbNameCheckResult, 0)
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		indexNames = append(indexNames, v.EdbName)
+		resp = append(resp, &data_manage.EdbNameCheckResult{
+			EdbCode: v.EdbCode,
+			EdbName: v.EdbName,
+		})
+		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_PURANG, 0, utils.EDB_DATA_LIMIT)
+		if err != nil && !utils.IsErrNoRow(err) {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
+			return
+		}
+		if len(dataItems) <= 0 {
+			respItem, err := data.AddEdbData(utils.DATA_SOURCE_PURANG, v.EdbCode, v.Frequency)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				return
+			}
+			if respItem.Ret != 200 {
+				br.Msg = "未搜索到该指标"
+				br.ErrMsg = respItem.ErrMsg + ";EdbCode:" + v.EdbCode
+				return
+			}
+		}
+	}
+
+	// 重名校验
+	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames, utils.EDB_INFO_TYPE)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取重名指标失败, Err: " + e.Error()
+		return
+	}
+	nameExists := make(map[string]bool)
+	for _, v := range edbList {
+		nameExists[v.EdbName] = true
+	}
+	if len(nameExists) > 0 {
+		for _, v := range resp {
+			v.Exist = nameExists[v.EdbName]
+		}
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// PurangAddCheck
+// @Title 加入指标库指标Id检测
+// @Description 加入指标库指标Id检测
+// @Param	request	body request.BatchAddCheckReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /purang/edb_info/add_check [post]
+func (c *BaseFromPurangController) PurangAddCheck() {
+	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
+	}
+	var req data_manage.BatchAddCheckReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	codeMaxT := 30
+	codeLen := len(req.IndexCodes)
+
+	// 获取指标库已有指标
+	existsEdb, e := data_manage.GetEdbCodesBySource(utils.DATA_SOURCE_PURANG)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取自有数据已添加的指标失败, Err: " + e.Error()
+		return
+	}
+	existMap := make(map[string]*data_manage.EdbInfo)
+	for _, v := range existsEdb {
+		existMap[v.EdbCode] = v
+	}
+
+	if codeLen == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if codeLen > codeMaxT {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMaxT)
+		return
+	}
+
+	// 查询选中的指标
+	cond := fmt.Sprintf(` AND index_code IN (%s)`, utils.GetOrmInReplace(codeLen))
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.IndexCodes)
+	list, err := data_manage.GetPurangIndex(cond, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
+		return
+	}
+
+	if len(list) > codeMaxT {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMaxT)
+		return
+	}
+
+	resp := make([]*data_manage.BaseFromPurangIndexList, 0)
+	for _, v := range list {
+		if edb, ok := existMap[v.IndexCode]; ok {
+			v.EdbInfoId = edb.EdbInfoId
+			v.EdbClassifyId = edb.ClassifyId
+			v.EdbUniqueCode = edb.UniqueCode
+			v.EdbExist = 1
+		}
+		resp = append(resp, v)
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// PurangEdbInfoAdd
+// @Title 新增指标接口
+// @Description 新增指标接口
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /purang/edb_info/add [post]
+func (this *BaseFromPurangController) PurangEdbInfoAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	deleteCache := true
+	cacheKey := "CACHE_EDB_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req data_manage.AddEdbInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	req.EdbName = strings.Trim(req.EdbName, " ")
+	req.EdbCode = strings.Trim(req.EdbCode, " ")
+
+	if req.EdbCode == "" {
+		br.Msg = "指标ID不能为空"
+		return
+	}
+
+	if req.EdbName == "" {
+		br.Msg = "指标名称不能为空"
+		return
+	}
+
+	if req.Frequency == "" {
+		br.Msg = "频率不能为空"
+		return
+	}
+
+	if req.Unit == "" {
+		br.Msg = "单位不能为空"
+		return
+	}
+
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	count, err := data_manage.GetPurangIndexDataCount(req.EdbCode)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if count == 0 {
+		br.Msg = "指标不存在"
+	}
+
+	// 指标入库
+	edbInfo, err, errMsg, isSendEmail := data.EdbInfoAdd(utils.DATA_SOURCE_PURANG, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, req.StartDate, req.EndDate, sysUser.AdminId, sysUser.RealName, this.Lang)
+	if err != nil {
+		br.Msg = "保存失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+
+	// 试用平台更新用户累计新增指标数
+	adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取系统用户数据失败,Err:" + e.Error()
+		return
+	}
+	if utils.BusinessCode == utils.BusinessCodeSandbox && adminItem.DepartmentName == "ETA试用客户" {
+		go func() {
+			var r etaTrialService.EtaTrialUserReq
+			r.Mobile = adminItem.Mobile
+			_, _ = etaTrialService.UpdateUserIndexNum(r)
+		}()
+	}
+
+	//新增操作日志
+	{
+		edbLog := new(data_manage.EdbInfoLog)
+		edbLog.EdbInfoId = edbInfo.EdbInfoId
+		edbLog.SourceName = edbInfo.SourceName
+		edbLog.Source = edbInfo.Source
+		edbLog.EdbCode = edbInfo.EdbCode
+		edbLog.EdbName = edbInfo.EdbName
+		edbLog.ClassifyId = edbInfo.ClassifyId
+		edbLog.SysUserId = sysUser.AdminId
+		edbLog.SysUserRealName = sysUser.RealName
+		edbLog.CreateTime = time.Now()
+		edbLog.Content = string(this.Ctx.Input.RequestBody)
+		edbLog.Status = "新增指标"
+		edbLog.Method = this.Ctx.Input.URI()
+		go data_manage.AddEdbInfoLog(edbLog)
+	}
+
+	// 更新es
+	go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+
+	resp := new(data_manage.AddEdbInfoResp)
+	resp.EdbInfoId = edbInfo.EdbInfoId
+	resp.UniqueCode = edbInfo.UniqueCode
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+	br.IsAddLog = true
+}
+
+// ExportPurangList
+// @Title 导出Purang数据
+// @Description 导出Purang数据
+// @Param   ClassifyId   query   int  true       "关键字搜索"
+// @Param   IndexCode   query   string  true       "指标编码"
+// @Success 200  导出成功
+// @router /purang/export [get]
+func (this *BaseFromPurangController) ExportPurangList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请重新登录"
+		return
+	}
+
+	classifyId, _ := this.GetInt("ClassifyId")
+	indexCode := this.GetString("IndexCode")
+
+	if classifyId <= 0 && indexCode == "" {
+		br.Msg = "请选择分类或者指标"
+		return
+	}
+	dir, _ := os.Executable()
+	exPath := filepath.Dir(dir)
+	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
+	xlsxFile := xlsx.NewFile()
+
+	var condition string
+	var pars []interface{}
+	var classifyName string
+	if classifyId > 0 {
+		classifyInfo, err := data_manage.GetBaseFromPurangClassifyById(classifyId)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				br.Msg = "分类不存在"
+				return
+			}
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取分类失败,Err:" + err.Error()
+			return
+		}
+		classifyName = classifyInfo.ClassifyName
+		childClassify, err := data_manage.GetBaseFromPurangClassifyByParentId(classifyId)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取分类失败,Err:" + err.Error()
+			return
+		}
+
+		if len(childClassify) > 0 {
+			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
+			for _, child := range childClassify {
+				pars = append(pars, child.ClassifyId)
+			}
+		} else {
+			condition += ` AND classify_id=?`
+			pars = append(pars, classifyId)
+		}
+	}
+	if indexCode != "" {
+		condition += ` AND index_code=? `
+		pars = append(pars, indexCode)
+	}
+
+	indexList, err := data_manage.GetPurangIndex(condition, pars)
+	if err != nil {
+		br.Msg = "下载失败"
+		br.ErrMsg = "获取指标失败,Err:" + err.Error()
+		fmt.Println("获取数据失败,Err:" + err.Error())
+		return
+	}
+	if len(indexList) <= 0 {
+		fmt.Println("indexList 为空")
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "success"
+		return
+	}
+
+	codeList := make([]string, 0)
+	frequenciesMap := make(map[string][]*data_manage.BaseFromPurangIndexList)
+	for _, v := range indexList {
+		codeList = append(codeList, v.IndexCode)
+		frequenciesMap[v.Frequency] = append(frequenciesMap[v.Frequency], v)
+	}
+	dataListMap := make(map[string][]*data_manage.BaseFromPurangData)
+	if len(indexList) > 0 {
+		allDataList, e := data_manage.GetPurangIndexDataByCodes(codeList)
+		if e != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取数据失败,Err:" + e.Error()
+			return
+		}
+		for _, v := range allDataList {
+			dataListMap[v.IndexCode] = append(dataListMap[v.IndexCode], v)
+		}
+	}
+	// 按照频率分组排序
+	frequencies := []string{
+		"日度", "周度", "旬度", "月度", "季度", "半年度", "年度",
+	}
+	for _, frequency := range frequencies {
+		//获取指标
+		indexCodeList, ok := frequenciesMap[frequency]
+		if !ok {
+			continue
+		}
+		if len(indexCodeList) <= 0 {
+			fmt.Printf("sheet:%s, 不存在指标", frequency)
+			return
+		}
+		var sheetName string
+		switch frequency {
+		case "日度":
+			sheetName = "日度(Daily)"
+		case "周度":
+			sheetName = "周度(Weekly)"
+		case "旬度":
+			sheetName = "旬度(ten-day)"
+		case "月度":
+			sheetName = "月度(Monthly)"
+		case "季度":
+			sheetName = "季度(Quarterly)"
+		case "半年度":
+			sheetName = "半年度(Semi-annual)"
+		case "年度":
+			sheetName = "年度(Annual)"
+		default:
+			sheetName = "其他数据"
+		}
+		sheetNew, err := xlsxFile.AddSheet(sheetName)
+		if err != nil {
+			fmt.Println("新增Sheet失败", err.Error())
+			return
+		}
+		secNameRow := sheetNew.AddRow()
+		frequencyRow := sheetNew.AddRow()
+		unitRow := sheetNew.AddRow()
+		lastModifyDateRow := sheetNew.AddRow()
+
+		var indexIdList []int
+		for _, idx := range frequenciesMap[frequency] {
+			indexIdList = append(indexIdList, idx.BaseFromPurangIndexId)
+		}
+		dataTimeList, err := data_manage.GetPurangDataDataTimeByIndexId(indexIdList)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取数据时间失败,Err:" + err.Error()
+			fmt.Println("获取数据时间失败", err.Error())
+			return
+		}
+
+		// 添加excel左侧指标日期
+		setRowIndex := 4
+		for rk, dv := range dataTimeList {
+			rowIndex := setRowIndex + rk
+			row := sheetNew.Row(rowIndex)
+			displayDate, _ := time.Parse(utils.FormatDate, dv)
+			displayDateCell := row.AddCell()
+			style := new(xlsx.Style)
+			style.ApplyAlignment = true
+			style.Alignment.WrapText = true
+			displayDateCell.SetStyle(style)
+			displayDateCell.SetDate(displayDate)
+
+		}
+		for k, icl := range indexCodeList {
+			// 获取数据
+			dataList, ok := dataListMap[icl.IndexCode]
+			if !ok {
+				continue
+			}
+			if k == 0 {
+				secNameRow.AddCell().SetValue("指标名称/Metric Name")
+				frequencyRow.AddCell().SetValue("频度/Frequency")
+				unitRow.AddCell().SetValue("单位/Unit")
+				lastModifyDateRow.AddCell().SetValue("更新时间/Update Time")
+				min := k * 3
+				sheetNew.SetColWidth(min, min, 15)
+			}
+			if len(dataList) == 0 {
+				continue
+			}
+			secNameRow.AddCell().SetValue(icl.IndexName)
+			frequencyRow.AddCell().SetValue(icl.Frequency)
+			unitRow.AddCell().SetValue(icl.Unit)
+
+			timeDate, err := time.Parse(utils.FormatDateTime, dataList[0].ModifyTime)
+			if err != nil {
+				continue
+			}
+			lastModifyDateRow.AddCell().SetValue(timeDate.Format(utils.FormatDate))
+			dataInfoMap := make(map[string]*data_manage.BaseFromPurangData)
+			for _, v := range dataList {
+				dataInfoMap[v.DataTime] = v
+			}
+
+			for rk, dtv := range dataTimeList {
+				rowIndex := setRowIndex + rk
+				row := sheetNew.Row(rowIndex)
+				displayDateCell := row.AddCell()
+				tmpData, ok := dataInfoMap[dtv]
+				if ok {
+					displayDateCell.SetValue(tmpData.Value)
+				}
+			}
+		}
+	}
+
+	err = xlsxFile.Save(downLoadnFilePath)
+	if err != nil {
+		//有指标无数据时先导出一遍空表
+		sheet, err := xlsxFile.AddSheet("无数据")
+		if err != nil {
+			br.Msg = "新增Sheet失败"
+			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
+			return
+		}
+		rowSecName := sheet.AddRow()
+		celSecName := rowSecName.AddCell()
+		celSecName.SetValue("")
+		e := xlsxFile.Save(downLoadnFilePath)
+		if e != nil {
+			br.Msg = "保存文件失败"
+			br.ErrMsg = "保存文件失败"
+			return
+		}
+	}
+
+	fileName := classifyName
+	if indexCode != "" && len(indexList) == 1 {
+		fileName = indexList[0].IndexName
+	}
+	fileName = strings.Replace(fileName, ": ", "_", -1)
+	fileName = strings.Replace(fileName, ", ", "_", -1)
+	fileName = strings.Replace(fileName, " ", "_", -1)
+	fileName += time.Now().Format("06.01.02") + `.xlsx` //文件名称
+	fmt.Println(fileName)
+	this.Ctx.Output.Download(downLoadnFilePath, fileName)
+	defer func() {
+		os.Remove(downLoadnFilePath)
+	}()
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "success"
+}
+
+// GetFrequency
+// @Title Purang数据频度
+// @Description Purang数据频度接口
+// @Param   ClassifyId   query   string  true       "分类Id"
+// @Success 200 {object} data_manage.LzFrequency
+// @router /purang/frequency [get]
+func (this *BaseFromPurangController) GetFrequency() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		return
+	}
+
+	frequencyList, err := data_manage.GetPurangFrequencyByClassifyId(classifyId)
+	if err != nil {
+		br.Msg = "获取频度失败"
+		br.ErrMsg = "获取频度失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = frequencyList
+} 

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

@@ -61,7 +61,7 @@ func (this *RangeChartClassifyController) ChartClassifyList() {
 	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
 	// 查询分类节点
 	rootList, err := data_manage.GetChartClassifyByParentId(parentId, utils.CHART_SOURCE_RANGE_ANALYSIS)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -154,19 +154,19 @@ func (this *RangeChartClassifyController) ChartClassifyList() {
 // getChartClassifyListForMe 获取我创建的图表
 func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
 	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_RANGE_ANALYSIS)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_RANGE_ANALYSIS)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
 
 	allChartInfo, err := data_manage.GetChartInfoByAdminId([]int{utils.CHART_SOURCE_RANGE_ANALYSIS, utils.CHART_SOURCE_RANGE_ANALYSIS}, adminInfo.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		errMsg = "获取失败"
 		return
 	}
@@ -262,7 +262,7 @@ func (this *RangeChartClassifyController) AddChartClassify() {
 	}
 
 	// 新增图表分类
-	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_RANGE_ANALYSIS, this.Lang, this.SysUser)
+	_, err, errMsg, isSendEmail := data.AddChartClassify(req.ChartClassifyName, req.ParentId, req.Level, utils.CHART_SOURCE_RANGE_ANALYSIS, 0, this.Lang, this.SysUser)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = "添加分类失败,Err:" + err.Error()
@@ -366,7 +366,7 @@ func (this *RangeChartClassifyController) DeleteChartClassifyCheck() {
 
 	if deleteStatus != 1 && req.ChartInfoId == 0 {
 		classifyCount, err := data_manage.GetChartClassifyCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "分类下是否含有图表失败,Err:" + err.Error()
 			return
@@ -428,7 +428,7 @@ func (this *RangeChartClassifyController) DeleteChartClassify() {
 	if req.ChartClassifyId > 0 && req.ChartInfoId == 0 {
 		//判断是否含有指标
 		count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 			return
@@ -452,7 +452,7 @@ func (this *RangeChartClassifyController) DeleteChartClassify() {
 	if req.ChartInfoId > 0 {
 		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "图表已删除,请刷新页面"
 				br.ErrMsg = "指标不存在,Err:" + err.Error()
 				return
@@ -503,7 +503,7 @@ func (this *RangeChartClassifyController) DeleteChartClassify() {
 		chartSeriesOb := new(data_manage.FactorEdbSeriesChartMapping)
 		seriesMappingItem, e := chartSeriesOb.GetItemByChartInfoId(chartInfo.ChartInfoId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 			} else {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取图表关联失败, Err: " + e.Error()
@@ -527,7 +527,7 @@ func (this *RangeChartClassifyController) DeleteChartClassify() {
 		}
 		// 删除配置关联指标数据
 		multiConfig, e := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfo.ChartInfoId)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取图表关联配置失败, Err: " + e.Error()
 			return
@@ -550,7 +550,7 @@ func (this *RangeChartClassifyController) DeleteChartClassify() {
 		pars = append(pars, req.ChartInfoId)
 
 		nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 			return
@@ -570,14 +570,14 @@ func (this *RangeChartClassifyController) DeleteChartClassify() {
 			pars = append(pars, chartInfo.ChartClassifyId)
 
 			classifyItem, err := data_manage.GetChartClassifyByCondition(condition, pars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "删除失败"
 				br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
 				return
 			}
 			if classifyItem != nil {
 				nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					br.Msg = "删除失败"
 					br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
 					return

+ 27 - 23
controllers/data_manage/range_analysis/chart_info.go

@@ -73,7 +73,7 @@ func (this *RangeChartChartInfoController) Preview() {
 	for _, v := range req.ChartEdbInfoList {
 		edbInfoMapping, e := data_manage.GetChartEdbMappingByEdbInfoId(v.EdbInfoId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = v.EdbAliasName + "指标不存在"
 				br.ErrMsg = v.EdbAliasName + "指标不存在"
 				return
@@ -336,7 +336,7 @@ func (this *RangeChartChartInfoController) Detail() {
 	chartInfo := new(data_manage.ChartInfoView)
 	chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图被删除,请刷新页面"
 			br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error()
 			return
@@ -415,7 +415,7 @@ func (this *RangeChartChartInfoController) Detail() {
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -564,7 +564,7 @@ func (this *RangeChartChartInfoController) DetailFromUniqueCode() {
 	status := true
 	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			status = false
 		} else {
 			br.Msg = "获取失败"
@@ -602,7 +602,7 @@ func (this *RangeChartChartInfoController) DetailFromUniqueCode() {
 					myCond += ` AND a.chart_info_id=? `
 					myPars = append(myPars, chartInfo.ChartInfoId)
 					myList, err := data_manage.GetMyChartByCondition(myCond, myPars)
-					if err != nil && err.Error() != utils.ErrNoRow() {
+					if err != nil && !utils.IsErrNoRow(err) {
 						br.Msg = "获取失败"
 						br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 						return
@@ -659,7 +659,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 				myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-				if err != nil && err.Error() != utils.ErrNoRow() {
+				if err != nil && !utils.IsErrNoRow(err) {
 					msg = "获取失败"
 					errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 					return
@@ -826,7 +826,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
 
 			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				msg = "获取失败"
 				errMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
 				return
@@ -937,7 +937,7 @@ func (this *RangeChartChartInfoController) List() {
 
 	if chartClassifyId > 0 {
 		chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取图表信息失败"
 			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
 			return
@@ -969,7 +969,7 @@ func (this *RangeChartChartInfoController) List() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -987,7 +987,7 @@ func (this *RangeChartChartInfoController) List() {
 
 	//获取图表信息
 	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Success = true
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
@@ -995,7 +995,7 @@ func (this *RangeChartChartInfoController) List() {
 	}
 
 	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取图表信息失败"
 		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
 		return
@@ -1039,7 +1039,7 @@ func (this *RangeChartChartInfoController) List() {
 	}
 
 	resp := new(data_manage.ChartListResp)
-	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+	if list == nil || len(list) <= 0 || (err != nil && utils.IsErrNoRow(err)) {
 		items := make([]*data_manage.ChartInfoView, 0)
 		resp.Paging = page
 		resp.List = items
@@ -1050,7 +1050,7 @@ func (this *RangeChartChartInfoController) List() {
 	}
 
 	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标信息失败"
 		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 		return
@@ -1147,7 +1147,7 @@ func (this *RangeChartChartInfoController) Copy() {
 
 		_, e = data_manage.GetChartClassifyById(req.ChartClassifyId)
 		if e != nil {
-			if e.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(e) {
 				br.Msg = "分类不存在"
 				return
 			}
@@ -1160,7 +1160,7 @@ func (this *RangeChartChartInfoController) Copy() {
 	// 图表信息
 	originChart, e := data_manage.GetChartInfoById(req.ChartInfoId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "原图表不存在"
 			return
 		}
@@ -1253,7 +1253,7 @@ func (this *RangeChartChartInfoController) Refresh() {
 		chartInfo, err = data_manage.GetChartInfoByUniqueCode(uniqueCode)
 	}
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,无需刷新"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -1818,7 +1818,7 @@ func (this *RangeChartChartInfoController) SearchByEs() {
 	sourceList := make([]int, 0)
 	sourceList = append(sourceList, utils.CHART_SOURCE_RANGE_ANALYSIS)
 
-	var searchList []*data_manage.ChartInfo
+	var searchList []*data_manage.ChartInfoMore
 	var total int64
 	var err error
 
@@ -1827,7 +1827,7 @@ func (this *RangeChartChartInfoController) SearchByEs() {
 	{
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -1841,7 +1841,7 @@ func (this *RangeChartChartInfoController) SearchByEs() {
 		searchList, total, err = data.EsSearchChartInfo(keyword, showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
 	} else {
 		total, searchList, err = data_manage.ChartInfoSearchByEmptyKeyWord(showSysId, sourceList, noPermissionChartIdList, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
 			return
@@ -1871,13 +1871,17 @@ func (this *RangeChartChartInfoController) SearchByEs() {
 
 		for _, v := range searchList {
 			tmp := new(data_manage.ChartInfoMore)
-			tmp.ChartInfo = *v
+			tmp.ChartInfo = v.ChartInfo
 			// 图表数据权限
 			tmp.HaveOperaAuth = true
 			//判断是否需要展示英文标识
 			if edbTmpList, ok := chartEdbMap[v.ChartInfoId]; ok {
 				tmp.IsEnChart = data.CheckIsEnChart(v.ChartNameEn, edbTmpList, v.Source, v.ChartType)
 			}
+			tmp.SearchText = v.SearchText
+			if tmp.SearchText == "" {
+				tmp.SearchText = v.ChartName
+			}
 			finalList = append(finalList, tmp)
 		}
 	}
@@ -1938,7 +1942,7 @@ func (this *RangeChartChartInfoController) BaseInfoEdit() {
 
 	chartItem, e := data_manage.GetChartInfoById(req.ChartInfoId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "图表已被删除, 请刷新页面"
 			return
 		}
@@ -1966,7 +1970,7 @@ func (this *RangeChartChartInfoController) BaseInfoEdit() {
 	pars = append(pars, req.ChartName)
 	existItem, err := data_manage.GetChartInfoByCondition(condition, pars)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "判断英文图表名称是否存在失败"
 			br.ErrMsg = "判断英文图表名称是否存在失败,Err:" + err.Error()
 			return
@@ -2059,7 +2063,7 @@ func (this *RangeChartChartInfoController) ChartInfoSave() {
 
 	chartItem, err := data_manage.GetChartInfoById(req.ChartInfoId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "图表已被删除,请刷新页面!"
 			br.ErrMsg = "图表已被删除,请刷新页面,ChartInfoId:" + strconv.Itoa(req.ChartInfoId)
 			return

+ 5 - 5
controllers/data_manage/sci_data.go

@@ -36,14 +36,14 @@ func (this *EdbInfoController) SciClassify() {
 	}
 
 	rootList, err := data_manage.GetBaseFromSciClassifyByParentId(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromSciClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -52,7 +52,7 @@ func (this *EdbInfoController) SciClassify() {
 	baseFromSciIndexMap := make(map[int][]*data_manage.BaseFromSciClassifyItems)
 
 	allBaseFromSciIndex, err := data_manage.GetSciIndexAll()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 		return
@@ -144,14 +144,14 @@ func (this *EdbInfoController) SciClassifyName() {
 	}
 
 	rootList, err := data_manage.GetBaseFromSciClassifyByParentId(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromSciClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return

+ 51 - 20
controllers/data_manage/sci_hq_data.go

@@ -180,7 +180,7 @@ func (this *SciHqDataController) EditClassify() {
 	}
 	classify, err := data_manage.GetSciHqClassifyById(req.ClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			return
 		}
@@ -264,7 +264,7 @@ func (this *SciHqDataController) MoveClassify() {
 		return
 	}
 
-	err, errMsg := data.MoveSciHqClassify(req.ClassifyId, req.ParentId, req.PrevClassifyId, req.NextClassifyId)
+	err, errMsg := data.MoveSciHqClassify(req.ClassifyId, req.ParentClassifyId, req.PrevClassifyId, req.NextClassifyId)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -295,7 +295,7 @@ func (this *SciHqDataController) IndexList() {
 	}()
 	classifyId, _ := this.GetInt("ClassifyId", 0)
 	indexList, err := data_manage.GetSciHqIndexBaseInfoByClassifyId(classifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 		return
@@ -333,12 +333,12 @@ func (this *SciHqDataController) BatchIndexList() {
 	}
 	if req.IsSelectAll {
 		if len(req.SelectedId) > 0 {
-			condition += ` AND base_from_sci_hq_index_id NOT IN (` + utils.GetOrmInReplace(len(req.SelectedId)) + `)`
+			condition += ` AND base_from_sci_hq_index_id NOT IN (?)`
 			pars = append(pars, req.SelectedId)
 		}
 	} else {
 		if len(req.SelectedId) > 0 {
-			condition += ` AND base_from_sci_hq_index_id IN (` + utils.GetOrmInReplace(len(req.SelectedId)) + `)`
+			condition += ` AND base_from_sci_hq_index_id IN (?)`
 			pars = append(pars, req.SelectedId)
 		}
 	}
@@ -353,11 +353,14 @@ func (this *SciHqDataController) BatchIndexList() {
 			br.ErrMsg = "获取分类失败,Err:" + err.Error()
 			return
 		}
-		if len(childClassify) > 0 {
-			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
-			for _, child := range childClassify {
-				pars = append(pars, child.ClassifyId)
-			}
+		var childIds []int
+		for _, v := range childClassify {
+			childIds = append(childIds, v.ClassifyId)
+		}
+		if len(childIds) > 0 {
+			childIds = append(childIds, req.ClassifyId)
+			condition += `AND classify_id IN (?)`
+			pars = append(pars, childIds)
 		} else {
 			condition += ` AND classify_id=?`
 			pars = append(pars, req.ClassifyId)
@@ -429,7 +432,7 @@ func (this *SciHqDataController) IndexPageList() {
 		}
 		total = tmpTotal
 		tmpIndexList, err := data_manage.GetSciHqIndexByPage(startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -457,7 +460,7 @@ func (this *SciHqDataController) IndexPageList() {
 		}
 		total = tmpTotal
 		tmpIndexList, err := data_manage.GetSciHqIndexByClassifyId(classifyIds, startSize, pageSize)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 			return
@@ -534,7 +537,7 @@ func (this *SciHqDataController) SingleData() {
 		return
 	}
 	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_SCI_HQ, indexInfo.IndexCode)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取指标数据失败"
 		br.ErrMsg = "获取指标库数据失败,Err:" + err.Error()
 		return
@@ -736,7 +739,7 @@ func (this *SciHqDataController) AddEdbInfo() {
 
 	_, err = data_manage.GetSciHqIndexByIndexCode(req.EdbCode)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "指标不存在"
 			return
 		}
@@ -757,6 +760,19 @@ func (this *SciHqDataController) AddEdbInfo() {
 		return
 	}
 
+	// 刷新指标数据
+	refreshRes, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, "")
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("刷新指标数据失败, %v", e)
+		return
+	}
+	if refreshRes != nil && refreshRes.Ret != 200 {
+		br.Msg = "操作失败"
+		br.ErrMsg = fmt.Sprintf("刷新指标数据失败, Ret: %d, Msg: %s, ErrMsg: %s", refreshRes.Ret, refreshRes.Msg, refreshRes.ErrMsg)
+		return
+	}
+
 	// 试用平台更新用户累计新增指标数
 	adminItem, e := system.GetSysAdminById(sysUser.AdminId)
 	if e != nil {
@@ -947,7 +963,7 @@ func (c *SciHqDataController) NameCheck() {
 			EdbName: v.EdbName,
 		})
 		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_SCI_HQ, 0, utils.EDB_DATA_LIMIT)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取卓创红期已存在信息失败,Err:" + err.Error()
 			return
@@ -1091,6 +1107,19 @@ func (this *SciHqDataController) BatchAdd() {
 			continue
 		}
 
+		// 刷新指标数据
+		refreshRes, e := data.RefreshEdbData(edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, "")
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("刷新指标数据失败, %v", e)
+			return
+		}
+		if refreshRes != nil && refreshRes.Ret != 200 {
+			br.Msg = "操作失败"
+			br.ErrMsg = fmt.Sprintf("刷新指标数据失败, Ret: %d, Msg: %s, ErrMsg: %s", refreshRes.Ret, refreshRes.Msg, refreshRes.ErrMsg)
+			return
+		}
+
 		// 试用平台更新用户累计新增指标数
 		if utils.BusinessCode == utils.BusinessCodeSandbox {
 			go func() {
@@ -1417,11 +1446,13 @@ func (this *SciHqDataController) ExportSciHqList() {
 			br.ErrMsg = "获取分类失败,Err:" + err.Error()
 			return
 		}
-		if len(childClassify) > 0 {
-			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
-			for _, child := range childClassify {
-				pars = append(pars, child.ClassifyId)
-			}
+		var childIds []int
+		for _, v := range childClassify {
+			childIds = append(childIds, v.ClassifyId)
+		}
+		if len(childIds) > 0 {
+			condition += `AND classify_id IN (?)`
+			pars = append(pars, childIds)
 		} else {
 			condition += ` AND classify_id=?`
 			pars = append(pars, classifyId)

+ 50 - 25
controllers/data_manage/smm_api.go

@@ -4,10 +4,10 @@ import (
 	"encoding/json"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
+	"eta/eta_api/services/elastic"
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
-	"strconv"
 	"strings"
 )
 
@@ -66,16 +66,16 @@ func (this *EdbInfoController) SmmApiList() {
 	if len(types) > 0 {
 		condition += " AND ( "
 		for _, v := range types {
-			typeArr := strings.Split(v,",")
+			typeArr := strings.Split(v, ",")
 			for i, v := range typeArr {
 				if i == 0 {
 					condition += " ( "
 				}
 				typeStr := "type_"
 				typeStr += fmt.Sprintf("%d", i+1)
-				condition += typeStr+" =? "
+				condition += typeStr + " =? "
 				pars = append(pars, v)
-				if i == len(typeArr) - 1 {
+				if i == len(typeArr)-1 {
 					condition += " ) "
 				} else {
 					condition += " AND "
@@ -88,13 +88,13 @@ func (this *EdbInfoController) SmmApiList() {
 	}
 
 	if frequency != "" {
-		frequencyArr := strings.Split(frequency,",")
+		frequencyArr := strings.Split(frequency, ",")
 		condition += ` AND frequency IN (` + utils.GetOrmInReplace(len(frequencyArr)) + `) `
 		pars = append(pars, frequencyArr)
 	}
 
 	if dataState != "" {
-		stateArr := strings.Split(dataState,",")
+		stateArr := strings.Split(dataState, ",")
 		if strings.Contains(dataState, "normal") {
 			stateArr = append(stateArr, "")
 			condition += ` AND data_state IN (` + utils.GetOrmInReplace(len(stateArr)) + `) `
@@ -107,25 +107,50 @@ func (this *EdbInfoController) SmmApiList() {
 
 	sortStr := ``
 
+	keyword = strings.TrimSpace(keyword)
 	if keyword != "" {
-		keyWordArr := strings.Split(keyword, " ")
-		if len(keyWordArr) > 0 {
-			condition += " AND ( "
-			keywordStr := strings.Replace(keyword, " ", "", -1)
-			condition += ` CONCAT(index_name,index_code) LIKE '%` + keywordStr + `%' OR `
-			sortStr += ` CASE WHEN CONCAT(index_name,index_code) LIKE '%` + keywordStr + `%' THEN 1 `
-			for i, v := range keyWordArr {
-				condition += ` CONCAT(index_name,index_code) LIKE '%` + v + `%' OR`
-				sortStr += ` WHEN CONCAT(index_name,index_code) LIKE '%` + v + `%' THEN  ` + strconv.Itoa(i+2) + ` `
+		//keyWordArr := strings.Split(keyword, " ")
+		//if len(keyWordArr) > 0 {
+		//	condition += " AND ( "
+		//	keywordStr := strings.Replace(keyword, " ", "", -1)
+		//	condition += ` CONCAT(index_name,index_code) LIKE '%` + keywordStr + `%' OR `
+		//	sortStr += ` CASE WHEN CONCAT(index_name,index_code) LIKE '%` + keywordStr + `%' THEN 1 `
+		//	for i, v := range keyWordArr {
+		//		condition += ` CONCAT(index_name,index_code) LIKE '%` + v + `%' OR`
+		//		sortStr += ` WHEN CONCAT(index_name,index_code) LIKE '%` + v + `%' THEN  ` + strconv.Itoa(i+2) + ` `
+		//	}
+		//	sortStr += ` END, `
+		//	condition = strings.TrimRight(condition, "OR")
+		//	condition += " ) "
+		//}
+
+		// ES搜
+		_, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keyword, utils.DATA_SOURCE_YS, 0, []int{}, []int{}, []string{}, startSize, req.PageSize)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("ES-搜索SMM指标失败, %v", e)
+			return
+		}
+		if len(list) == 0 {
+			br.Data = data_manage.BaseFromSmmIndexListResp{
+				Paging: paging.GetPaging(req.CurrentIndex, req.PageSize, 0),
+				List:   make([]*data_manage.BaseFromSmmIndexItem, 0),
 			}
-			sortStr += ` END, `
-			condition = strings.TrimRight(condition, "OR")
-			condition += " ) "
+			br.Ret = 200
+			br.Success = true
+			br.Msg = "获取成功"
+			return
 		}
+		var indexIds []int
+		for _, v := range list {
+			indexIds = append(indexIds, v.PrimaryId)
+		}
+		condition += fmt.Sprintf(" AND base_from_smm_index_id IN (%s)", utils.GetOrmInReplace(len(indexIds)))
+		pars = append(pars, indexIds)
 	}
 
 	if indexCodes != "" {
-		indexCodeArr := strings.Split(indexCodes,",")
+		indexCodeArr := strings.Split(indexCodes, ",")
 		indexCodeStr := ""
 		for _, v := range indexCodeArr {
 			indexCodeStr += "'" + v + "',"
@@ -141,7 +166,7 @@ func (this *EdbInfoController) SmmApiList() {
 	}
 
 	total, err := data_manage.GetSmmIndexDataListCount(condition, pars)
-	if err!= nil {
+	if err != nil {
 		br.Msg = "获取指标总数失败"
 		br.ErrMsg = "获取指标总数失败,Err:" + err.Error()
 		return
@@ -203,11 +228,11 @@ func (this *EdbInfoController) SmmApiTypeList() {
 
 	// 初始化
 	for _, v := range typeList {
-		if v.Type1 != ""{
-			if _, ok := typeMap[v.Type1];!ok {
+		if v.Type1 != "" {
+			if _, ok := typeMap[v.Type1]; !ok {
 				typeMap[v.Type1] = make(map[string][]string)
 			} else {
-				if _, ok := typeMap[v.Type1][v.Type2];!ok {
+				if _, ok := typeMap[v.Type1][v.Type2]; !ok {
 					typeMap[v.Type1][v.Type2] = make([]string, 0)
 				}
 			}
@@ -215,7 +240,7 @@ func (this *EdbInfoController) SmmApiTypeList() {
 	}
 
 	for _, v := range typeList {
-		if v.Type1 != ""{
+		if v.Type1 != "" {
 			typeMap[v.Type1][v.Type2] = append(typeMap[v.Type1][v.Type2], v.Type3)
 		}
 	}
@@ -227,7 +252,7 @@ func (this *EdbInfoController) SmmApiTypeList() {
 			var child data_manage.TypeListRespItem
 			child.Type = type2
 			for _, type3 := range type3List {
-				child.Child = append(child.Child, data_manage.TypeListRespItem{type3,nil})
+				child.Child = append(child.Child, data_manage.TypeListRespItem{type3, nil})
 			}
 			item.Child = append(item.Child, child)
 		}

+ 7 - 4
controllers/data_manage/smm_data.go

@@ -13,6 +13,7 @@ import (
 	"github.com/tealeg/xlsx"
 	"os"
 	"path/filepath"
+	"strconv"
 	"strings"
 	"time"
 )
@@ -36,14 +37,14 @@ func (this *EdbInfoController) SmmClassify() {
 	}
 
 	rootList, err := data_manage.GetBaseFromSmmClassifyByParentId(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromSmmClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -63,6 +64,7 @@ func (this *EdbInfoController) SmmClassify() {
 
 	rootChildMap := make(map[int][]*data_manage.BaseFromSmmClassifyItems)
 	for _, v := range classifyAll {
+		v.UniqueCode = strconv.Itoa(v.ClassifyId)
 		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
 		/*if existItems, ok := baseFromSmmIndexMap[v.ClassifyId]; ok {
 			v.Children = existItems
@@ -93,6 +95,7 @@ func (this *EdbInfoController) SmmClassify() {
 		Level:              1,
 		Sort:               0,
 		Children:           nil,
+		UniqueCode:         "0",
 	}
 	/*initIndexList, err := data_manage.GetBaseFromSmmIndexByClassifyId(initClassify.ClassifyId)
 	if err != nil {
@@ -193,14 +196,14 @@ func (this *EdbInfoController) SmmClassifyName() {
 	}
 
 	rootList, err := data_manage.GetBaseFromSmmClassifyByParentId(0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromSmmClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return

+ 6 - 1
controllers/data_manage/stl/stl.go

@@ -6,6 +6,7 @@ import (
 	"eta/eta_api/models"
 	"eta/eta_api/services/data/stl"
 	"eta/eta_api/utils"
+	"strings"
 
 	"eta/eta_api/models/data_manage/stl/request"
 	"eta/eta_api/models/data_manage/stl/response"
@@ -196,6 +197,10 @@ func (this *STLController) EdbInfoFilterByEs() {
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
 	keyWord := this.GetString("KeyWord")
+	if keyWord == "" {
+		keyWord = this.GetString("Keyword")
+	}
+	keyWord = strings.TrimSpace(keyWord)
 
 	if pageSize <= 0 {
 		pageSize = utils.PageSize20
@@ -203,7 +208,7 @@ func (this *STLController) EdbInfoFilterByEs() {
 	if currentIndex <= 0 {
 		currentIndex = 1
 	}
-	resp, msg, err := stl.SearchEdbInfoWithStl(this.SysUser.AdminId, keyWord, currentIndex, pageSize)
+	resp, msg, err := stl.SearchEdbInfoWithStl(this.SysUser.AdminId, keyWord, currentIndex, pageSize, this.Lang)
 	if err != nil {
 		if msg == "" {
 			msg = "获取异常"

+ 8 - 8
controllers/data_manage/supply_analysis/variety.go

@@ -76,7 +76,7 @@ func (this *VarietyController) List() {
 		}
 		total, list, err = varietyObj.GetListByPage(condition, pars, startSize, pageSize)
 	}
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -146,12 +146,12 @@ func (this *VarietyController) Add() {
 	}
 	varietyName := utils.TrimStr(req.VarietyName)
 	item, err := supply_analysis.GetVarietyByName(varietyName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "添加失败"
 		br.ErrMsg = "添加失败,Err:" + err.Error()
 		return
 	}
-	if item != nil {
+	if item != nil && item.VarietyId > 0 {
 		br.Msg = "添加失败,品种名称不能重复"
 		br.IsSendEmail = false
 		return
@@ -219,12 +219,12 @@ func (this *VarietyController) Edit() {
 	varietyName := utils.TrimStr(req.VarietyName)
 
 	item, err := supply_analysis.GetVarietyByName(varietyName)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "添加失败"
 		br.ErrMsg = "添加失败,Err:" + err.Error()
 		return
 	}
-	if item != nil && item.VarietyId != req.VarietyId {
+	if item != nil && item.VarietyId != req.VarietyId && item.VarietyId > 0 {
 		br.Msg = "添加失败,品种名称不能重复"
 		br.IsSendEmail = false
 		return
@@ -364,7 +364,7 @@ func (this *VarietyController) Delete() {
 
 	varietyInfo, err := supply_analysis.GetVarietyById(req.VarietyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "该品种不存在或已删除"
 			br.IsSendEmail = false
 		} else {
@@ -411,7 +411,7 @@ func (this *VarietyController) Detail() {
 	if err != nil {
 		br.Msg = "查询品种失败"
 		br.ErrMsg = "查询品种失败;ERR:" + err.Error()
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "不存在该品种或该品种已被删除"
 			br.ErrMsg = "不存在该品种或该品种已被删除"
 			br.IsSendEmail = false
@@ -626,7 +626,7 @@ func (this *VarietyController) ModifyProductionDay() {
 	var hasPermission bool //是否有操作权限
 	// 是否有装置的操作权限
 	hasPermission, err = supply_analysisServ.HasVarietyPlantPermission(this.SysUser, req.VarietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "查询是否有装置的操作权限失败;ERR:" + err.Error()
 		return

+ 10 - 7
controllers/data_manage/supply_analysis/variety_edb.go

@@ -57,7 +57,7 @@ func (this *VarietyController) EdbList() {
 	var hasPermission bool //是否有操作权限
 	// 是否有装置的操作权限
 	hasPermission, err = supply_analysisServ.HasVarietyPlantPermission(this.SysUser, varietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "查询是否有装置的操作权限失败;ERR:" + err.Error()
 		return
@@ -65,7 +65,7 @@ func (this *VarietyController) EdbList() {
 
 	var list []*supply_analysis.VarietyEdbInfoItem
 	list, err = supply_analysis.GetAllVarietyEdbInfoByVarietyId(varietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -206,7 +206,7 @@ func (this *VarietyController) AddToEdb() {
 
 	varietyEdbInfo, err := supply_analysis.GetVarietyEdbInfoByVarietyEdbId(req.VarietyEdbId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "找不到该指标"
 			br.IsSendEmail = false
 		} else {
@@ -219,7 +219,7 @@ func (this *VarietyController) AddToEdb() {
 	var hasPermission bool //是否有操作权限
 	// 是否有装置的操作权限
 	hasPermission, err = supply_analysisServ.HasVarietyPlantPermission(this.SysUser, varietyEdbInfo.VarietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "查询是否有装置的操作权限失败;ERR:" + err.Error()
 		return
@@ -232,7 +232,7 @@ func (this *VarietyController) AddToEdb() {
 
 	if varietyEdbInfo.EdbInfoId > 0 {
 		tmpEdbInfo, err := data_manage.GetEdbInfoById(varietyEdbInfo.EdbInfoId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "添加失败"
 			br.ErrMsg = "查询ETA指标失败,ERR:" + err.Error()
 			return
@@ -347,7 +347,7 @@ func (this *VarietyController) EdbDataExport() {
 
 	var list []*supply_analysis.VarietyEdbInfoItem
 	list, err = supply_analysis.GetAllVarietyEdbInfoByVarietyId(varietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -750,7 +750,10 @@ func (this *VarietyController) EdbInfoDataSeasonal() {
 		Calendar:         "",
 	}
 
-	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, varietyEdbInfo.EndDate)
+	// 特殊处理季节性图的日期
+	maxDate := time.Date(varietyEdbInfo.EndDate.Year()+1, 1, 1, 0, 0, 0, 0, time.Local)
+
+	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, maxDate)
 
 	dataList, minVal, maxVal, err := supply_analysisServ.GetChartEdbSeasonalData(varietyEdbId, calendar, startDate, endDate, edbInfo.LatestDate)
 	if err != nil {

+ 8 - 8
controllers/data_manage/supply_analysis/variety_plant.go

@@ -50,7 +50,7 @@ func (this *VarietyController) PlantList() {
 	var hasPermission bool //是否有操作权限
 	// 是否有装置的操作权限
 	hasPermission, err = supply_analysisServ.HasVarietyPlantPermission(this.SysUser, varietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "查询是否有装置的操作权限失败;ERR:" + err.Error()
 		return
@@ -58,7 +58,7 @@ func (this *VarietyController) PlantList() {
 
 	var list []*supply_analysis.VarietyPlantItem
 	list, err = supply_analysis.GetAllVarietyPlantByVarietyId(varietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -141,7 +141,7 @@ func (this *VarietyController) AddPlant() {
 	var hasPermission bool //是否有操作权限
 	// 是否有装置的操作权限
 	hasPermission, err = supply_analysisServ.HasVarietyPlantPermission(this.SysUser, req.VarietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "查询是否有装置的操作权限失败;ERR:" + err.Error()
 		return
@@ -320,7 +320,7 @@ func (this *VarietyController) EditPlant() {
 	var hasPermission bool //是否有操作权限
 	// 是否有装置的操作权限
 	hasPermission, err = supply_analysisServ.HasVarietyPlantPermission(this.SysUser, varietyPlantInfo.VarietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "查询是否有装置的操作权限失败;ERR:" + err.Error()
 		return
@@ -443,7 +443,7 @@ func (this *VarietyController) DeletePlant() {
 	}
 
 	varietyPlantInfo, err := supply_analysis.GetVarietyPlantById(req.VarietyPlantId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "删除失败"
 		br.ErrMsg = "查找品种装置失败,Err:" + err.Error()
 		return
@@ -471,7 +471,7 @@ func (this *VarietyController) DeletePlant() {
 	// 是否有装置的操作权限
 	var hasPermission bool
 	hasPermission, err = supply_analysisServ.HasVarietyPlantPermission(this.SysUser, varietyPlantInfo.VarietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "查询是否有装置的操作权限失败;ERR:" + err.Error()
 		return
@@ -485,7 +485,7 @@ func (this *VarietyController) DeletePlant() {
 	// 保留一条装置校验
 	{
 		total, err := supply_analysis.GetCountVarietyPlantByVarietyId(varietyInfo.VarietyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "删除失败"
 			br.ErrMsg = "查找品种装置总数量失败,Err:" + err.Error()
 			return
@@ -542,7 +542,7 @@ func (this *VarietyController) CopyPlant() {
 	var hasPermission bool //是否有操作权限
 	// 是否有装置的操作权限
 	hasPermission, err = supply_analysisServ.HasVarietyPlantPermission(this.SysUser, req.VarietyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "查询是否有装置的操作权限失败;ERR:" + err.Error()
 		return

+ 6 - 6
controllers/data_manage/usda_fas_data.go

@@ -44,7 +44,7 @@ func (this *BaseFromUsdaFasController) UsdaFasClassify() {
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromUsdaFasClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -134,7 +134,7 @@ func (this *BaseFromUsdaFasController) UsdaFasIndexData() {
 	if classifyId >= 0 {
 		classifyInfo, err := data_manage.GetBaseFromUsdaFasClassifyById(classifyId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "分类不存在"
 				return
 			}
@@ -371,7 +371,7 @@ func (this *BaseFromUsdaFasController) UsdaFasSingleData() {
 		return
 	}
 	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_USDA_FAS, indexCode)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取数据源失败"
 		br.ErrMsg = "获取数据源失败,Err:" + err.Error()
 		return
@@ -421,7 +421,7 @@ func (this *BaseFromUsdaFasController) UsdaFasIndexList() {
 	}()
 	classifyId, _ := this.GetInt("ClassifyId", 0)
 	indexList, err := data_manage.GetUsdaFasIndexByClassifyId(classifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 		return
@@ -736,7 +736,7 @@ func (this *BaseFromUsdaFasController) UsdaFasNameCheck() {
 			EdbName: v.EdbName,
 		})
 		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_USDA_FAS, 0, utils.EDB_DATA_LIMIT)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
 			return
@@ -1039,7 +1039,7 @@ func (this *BaseFromUsdaFasController) ExportUsdaFasList() {
 	if classifyId > 0 {
 		classifyInfo, err := data_manage.GetBaseFromUsdaFasClassifyById(classifyId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "分类不存在"
 				return
 			}

+ 7 - 7
controllers/data_manage/wind_data.go

@@ -29,7 +29,7 @@ func (this *EdbInfoController) WindClassify() {
 	parentId, _ := this.GetInt("ParentId")
 	// 特殊处理顶级分类
 	rootList, err := data_manage.GetEdbClassifyByParentId(parentId, 0)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -38,7 +38,7 @@ func (this *EdbInfoController) WindClassify() {
 	if parentId == 0 {
 		// 查询wind指标的所有一级分类
 		classifyIdList, e := data_manage.GetEdbClassifyIdListBySource(utils.DATA_SOURCE_WIND)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取分类列表失败,Err:" + e.Error()
 			return
@@ -53,7 +53,7 @@ func (this *EdbInfoController) WindClassify() {
 		}
 		// 查询wind指标的所有一级分类下的指标信息
 		rootIds, e := data_manage.GetEdbClassifyRootIdsByClassifyIds(classifyIdList)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取分类列表失败,Err:" + e.Error()
 			return
@@ -70,7 +70,7 @@ func (this *EdbInfoController) WindClassify() {
 		// 获取当前账号的不可见指标
 		obj := data_manage.EdbInfoNoPermissionAdmin{}
 		confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
 			return
@@ -218,7 +218,7 @@ func (this *EdbInfoController) WindEdbInfoList() {
 	edbInfoId, _ := this.GetInt("EdbInfoId")
 	if classifyId > 0 {
 		childClassify, e, _ := data.GetChildClassifyByClassifyId(classifyId)
-		if e != nil && e.Error() != utils.ErrNoRow() {
+		if e != nil && !utils.IsErrNoRow(e) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error()
 			return
@@ -270,7 +270,7 @@ func (this *EdbInfoController) WindEdbInfoList() {
 		if classifyId > 0 { // todo 当没有传入分类ID时,如何处理 同一个分类ID,顶级分类是一样的
 			targetClassify, err := data_manage.GetEdbClassifyById(classifyId)
 			if err != nil {
-				if err.Error() == utils.ErrNoRow() {
+				if utils.IsErrNoRow(err) {
 					br.Msg = "当前分类不存在"
 					return
 				}
@@ -279,7 +279,7 @@ func (this *EdbInfoController) WindEdbInfoList() {
 				return
 			}
 			targetClassifyList, err = data_manage.GetEdbClassifyByRootIdLevel(targetClassify.RootId, targetClassify.ClassifyType, "")
-			if err != nil && err.Error() != utils.ErrNoRow() {
+			if err != nil && !utils.IsErrNoRow(err) {
 				br.Msg = "获取失败"
 				br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
 				return

+ 10 - 8
controllers/data_manage/yongyi_data.go

@@ -40,7 +40,7 @@ func (this *EdbInfoController) YongyiClassify() {
 	}
 
 	classifyAll, err := data_manage.GetAllBaseFromYongyiClassify()
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
@@ -128,7 +128,7 @@ func (this *EdbInfoController) YongyiIndexData() {
 	if classifyId >= 0 {
 		classifyInfo, err := data_manage.GetBaseFromYongyiClassifyById(classifyId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "分类不存在"
 				return
 			}
@@ -320,7 +320,7 @@ func (this *EdbInfoController) YongyiSingleData() {
 		return
 	}
 	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_YONYI, indexCode)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取数据源失败"
 		br.ErrMsg = "获取数据源失败,Err:" + err.Error()
 		return
@@ -343,7 +343,7 @@ func (this *EdbInfoController) YongyiSingleData() {
 	ret.Unit = indexInfo.Unit
 	for _, v := range dataTmpList {
 		tmp := &data_manage.YongyiSingleData{
-			Value:    v.Value,
+			Value:    v.Value.String(),
 			DataTime: v.DataTime,
 		}
 		dataList = append(dataList, tmp)
@@ -370,7 +370,7 @@ func (this *EdbInfoController) YongyiIndexList() {
 	}()
 	classifyId, _ := this.GetInt("ClassifyId", 0)
 	indexList, err := data_manage.GetYongyiIndexByClassifyId(classifyId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
 		return
@@ -660,7 +660,7 @@ func (this *EdbInfoController) YongyiNameCheck() {
 			EdbName: v.EdbName,
 		})
 		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_YONYI, 0, utils.EDB_DATA_LIMIT)
-		if err != nil && err.Error() != utils.ErrNoRow() {
+		if err != nil && !utils.IsErrNoRow(err) {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
 			return
@@ -962,7 +962,7 @@ func (this *EdbInfoController) ExportYongyiList() {
 	if classifyId > 0 {
 		classifyInfo, err := data_manage.GetBaseFromYongyiClassifyById(classifyId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "分类不存在"
 				return
 			}
@@ -980,9 +980,11 @@ func (this *EdbInfoController) ExportYongyiList() {
 
 		if len(childClassify) > 0 {
 			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
+			var classifyIdList []int
 			for _, child := range childClassify {
-				pars = append(pars, child.ClassifyId)
+				classifyIdList = append(classifyIdList, child.ClassifyId)
 			}
+			pars = append(pars, classifyIdList)
 		} else {
 			condition += ` AND classify_id=?`
 			pars = append(pars, classifyId)

+ 309 - 0
controllers/data_source/data_source.go

@@ -0,0 +1,309 @@
+package data_source
+
+import (
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	dataSourceModel "eta/eta_api/models/data_source"
+	"eta/eta_api/services/elastic"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strconv"
+)
+
+// SearchByEs
+// @Title ES搜索
+// @Description ES搜索
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   Keyword   query   string  true       "搜索关键词"
+// @Param   Source   query   int  true       "数据源"
+// @Success 200 {object} response.ExcelListResp
+// @router /common/search_by_es [get]
+func (c *DataSourceController) SearchByEs() {
+	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")
+	keyword := c.GetString("KeyWord")
+	if keyword == `` {
+		keyword = c.GetString("Keyword")
+	}
+	source, _ := c.GetInt("Source")
+	if source <= 0 {
+		br.Msg = "来源有误"
+		br.ErrMsg = fmt.Sprintf("数据来源有误, Source: %d", source)
+		return
+	}
+	subSource, _ := c.GetInt("SubSource")
+
+	// 以下为兼容各旧接口的额外传参,不为空时修改Resp对应的Key
+	primaryIdKey := c.GetString("PrimaryIdKey")
+	indexNameKey := c.GetString("IndexNameKey")
+	classifyIdKey := c.GetString("ClassifyIdKey")
+
+	var total, startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize15
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	// es搜索
+	t, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keyword, source, subSource, []int{}, []int{}, []string{}, startSize, pageSize)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = fmt.Sprintf("ES-搜索数据源列表失败, %v", e)
+		return
+	}
+	total = int(t)
+
+	// (短期方案)中国煤炭市场网/煤炭江湖额外补充基础字段
+	indexModifyTime := make(map[string]string)
+	indexBaseInfo := make(map[string]*dataSourceModel.BaseFromCoalmineIndexBase)
+	{
+		if source == utils.DATA_SOURCE_MTJH {
+			var updateCodes []string
+			for _, v := range list {
+				if v.ModifyTime == "" {
+					updateCodes = append(updateCodes, v.IndexCode)
+				}
+			}
+			if len(updateCodes) > 0 {
+				baseIndexes, e := dataSourceModel.GetMtjhBaseInfoFromDataTable(updateCodes)
+				if e != nil {
+					br.Msg = "获取失败"
+					br.ErrMsg = fmt.Sprintf("获取煤炭江湖指标基础信息失败, %v", e)
+					return
+				}
+				for _, v := range baseIndexes {
+					indexModifyTime[v.IndexCode] = utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime)
+				}
+			}
+		}
+		if source == utils.DATA_SOURCE_COAL {
+			var updateCodes []string
+			for _, v := range list {
+				if v.Unit == "" || v.Frequency == "" || v.ModifyTime == "" {
+					updateCodes = append(updateCodes, v.IndexCode)
+				}
+			}
+			if len(updateCodes) > 0 {
+				baseIndexes, e := dataSourceModel.GetCoalmineBaseInfoFromDataTable(updateCodes)
+				if e != nil {
+					br.Msg = "获取失败"
+					br.ErrMsg = fmt.Sprintf("获取中国煤炭市场网指标基础信息失败, %v", e)
+					return
+				}
+				for _, v := range baseIndexes {
+					indexBaseInfo[v.IndexCode] = v
+				}
+			}
+		}
+	}
+
+	listMap := make([]map[string]interface{}, 0)
+	for _, v := range list {
+		// (短期方案)由于start_date、end_date和latest_value字段不全的历史遗留问题,这里查出来并补充进ES里面去
+		var updateEs bool
+		if v.StartDate == "" || v.EndDate == "" || v.LatestValue == "" || v.LatestValue == "0" {
+			minMax, e := dataSourceModel.GetBaseIndexDataMinMax(v.Source, v.SubSource, v.IndexCode)
+			if e != nil && !utils.IsErrNoRow(e) {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("获取指标开始结束时间失败, %v", e)
+				return
+			}
+			if minMax != nil {
+				v.StartDate = minMax.MinDate
+				v.EndDate = minMax.MaxDate
+				v.LatestValue = minMax.LatestValue
+				updateEs = true
+			}
+		}
+
+		// 煤炭江湖缺ModifyTime
+		if source == utils.DATA_SOURCE_MTJH && v.ModifyTime == "" && indexModifyTime[v.IndexCode] != "" {
+			v.ModifyTime = indexModifyTime[v.IndexCode]
+			updateEs = true
+		}
+
+		// 中国煤炭市场网缺Unit, Frequency, ModifyTime
+		if source == utils.DATA_SOURCE_COAL && (v.Unit == "" || v.Frequency == "" || v.ModifyTime == "") {
+			if indexBaseInfo[v.IndexCode] != nil {
+				v.Unit = indexBaseInfo[v.IndexCode].Unit
+				v.Frequency = indexBaseInfo[v.IndexCode].Frequency
+				v.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, indexBaseInfo[v.IndexCode].ModifyTime)
+				updateEs = true
+			}
+		}
+
+		// 写入ES更新队列
+		if updateEs {
+			if e := utils.Rc.LPush(utils.CACHE_DATA_SOURCE_ES_HANDLE, v); e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("写入ES更新队列失败, Source: %d, IndexCode: %s, err: %v", v.Source, v.IndexCode, e)
+				return
+			}
+		}
+
+		// 转换成map返回
+		listMap = append(listMap, v.ToMap(primaryIdKey, indexNameKey, classifyIdKey))
+	}
+
+	// 美国农业部(多一个ParentClassifyId字段)
+	if source == utils.DATA_SOURCE_USDA_FAS {
+		// 父级分类ID
+		classifyIds := make([]int, 0)
+		for _, v := range list {
+			classifyIds = append(classifyIds, v.ClassifyId)
+		}
+		classifyList, e := data_manage.GetBaseFromUsdaFasClassifyByIds(classifyIds)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取美国农业部分类失败, %v", e)
+			return
+		}
+		classifyMap := make(map[int]int)
+		for _, v := range classifyList {
+			classifyMap[v.ClassifyId] = v.ParentId
+		}
+		for _, v := range listMap {
+			id, ok := v["ClassifyId"].(int)
+			if !ok {
+				v["ParentClassifyId"] = 0
+				continue
+			}
+			v["ParentClassifyId"] = classifyMap[id]
+		}
+	}
+
+	// 煤炭江湖(多一个Area字段)
+	if source == utils.DATA_SOURCE_MTJH {
+		cond := ``
+		pars := make([]interface{}, 0)
+		indexes, e := data_manage.GetMtjhItemsByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取煤炭江湖指标失败, %v", e)
+			return
+		}
+		indexArea := make(map[string]string)
+		for _, v := range indexes {
+			indexArea[v.IndexCode] = v.Area
+		}
+		for _, v := range listMap {
+			code, ok := v["IndexCode"].(string)
+			if !ok {
+				v["Area"] = ""
+				continue
+			}
+			v["Area"] = indexArea[code]
+		}
+	}
+
+	// 分类的唯一编码(前端定位用)
+	if classifyIdKey == "" {
+		classifyIdKey = "ClassifyId"
+	}
+	idUniqueCodeArr := []int{
+		utils.DATA_SOURCE_SCI_HQ, utils.DATA_SOURCE_MYSTEEL_CHEMICAL, utils.DATA_SOURCE_YS, utils.DATA_SOURCE_EIA_STEO,
+	}
+	if utils.InArrayByInt(idUniqueCodeArr, source) {
+		for _, v := range listMap {
+			classifyId, ok := v[classifyIdKey].(int)
+			if !ok {
+				v["ClassifyUniqueCode"] = ""
+				continue
+			}
+			v["ClassifyUniqueCode"] = strconv.Itoa(classifyId)
+		}
+	}
+	//if source == utils.DATA_SOURCE_MANUAL {
+	//	// 手工指标
+	//	var wxUserId int64
+	//	wxUserId = int64(sysUser.AdminId)
+	//	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
+	//		wxUserId = 0
+	//	}
+	//	classifies, err := models.GetEdbdataClassify(wxUserId)
+	//	if err != nil {
+	//		br.Msg = "获取失败"
+	//		br.ErrMsg = fmt.Sprintf("获取手工指标分类失败, %v", e)
+	//		return
+	//	}
+	//	unicodeMap := make(map[int]string)
+	//	for _, v := range classifies {
+	//		unicodeMap[v.ClassifyId] = v.UniqueCode
+	//	}
+	//	for _, v := range listMap {
+	//		classifyId, ok := v["ClassifyId"].(int)
+	//		if !ok {
+	//			continue
+	//		}
+	//		v["ClassifyUniqueCode"] = unicodeMap[classifyId]
+	//	}
+	//}
+
+	// 萝卜投研-LevelPath用作前端定位
+	levelPathMap := make(map[int]string)
+	if source == utils.DATA_SOURCE_RADISH_RESEARCH {
+		classifyOb := new(data_manage.BaseFromRadishResearchClassify)
+		classifies, e := classifyOb.GetItemsByCondition("", make([]interface{}, 0), []string{classifyOb.Cols().PrimaryId, classifyOb.Cols().LevelPath}, "")
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取萝卜投研分类失败, %v", e)
+			return
+		}
+		for _, v := range classifies {
+			levelPathMap[v.BaseFromRadishResearchClassifyId] = v.LevelPath
+		}
+	}
+
+	for _, v := range listMap {
+		classifyId, ok := v[classifyIdKey].(int)
+		if !ok {
+			v["ClassifyUniqueCode"] = ""
+			continue
+		}
+		v["ClassifyUniqueCode"] = strconv.Itoa(classifyId)
+		startDate := v["StartDate"].(string)
+		v["StartDate"] = utils.GormDateStrToDateStr(startDate)
+		endDate := v["EndDate"].(string)
+		v["EndDate"] = utils.GormDateStrToDateStr(endDate)
+
+		if source == utils.DATA_SOURCE_RADISH_RESEARCH {
+			// 未分类
+			if classifyId == 0 {
+				v["ClassifyLevelPath"] = "0"
+				continue
+			}
+			v["ClassifyLevelPath"] = levelPathMap[classifyId]
+		}
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := dataSourceModel.SearchDataSourceResp{
+		Paging: page,
+		List:   listMap,
+	}
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 7 - 8
controllers/data_source/sci99.go

@@ -103,7 +103,6 @@ func (this *DataSourceController) Sci99Data() {
 		pars = append(pars, "%"+keyword+"%")
 	}
 
-
 	sci99List, err := data_source.GetSci99Index(condition, pars)
 	if err != nil {
 		br.Msg = "获取数据失败"
@@ -121,13 +120,13 @@ func (this *DataSourceController) Sci99Data() {
 		product.Unit = v.Unit
 		product.ModifyTime = v.ModifyTime
 
-		modifyTime, err := data_source.GetSci99IndexLatestDate(v.IndexCode)
-		if err != nil && err.Error() != utils.ErrNoRow() {
-			br.Msg = "获取更新时间失败"
-			br.ErrMsg = "获取更新时间失败,Err:" + err.Error()
-			return
-		}
-		product.ModifyTime = modifyTime
+		// modifyTime, err := data_source.GetSci99IndexLatestDate(v.IndexCode)
+		// if err != nil && !utils.IsErrNoRow(err) {
+		// 	br.Msg = "获取更新时间失败"
+		// 	br.ErrMsg = "获取更新时间失败,Err:" + err.Error()
+		// 	return
+		// }
+		// product.ModifyTime = modifyTime
 
 		total, err := data_source.GetSci99IndexDataCount(v.IndexCode)
 		page := paging.GetPaging(currentIndex, pageSize, total)

+ 25 - 26
controllers/data_stat/edb_source_stat.go

@@ -225,7 +225,7 @@ func (this *EdbSourceStatController) EdbDeleteLog() {
 	}
 	total, err := data_stat.GetEdbDeleteLogCount(condition, pars)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "获取指标删除列表总数失败"
 			br.ErrMsg = "获取指标删除列表总数失败,Err:" + err.Error()
 			return
@@ -378,7 +378,7 @@ func (this *EdbSourceStatController) EdbUpdateLog() {
 	}
 	total, err := data_stat.GetEdbUpdateLogCount(condition, pars)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "获取指标删除列表总数失败"
 			br.ErrMsg = "获取指标删除列表总数失败,Err:" + err.Error()
 			return
@@ -555,7 +555,7 @@ func (this *EdbSourceStatController) EdbUpdateStat() {
 	}
 	total, err := data_stat.GetEdbUpdateStatCount(condition, pars)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "获取指标列表总数失败"
 			br.ErrMsg = "获取指标列表总数失败,Err:" + err.Error()
 			return
@@ -727,7 +727,7 @@ func (this *EdbSourceStatController) EdbSourceStat() {
 	}
 	total, err := data_stat.GetEdbSourceStatCount(condition, pars)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "获取数据源统计列表总数失败"
 			br.ErrMsg = "获取数据源统计列表总数失败,Err:" + err.Error()
 			return
@@ -805,24 +805,27 @@ func (this *EdbSourceStatController) EdbUpdateFailedList() {
 	terminalCode := this.GetString("TerminalCode", "")
 	createTime := this.GetString("CreateTime", "")
 
-	if terminalCode == "" {
-		br.Msg = "请选择对应的终端信息"
-		return
-	}
-	terminalInfo, err := data_manage.GetEdbTerminalByTerminalCode(terminalCode)
-	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
-			br.Msg = "终端不存在"
-			return
-		}
-		br.Msg = "查询终端信息出错"
-		br.ErrMsg = "查询终端信息出错 Err:" + err.Error()
-		return
-	}
 	condition := " and source = ? and terminal_code = ?"
 	var pars []interface{}
 	pars = append(pars, utils.DATA_SOURCE_MYSTEEL_CHEMICAL, terminalCode)
 
+	terminalName := ""
+	terminalDir := ""
+	if terminalCode != "" {
+		terminalInfo, err := data_manage.GetEdbTerminalByTerminalCode(terminalCode)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				br.Msg = "终端不存在"
+				return
+			}
+			br.Msg = "查询终端信息出错"
+			br.ErrMsg = "查询终端信息出错 Err:" + err.Error()
+			return
+		}
+		terminalName = terminalInfo.Name
+		terminalDir = terminalInfo.DirPath
+	}
+
 	if createTime != "" {
 		startT, err := time.ParseInLocation(utils.FormatDate, createTime, time.Local)
 		if err != nil {
@@ -856,9 +859,9 @@ func (this *EdbSourceStatController) EdbUpdateFailedList() {
 	}
 	resp := data_stat.GetEdbUpdateFailedResp{
 		List:             list,
-		Name:             terminalInfo.Name,
+		Name:             terminalName,
 		TerminalCode:     terminalCode,
-		DirPath:          terminalInfo.DirPath,
+		DirPath:          terminalDir,
 		UpdateSuccessNum: successNum,
 		UpdateFailedNum:  failedNum,
 	}
@@ -909,16 +912,12 @@ func (this *EdbSourceStatController) EdbUpdateFailedDetailList() {
 		return
 	}
 
-	if terminalCode == "" {
-		br.Msg = "请选择对应的终端信息"
-		return
-	}
 	if frequency == "" {
 		br.Msg = "请选择对应的频度"
 		return
 	}
 
-	condition := " and source = ? and terminal_code = ? and frequency=? and data_update_failed_reason=? and data_update_result = 2"
+	condition := " and source = ? AND terminal_code = ? and frequency=? and data_update_failed_reason=? and data_update_result = 2"
 	var pars []interface{}
 	pars = append(pars, utils.DATA_SOURCE_MYSTEEL_CHEMICAL, terminalCode, frequency, sourceUpdateFailedReason)
 
@@ -935,7 +934,7 @@ func (this *EdbSourceStatController) EdbUpdateFailedDetailList() {
 
 	total, err := data_stat.GetEdbUpdateStatCount(condition, pars)
 	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(err) {
 			br.Msg = "获取指标列表总数失败"
 			br.ErrMsg = "获取指标列表总数失败,Err:" + err.Error()
 			return

+ 5 - 3
controllers/document_manage/document_manage_controller.go

@@ -156,7 +156,8 @@ func (this *DocumentManageController) DocumentReportList() {
 	if currentIndex <= 0 {
 		currentIndex = 1
 	}
-	documentReportPage, err := document_manage_service.DocumentReportList(documentType, chartPermissionIdList, classifyIdList, keyword, orderField, orderType, currentIndex, pageSize)
+	startSize := utils.StartIndex(currentIndex, pageSize)
+	documentReportPage, err := document_manage_service.DocumentReportList(documentType, chartPermissionIdList, classifyIdList, keyword, orderField, orderType, startSize, pageSize)
 	if err != nil {
 		br.Msg = "获取报告列表失败"
 		br.ErrMsg = "获取报告列表失败,Err:" + err.Error()
@@ -211,7 +212,8 @@ func (this *DocumentManageController) RuiSiReportList() {
 	if currentIndex <= 0 {
 		currentIndex = 1
 	}
-	RuiSiReportPage, err := document_manage_service.RuiSiReportList(classifyIdFirst, classifyIdSecond, classifyIdThird, chartPermissionIdList, keyword, orderField, orderType, currentIndex, pageSize)
+	startSize := utils.StartIndex(currentIndex, pageSize)
+	RuiSiReportPage, err := document_manage_service.RuiSiReportList(classifyIdFirst, classifyIdSecond, classifyIdThird, chartPermissionIdList, keyword, orderField, orderType, startSize, pageSize)
 	if err != nil {
 		br.Msg = "获取报告列表失败"
 		br.ErrMsg = "获取报告列表失败,Err:" + err.Error()
@@ -257,7 +259,7 @@ func (this *DocumentManageController) DocumentRuiSiDetail() {
 
 	reportDetail, err := document_manage_service.DocumentRuiSiDetail(reportId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "报告已被删除"
 			return
 		}

+ 14 - 2
controllers/english_report/email.go

@@ -187,7 +187,7 @@ func (this *EnglishReportEmailController) Save() {
 
 	// 英文客户以邮箱为主, 邮箱去重, 手机号非必填, 此处不做手机号去重
 	exist, e := models.GetEnglishReportEmailByEmail(req.Email)
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "保存失败"
 		br.ErrMsg = "获取同名邮箱失败, Err:" + e.Error()
 		return
@@ -595,6 +595,18 @@ func (this *EnglishReportEmailController) Send() {
 			noCompanyIdsMap[v] = struct{}{}
 		}
 	}
+
+	// 加个缓存吧,避免重复点击
+	cacheKey := "CACHE_ENGLISH_REPORT_SEND_" + strconv.Itoa(req.ReportId)
+	if !utils.Rc.SetNX(cacheKey, 1, 300*time.Second) {
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	defer func() {
+		_ = utils.Rc.Delete(cacheKey)
+	}()
+
 	// 指定品种的客户
 	sendCompanyIds := make([]int, 0)
 	if len(req.EnPermissions) > 0 {
@@ -933,7 +945,7 @@ func (this *EnglishReportEmailController) ImportListMatch() {
 	}
 	companyItem, e := models.GetEnglishCompanyById(companyId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "客户已被删除, 请刷新页面"
 			return
 		}

+ 5 - 5
controllers/english_report/en_permission.go

@@ -62,7 +62,7 @@ func (this *EnPermissionController) Add() {
 	existPars := make([]interface{}, 0)
 	existPars = append(existPars, req.PermissionName, req.ParentId)
 	exist, e := existOB.GetItemByCondition(existCond, existPars)
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "操作失败"
 		br.ErrMsg = "获取重名品种权限失败, Err: " + e.Error()
 		return
@@ -143,7 +143,7 @@ func (this *EnPermissionController) Edit() {
 	existPars := make([]interface{}, 0)
 	existPars = append(existPars, req.PermissionName, req.ParentId, req.PermissionId)
 	exist, e := ob.GetItemByCondition(existCond, existPars)
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "操作失败"
 		br.ErrMsg = "获取重名品种权限失败, Err: " + e.Error()
 		return
@@ -155,7 +155,7 @@ func (this *EnPermissionController) Edit() {
 
 	item, e := ob.GetItemById(req.PermissionId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "品种不存在, 请刷新页面"
 			return
 		}
@@ -384,7 +384,7 @@ func (this *EnPermissionController) Remove() {
 	ob := new(models.EnPermission)
 	item, e := ob.GetItemById(req.PermissionId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "品种不存在, 请刷新页面"
 			return
 		}
@@ -522,7 +522,7 @@ func (this *EnPermissionController) SetEnabled() {
 
 	item, e := ob.GetItemById(req.PermissionId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "品种不存在, 请刷新页面"
 			return
 		}

+ 8 - 8
controllers/english_report/english_classify.go

@@ -206,7 +206,7 @@ func (this *EnglishReportController) AddClassify() {
 	if parentId > 0 {
 		parentClassify, err := models.GetEnglishReportClassifyById(parentId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "上级分类不存在"
 				return
 			}
@@ -331,7 +331,7 @@ func (this *EnglishReportController) EditClassify() {
 
 	oldItem, err := models.GetEnglishReportClassifyById(classifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "当前分类不存在"
 			return
 		}
@@ -350,7 +350,7 @@ func (this *EnglishReportController) EditClassify() {
 	if parentId > 0 {
 		parent, err = models.GetEnglishReportClassifyById(parentId)
 		if err != nil {
-			if err.Error() == utils.ErrNoRow() {
+			if utils.IsErrNoRow(err) {
 				br.Msg = "上级分类不存在"
 				return
 			}
@@ -377,7 +377,7 @@ func (this *EnglishReportController) EditClassify() {
 	//判断是否已存在同个名称的分类
 	existItem, e := models.GetEnglishClassifyByClassifyNameParentId(classifyName, parentId)
 	if e != nil {
-		if e.Error() != utils.ErrNoRow() {
+		if !utils.IsErrNoRow(e) {
 			br.Msg = "查询已存在的分类出错"
 			br.ErrMsg = "查询已存在的分类出错, Err:" + e.Error()
 			return
@@ -482,7 +482,7 @@ func (this *EnglishReportController) DelClassify() {
 
 	classifyInfo, err := models.GetEnglishReportClassifyById(classifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "当前分类不存在"
 			br.ErrMsg = "当前分类不存在"
 			return
@@ -505,7 +505,7 @@ func (this *EnglishReportController) DelClassify() {
 	// 	return
 	// }
 	reportCount, e := models.GetEnglishReportCounts(classifyId, classifyInfo.ParentId)
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "获取信息失败"
 		br.ErrMsg = "获取失败,Err:" + e.Error()
 		return
@@ -517,7 +517,7 @@ func (this *EnglishReportController) DelClassify() {
 		return
 	}
 	videoCount, e := models.GetEnglishVideoCounts(classifyId, classifyInfo.ParentId)
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "获取信息失败"
 		br.ErrMsg = "获取失败,Err:" + e.Error()
 		return
@@ -754,7 +754,7 @@ func (this *EnglishReportController) SetEnabled() {
 	}
 	item, err := models.GetEnglishReportClassifyById(req.ClassifyId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "分类不存在"
 			return
 		}

+ 3 - 3
controllers/english_report/english_company.go

@@ -266,7 +266,7 @@ func (this *EnglishCompanyController) Save() {
 
 	// 重名校验
 	exist, e := models.GetEnglishCompanyByName(req.CompanyName)
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "保存失败"
 		br.ErrMsg = "获取客户信息失败, Err:" + e.Error()
 		return
@@ -298,7 +298,7 @@ func (this *EnglishCompanyController) Save() {
 			return
 		}
 	} else {
-		if exist != nil && exist.CompanyId != req.CompanyId {
+		if exist != nil && exist.CompanyId != req.CompanyId && exist.CompanyId > 0 {
 			br.Msg = "客户名称已存在"
 			return
 		}
@@ -721,7 +721,7 @@ func (this *EnglishCompanyController) SavePermission() {
 	nowTime := time.Now().Local()
 	item, e := models.GetEnglishCompanyById(req.CompanyId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "客户已被删除, 请刷新页面"
 			return
 		}

+ 2 - 2
controllers/english_report/english_company_todo.go

@@ -2,12 +2,12 @@ package english_report
 
 import (
 	"encoding/json"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/system"
 	"eta/eta_api/services"
 	"eta/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"html"
 	"time"
 )
@@ -524,7 +524,7 @@ func (this *EnglishCompanyTodoController) LastPublicTodo() {
 	}
 
 	item, e := models.GetLastEnglishCompanyTodoPublic()
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if e != nil && !utils.IsErrNoRow(e) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取最新的公共TODO失败, Err: " + e.Error()
 		return

+ 5 - 5
controllers/english_report/english_video.go

@@ -2,12 +2,12 @@ package english_report
 
 import (
 	"encoding/json"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/company"
 	"eta/eta_api/services"
 	"eta/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"strconv"
 	"strings"
 )
@@ -251,7 +251,7 @@ func (this *EnglishVideoController) Detail() {
 	}
 	item, err := models.GetEnglishVideoById(id)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "路演视频不存在"
 			return
 		}
@@ -408,7 +408,7 @@ func (this *EnglishVideoController) PublishVideo() {
 	}
 	videoInfo, err := models.GetEnglishVideoById(id)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "路演视频不存在"
 			return
 		}
@@ -474,7 +474,7 @@ func (this *EnglishVideoController) PublishCancleVideo() {
 	}
 	videoInfo, err := models.GetEnglishVideoById(req.Id)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "路演视频不存在"
 			return
 		}
@@ -526,7 +526,7 @@ func (this *EnglishVideoController) Delete() {
 	}
 	videoInfo, err := models.GetEnglishVideoById(req.Id)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "路演视频不存在"
 			return
 		}

+ 1 - 1
controllers/english_report/policy_report.go

@@ -39,7 +39,7 @@ func (this *EnglishPolicyReportController) Detail() {
 	}
 	item, err := models.GetEnglishPolicyReportById(reportId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "报告不存在!"
 			return
 		}

+ 134 - 14
controllers/english_report/report.go

@@ -5,6 +5,7 @@ import (
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/company"
+	"eta/eta_api/models/data_manage/excel"
 	"eta/eta_api/models/report_approve"
 	"eta/eta_api/models/system"
 	"eta/eta_api/services"
@@ -65,6 +66,8 @@ func (this *EnglishReportController) Add() {
 
 	var contentSub string
 	if req.Content != "" {
+		req.Content = services.HandleReportContent(req.Content, "del", nil)
+
 		e := utils.ContentXssCheck(req.Content)
 		if e != nil {
 			br.Msg = "存在非法标签"
@@ -93,7 +96,7 @@ func (this *EnglishReportController) Add() {
 	}
 	reportClassify, e := models.GetEnglishReportClassifyById(req.ClassifyIdFirst)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "报告所在分类异常"
 			return
 		}
@@ -140,6 +143,32 @@ func (this *EnglishReportController) Add() {
 	{
 		go models.ModifyEnglishReportCode(newReportId, reportCode)
 	}
+
+	excelReferences := make([]*excel.ReferencedExcelConfig, 0)
+	for _, r := range req.ExcelReferences {
+		refItem := excel.ReferencedExcelConfig{
+			UniqueCode:   r.UniqueCode,
+			ReferencedId: int(newReportId),
+			FromScene:    utils.TableReferencedByEnReport,
+			Uuid:         r.Uuid,
+			WidthList:    r.WidthList,
+			HeightList:   r.HeightList,
+			OpUserId:     this.SysUser.AdminId,
+			OpUserName:   this.SysUser.RealName,
+			CreateTime:   time.Now(),
+			ModifyTime:   time.Now(),
+		}
+		excelReferences = append(excelReferences, &refItem)
+	}
+	if len(excelReferences) > 0 {
+		err = excel.AddReferencedExcelConfig(excelReferences)
+		if err != nil {
+			br.Msg = "新增引用失败"
+			br.ErrMsg = "新增引用失败,Err:" + err.Error()
+			return
+		}
+	}
+
 	resp := new(models.AddEnglishReportResp)
 	resp.ReportId = newReportId
 	resp.ReportCode = reportCode
@@ -198,6 +227,8 @@ func (this *EnglishReportController) Edit() {
 	}
 	var contentSub string
 	if req.Content != "" {
+		req.Content = services.HandleReportContentTable(int(req.ReportId), req.Content)
+		req.Content = services.HandleReportContent(req.Content, "del", nil)
 		e := utils.ContentXssCheck(req.Content)
 		if e != nil {
 			br.Msg = "存在非法标签"
@@ -222,7 +253,7 @@ func (this *EnglishReportController) Edit() {
 	var stage int
 	report, e := models.GetEnglishReportById(int(req.ReportId))
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "报告已被删除, 请刷新页面"
 			return
 		}
@@ -309,7 +340,7 @@ func (this *EnglishReportController) Detail() {
 	}
 	item, err := models.GetEnglishReportById(reportId)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "报告已被删除"
 			return
 		}
@@ -320,6 +351,19 @@ func (this *EnglishReportController) Detail() {
 
 	item.Content = html.UnescapeString(item.Content)
 	item.ContentSub = html.UnescapeString(item.ContentSub)
+	// 处理关联excel的表格id
+	item.Content = services.HandleReportContentTable(item.Id, item.Content)
+
+	businessConf, err := models.GetBusinessConfByKey(models.BusinessConfIsOpenChartExpired)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取配置失败,Err:" + err.Error()
+		return
+	}
+	if businessConf.ConfVal == `true` {
+		tokenMap := make(map[string]string)
+		item.Content = services.HandleReportContent(item.Content, "add", tokenMap)
+	}
 
 	classifyNameMap := make(map[int]*models.EnglishClassifyFullName)
 	if item.ClassifyIdSecond > 0 {
@@ -706,8 +750,9 @@ func (this *EnglishReportController) PublishReport() {
 			}()
 
 			// 生成报告pdf和长图
-			if req.ReportUrl != "" {
-				go services.Report2pdfAndJpeg(req.ReportUrl, report.Id, 2)
+			pdfUrl := services.GetGeneralEnglishReportPdfUrl(report.Id, report.ReportCode)
+			if pdfUrl != "" {
+				go services.Report2pdfAndJpeg(pdfUrl, report.Id, 2)
 			}
 		} else {
 			// 从无审批切换为有审批, 状态重置
@@ -809,8 +854,9 @@ func (this *EnglishReportController) PrePublishReport() {
 	}
 
 	// 生成报告pdf和长图
-	if req.ReportUrl != "" {
-		go services.Report2pdfAndJpeg(req.ReportUrl, report.Id, 2)
+	pdfUrl := services.GetGeneralEnglishReportPdfUrl(report.Id, report.ReportCode)
+	if pdfUrl != "" {
+		go services.Report2pdfAndJpeg(pdfUrl, report.Id, 2)
 	}
 
 	br.Ret = 200
@@ -896,7 +942,7 @@ func (this *EnglishReportController) Delete() {
 	}
 	reportInfo, err := models.GetEnglishReportById(req.ReportIds)
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "报告不存在"
 			return
 		}
@@ -969,6 +1015,7 @@ func (this *EnglishReportController) SaveReportContent() {
 	}
 
 	if noChangeFlag != 1 {
+		req.Content = services.HandleReportContent(req.Content, "del", nil)
 		content := req.Content
 		if content == "" {
 			content = this.GetString("Content")
@@ -1041,7 +1088,7 @@ func (this *EnglishReportController) ClassifyIdDetail() {
 		classifyIdSecond, _ = this.GetInt("ClassifyIdSecond")
 	}
 	item, err := models.GetEnglishReportDetailByClassifyId(classifyIdFirst, classifyIdSecond)
-	if err != nil && err.Error() != utils.ErrNoRow() {
+	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败!"
 		br.ErrMsg = "获取失败,Err:" + err.Error()
 		return
@@ -1050,6 +1097,18 @@ func (this *EnglishReportController) ClassifyIdDetail() {
 		item.Content = html.UnescapeString(item.Content)
 		item.ContentSub = html.UnescapeString(item.ContentSub)
 
+		businessConf, err := models.GetBusinessConfByKey(models.BusinessConfIsOpenChartExpired)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取配置失败,Err:" + err.Error()
+			return
+		}
+
+		if businessConf.ConfVal == `true` {
+			tokenMap := make(map[string]string)
+			item.Content = services.HandleReportContent(item.Content, "add", tokenMap)
+		}
+
 		classifyNameMap := make(map[int]*models.EnglishClassifyFullName)
 		if item.ClassifyIdSecond > 0 {
 			nameList, tErr := models.GetEnglishClassifyFullNameByIds([]int{item.ClassifyIdSecond})
@@ -1068,6 +1127,7 @@ func (this *EnglishReportController) ClassifyIdDetail() {
 			}
 		}
 	}
+	item.Content = services.HandleReportContentTable(0, item.Content)
 
 	br.Ret = 200
 	br.Success = true
@@ -1220,7 +1280,7 @@ func (this *EnglishReportController) EditPolicy() {
 	//查询报告是否存在
 	reportInfo, err := models.GetEnglishReportItemById(int(req.ReportId))
 	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(err) {
 			br.Msg = "报告不存在"
 			return
 		}
@@ -1302,7 +1362,7 @@ func (this *EnglishReportController) SubmitApprove() {
 	reportOb := new(models.EnglishReport)
 	reportItem, e := reportOb.GetItemById(reportId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "报告已被删除, 请刷新页面"
 			return
 		}
@@ -1312,7 +1372,7 @@ func (this *EnglishReportController) SubmitApprove() {
 	}
 	reportClassify, e := models.GetEnglishReportClassifyById(reportItem.ClassifyIdFirst)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "报告所在分类异常"
 			return
 		}
@@ -1403,7 +1463,7 @@ func (this *EnglishReportController) CancelApprove() {
 	reportOb := new(models.EnglishReport)
 	reportItem, e := reportOb.GetItemById(reportId)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "报告已被删除, 请刷新页面"
 			return
 		}
@@ -1413,7 +1473,7 @@ func (this *EnglishReportController) CancelApprove() {
 	}
 	reportClassify, e := models.GetEnglishReportClassifyById(reportItem.ClassifyIdFirst)
 	if e != nil {
-		if e.Error() == utils.ErrNoRow() {
+		if utils.IsErrNoRow(e) {
 			br.Msg = "报告所在分类异常"
 			return
 		}
@@ -1471,3 +1531,63 @@ func (this *EnglishReportController) CancelApprove() {
 	br.Success = true
 	br.Msg = "操作成功"
 }
+
+// @Title 获取报告分享链接
+// @Description 获取报告分享链接
+// @Param   ReportId   query   int  true       "报告id"
+// @Success 200 {object} models.EnglishReportDetailView
+// @router /share_url [get]
+func (this *EnglishReportController) GetShareUrl() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	/*var req models.ReportDetailReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ReportId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}*/
+	reportId, err := this.GetInt("ReportId")
+	if err != nil {
+		br.Msg = "获取参数失败!"
+		br.ErrMsg = "获取参数失败,Err:" + err.Error()
+		return
+	}
+	if reportId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	item, err := models.GetEnglishReportById(reportId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "报告已被删除"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	token, err := services.GetEnglishReportToken(reportId, item.ReportCode)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "报告已被删除"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Data = token
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}

+ 256 - 0
controllers/eta_forum/eta_forum.go

@@ -0,0 +1,256 @@
+package eta_forum
+
+import (
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/services/eta_forum"
+	"eta/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type EtaForumController struct {
+	controllers.BaseAuthController
+}
+
+// UserChartList
+// @Title 查询用户在eta社区中有权限查看的图表列表
+// @Description 查询用户在eta社区中有权限查看的图表列表
+// @Param	request	body data_manage.SetChartInfoImageReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /chart_list [get]
+func (this *EtaForumController) UserChartList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	keyword := this.GetString("Keyword")
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	businessCode := utils.BusinessCode
+	userMobile := sysUser.Mobile
+	telAreaCode := sysUser.TelAreaCode
+	if businessCode == "" {
+		br.Msg = "商户号未配置"
+		return
+	}
+
+	if userMobile == "" {
+		br.Msg = "请先绑定手机号"
+		return
+	}
+	if telAreaCode == "" {
+		telAreaCode = utils.TelAreaCodeHome
+	}
+
+	resp, err, _ := eta_forum.GetUserChartList(businessCode, userMobile, telAreaCode, keyword, currentIndex, pageSize)
+	if err != nil {
+		/*br.Msg = errMsg
+		br.ErrMsg = err.Error()*/
+		page := paging.GetPaging(currentIndex, pageSize, 0)
+		resp = eta_forum.UserChartListRespItem{
+			ChartInfoList: make([]*data_manage.ChartInfo, 0),
+			Paging:        page,
+		}
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "保存成功"
+		br.Data = resp
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+}
+
+// UserCollectChartClassifyList
+// @Title 查询社区中用户收藏的分类列表
+// @Description 查询社区中用户收藏的分类列表
+// @Param	request	body data_manage.SetChartInfoImageReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /collect/chart_classify [get]
+func (this *EtaForumController) UserCollectChartClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	businessCode := utils.BusinessCode
+	userMobile := sysUser.Mobile
+	telAreaCode := sysUser.TelAreaCode
+	if businessCode == "" {
+		br.Msg = "商户号未配置"
+		return
+	}
+
+	if userMobile == "" {
+		br.Msg = "请先绑定手机号"
+		return
+	}
+	if telAreaCode == "" {
+		telAreaCode = utils.TelAreaCodeHome
+	}
+
+	resp, err, _ := eta_forum.GetUserCollectChartClassifyList(businessCode, userMobile, telAreaCode)
+	if err != nil {
+		resp = eta_forum.UserCollectChartClassifyListItem{
+			List:     make([]*eta_forum.ChartCollectClassifyItem, 0),
+			Language: "CN",
+		}
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "保存成功"
+		br.Data = resp
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+}
+
+// UserCollectChartList
+// @Title 查询社区中用户收藏的图表列表
+// @Description 查询社区中用户收藏的图表列表
+// @Param	request	body data_manage.SetChartInfoImageReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /collect/chart [get]
+func (this *EtaForumController) UserCollectChartList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	businessCode := utils.BusinessCode
+	userMobile := sysUser.Mobile
+	telAreaCode := sysUser.TelAreaCode
+	if businessCode == "" {
+		br.Msg = "商户号未配置"
+		return
+	}
+
+	if userMobile == "" {
+		br.Msg = "请先绑定手机号"
+		return
+	}
+	if telAreaCode == "" {
+		telAreaCode = utils.TelAreaCodeHome
+	}
+
+	collectClassifyIds := this.GetString("CollectClassifyIds")
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	keyword := this.GetString("Keyword")
+
+	resp, err, _ := eta_forum.GetUserCollectChartList(businessCode, userMobile, telAreaCode, keyword, collectClassifyIds, currentIndex, pageSize)
+	if err != nil {
+		page := paging.GetPaging(currentIndex, pageSize, 0)
+		resp = eta_forum.UserCollectChartListRespItem{
+			List:   make([]*eta_forum.ChartCollectView, 0),
+			Paging: page,
+		}
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "保存成功"
+		br.Data = resp
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+}
+
+// CommonChartInfoDetailFromUniqueCode
+// @Title 根据编码获取图表详情
+// @Description 根据编码获取图表详情接口
+// @Param   UniqueCode   query   int  true       "图表唯一编码,如果是管理后台访问,传固定字符串:7c69b590249049942070ae9dcd5bf6dc"
+// @Param   IsCache   query   bool  true       "是否走缓存,默认false"
+// @Success 200 {object} data_manage.ChartInfoDetailFromUniqueCodeResp
+// @router /chart/from_unique_code [get]
+func (this *EtaForumController) CommonChartInfoDetailFromUniqueCode() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	uniqueCode := this.GetString("UniqueCode")
+	if uniqueCode == "" {
+		br.Msg = "参数错误"
+		br.ErrMsg = "参数错误,uniqueCode is empty"
+		return
+	}
+
+	//是否走缓存
+	isCache, _ := this.GetBool("IsCache")
+	resp := new(data_manage.ChartInfoDetailFromUniqueCodeResp)
+	status := true
+	forumResp, err, _ := eta_forum.GeChartFromUniqueCode(uniqueCode, isCache)
+	if err != nil {
+		endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+		resp.EdbInfoList = endInfoList
+		resp.ChartInfo = nil
+		resp.Status = false
+
+		br.Data = resp
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+	chartInfo := forumResp.ChartInfo
+	if chartInfo == nil {
+		endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+		resp.EdbInfoList = endInfoList
+		resp.ChartInfo = nil
+		resp.Status = false
+
+		br.Data = resp
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+	resp.ChartInfo = chartInfo
+	resp.Status = status
+	resp.DataResp = forumResp.DataResp
+	resp.EdbInfoList = forumResp.EdbInfoList
+	resp.XDataList = forumResp.XDataList
+	resp.YDataList = forumResp.YDataList
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini