浏览代码

Merge branch 'master' of http://8.136.199.33:3000/eta_server/eta_api into bzq1/lt_excel

zqbao 3 月之前
父节点
当前提交
40f666b95b
共有 66 个文件被更改,包括 3639 次插入747 次删除
  1. 9 0
      controllers/classify.go
  2. 105 2
      controllers/data_manage/chart_classify.go
  3. 123 1
      controllers/data_manage/chart_common.go
  4. 499 8
      controllers/data_manage/chart_info.go
  5. 12 5
      controllers/data_manage/correlation/correlation_chart_info.go
  6. 12 0
      controllers/data_manage/cross_variety/chart_info.go
  7. 27 46
      controllers/data_manage/edb_info.go
  8. 2 1
      controllers/data_manage/excel/excel_info.go
  9. 12 0
      controllers/data_manage/future_good/future_good_chart_info.go
  10. 12 0
      controllers/data_manage/future_good/future_good_profit_chart_info.go
  11. 12 0
      controllers/data_manage/line_equation/line_chart_info.go
  12. 12 0
      controllers/data_manage/line_feature/chart_info.go
  13. 8 2
      controllers/data_manage/manual_edb.go
  14. 23 6
      controllers/data_manage/my_chart.go
  15. 58 73
      controllers/data_manage/mysteel_chemical_data.go
  16. 211 106
      controllers/data_manage/predict_edb_info.go
  17. 12 0
      controllers/data_manage/range_analysis/chart_info.go
  18. 807 102
      controllers/data_manage/yongyi_data.go
  19. 6 1
      controllers/document_manage/document_manage_controller.go
  20. 118 33
      controllers/report_approve/report_approve.go
  21. 38 10
      controllers/report_approve/report_approve_flow.go
  22. 4 2
      controllers/report_chapter.go
  23. 1 1
      controllers/report_v2.go
  24. 8 0
      controllers/resource.go
  25. 26 18
      controllers/target.go
  26. 2 0
      models/business_conf.go
  27. 59 5
      models/data_manage/base_from_yongyi.go
  28. 14 1
      models/data_manage/base_from_yongyi_classify.go
  29. 122 0
      models/data_manage/chart_classify.go
  30. 32 0
      models/data_manage/chart_info.go
  31. 16 0
      models/data_manage/chart_info_correlation.go
  32. 2 0
      models/data_manage/edb_data_base.go
  33. 4 2
      models/data_manage/edb_info.go
  34. 2 2
      models/data_manage/excel/request/mixed_table.go
  35. 30 0
      models/data_manage/my_chart.go
  36. 11 0
      models/data_manage/mysteel_chemical_index.go
  37. 11 0
      models/data_manage/request/predict_edb_info.go
  38. 11 0
      models/data_manage/request/yongyi.go
  39. 5 2
      models/document_manage_model/outside_report.go
  40. 11 1
      models/permission.go
  41. 17 2
      models/report.go
  42. 7 3
      models/report_approve/report_approve.go
  43. 31 21
      models/target.go
  44. 68 0
      models/user_collect_classify.go
  45. 99 0
      routers/commentsRouter.go
  46. 84 35
      services/classify.go
  47. 10 0
      services/data/base_edb_lib.go
  48. 176 10
      services/data/chart_classify.go
  49. 4 0
      services/data/chart_info.go
  50. 25 0
      services/data/edb_classify.go
  51. 200 1
      services/data/edb_info.go
  52. 2 1
      services/data/edb_info_relation.go
  53. 1 1
      services/data/excel/excel_info.go
  54. 57 9
      services/data/excel/mixed_table.go
  55. 3 91
      services/data/predict_edb_info.go
  56. 165 103
      services/data/predict_edb_info_rule.go
  57. 14 0
      services/data/range_analysis/chart_info.go
  58. 50 0
      services/data/yongyi.go
  59. 28 6
      services/document_manage_service/document_manage_service.go
  60. 65 27
      services/excel/lucky_sheet.go
  61. 1 1
      services/ppt.go
  62. 26 5
      services/report_v2.go
  63. 1 1
      services/smart_report.go
  64. 13 0
      utils/common.go
  65. 2 0
      utils/config.go
  66. 1 0
      utils/constants.go

+ 9 - 0
controllers/classify.go

@@ -863,3 +863,12 @@ func (this *ClassifyController) ClassifyPermissionV2() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+// 处理禅道bug6445,对数据进行补偿刷新
+/*func init() {
+	err := services.DealBug6445()
+	if err != nil {
+		return
+	}
+}
+*/

+ 105 - 2
controllers/data_manage/chart_classify.go

@@ -260,6 +260,7 @@ func (this *ChartClassifyController) ChartClassifyItems() {
 		this.ServeJSON()
 	}()
 
+	level, _ := this.GetInt(`Level`)
 	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
 	if err != nil {
 		br.Msg = "获取失败"
@@ -285,7 +286,7 @@ func (this *ChartClassifyController) ChartClassifyItems() {
 	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
 	for k := range rootList {
 		rootNode := rootList[k]
-		data.ChartClassifyItemsMakeTree(this.SysUser, classifyAll, rootNode, permissionClassifyIdList)
+		data.ChartClassifyItemsMakeTree(this.SysUser, classifyAll, rootNode, permissionClassifyIdList, level)
 		nodeAll = append(nodeAll, rootNode)
 	}
 
@@ -395,7 +396,7 @@ func (this *ChartClassifyController) EditChartClassify() {
 	}
 
 	// 编辑图表分类
-	_, err, errMsg, isSendEmail := data.EditChartClassify(req.ChartClassifyId, utils.CHART_SOURCE_DEFAULT, req.ChartClassifyName, this.Lang, this.SysUser)
+	_, err, errMsg, isSendEmail := data.EditChartClassifyV2(req.ChartClassifyId, req.ParentId, utils.CHART_SOURCE_DEFAULT, req.ChartClassifyName, this.Lang)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = "保存分类失败,Err:" + err.Error()
@@ -1034,3 +1035,105 @@ func (this *ChartClassifyController) ChartClassifyChartListV2() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+// ChartClassifyChartListV3
+// @Title 根据图表分类获取图表列表-包含分类和图表
+// @Description 根据图表分类获取图表列表接口-包含分类和图表
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Param   ChartClassifyId   query   bool  true       "图片分类id"
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /chart_classify/chart/listV2 [get]
+func (this *ChartClassifyController) ChartClassifyChartListV3() {
+	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
+	}
+
+	resp := new(data_manage.ChartClassifyListResp)
+
+	chartClassifyId, _ := this.GetInt("ChartClassifyId")
+	if chartClassifyId < 0 {
+		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() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range confList {
+			noPermissionChartIdMap[v.ChartInfoId] = true
+		}
+	}
+
+	isShowMe, _ := this.GetBool("IsShowMe")
+	if isShowMe {
+		allChartInfo, err := data_manage.GetChartClassifyAndInfoByParentIdForMe(chartClassifyId, sysUser.AdminId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取数据失败,Err:" + err.Error()
+			return
+		}
+		// 移除没有权限的图表
+		allNodes := data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap, this.SysUser.AdminId)
+		resp.AllNodes = allNodes
+
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = resp
+		fmt.Println("source my classify")
+		return
+	}
+
+	allChartInfo, err := data_manage.GetChartClassifyAndInfoByParentId(chartClassifyId)
+	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)
+
+	for k, item := range allNodes {
+		item.Button = data.GetChartOpButton(this.SysUser, item.SysUserId, item.HaveOperaAuth)
+		if item.ChartInfoId > 0 {
+			item.Button.AddButton = false
+			item.Button.OpButton = false
+			item.Button.DeleteButton = false
+			item.Button.MoveButton = true
+		} else if item.Level == 6 {
+			item.Button.AddButton = false
+		}
+		allNodes[k] = item
+	}
+
+	resp.AllNodes = allNodes
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 123 - 1
controllers/data_manage/chart_common.go

@@ -11,10 +11,12 @@ import (
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/excel"
 	"eta/eta_api/utils"
 	"fmt"
+	"strings"
 	"time"
 )
 
@@ -83,6 +85,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_DEFAULT:
 		resp, isOk, msg, errMsg := GetChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -94,6 +108,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_FUTURE_GOOD:
 		resp, isOk, msg, errMsg := future_good.GetChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -105,6 +131,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_FUTURE_GOOD_PROFIT:
 		resp, isOk, msg, errMsg := future_good.GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -116,6 +154,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_CORRELATION, utils.CHART_SOURCE_ROLLING_CORRELATION:
 		resp, isOk, msg, errMsg := correlation.GetChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -127,6 +177,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_LINE_EQUATION:
 		resp, isOk, msg, errMsg := line_equation.GetChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -138,6 +200,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY:
 		resp, isOk, msg, errMsg := line_feature.GetChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -149,6 +223,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_CROSS_HEDGING:
 		resp, isOk, msg, errMsg := cross_variety.GetChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -160,6 +246,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_BALANCE_EXCEL:
 		resp, isOk, msg, errMsg := getBalanceChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -171,6 +269,18 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 	case utils.CHART_SOURCE_RANGE_ANALYSIS:
 		resp, isOk, msg, errMsg := range_analysis.GetChartInfoDetailFromUniqueCode(chartInfo, isCache, sysUser)
 		if !isOk {
+			if strings.Contains(errMsg, utils.ErrNoRow()) {
+				endInfoList := make([]*data_manage.ChartEdbInfoMapping, 0)
+				resp.EdbInfoList = endInfoList
+				resp.ChartInfo = chartInfo
+				resp.Status = false
+
+				br.Data = resp
+				br.Ret = 200
+				br.Success = true
+				br.Msg = "获取成功"
+				return
+			}
 			br.Msg = msg
 			br.ErrMsg = errMsg
 			return
@@ -188,7 +298,19 @@ func (this *ChartInfoController) CommonChartInfoDetailFromUniqueCode() {
 
 func getBalanceChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCache bool, sysUser *system.Admin) (resp *data_manage.ChartInfoDetailFromUniqueCodeResp, isOk bool, msg, errMsg string) {
 	resp = new(data_manage.ChartInfoDetailFromUniqueCodeResp)
-
+	defer func() {
+		if !isOk {
+			if errMsg != "" {
+				uniqueCode := ""
+				if chartInfo != nil {
+					uniqueCode = chartInfo.UniqueCode
+				}
+				tmpTip := fmt.Sprintf("查询图表详情失败,getBalanceChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
+				utils.FileLog.Info(tmpTip)
+				go alarm_msg.SendAlarmMsg(tmpTip, 3)
+			}
+		}
+	}()
 	resp, isOk, msg, errMsg = data.CheckBalanceChartCacheAndPermission(chartInfo, isCache, sysUser)
 	if isOk {
 		return

+ 499 - 8
controllers/data_manage/chart_info.go

@@ -8,6 +8,7 @@ import (
 	"eta/eta_api/models/data_manage/response"
 	"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/data_manage_permission"
 	"eta/eta_api/services/data/excel"
@@ -18,6 +19,7 @@ import (
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"os"
 	"os/exec"
+	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -81,12 +83,6 @@ func (this *ChartInfoController) ChartInfoSave() {
 	//	return
 	//}
 
-	if chartItem.ChartType == 2 && len(req.ChartEdbInfoList) > 1 {
-		br.Msg = "您选择的图表样式为季节性图表,只支持单指标画图!"
-		br.ErrMsg = "您选择的图表样式为季节性图表,只支持单指标画图,Data:" + string(this.Ctx.Input.RequestBody)
-		return
-	}
-
 	if req.Calendar == "" {
 		req.Calendar = "公历"
 	}
@@ -959,7 +955,6 @@ func (this *ChartInfoController) ChartInfoDetail() {
 	var err error
 	chartInfo := new(data_manage.ChartInfoView)
 	chartInfo.HaveOperaAuth = true
-
 	if chartInfoId > 0 {
 		chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
 		if err != nil {
@@ -1184,6 +1179,26 @@ func (this *ChartInfoController) ChartInfoDetail() {
 		IsSetName: chartInfo.IsSetName,
 	}
 
+	// 图表当前分类的分类树
+	classifyLevels := make([]string, 0)
+	{
+		list, e := data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_DEFAULT)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", e)
+			return
+		}
+		parents := data.GetChartClassifyParentRecursive(list, chartInfo.ChartClassifyId)
+		sort.Slice(parents, func(i, j int) bool {
+			return parents[i].Level < parents[i].Level
+		})
+		for _, v := range parents {
+			classifyLevels = append(classifyLevels, v.UniqueCode)
+		}
+	}
+
+	resp.ClassifyLevels = classifyLevels
+
 	resp.ChartInfo = chartInfo
 	resp.BarChartInfo = barConfig
 	br.Ret = 200
@@ -1508,7 +1523,6 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 	}
 
 	resp := new(data_manage.ChartInfoDetailResp)
-
 	// 图表数据权限
 	{
 		// 图表分类
@@ -1722,6 +1736,26 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 		resp.EdbInfoList = mappingList
 	}
 
+	// 图表当前分类的分类树
+	classifyLevels := make([]string, 0)
+	{
+		list, e := data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_DEFAULT)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", e)
+			return
+		}
+		parents := data.GetChartClassifyParentRecursive(list, chartInfo.ChartClassifyId)
+		sort.Slice(parents, func(i, j int) bool {
+			return parents[i].Level < parents[i].Level
+		})
+		for _, v := range parents {
+			classifyLevels = append(classifyLevels, v.UniqueCode)
+		}
+	}
+
+	resp.ClassifyLevels = classifyLevels
+	
 	//图表操作权限
 	chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId, chartInfo.HaveOperaAuth)
 	chartInfo.Button = data_manage.ChartViewButton{
@@ -2641,6 +2675,12 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				}
 			}
 		}
+		if !isOk {
+			if errMsg != "" {
+				utils.FileLog.Info("查询图表详情失败,GetChartInfoDetailFromUniqueCode err:" + errMsg)
+				go alarm_msg.SendAlarmMsg("查询图表详情失败,GetChartInfoDetailFromUniqueCode,errmsg:"+errMsg, 3)
+			}
+		}
 	}()
 
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取
@@ -4522,3 +4562,454 @@ func (this *ChartInfoController) ChartInfoImgSetBySvg() {
 	br.Data = resp
 	return
 }
+
+// @Title ETA图表列表接口
+// @Description ETA图表列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ChartClassifyId   query   int  true       "分类id"
+// @Param   KeyWord   query   string  true       "搜索关键词"
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Success 200 {object} data_manage.ChartListResp
+// @router /chart/list [get]
+func (this *ChartInfoController) ChartList() {
+	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
+	}
+
+	subClassify, _ := this.GetBool("SubClassify")
+
+	chartClassifyIdsStr := this.GetString("ChartClassifyIds")
+	chartClassifyIds := strings.Split(chartClassifyIdsStr, ",")
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	keyWord := this.GetString("KeyWord")
+	sysUserIds := this.GetString("SysUserIds")
+	chartTypeIds := this.GetString("ChartTypeIds")
+
+	var total int
+	page := paging.GetPaging(currentIndex, pageSize, total)
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+
+	// 普通图表
+	condition += ` AND source = ? `
+	pars = append(pars, utils.CHART_SOURCE_DEFAULT)
+
+	if len(chartClassifyIdsStr) > 0 {
+		if !subClassify {
+			chartClassifyId, err := data_manage.GetChartClassifyByIdsNoSubClassify(chartClassifyIds)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取图表信息失败"
+				br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
+				return
+			}
+			condition += " AND chart_classify_id IN(" + chartClassifyId + ") "
+			//pars = append(pars, chartClassifyId)
+		} else {
+			//chartClassifyId, err := data_manage.GetChartClassifyByIds(chartClassifyIds)
+			//if err != nil && err.Error() != utils.ErrNoRow() {
+			//	br.Msg = "获取图表信息失败"
+			//	br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
+			//	return
+			//}
+			//condition += " AND chart_classify_id IN(" + chartClassifyId + ") "
+			//pars = append(pars, chartClassifyId)
+
+			list, e := data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_DEFAULT)
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", e)
+				return
+			}
+			finalClassifyIds := make([]int, 0)
+			parents := data.GetChartClassifyChildrenRecursiveByParentIds(list, chartClassifyIds)
+			sort.Slice(parents, func(i, j int) bool {
+				return parents[i].Level < parents[i].Level
+			})
+			for _, v := range parents {
+				finalClassifyIds = append(finalClassifyIds, v.ChartClassifyId)
+			}
+
+			condition += " AND chart_classify_id IN(" + utils.GetOrmInReplace(len(finalClassifyIds)) + ") "
+			pars = append(pars, finalClassifyIds)
+		}
+	}
+	if keyWord != "" {
+		condition += ` AND  ( chart_name LIKE '%` + keyWord + `%' OR chart_name_en LIKE '%` + keyWord + `%' )`
+	}
+	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)
+	}
+	if chartTypeIds != "" {
+		chartTypeIdList := strings.Split(chartTypeIds, ",")
+		condition += "  AND chart_type in (" + utils.GetOrmInReplace(len(chartTypeIdList)) + ") "
+		pars = append(pars, chartTypeIdList)
+	}
+
+	//只看我的
+	//isShowMe, _ := this.GetBool("IsShowMe")
+	//if isShowMe {
+	//	condition += ` AND sys_user_id = ? `
+	//	pars = append(pars, sysUser.AdminId)
+	//}
+
+	// 获取当前账号的不可见指标
+	noPermissionChartIdList := make([]int, 0)
+	{
+		obj := data_manage.EdbInfoNoPermissionAdmin{}
+		confList, err := obj.GetAllChartListByAdminId(this.SysUser.AdminId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range confList {
+			noPermissionChartIdList = append(noPermissionChartIdList, v.ChartInfoId)
+		}
+	}
+
+	lenNoPermissionChartIdList := len(noPermissionChartIdList)
+	if lenNoPermissionChartIdList > 0 {
+		condition += ` AND chart_info_id not in (` + utils.GetOrmInReplace(lenNoPermissionChartIdList) + `) `
+		pars = append(pars, noPermissionChartIdList)
+	}
+
+	//获取图表信息
+	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		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() {
+		br.Msg = "获取图表信息失败"
+		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
+		return
+	}
+	myChartMap := make(map[int]*data_manage.MyChartView)
+	for _, v := range myChartList {
+		myChartMap[v.ChartInfoId] = v
+	}
+	listLen := len(list)
+	chartEdbMap := make(map[int][]*data_manage.ChartEdbInfoMapping)
+	if listLen > 0 {
+		// 分类id
+		classifyIdList := make([]int, 0)
+		// 当前列表中的分类map
+		classifyMap := make(map[int]*data_manage.ChartClassify)
+		for _, v := range list {
+			classifyIdList = append(classifyIdList, v.ChartClassifyId)
+		}
+		classifyList, err := data_manage.GetChartClassifyByIdList(classifyIdList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取分类列表失败,Err:" + err.Error()
+			return
+		}
+
+		for _, v := range classifyList {
+			classifyMap[v.ChartClassifyId] = v
+		}
+
+		// 已授权分类id
+		permissionChartIdList, permissionClassifyIdList, err := data_manage_permission.GetUserChartAndClassifyPermissionList(this.SysUser.AdminId, 0, 0)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取已授权分类id数据失败,Err:" + err.Error()
+			return
+		}
+
+		// 权限
+		for k, chartViewInfo := range list {
+			if currClassify, ok := classifyMap[chartViewInfo.ChartClassifyId]; ok {
+				list[k].HaveOperaAuth = data_manage_permission.CheckChartPermissionByPermissionIdList(chartViewInfo.IsJoinPermission, currClassify.IsJoinPermission, chartViewInfo.ChartInfoId, chartViewInfo.ChartClassifyId, permissionChartIdList, permissionClassifyIdList)
+			}
+		}
+
+		chartInfoIds := ""
+		for _, v := range list {
+			chartInfoIds += strconv.Itoa(v.ChartInfoId) + ","
+		}
+		if chartInfoIds != "" {
+			chartInfoIds = strings.Trim(chartInfoIds, ",")
+			//判断是否需要展示英文标识
+			edbList, e := data_manage.GetChartEdbMappingListByChartInfoIds(chartInfoIds)
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取图表,指标信息失败,Err:" + e.Error()
+				return
+			}
+			for _, v := range edbList {
+				chartEdbMap[v.ChartInfoId] = append(chartEdbMap[v.ChartInfoId], v)
+			}
+		}
+	}
+
+	listTmp, err := data_manage.GetChartTypeList()
+	if err != nil {
+		br.Msg = "获取图表类型失败"
+		br.ErrMsg = "获取图表类型失败,Err:" + err.Error()
+		return
+	}
+	//遍历list,将id和name组成map
+	chartTypeMap := make(map[int]data_manage.ChartType)
+	for _, v := range listTmp {
+		chartTypeMap[v.ChartTypeId] = v
+	}
+
+	for i := 0; i < listLen; i++ {
+		//判断是否需要展示英文标识
+		if edbTmpList, ok := chartEdbMap[list[i].ChartInfoId]; ok {
+			list[i].IsEnChart = data.CheckIsEnChart(list[i].ChartNameEn, edbTmpList, list[i].Source, list[i].ChartType)
+		}
+
+		if existItem, ok := myChartMap[list[i].ChartInfoId]; ok {
+			list[i].IsAdd = true
+			list[i].MyChartId = existItem.MyChartId
+			list[i].MyChartClassifyId = existItem.MyChartClassifyId
+		}
+		list[i].ChartTypeName = chartTypeMap[list[i].ChartType].ChartTypeName
+		list[i].ChartTypeNameEn = chartTypeMap[list[i].ChartType].ChartTypeNameEn
+	}
+
+	resp := new(data_manage.ChartListResp)
+	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+		items := make([]*data_manage.ChartInfoView, 0)
+		resp.Paging = page
+		resp.List = items
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+
+	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
+		return
+	}
+	page = paging.GetPaging(currentIndex, pageSize, dataCount)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ModifyChartList
+// @Title 批量修改图表
+// @Description 批量修改图表
+// @Param   SysUserIds   query   string  true       "根据创建人查询"
+// @Param   ChartClassifyIds   query   string  true       "图片分类id"
+// @Success 200 {object} models.ChartClassifyListResp
+// @router /modify/chartList [post]
+func (this *ChartInfoController) ModifyChartList() {
+	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.ModifyChartListReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if !req.SelectAll && req.ChartInfoIds == "" {
+		br.Msg = "请选择图表"
+		return
+	}
+	if req.ChartClassifyId < 0 {
+		br.Msg = "请选择新分类"
+		return
+	}
+
+	var chartIds []int
+
+	if req.SelectAll {
+		//根据查询条件筛选
+		chartClassifyIds := strings.Split(req.ChartClassifyIds, ",")
+		sysUserIds := req.SysUserIds
+		keyword := req.KeyWord
+		chartTypeIdsStr := req.ChartTypeIds
+
+		condition := " AND source = ? "
+		pars := make([]interface{}, 0)
+		pars = append(pars, utils.CHART_SOURCE_DEFAULT)
+
+		if len(chartClassifyIds) > 0 {
+			if !req.SubClassify {
+				chartClassifyId, err := data_manage.GetChartClassifyByIdsNoSubClassify(chartClassifyIds)
+				if err != nil && err.Error() != utils.ErrNoRow() {
+					br.Msg = "获取图表信息失败"
+					br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
+					return
+				}
+				condition += " AND chart_classify_id IN(" + chartClassifyId + ") "
+				//pars = append(pars, chartClassifyId)
+			} else {
+				//chartClassifyId, err := data_manage.GetChartClassifyByIds(chartClassifyIds)
+				//if err != nil && err.Error() != utils.ErrNoRow() {
+				//	br.Msg = "获取图表信息失败"
+				//	br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
+				//	return
+				//}
+				//condition += " AND chart_classify_id IN(" + chartClassifyId + ") "
+				//pars = append(pars, chartClassifyId)
+
+				list, e := data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_DEFAULT)
+				if e != nil {
+					br.Msg = "获取失败"
+					br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", e)
+					return
+				}
+				finalClassifyIds := make([]int, 0)
+				parents := data.GetChartClassifyChildrenRecursiveByParentIds(list, chartClassifyIds)
+				sort.Slice(parents, func(i, j int) bool {
+					return parents[i].Level < parents[i].Level
+				})
+				for _, v := range parents {
+					finalClassifyIds = append(finalClassifyIds, v.ChartClassifyId)
+				}
+
+				condition += " AND chart_classify_id IN(" + utils.GetOrmInReplace(len(finalClassifyIds)) + ") "
+				pars = append(pars, finalClassifyIds)
+			}
+		}
+
+		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)
+		}
+
+		if keyword != "" {
+			condition = " AND chart_name LIKE ? "
+			pars = append(pars, utils.GetLikeKeyword(keyword))
+		}
+
+		if chartTypeIdsStr != "" {
+			chartTypeIds := strings.Split(chartTypeIdsStr, ",")
+			if len(chartTypeIds) == 0 {
+				br.Msg = "请选择正确的图表类型"
+				return
+			}
+			condition += " AND chart_type IN(" + utils.GetOrmInReplace(len(chartTypeIds)) + ") "
+			pars = append(pars, chartTypeIds)
+		}
+
+		allChartInfo, err := data_manage.GetChartInfoItemsByCondition(condition, pars)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+			return
+		}
+		// 判断是否超过100 个
+		if len(allChartInfo) > 100 {
+			br.Msg = "最多只能选择100个图表"
+			return
+		}
+		for _, v := range allChartInfo {
+			chartIds = append(chartIds, v.ChartInfoId)
+		}
+	} else {
+		chartIdStr := strings.Split(req.ChartInfoIds, ",")
+		if len(chartIdStr) == 0 {
+			br.Msg = "请选择正确的图表"
+			return
+		}
+		for _, id := range chartIdStr {
+			tmp, e := strconv.Atoi(id)
+			if e != nil {
+				br.Msg = "请选择正确的分类"
+				return
+			}
+			chartIds = append(chartIds, tmp)
+		}
+		// 判断是否超过100 个
+		if len(chartIds) > 100 {
+			br.Msg = "最多只能选择100个图表"
+			return
+		}
+	}
+
+	if len(chartIds) == 0 {
+		br.Msg = "请选择正确的图表"
+		return
+	}
+
+	err = data_manage.UpdateChartClassifyIdByChartInfoId(chartIds, req.ChartClassifyId)
+	if err != nil {
+		br.Msg = "更新失败"
+		br.ErrMsg = "更新图表分类失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 12 - 5
controllers/data_manage/correlation/correlation_chart_info.go

@@ -7,6 +7,7 @@ import (
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/data_manage/correlation/request"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	correlationServ "eta/eta_api/services/data/correlation"
 	"eta/eta_api/services/data/data_manage_permission"
@@ -1012,11 +1013,6 @@ func (this *CorrelationChartInfoController) DetailFromUniqueCode() {
 		br.ErrMsg = errMsg
 		return
 	}
-	if !isOk {
-		br.Msg = msg
-		br.ErrMsg = errMsg
-		return
-	}
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "获取成功"
@@ -1563,6 +1559,17 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				}
 			}
 		}
+		if !isOk {
+			if errMsg != "" {
+				uniqueCode := ""
+				if chartInfo != nil {
+					uniqueCode = chartInfo.UniqueCode
+				}
+				tmpTip := fmt.Sprintf("查询图表详情失败,correlation.GetChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
+				utils.FileLog.Info(tmpTip)
+				go alarm_msg.SendAlarmMsg(tmpTip, 3)
+			}
+		}
 	}()
 
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取

+ 12 - 0
controllers/data_manage/cross_variety/chart_info.go

@@ -9,6 +9,7 @@ import (
 	"eta/eta_api/models/data_manage/cross_variety/request"
 	"eta/eta_api/models/data_manage/cross_variety/response"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/cross_variety"
 	"eta/eta_api/services/data/data_manage_permission"
@@ -1609,6 +1610,17 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				}
 			}
 		}
+		if !isOk {
+			if errMsg != "" {
+				uniqueCode := ""
+				if chartInfo != nil {
+					uniqueCode = chartInfo.UniqueCode
+				}
+				tmpTip := fmt.Sprintf("查询图表详情失败,cross_variety.GetChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
+				utils.FileLog.Info(tmpTip)
+				go alarm_msg.SendAlarmMsg(tmpTip, 3)
+			}
+		}
 	}()
 
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取

+ 27 - 46
controllers/data_manage/edb_info.go

@@ -85,9 +85,18 @@ func (this *EdbInfoController) EdbInfoSearch() {
 	//判断指标是否存在
 	var item *data_manage.EdbInfo
 	var err error
-	if source == utils.DATA_SOURCE_GL {
-		// 如果是钢联的话,那么就先判断是不是存在钢联化工
-		item, err = data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_MYSTEEL_CHEMICAL, edbCode)
+	if utils.InArrayByInt([]int{utils.DATA_SOURCE_GL, utils.DATA_SOURCE_MYSTEEL_CHEMICAL}, source) {
+		//source = utils.DATA_SOURCE_MYSTEEL_CHEMICAL
+		source, item, err = data.GetMySteelSourceByEdbCode(edbCode)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	if item == nil {
+		item, err = data_manage.GetEdbInfoByEdbCode(source, edbCode)
 		if err != nil {
 			if err.Error() != utils.ErrNoRow() {
 				br.Msg = "获取失败"
@@ -95,50 +104,8 @@ func (this *EdbInfoController) EdbInfoSearch() {
 				return
 			}
 		}
-		err = nil
-		if item != nil {
-			source = utils.DATA_SOURCE_MYSTEEL_CHEMICAL
-		} else {
-			// 判断是不是已经在钢联这边已经存在了
-			item, err = data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_GL, edbCode)
-			if err != nil {
-				if err.Error() != utils.ErrNoRow() {
-					br.Msg = "获取失败"
-					br.ErrMsg = "获取失败,Err:" + err.Error()
-					return
-				}
-			}
-			err = nil
-
-			// 如果在钢联来源也没找到,那么就需要再判断下是否处于 《钢联化工》 数据源里面
-			if item == nil {
-				tmpInfo, err := data_manage.GetBaseFromMysteelChemicalIndexByCode(edbCode)
-				if err != nil {
-					if err.Error() != utils.ErrNoRow() {
-						br.Msg = "获取失败"
-						br.ErrMsg = "获取失败,Err:" + err.Error()
-						return
-					}
-				}
-				err = nil
-				if tmpInfo != nil {
-					source = utils.DATA_SOURCE_MYSTEEL_CHEMICAL
-				}
-			}
-
-		}
 	}
 
-	if item == nil {
-		item, err = data_manage.GetEdbInfoByEdbCode(source, edbCode)
-	}
-	if err != nil {
-		if err.Error() != utils.ErrNoRow() {
-			br.Msg = "获取失败"
-			br.ErrMsg = "获取失败,Err:" + err.Error()
-			return
-		}
-	}
 	var isAdd bool
 	var isInEdb bool //是否在指标库中
 	if item != nil && item.EdbInfoId > 0 {
@@ -2435,7 +2402,7 @@ func (this *EdbInfoController) EdbInfoAdd() {
 	//}
 
 	// 兼容钢联与钢联化工数据
-	if source == utils.DATA_SOURCE_GL {
+	if utils.InArrayByInt([]int{utils.DATA_SOURCE_GL, utils.DATA_SOURCE_MYSTEEL_CHEMICAL}, source) {
 		// 如果是钢联的话,那么就先判断是不是存在钢联化工
 		tmpInfo, err := data_manage.GetBaseFromMysteelChemicalIndexByCode(req.EdbCode)
 		if err != nil {
@@ -2448,6 +2415,9 @@ func (this *EdbInfoController) EdbInfoAdd() {
 		if tmpInfo != nil {
 			source = utils.DATA_SOURCE_MYSTEEL_CHEMICAL
 			req.Source = utils.DATA_SOURCE_MYSTEEL_CHEMICAL
+		} else {
+			source = utils.DATA_SOURCE_GL
+			req.Source = utils.DATA_SOURCE_GL
 		}
 	}
 
@@ -4142,6 +4112,17 @@ func (this *EdbInfoController) RelationChartList() {
 			chartIdMap[v.ChartInfoId] = true
 		}
 	}
+	// 查询相关性的图表
+	correlationChart := new(data_manage.ChartInfoCorrelation)
+	correlationChartId, err := correlationChart.GetChartInfoIdByEdb(edbInfoId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取图表信息失败"
+		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		return
+	}
+	if correlationChartId > 0 {
+		chartIdMap[correlationChartId] = true
+	}
 	// 查询跨品种的图表
 	tagXList, err := cross_variety.GetChartInfoCrossVarietyByXEdbInfoId(edbInfoId)
 	if err != nil && err.Error() != utils.ErrNoRow() {

+ 2 - 1
controllers/data_manage/excel/excel_info.go

@@ -1782,8 +1782,9 @@ func (c *ExcelInfoController) Calculate() {
 		br.ErrMsg = "计算失败, Err: " + e.Error()
 		return
 	}
-	calVal := utils.FormatTableDataShowValue(calFloat)
 
+	calFloat, _ = decimal.NewFromFloat(calFloat).Round(4).Float64()
+	calVal := utils.FormatMixTableDataShowValue(calFloat)
 	//calVal := calResult.String()
 	//if err != nil {
 	//	br.Msg = "计算失败"

+ 12 - 0
controllers/data_manage/future_good/future_good_chart_info.go

@@ -9,6 +9,7 @@ import (
 	"eta/eta_api/models/data_manage/future_good/request"
 	"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/data_manage_permission"
 	future_goodServ "eta/eta_api/services/data/future_good"
@@ -1615,6 +1616,17 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				}
 			}
 		}
+		if !isOk {
+			if errMsg != "" {
+				uniqueCode := ""
+				if chartInfo != nil {
+					uniqueCode = chartInfo.UniqueCode
+				}
+				tmpTip := fmt.Sprintf("查询图表详情失败,future_good.GetChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
+				utils.FileLog.Info(tmpTip)
+				go alarm_msg.SendAlarmMsg(tmpTip, 3)
+			}
+		}
 	}()
 
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取

+ 12 - 0
controllers/data_manage/future_good/future_good_profit_chart_info.go

@@ -8,6 +8,7 @@ import (
 	"eta/eta_api/models/data_manage/future_good/request"
 	"eta/eta_api/models/data_manage/future_good/response"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
 	future_goodServ "eta/eta_api/services/data/future_good"
@@ -1260,6 +1261,17 @@ func GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo *data_manage.Cha
 				}
 			}
 		}
+		if !isOk {
+			if errMsg != "" {
+				uniqueCode := ""
+				if chartInfo != nil {
+					uniqueCode = chartInfo.UniqueCode
+				}
+				tmpTip := fmt.Sprintf("查询图表详情失败,future_good.GetFutureGoodProfitChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
+				utils.FileLog.Info(tmpTip)
+				go alarm_msg.SendAlarmMsg(tmpTip, 3)
+			}
+		}
 	}()
 
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取

+ 12 - 0
controllers/data_manage/line_equation/line_chart_info.go

@@ -8,6 +8,7 @@ import (
 	"eta/eta_api/models/data_manage/line_equation/request"
 	"eta/eta_api/models/data_manage/line_equation/response"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
 	"eta/eta_api/services/data/line_equation"
@@ -1291,6 +1292,17 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				}
 			}
 		}
+		if !isOk {
+			if errMsg != "" {
+				uniqueCode := ""
+				if chartInfo != nil {
+					uniqueCode = chartInfo.UniqueCode
+				}
+				tmpTip := fmt.Sprintf("查询图表详情失败,line_equation.GetChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
+				utils.FileLog.Info(tmpTip)
+				go alarm_msg.SendAlarmMsg(tmpTip, 3)
+			}
+		}
 	}()
 
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取

+ 12 - 0
controllers/data_manage/line_feature/chart_info.go

@@ -9,6 +9,7 @@ import (
 	"eta/eta_api/models/data_manage/line_feature/request"
 	"eta/eta_api/models/data_manage/line_feature/response"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
 	lineFeatureServ "eta/eta_api/services/data/line_feature"
@@ -2388,6 +2389,17 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				}
 			}
 		}
+		if !isOk {
+			if errMsg != "" {
+				uniqueCode := ""
+				if chartInfo != nil {
+					uniqueCode = chartInfo.UniqueCode
+				}
+				tmpTip := fmt.Sprintf("查询图表详情失败,line_feature.GetChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
+				utils.FileLog.Info(tmpTip)
+				go alarm_msg.SendAlarmMsg(tmpTip, 3)
+			}
+		}
 	}()
 
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取

+ 8 - 2
controllers/data_manage/manual_edb.go

@@ -10,12 +10,13 @@ import (
 	etaTrialService "eta/eta_api/services/eta_trial"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
-	"github.com/shopspring/decimal"
 	"os"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/shopspring/decimal"
 )
 
 // ManualEdbController 手工指标服务(鉴权)
@@ -585,6 +586,11 @@ func (c *ManualEdbController) EditExcelData() {
 	dateValueMap := make(map[string]string)
 	//取到所有数据
 	for _, dateValue := range req.Data {
+		// 检验时间格式
+		_, err := time.Parse(utils.FormatDate, dateValue.Date)
+		if err != nil {
+			continue
+		}
 		dateValueMap[dateValue.Date] = strconv.FormatFloat(dateValue.Value, 'f', -1, 64)
 	}
 

+ 23 - 6
controllers/data_manage/my_chart.go

@@ -11,6 +11,7 @@ import (
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
+	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -69,15 +70,31 @@ func (this *MyChartController) ChartList() {
 	condition += ` AND source = ? `
 	pars = append(pars, utils.CHART_SOURCE_DEFAULT)
 
+	chartClassifyIds := make([]int, 0)
 	if chartClassifyId > 0 {
-		chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
-		if err != nil && err.Error() != utils.ErrNoRow() {
-			br.Msg = "获取图表信息失败"
-			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
+
+		list, e := data_manage.GetChartClassifyAllBySource(utils.CHART_SOURCE_DEFAULT)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = fmt.Sprintf("获取图表分类失败, Err: %v", e)
 			return
 		}
-		condition += " AND chart_classify_id IN(" + chartClassifyId + ") "
-		//pars = append(pars, chartClassifyId)
+		parents := data.GetChartClassifyChildrenRecursive(list, 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)) + ") "
+		pars = append(pars, chartClassifyIds)
 	}
 	if keyWord != "" {
 		condition += ` AND  ( chart_name LIKE '%` + keyWord + `%' OR chart_name_en LIKE '%` + keyWord + `%' )`

+ 58 - 73
controllers/data_manage/mysteel_chemical_data.go

@@ -666,23 +666,20 @@ func (this *EdbClassifyController) MysteelChemicalExport() {
 	}
 
 	var frequencies []string
+	frequencieSet := make(map[string]struct{})
 	frequencyList, err := data_manage.GetMysteelChemicalFrequency(condition, pars)
-	for _, v := range frequencyList {
-		frequencies = append(frequencies, v.Frequency)
+	if err != nil {
+		br.Msg = "获取频度失败"
+		br.ErrMsg = "获取频度失败,Err:" + err.Error()
+		return
 	}
-
-	fileName := `钢联化工数据`
-	if frequencies == nil {
-		sheet, err := xlsxFile.AddSheet("无数据")
-		if err != nil {
-			br.Msg = "新增Sheet失败"
-			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
-			return
+	for _, v := range frequencyList {
+		if _, ok := frequencieSet[v.Frequency]; !ok {
+			frequencies = append(frequencies, v.Frequency)
+			frequencieSet[v.Frequency] = struct{}{}
 		}
-		rowSecName := sheet.AddRow()
-		celSecName := rowSecName.AddCell()
-		celSecName.SetValue("")
 	}
+	secNameList := make([]*data_manage.MysteelChemicalList, 0)
 	for _, frequency := range frequencies {
 		//获取指标
 		var tmpCondition string
@@ -706,7 +703,7 @@ func (this *EdbClassifyController) MysteelChemicalExport() {
 			pars = utils.GetLikeKeywordPars(pars, keyword, 2)
 		}
 		//获取指标
-		secNameList, err := data_manage.GetMysteelChemicalIndex(tmpCondition, tmpPars)
+		secNameList, err = data_manage.GetMysteelChemicalIndex(tmpCondition, tmpPars)
 		if err != nil {
 			fmt.Println("获取数据失败,Err:" + err.Error())
 			return
@@ -730,14 +727,31 @@ func (this *EdbClassifyController) MysteelChemicalExport() {
 		frequencyRow := sheetNew.AddRow()
 		unitRow := sheetNew.AddRow()
 		lastModifyDateRow := sheetNew.AddRow()
-		//获取分类下指标最大数据量
-		dataMax, err := data_manage.GetBaseFromMysteelChemicalDataMaxCount(classifyId)
+
+		var indexIdList []int
+		for _, sv := range secNameList {
+			indexIdList = append(indexIdList, sv.Id)
+		}
+		dataTimeList, err := data_manage.GetBaseFromMysteelChemicalDataTimeByIndexId(indexIdList)
 		if err != nil {
-			fmt.Println("获取指标最大数据量失败", err.Error())
+			fmt.Println("获取数据时间失败", err.Error())
 			return
 		}
-		fmt.Println("dataMax:", dataMax)
+
+		//获取分类下指标最大数据量
 		setRowIndex := 6
+		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.GetMysteelChemicalIndexDataByCode(sv.IndexCode)
@@ -746,7 +760,7 @@ func (this *EdbClassifyController) MysteelChemicalExport() {
 				br.ErrMsg = "获取数据失败,Err:" + err.Error()
 				return
 			}
-			if len(dataList) > 0 {
+			if k == 0 {
 				windRow.AddCell().SetValue("钢联")
 				secNameRow.AddCell().SetValue("指标名称")
 				indexCodeRow.AddCell().SetValue("指标ID")
@@ -754,58 +768,29 @@ func (this *EdbClassifyController) MysteelChemicalExport() {
 				unitRow.AddCell().SetValue("单位")
 				lastModifyDateRow.AddCell().SetValue("更新时间")
 
-				secNameRow.AddCell().SetValue(sv.IndexName)
-				indexCodeRow.AddCell().SetValue(sv.IndexCode)
-				frequencyRow.AddCell().SetValue(sv.FrequencyName)
-
-				unitRow.AddCell().SetValue(sv.UnitName)
-				lastModifyDateRow.AddCell().SetValue(sv.UpdateTime)
-
-				windRow.AddCell()
-				windRow.AddCell()
-				secNameRow.AddCell()
-				indexCodeRow.AddCell()
-				frequencyRow.AddCell()
-				unitRow.AddCell()
-				lastModifyDateRow.AddCell()
-				min := k * 3
-				sheetNew.SetColWidth(min, min, 15)
-
-				if len(dataList) <= 0 {
-					for n := 0; n < dataMax; n++ {
-						rowIndex := setRowIndex + n
-						row := sheetNew.Row(rowIndex)
-						row.AddCell()
-						row.AddCell()
-						row.AddCell()
-					}
-				} else {
-					endRowIndex := 0
-					for rk, dv := range dataList {
-						rowIndex := setRowIndex + rk
-						row := sheetNew.Row(rowIndex)
-						displayDate, _ := time.Parse(utils.FormatDate, dv.DataTime)
-						displayDateCell := row.AddCell()
-						style := new(xlsx.Style)
-						style.ApplyAlignment = true
-						style.Alignment.WrapText = true
-						displayDateCell.SetStyle(style)
-						displayDateCell.SetDate(displayDate)
-
-						row.AddCell().SetValue(dv.InputValue)
-						row.AddCell()
-						endRowIndex = rowIndex
-					}
-					if len(dataList) < dataMax {
-						dataLen := dataMax - len(dataList)
-						for n := 0; n < dataLen; n++ {
-							rowIndex := (endRowIndex + 1) + n
-							row := sheetNew.Row(rowIndex)
-							row.AddCell()
-							row.AddCell()
-							row.AddCell()
-						}
-					}
+			}
+			if len(dataList) == 0 {
+				continue
+
+			}
+			secNameRow.AddCell().SetValue(sv.IndexName)
+			indexCodeRow.AddCell().SetValue(sv.IndexCode)
+			frequencyRow.AddCell().SetValue(sv.FrequencyName)
+			unitRow.AddCell().SetValue(sv.UnitName)
+			lastModifyDateRow.AddCell().SetValue(sv.UpdateTime)
+
+			dataInfoMap := make(map[string]*data_manage.MysteelChemicalData)
+			for _, dv := range dataList {
+				dataInfoMap[dv.DataTime] = dv
+			}
+
+			for rk, dtv := range dataTimeList {
+				rowIndex := setRowIndex + rk
+				row := sheetNew.Row(rowIndex)
+				displayDateCell := row.AddCell()
+				tmpData, ok := dataInfoMap[dtv]
+				if ok {
+					displayDateCell.SetValue(tmpData.InputValue)
 				}
 			}
 		}
@@ -830,7 +815,7 @@ func (this *EdbClassifyController) MysteelChemicalExport() {
 			return
 		}
 	}
-
+	fileName := "上海钢联"
 	fileName += time.Now().Format("06.01.02") + `.xlsx` //文件名称
 	this.Ctx.Output.Download(downLoadnFilePath, fileName)
 	defer func() {
@@ -1699,7 +1684,7 @@ func (c *EdbInfoController) AddCheck() {
 		br.Ret = 408
 		return
 	}
-	var req *data_manage.MysteelChemicalDataBatchAddCheckReq
+	var req *data_manage.BatchAddCheckReq
 	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
 		br.Msg = "参数解析异常!"
 		br.ErrMsg = "参数解析失败,Err:" + e.Error()

+ 211 - 106
controllers/data_manage/predict_edb_info.go

@@ -285,119 +285,31 @@ func (this *PredictEdbInfoController) List() {
 		br.ErrMsg = "查找预测指标关联信息失败"
 		return
 	}
-	if edbInfoItem.EdbType == 1 { //普通的预测指标
-		// 查找该预测指标配置
-		predictEdbConfList, err := data_manage.GetPredictEdbConfListById(edbInfoId)
+
+	//获取指标数据(实际已生成)
+	{
+		dataCount, dataList, err := data.GetPageData(edbInfoItem.EdbInfoId, edbInfoItem.Source, edbInfoItem.SubSource, edbInfoItem.LatestDate, startSize, pageSize)
 		if err != nil && err.Error() != utils.ErrNoRow() {
-			br.Msg = "获取失败"
-			br.ErrMsg = "获取预测指标配置信息失败,Err:" + err.Error()
+			br.Msg = "获取指标信息失败"
+			br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
 			return
 		}
-		if len(predictEdbConfList) == 0 {
-			br.Msg = "找不到该预测指标配置"
-			br.ErrMsg = "找不到该预测指标配置"
-			return
-		}
-		predictEdbConf := predictEdbConfList[0]
-
-		//预测数据的配置
-		edbInfoItem.RuleType = predictEdbConf.RuleType
-		edbInfoItem.FixedValue = predictEdbConf.FixedValue
+		page = paging.GetPaging(currentIndex, pageSize, dataCount)
+		edbInfoItem.DataList = dataList
+	}
 
-		// 来源指标
-		//sourceEdbInfoId := sourceEdbInfoCalculateMappingList[0].FromEdbInfoId
-		sourceEdbInfoId := predictEdbConf.SourceEdbInfoId
-		sourceEdbInfoItem, err := data_manage.GetEdbInfoById(sourceEdbInfoId)
+	// 第一页才需要 获取预测指标未来的数据
+	if currentIndex == 1 {
+		predictDataList, err = data_manage.GetAllEdbDataListData(edbInfoItem.EdbInfoId, edbInfoItem.Source, edbInfoItem.SubSource, edbInfoItem.LatestDate)
 		if err != nil {
-			br.Msg = "获取来源指标信息失败"
-			br.ErrMsg = "获取来源指标信息失败"
-			if err.Error() != utils.ErrNoRow() {
-				br.ErrMsg = "获取来源指标信息失败,Err:" + err.Error()
-			}
-			br.Success = true
+			br.Msg = "获取指标信息失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
 			return
 		}
-
-		//获取指标数据(实际已生成)
-		{
-			dataCount, dataList, err := data.GetPageData(sourceEdbInfoItem.EdbInfoId, sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, "", startSize, pageSize)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				br.Msg = "获取指标信息失败"
-				br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
-				return
-			}
-			page = paging.GetPaging(currentIndex, pageSize, dataCount)
-			edbInfoItem.DataList = dataList
-		}
-
-		// 第一页才需要 获取预测指标未来的数据
-		if currentIndex == 1 {
-			allDataList, err := data_manage.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, "", "")
-			if err != nil {
-				br.Msg = "获取失败"
-				br.Msg = "获取失败,Err:" + err.Error()
-				return
-			}
-			predictEdbConfDataList := make([]data_manage.PredictEdbConfAndData, 0)
-			for _, v := range predictEdbConfList {
-				predictEdbConfDataList = append(predictEdbConfDataList, data_manage.PredictEdbConfAndData{
-					ConfigId:         v.ConfigId,
-					PredictEdbInfoId: v.PredictEdbInfoId,
-					SourceEdbInfoId:  v.SourceEdbInfoId,
-					RuleType:         v.RuleType,
-					FixedValue:       v.FixedValue,
-					Value:            v.Value,
-					EndDate:          v.EndDate,
-					ModifyTime:       v.ModifyTime,
-					CreateTime:       v.CreateTime,
-					DataList:         make([]*data_manage.EdbDataList, 0),
-				})
-			}
-			tmpPredictDataList, _, _, err, _ := data.GetChartPredictEdbInfoDataListByConfList(predictEdbConfDataList, sourceEdbInfoItem.LatestDate, sourceEdbInfoItem.LatestDate, edbInfoItem.EndDate, sourceEdbInfoItem.Frequency, edbInfoItem.DataDateType, allDataList)
-			if err != nil {
-				br.Msg = "获取预测指标数据失败"
-				br.ErrMsg = "获取预测指标数据失败" + err.Error()
-				return
-			}
-			lenTmpPredictDataList := len(tmpPredictDataList)
-			if lenTmpPredictDataList > 0 {
-				for i := lenTmpPredictDataList - 1; i >= 0; i-- {
-					v := tmpPredictDataList[i]
-					predictDataList = append(predictDataList, &data_manage.EdbData{
-						EdbDataId: v.EdbDataId,
-						EdbInfoId: v.EdbInfoId,
-						DataTime:  v.DataTime,
-						Value:     v.Value,
-					})
-				}
-			}
-		}
-	} else {
-		//获取指标数据(实际已生成)
-		{
-			dataCount, dataList, err := data.GetPageData(edbInfoItem.EdbInfoId, edbInfoItem.Source, edbInfoItem.SubSource, edbInfoItem.LatestDate, startSize, pageSize)
-			if err != nil && err.Error() != utils.ErrNoRow() {
-				br.Msg = "获取指标信息失败"
-				br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
-				return
-			}
-			page = paging.GetPaging(currentIndex, pageSize, dataCount)
-			edbInfoItem.DataList = dataList
-		}
-
-		// 第一页才需要 获取预测指标未来的数据
-		if currentIndex == 1 {
-			predictDataList, err = data_manage.GetAllEdbDataListData(edbInfoItem.EdbInfoId, edbInfoItem.Source, edbInfoItem.SubSource, edbInfoItem.LatestDate)
-			if err != nil {
-				br.Msg = "获取指标信息失败"
-				br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
-				return
-			}
-			if err != nil {
-				br.Msg = "获取预测指标数据失败"
-				br.ErrMsg = "获取预测指标数据失败" + err.Error()
-				return
-			}
+		if err != nil {
+			br.Msg = "获取预测指标数据失败"
+			br.ErrMsg = "获取预测指标数据失败" + err.Error()
+			return
 		}
 	}
 
@@ -956,6 +868,26 @@ func (this *PredictEdbInfoController) Detail() {
 			if len(tmpPredictEdbConfCalculateMappingDetail) <= 0 {
 				tmpPredictEdbConfCalculateMappingDetail = make([]*data_manage.PredictEdbConfCalculateMappingDetail, 0)
 			}
+			if v.RuleType == 16 {
+				if !strings.Contains(v.Value, "YearList") {
+					// 解析json串,加入YearList字段重新生成json字符串
+					var tmpValue *data.AnnualValueInversionConf
+					err = json.Unmarshal([]byte(v.Value), &tmpValue)
+					if err != nil {
+						br.Msg = "获取失败"
+						br.ErrMsg = "获取预测指标配置与关联指标信息失败,Err:" + err.Error()
+						return
+					}
+					tmpValue.YearList = append(tmpValue.YearList, tmpValue.Year)
+					tmpValueByte, err := json.Marshal(tmpValue)
+					if err != nil {
+						br.Msg = "获取失败"
+						br.ErrMsg = "获取预测指标配置与关联指标信息失败,Err:" + err.Error()
+						return
+					}
+					v.Value = string(tmpValueByte)
+				}
+			}
 			tmp := data_manage.PredictEdbConfDetail{
 				ConfigId:         v.ConfigId,
 				PredictEdbInfoId: v.PredictEdbInfoId,
@@ -2184,3 +2116,176 @@ func (this *PredictEdbInfoController) ChartImageSetBySvg() {
 	br.Success = true
 	br.Msg = "保存成功"
 }
+
+// AddStaticEdb
+// @Title 新增静态指标接口
+// @Description 新增静态指标接口
+// @Param	request	body request.AddPredictEdbInfoReq true "type json string"
+// @Success 200 {object} response.AddEdbInfoResp
+// @router /predict_edb_info/static_edb/add [post]
+func (this *PredictEdbInfoController) AddStaticEdb() {
+	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 request.AddStaticPredictEdbInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	sourceEdbInfoId := req.SourceEdbInfoId
+	if sourceEdbInfoId <= 0 {
+		br.Msg = "请选择来源指标"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.EdbName == "" {
+		br.Msg = "指标名称不能为空"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.Frequency == "" {
+		br.Msg = "请选择频度"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.Unit == "" {
+		br.Msg = "请选择单位"
+		br.IsSendEmail = false
+		return
+	}
+
+	//传入操作人
+	req.AdminId = sysUser.AdminId
+	req.AdminName = sysUser.RealName
+	// 添加计算指标
+	reqJson, err := json.Marshal(req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	respItem, err := data.SavePredictStaticEdbData(string(reqJson), this.Lang)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	if respItem.Ret != 200 {
+		br.Msg = respItem.Msg
+		br.ErrMsg = respItem.ErrMsg
+		return
+	}
+	resp := respItem.Data
+
+	//添加es
+	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+	br.IsAddLog = true
+}
+
+// EdbInfoBaseEdit
+// @Title 指标基础信息编辑接口
+// @Description 指标基础信息编辑接口
+// @Success 200 {object} data_manage.EditEdbInfoReq
+// @router /predict_edb_info/base/edit [post]
+func (this *PredictEdbInfoController) EdbInfoBaseEdit() {
+	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.EditEdbInfoReq
+	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, " ")
+
+	if req.EdbInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "指标id小于等于0"
+		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
+	}
+
+	isSendEmail, err, errMsg := data.EditBaseEdbInfo(req, this.SysUser, this.Lang, string(this.Ctx.Input.RequestBody), this.Ctx.Input.URI())
+	if err != nil {
+		br.Msg = errMsg
+		br.ErrMsg = err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.IsAddLog = true
+}

+ 12 - 0
controllers/data_manage/range_analysis/chart_info.go

@@ -7,6 +7,7 @@ import (
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/data_manage/chart_theme"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
 	rangeServ "eta/eta_api/services/data/range_analysis"
@@ -731,6 +732,17 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 				}
 			}
 		}
+		if !isOk {
+			if errMsg != "" {
+				uniqueCode := ""
+				if chartInfo != nil {
+					uniqueCode = chartInfo.UniqueCode
+				}
+				tmpTip := fmt.Sprintf("查询图表详情失败,range_analysis.GetChartInfoDetailFromUniqueCode UniqueCode:%s,err:%s", uniqueCode, errMsg)
+				utils.FileLog.Info(tmpTip)
+				go alarm_msg.SendAlarmMsg(tmpTip, 3)
+			}
+		}
 	}()
 
 	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取

文件差异内容过多而无法显示
+ 807 - 102
controllers/data_manage/yongyi_data.go


+ 6 - 1
controllers/document_manage/document_manage_controller.go

@@ -193,6 +193,11 @@ func (this *DocumentManageController) RuiSiReportList() {
 	classifyIdFirst, _ := this.GetInt("ClassifyIdFirst", 0)
 	classifyIdSecond, _ := this.GetInt("ClassifyIdSecond", 0)
 	classifyIdThird, _ := this.GetInt("ClassifyIdThird", 0)
+	chartPermissionIdString := this.GetString("ChartPermissionIdList")
+	var chartPermissionIdList []string
+	if strings.TrimSpace(chartPermissionIdString) != "" {
+		chartPermissionIdList = strings.Split(chartPermissionIdString, ",")
+	}
 
 	keyword := this.GetString("Keyword")
 	orderField := this.GetString("OrderField")
@@ -206,7 +211,7 @@ func (this *DocumentManageController) RuiSiReportList() {
 	if currentIndex <= 0 {
 		currentIndex = 1
 	}
-	RuiSiReportPage, err := document_manage_service.RuiSiReportList(classifyIdFirst, classifyIdSecond, classifyIdThird, keyword, orderField, orderType, currentIndex, pageSize)
+	RuiSiReportPage, err := document_manage_service.RuiSiReportList(classifyIdFirst, classifyIdSecond, classifyIdThird, chartPermissionIdList, keyword, orderField, orderType, currentIndex, pageSize)
 	if err != nil {
 		br.Msg = "获取报告列表失败"
 		br.ErrMsg = "获取报告列表失败,Err:" + err.Error()

+ 118 - 33
controllers/report_approve/report_approve.go

@@ -8,11 +8,12 @@ import (
 	"eta/eta_api/services"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"sort"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // ReportApproveController 报告审批
@@ -29,6 +30,7 @@ type ReportApproveController struct {
 // @Param   ReportType			query   int     false	"报告类型:1-中文研报;2-英文研报;3-智能研报"
 // @Param   ClassifyIdFirst		query	int		false	"一级分类ID"
 // @Param   ClassifyIdSecond	query	int		false	"二级分类ID"
+// @Param   ClassifyIdThird		query	int		false	"三级级分类ID"
 // @Param   Keyword				query	string	false	"搜索关键词"
 // @Param   ApproveState		query	int		false	"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"
 // @Param   TimeType			query	int		false	"时间类型:1-提交时间;2-处理时间;3-审批时间"
@@ -114,9 +116,21 @@ func (this *ReportApproveController) List() {
 		order := ""
 
 		// 筛选条件
-		if params.ReportType > 0 && params.ClassifySecondId > 0 {
-			cond += fmt.Sprintf(` AND b.%s = ? AND b.%s = ?`, report_approve.ReportApproveCols.ReportType, report_approve.ReportApproveCols.ClassifySecondId)
-			pars = append(pars, params.ReportType, params.ClassifySecondId)
+		if params.ReportType > 0 {
+			cond += fmt.Sprintf(` AND b.%s = ?`, report_approve.ReportApproveCols.ReportType)
+			pars = append(pars, params.ReportType)
+		}
+		if params.ClassifyFirstId > 0 {
+			cond += fmt.Sprintf(` AND b.%s = ?`, report_approve.ReportApproveCols.ClassifyFirstId)
+			pars = append(pars, params.ClassifyFirstId)
+		}
+		if params.ClassifySecondId > 0 {
+			cond += fmt.Sprintf(` AND b.%s = ?`, report_approve.ReportApproveCols.ClassifySecondId)
+			pars = append(pars, params.ClassifySecondId)
+		}
+		if params.ClassifyThirdId > 0 {
+			cond += fmt.Sprintf(` AND b.%s = ?`, report_approve.ReportApproveCols.ClassifyThirdId)
+			pars = append(pars, params.ClassifyThirdId)
 		}
 		if params.TimeType <= 0 {
 			params.TimeType = 1
@@ -180,9 +194,21 @@ func (this *ReportApproveController) List() {
 		order := ""
 
 		// 筛选条件
-		if params.ReportType > 0 && params.ClassifySecondId > 0 {
-			cond += fmt.Sprintf(` AND b.%s = ? AND b.%s = ?`, report_approve.ReportApproveCols.ReportType, report_approve.ReportApproveCols.ClassifySecondId)
-			pars = append(pars, params.ReportType, params.ClassifySecondId)
+		if params.ReportType > 0 {
+			cond += fmt.Sprintf(` AND b.%s = ?`, report_approve.ReportApproveCols.ReportType)
+			pars = append(pars, params.ReportType)
+		}
+		if params.ClassifyFirstId > 0 {
+			cond += fmt.Sprintf(` AND b.%s = ?`, report_approve.ReportApproveCols.ClassifyFirstId)
+			pars = append(pars, params.ClassifyFirstId)
+		}
+		if params.ClassifySecondId > 0 {
+			cond += fmt.Sprintf(` AND b.%s = ?`, report_approve.ReportApproveCols.ClassifySecondId)
+			pars = append(pars, params.ClassifySecondId)
+		}
+		if params.ClassifyThirdId > 0 {
+			cond += fmt.Sprintf(` AND b.%s = ?`, report_approve.ReportApproveCols.ClassifyThirdId)
+			pars = append(pars, params.ClassifyThirdId)
 		}
 		if params.TimeType > 0 && params.StartTime != "" && params.EndTime != "" {
 			_, e := time.Parse(utils.FormatDate, params.StartTime)
@@ -253,10 +279,23 @@ func (this *ReportApproveController) List() {
 		order := ""
 
 		// 筛选条件
-		if params.ReportType > 0 && params.ClassifySecondId > 0 {
-			cond += fmt.Sprintf(` AND a.%s = ? AND a.%s = ?`, report_approve.ReportApproveCols.ReportType, report_approve.ReportApproveCols.ClassifySecondId)
-			pars = append(pars, params.ReportType, params.ClassifySecondId)
+		if params.ReportType > 0 {
+			cond += fmt.Sprintf(` AND a.%s = ?`, report_approve.ReportApproveCols.ReportType)
+			pars = append(pars, params.ReportType)
+		}
+		if params.ClassifyFirstId > 0 {
+			cond += fmt.Sprintf(` AND a.%s = ?`, report_approve.ReportApproveCols.ClassifyFirstId)
+			pars = append(pars, params.ClassifyFirstId)
+		}
+		if params.ClassifySecondId > 0 {
+			cond += fmt.Sprintf(` AND a.%s = ?`, report_approve.ReportApproveCols.ClassifySecondId)
+			pars = append(pars, params.ClassifySecondId)
 		}
+		if params.ClassifyThirdId > 0 {
+			cond += fmt.Sprintf(` AND a.%s = ?`, report_approve.ReportApproveCols.ClassifyThirdId)
+			pars = append(pars, params.ClassifyThirdId)
+		}
+
 		if params.TimeType > 0 && params.StartTime != "" && params.EndTime != "" {
 			_, e := time.Parse(utils.FormatDate, params.StartTime)
 			if e != nil {
@@ -365,17 +404,36 @@ func (this *ReportApproveController) List() {
 	for _, v := range ormList {
 		t := report_approve.FormatReportApproveOrm2Item(v)
 		if v.ReportType == report_approve.FlowReportTypeEnglish {
-			t.ReportClassify = fmt.Sprintf("%s/%s/%s/%s", report_approve.FlowReportTypeMap[v.ReportType], enClassifyIdName[enRootIdMap[v.ClassifySecondId]], enClassifyIdName[v.ClassifyFirstId], enClassifyIdName[v.ClassifySecondId])
+			var classifyPath []string
+			if v.ReportType > 0 {
+				classifyPath = append(classifyPath, report_approve.FlowReportTypeMap[v.ReportType])
+			}
+			if v.ClassifyFirstId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[v.ClassifyFirstId])
+			}
+			if v.ClassifySecondId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[v.ClassifySecondId])
+			}
+			if v.ClassifyThirdId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[v.ClassifyThirdId])
+			}
+			t.ReportClassify = strings.Join(classifyPath, "/")
 		} else {
 			//t.ReportClassify = fmt.Sprintf("%s/%s/%s", report_approve.FlowReportTypeMap[v.ReportType], cnClassifyIdName[v.ClassifyFirstId], cnClassifyIdName[v.ClassifySecondId])
-			reportClassify := fmt.Sprintf("%s/%s", report_approve.FlowReportTypeMap[v.ReportType], cnClassifyIdName[v.ClassifyFirstId])
+			var classifyPath []string
+			if v.ReportType > 0 {
+				classifyPath = append(classifyPath, report_approve.FlowReportTypeMap[v.ReportType])
+			}
+			if v.ClassifyFirstId > 0 {
+				classifyPath = append(classifyPath, cnClassifyIdName[v.ClassifyFirstId])
+			}
 			if v.ClassifySecondId > 0 {
-				reportClassify = fmt.Sprintf("%s/%s", reportClassify, cnClassifyIdName[v.ClassifySecondId])
+				classifyPath = append(classifyPath, cnClassifyIdName[v.ClassifySecondId])
 			}
 			if v.ClassifyThirdId > 0 {
-				reportClassify = fmt.Sprintf("%s/%s", reportClassify, cnClassifyIdName[v.ClassifyThirdId])
+				classifyPath = append(classifyPath, cnClassifyIdName[v.ClassifyThirdId])
 			}
-			t.ReportClassify = reportClassify
+			t.ReportClassify = strings.Join(classifyPath, "/")
 		}
 
 		k := fmt.Sprintf("%d-%d", t.ReportType, t.ReportId)
@@ -568,26 +626,53 @@ func (this *ReportApproveController) Detail() {
 	detail.Report.ReportLayout = 1
 
 	// 报告分类路由
-	if approveItem.ReportType == report_approve.FlowReportTypeChinese {
-		reportInfo, e := models.GetReportLayoutByReportId(approveItem.ReportId)
-		if e != nil {
-			br.Msg = "获取失败"
-			br.ErrMsg = "获取报告失败, Err: " + e.Error()
-			return
+	{
+		if approveItem.ReportType == report_approve.FlowReportTypeChinese {
+			reportInfo, e := models.GetReportLayoutByReportId(approveItem.ReportId)
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取报告失败, Err: " + e.Error()
+				return
+			}
+			detail.Report.ReportLayout = reportInfo.ReportLayout
+
+			detail.Report.ReportCode = utils.MD5(strconv.Itoa(approveItem.ReportId))
+		}
+		if approveItem.ReportType == report_approve.FlowReportTypeEnglish {
+			detail.Report.ReportCode = utils.MD5(strconv.Itoa(approveItem.ReportId))
+		}
+		if approveItem.ReportType == report_approve.FlowReportTypeSmart {
+			detail.Report.ReportLayout = 2
+			detail.Report.ReportCode = utils.MD5(fmt.Sprint("smart_", approveItem.ReportId))
 		}
-		detail.Report.ReportLayout = reportInfo.ReportLayout
 
-		detail.Report.ReportCode = utils.MD5(strconv.Itoa(approveItem.ReportId))
-		detail.Report.ReportClassify = fmt.Sprintf("%s/%s/%s", report_approve.FlowReportTypeMap[approveItem.ReportType], cnClassifyIdName[approveItem.ClassifyFirstId], cnClassifyIdName[approveItem.ClassifySecondId])
-	}
-	if approveItem.ReportType == report_approve.FlowReportTypeEnglish {
-		detail.Report.ReportCode = utils.MD5(strconv.Itoa(approveItem.ReportId))
-		detail.Report.ReportClassify = fmt.Sprintf("%s/%s/%s/%s", report_approve.FlowReportTypeMap[approveItem.ReportType], enClassifyIdName[enRootIdMap[approveItem.ClassifySecondId]], enClassifyIdName[approveItem.ClassifyFirstId], enClassifyIdName[approveItem.ClassifySecondId])
-	}
-	if approveItem.ReportType == report_approve.FlowReportTypeSmart {
-		detail.Report.ReportLayout = 2
-		detail.Report.ReportCode = utils.MD5(fmt.Sprint("smart_", approveItem.ReportId))
-		detail.Report.ReportClassify = fmt.Sprintf("%s/%s/%s", report_approve.FlowReportTypeMap[approveItem.ReportType], cnClassifyIdName[approveItem.ClassifyFirstId], cnClassifyIdName[approveItem.ClassifySecondId])
+		var classifyPath []string
+		if approveItem.ReportType > 0 {
+			classifyPath = append(classifyPath, report_approve.FlowReportTypeMap[approveItem.ReportType])
+		}
+		if approveItem.ReportType == report_approve.FlowReportTypeEnglish {
+			if approveItem.ClassifyFirstId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[approveItem.ClassifyFirstId])
+			}
+			if approveItem.ClassifySecondId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[approveItem.ClassifySecondId])
+			}
+			if approveItem.ClassifyThirdId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[approveItem.ClassifyThirdId])
+			}
+			detail.Report.ReportClassify = strings.Join(classifyPath, "/")
+		} else {
+			if approveItem.ClassifyFirstId > 0 {
+				classifyPath = append(classifyPath, cnClassifyIdName[approveItem.ClassifyFirstId])
+			}
+			if approveItem.ClassifySecondId > 0 {
+				classifyPath = append(classifyPath, cnClassifyIdName[approveItem.ClassifySecondId])
+			}
+			if approveItem.ClassifyThirdId > 0 {
+				classifyPath = append(classifyPath, cnClassifyIdName[approveItem.ClassifyThirdId])
+			}
+			detail.Report.ReportClassify = strings.Join(classifyPath, "/")
+		}
 	}
 
 	br.Data = detail

+ 38 - 10
controllers/report_approve/report_approve_flow.go

@@ -8,10 +8,11 @@ import (
 	"eta/eta_api/services"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"strings"
 	"sync"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // ReportApproveFlowController 报告审批流
@@ -66,13 +67,21 @@ func (this *ReportApproveFlowController) List() {
 			cond += fmt.Sprintf(` AND %s LIKE ?`, report_approve.ReportApproveFlowCols.FlowName)
 			pars = append(pars, kw)
 		}
-		if params.ReportType > 0 && params.ClassifySecondId > 0 {
-			cond += fmt.Sprintf(` AND %s = ? AND %s = ?`, report_approve.ReportApproveFlowCols.ReportType, report_approve.ReportApproveFlowCols.ClassifySecondId)
-			pars = append(pars, params.ReportType, params.ClassifySecondId)
+		if params.ReportType > 0 {
+			cond += fmt.Sprintf(` AND %s = ? `, report_approve.ReportApproveFlowCols.ReportType)
+			pars = append(pars, params.ReportType)
+		}
+		if params.ClassifyFirstId > 0 {
+			cond += fmt.Sprintf(` AND %s = ? `, report_approve.ReportApproveFlowCols.ClassifyFirstId)
+			pars = append(pars, params.ClassifyFirstId)
+		}
+		if params.ClassifySecondId > 0 {
+			cond += fmt.Sprintf(` AND %s = ?`, report_approve.ReportApproveFlowCols.ClassifySecondId)
+			pars = append(pars, params.ClassifySecondId)
 		}
 		if params.ClassifyThirdId > 0 {
 			cond += fmt.Sprintf(` AND %s = ? `, report_approve.ReportApproveFlowCols.ClassifyThirdId)
-			pars = append(pars, params.ReportType, params.ClassifyThirdId)
+			pars = append(pars, params.ClassifyThirdId)
 		}
 		if params.SortRule > 0 {
 			orderMap := map[int]string{1: "ASC", 2: "DESC"}
@@ -141,16 +150,35 @@ func (this *ReportApproveFlowController) List() {
 	for _, v := range list {
 		t := report_approve.FormatReportApproveFlow2Item(v)
 		if v.ReportType == report_approve.FlowReportTypeEnglish {
-			t.ReportClassify = fmt.Sprintf("%s/%s/%s/%s", report_approve.FlowReportTypeMap[v.ReportType], enClassifyIdName[enRootIdMap[v.ClassifySecondId]], enClassifyIdName[v.ClassifyFirstId], enClassifyIdName[v.ClassifySecondId])
+			var classifyPath []string
+			if v.ReportType > 0 {
+				classifyPath = append(classifyPath, report_approve.FlowReportTypeMap[v.ReportType])
+			}
+			if v.ClassifyFirstId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[v.ClassifyFirstId])
+			}
+			if v.ClassifySecondId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[v.ClassifySecondId])
+			}
+			if v.ClassifyThirdId > 0 {
+				classifyPath = append(classifyPath, enClassifyIdName[v.ClassifyThirdId])
+			}
+			t.ReportClassify = strings.Join(classifyPath, "/")
 		} else {
-			reportClassify := fmt.Sprintf("%s/%s", report_approve.FlowReportTypeMap[v.ReportType], cnClassifyIdName[v.ClassifyFirstId])
+			var classifyPath []string
+			if v.ReportType > 0 {
+				classifyPath = append(classifyPath, report_approve.FlowReportTypeMap[v.ReportType])
+			}
+			if v.ClassifyFirstId > 0 {
+				classifyPath = append(classifyPath, cnClassifyIdName[v.ClassifyFirstId])
+			}
 			if v.ClassifySecondId > 0 {
-				reportClassify = fmt.Sprintf("%s/%s", reportClassify, cnClassifyIdName[v.ClassifySecondId])
+				classifyPath = append(classifyPath, cnClassifyIdName[v.ClassifySecondId])
 			}
 			if v.ClassifyThirdId > 0 {
-				reportClassify = fmt.Sprintf("%s/%s", reportClassify, cnClassifyIdName[v.ClassifyThirdId])
+				classifyPath = append(classifyPath, cnClassifyIdName[v.ClassifyThirdId])
 			}
-			t.ReportClassify = reportClassify
+			t.ReportClassify = strings.Join(classifyPath, "/")
 		}
 		resp.List = append(resp.List, t)
 	}

+ 4 - 2
controllers/report_chapter.go

@@ -377,6 +377,7 @@ func (this *ReportController) EditDayWeekChapter() {
 	reportInfo.LastModifyAdminName = sysUser.RealName
 	reportInfo.ModifyTime = time.Now()
 
+	updateCols := make([]string, 0)
 	reqTickerList := req.TickerList
 	// 更新章节及指标
 	contentSub := ""
@@ -405,6 +406,7 @@ func (this *ReportController) EditDayWeekChapter() {
 
 	if req.Title != "" {
 		reportChapterInfo.Title = req.Title
+		updateCols = append(updateCols, "Title")
 	}
 	//reportChapterInfo.AddType = req.AddType
 	reportChapterInfo.Author = req.Author
@@ -414,6 +416,7 @@ func (this *ReportController) EditDayWeekChapter() {
 	reportChapterInfo.ModifyTime = time.Now()
 	if req.CreateTime != `` {
 		reportChapterInfo.CreateTime = req.CreateTime
+		updateCols = append(updateCols, "CreateTime")
 	}
 
 	reportChapterInfo.LastModifyAdminId = sysUser.AdminId
@@ -421,8 +424,7 @@ func (this *ReportController) EditDayWeekChapter() {
 	reportChapterInfo.ContentModifyTime = time.Now()
 	reportChapterInfo.ContentStruct = html.EscapeString(req.ContentStruct)
 
-	updateCols := make([]string, 0)
-	updateCols = append(updateCols, "Title", "AddType", "Author", "Content", "ContentSub", "IsEdit", "CreateTime", "ModifyTime")
+	updateCols = append(updateCols, "Author", "Content", "ContentSub", "IsEdit", "ModifyTime")
 
 	updateCols = append(updateCols, "LastModifyAdminId", "LastModifyAdminName", "ContentModifyTime", "ContentStruct")
 

+ 1 - 1
controllers/report_v2.go

@@ -886,7 +886,7 @@ func (this *ReportController) AuthorizedListReport() {
 	}
 	if classifyIdThird > 0 {
 		condition += ` AND a.classify_id_third = ? `
-		pars = append(pars, classifyIdSecond)
+		pars = append(pars, classifyIdThird)
 	}
 
 	if keyword != `` {

+ 8 - 0
controllers/resource.go

@@ -1040,7 +1040,15 @@ func (this *ResourceAuthController) FileDownload() {
 		return
 	}
 	fileName := fileArr[len(fileArr)-1]
+
 	//fmt.Println(fileName)
+	if utils.MinIoFileDownloadHost != "" {
+		fmt.Println("fileUrl replace before:" + fileUrl)
+
+		fileUrl = strings.Replace(fileUrl, utils.MinIoImghost, utils.MinIoFileDownloadHost, -1)
+
+		fmt.Println("fileUrl replace after:" + fileUrl)
+	}
 
 	// 获取文件
 	down, e := http.Get(fileUrl)

+ 26 - 18
controllers/target.go

@@ -767,34 +767,42 @@ func (this *TargetController) ClassifyList() {
 		return
 	}
 
-	classifyIdStrList := make([]string, 0)
+	classifyIdList := make([]int, 0)
 	for _, classifyList := range list {
 		if classifyList.Child != nil {
 			for _, classify := range classifyList.Child {
-				classifyIdStrList = append(classifyIdStrList, strconv.Itoa(classify.ClassifyId))
+				classifyIdList = append(classifyIdList, classify.ClassifyId)
 			}
 		}
 	}
-	if len(classifyIdStrList) > 0 {
-		edbInfoGroupCountList, err := models.GetEdbInfoGroupCountByClassifyIds(strings.Join(classifyIdStrList, ","))
-		if err != nil {
-			br.Msg = "获取失败"
-			br.ErrMsg = "获取分类下有数据的指标数量失败,Err:" + err.Error()
-			return
-		}
-
-		edbInfoGroupCountMap := make(map[int]int)
-		for _, edbInfoGroupCount := range edbInfoGroupCountList {
-			edbInfoGroupCountMap[edbInfoGroupCount.ClassifyId] = edbInfoGroupCount.Count
-		}
+	if len(classifyIdList) > 0 {
+		//edbInfoGroupCountList, err := models.GetEdbInfoGroupCountByClassifyIds(classifyIdList)
+		//if err != nil {
+		//	br.Msg = "获取失败"
+		//	br.ErrMsg = "获取分类下有数据的指标数量失败,Err:" + err.Error()
+		//	return
+		//}
+		//
+		//edbInfoGroupCountMap := make(map[int]int)
+		//for _, edbInfoGroupCount := range edbInfoGroupCountList {
+		//	edbInfoGroupCountMap[edbInfoGroupCount.ClassifyId] = edbInfoGroupCount.Count
+		//}
+		//for _, classifyList := range list {
+		//	classifyList.UniqueCode = utils.MD5(fmt.Sprint(classifyList.ClassifyId))
+		//	if classifyList.Child != nil {
+		//		for _, classify := range classifyList.Child {
+		//			if total, ok := edbInfoGroupCountMap[classify.ClassifyId]; ok {
+		//				classify.EdbInfoTotal = total
+		//				classify.UniqueCode = utils.MD5(fmt.Sprint(classify.ClassifyId))
+		//			}
+		//		}
+		//	}
+		//}
 		for _, classifyList := range list {
 			classifyList.UniqueCode = utils.MD5(fmt.Sprint(classifyList.ClassifyId))
 			if classifyList.Child != nil {
 				for _, classify := range classifyList.Child {
-					if total, ok := edbInfoGroupCountMap[classify.ClassifyId]; ok {
-						classify.EdbInfoTotal = total
-						classify.UniqueCode = utils.MD5(fmt.Sprint(classify.ClassifyId))
-					}
+					classify.UniqueCode = utils.MD5(fmt.Sprint(classify.ClassifyId))
 				}
 			}
 		}

+ 2 - 0
models/business_conf.go

@@ -50,6 +50,8 @@ const (
 	BusinessConfSmsJhgjVariable              = "SmsJhgjVariable"              // 聚合国际短信变量
 
 	BusinessConfEdbStopRefreshRule = "EdbStopRefreshRule" // 是否停止指标刷新规则
+	BusinessConfReport2ImgUrl      = "Report2ImgUrl"      // 报告转长图地址(用于兼容内外网环境的)
+	BusinessConfReportViewUrl      = "ReportViewUrl"      // 报告详情地址
 )
 
 const (

+ 59 - 5
models/data_manage/base_from_yongyi.go

@@ -2,9 +2,10 @@ package data_manage
 
 import (
 	"eta/eta_api/utils"
+	"time"
+
 	"github.com/beego/beego/v2/client/orm"
 	"github.com/rdlucklib/rdluck_tools/paging"
-	"time"
 )
 
 type BaseFromYongyiIndex struct {
@@ -23,6 +24,9 @@ type BaseFromYongyiIndexList struct {
 	YongyiIndexId int `orm:"column(yongyi_index_id);pk"`
 	ClassifyId    int
 	Interface     string
+	EdbInfoId     int
+	EdbUniqueCode string `description:"指标库唯一编码"`
+	EdbClassifyId int    `description:"指标库分类ID"`
 	IndexCode     string
 	IndexName     string
 	Frequency     string
@@ -30,6 +34,7 @@ type BaseFromYongyiIndexList struct {
 	Sort          int
 	CreateTime    string
 	ModifyTime    string
+	EdbExist      int `description:"指标库是否已添加:0-否;1-是"`
 	DataList      []*BaseFromYongyiData
 	Paging        *paging.PagingItem `description:"分页数据"`
 }
@@ -37,6 +42,7 @@ type BaseFromYongyiIndexList struct {
 type YongyiSingleDataResp struct {
 	YongyiIndexId int
 	ClassifyId    int
+	EdbInfoId     int
 	IndexCode     string
 	IndexName     string
 	Frequency     string
@@ -44,6 +50,7 @@ type YongyiSingleDataResp struct {
 	StartTime     string
 	CreateTime    string
 	ModifyTime    string
+	EdbExist      int `description:"指标库是否已添加:0-否;1-是"`
 	Data          []*YongyiSingleData
 }
 
@@ -52,6 +59,13 @@ type YongyiSingleData struct {
 	DataTime string `orm:"column(data_time)" description:"值"`
 }
 
+func GetYongyiIndexByClassifyId(classifyId int) (items []*BaseFromYongyiIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT yongyi_index_id, classify_id, index_code, index_name FROM base_from_yongyi_index WHERE classify_id=? ORDER BY sort ASC, yongyi_index_id ASC `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
 func GetYongyiIndex(condition string, pars interface{}) (items []*BaseFromYongyiIndexList, err error) {
 	o := orm.NewOrmUsingDB("data")
 	sql := ` SELECT * FROM base_from_yongyi_index WHERE 1=1  `
@@ -78,12 +92,51 @@ func GetYongyiIndexData(indexCode string, startSize, pageSize int) (items []*Bas
 }
 
 func GetYongyiIndexDataByCodes(indexCode []string) (items []*BaseFromYongyiData, err error) {
+	if len(indexCode) == 0 {
+		return
+	}
 	o := orm.NewOrmUsingDB("data")
 	sql := ` SELECT *  FROM base_from_yongyi_data WHERE index_code in (` + utils.GetOrmInReplace(len(indexCode)) + `) ORDER BY data_time DESC  `
 	_, err = o.Raw(sql, indexCode).QueryRows(&items)
 	return
 }
 
+// GetYongyiByConditionAndFrequency 根据条件获取涌益咨询指标列表
+func GetYongyiByConditionAndFrequency(condition, frequency string, pars []interface{}) (items []*BaseFromYongyiIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_yongyi_index WHERE 1=1 `
+
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` AND frequency=?`
+	sql += ` ORDER BY sort ASC, yongyi_index_id ASC`
+	_, err = o.Raw(sql, pars, frequency).QueryRows(&items)
+	return
+}
+
+func GetYongyiFrequencyByCondition(condition string, pars []interface{}) (items []string, err error) {
+	sql := `SELECT DISTINCT frequency FROM base_from_yongyi_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY FIELD(frequency,'日度','周度','旬度','月度','季度','半年度','年度') `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, pars...).QueryRows(&items)
+	return
+}
+
+// GetYongyiDataDataTimeByIndexId 根据指标id获取指标数据的日期列表
+func GetYongyiDataDataTimeByIndexId(indexIdList []int) (items []string, err error) {
+	if len(indexIdList) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT DISTINCT data_time FROM base_from_yongyi_data WHERE yongyi_index_id IN (` + utils.GetOrmInReplace(len(indexIdList)) + `) ORDER BY data_time DESC`
+	_, err = o.Raw(sql, indexIdList).QueryRows(&items)
+	return
+}
+
 type BaseFromYongyiData struct {
 	YongyiDataId  int `orm:"column(yongyi_data_id);pk"`
 	YongyiIndexId int
@@ -96,10 +149,11 @@ type BaseFromYongyiData struct {
 }
 
 type BaseFromYongyiIndexSearchItem struct {
-	YongyiIndexId int `orm:"column(yongyi_index_id);pk"`
-	ClassifyId    int
-	IndexCode     string
-	IndexName     string
+	YongyiIndexId    int `orm:"column(yongyi_index_id);pk"`
+	ClassifyId       int
+	ParentClassifyId int
+	IndexCode        string
+	IndexName        string
 }
 
 // GetYongyiItemList 模糊查询Yongyi数据库指标列表

+ 14 - 1
models/data_manage/base_from_yongyi_classify.go

@@ -3,8 +3,9 @@ package data_manage
 import (
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/beego/beego/v2/client/orm"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
 )
 
 // BaseFromYongyiClassify Yongyi原始数据分类表
@@ -43,6 +44,17 @@ func GetBaseFromYongyiClassifyById(classifyId int) (item *BaseFromYongyiClassify
 	return
 }
 
+// GetBaseFromYongyiClassifyById 通过分类id的获取分类信息
+func GetBaseFromYongyiClassifyByIds(classifyIds []int) (items []*BaseFromYongyiClassify, err error) {
+	if len(classifyIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM base_from_yongyi_classify WHERE classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) `
+	_, err = o.Raw(sql, classifyIds).QueryRows(&items)
+	return
+}
+
 // EditBaseFromYongyiClassify 修改Yongyi原始数据分类
 func EditBaseFromYongyiClassify(classifyId int, classifyName string) (err error) {
 	o := orm.NewOrmUsingDB("data")
@@ -64,6 +76,7 @@ type BaseFromYongyiClassifyItems struct {
 	YongyiIndexId   int    `description:"指标类型ID"`
 	YongyiIndexCode string `description:"指标唯一编码"`
 	ClassifyName    string `description:"分类名称"`
+	UniqueCode      string `description:"分类唯一编码"`
 	ParentId        int    `description:"父级id"`
 	Level           int    `description:"层级"`
 	Sort            int    `description:"排序字段,越小越靠前,默认值:10"`

+ 122 - 0
models/data_manage/chart_classify.go

@@ -77,6 +77,7 @@ func GetChartClassifyEnCount(chartClassifyNameEn string, parentId, source int) (
 type EditChartClassifyReq struct {
 	ChartClassifyName string `description:"分类名称"`
 	ChartClassifyId   int    `description:"分类id"`
+	ParentId          int    `description:"父级分类id"`
 }
 
 func GetChartClassifyById(classifyId int) (item *ChartClassify, err error) {
@@ -206,6 +207,7 @@ type ChartClassifyItems struct {
 	Button              ChartClassifyItemsButton `description:"按钮权限"`
 	IsJoinPermission    int                      `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
 	HaveOperaAuth       bool                     `description:"是否有数据权限,默认:false"`
+	Disable             bool                     `description:"勾选是否禁用"`
 }
 
 // ChartClassifyItemsButton 操作按钮
@@ -463,3 +465,123 @@ func GetChartClassifyAllBySource(source int) (items []*ChartClassifyItems, err e
 	_, err = o.Raw(sql, source).QueryRows(&items)
 	return
 }
+
+// GetChartClassifyAndInfoByParentId
+func GetChartClassifyAndInfoByParentId(parentId int) (items []*ChartClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT
+	0 AS chart_info_id,
+	chart_classify_id,
+	chart_classify_name,
+	chart_classify_name_en,
+	parent_id,
+	create_time,
+	modify_time,
+	sys_user_id,
+	sys_user_real_name,
+	sort,
+	level,
+	unique_code,
+	source,
+	0 as date_type,
+	'' as start_date,
+	'' as end_date,
+	0 as chart_type,
+	'' as calendar,
+	'' as season_start_date,
+	'' as season_end_date
+FROM
+	chart_classify 
+WHERE
+	parent_id = ? and source = 1 UNION ALL
+SELECT
+	chart_info_id,
+	chart_classify_id,
+	chart_name AS chart_classify_name,
+	chart_name_en AS chart_classify_name_en,
+	0 AS parent_id,
+	create_time,
+	modify_time,
+	sys_user_id,
+	sys_user_real_name,
+	sort,
+	0 AS level,
+	unique_code,
+	source,
+	date_type,
+	start_date,
+	end_date,
+	chart_type,
+	calendar,
+	season_start_date,
+	season_end_date
+FROM
+	chart_info 
+WHERE
+	chart_classify_id = ? AND source = 1
+ORDER BY
+	sort ASC,
+	chart_classify_id ASC`
+	_, err = o.Raw(sql, parentId, parentId).QueryRows(&items)
+	return
+}
+
+// GetChartClassifyAndInfoByParentId
+func GetChartClassifyAndInfoByParentIdForMe(parentId, adminId int) (items []*ChartClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT
+	0 AS chart_info_id,
+	chart_classify_id,
+	chart_classify_name,
+	chart_classify_name_en,
+	parent_id,
+	create_time,
+	modify_time,
+	sys_user_id,
+	sys_user_real_name,
+	sort,
+	level,
+	unique_code
+FROM
+	chart_classify 
+WHERE
+	parent_id = ? and source = 1 UNION ALL
+SELECT
+	chart_info_id,
+	chart_classify_id,
+	chart_name AS chart_classify_name,
+	chart_name_en AS chart_classify_name_en,
+	0 AS parent_id,
+	create_time,
+	modify_time,
+	sys_user_id,
+	sys_user_real_name,
+	sort,
+	0 AS level,
+	unique_code
+FROM
+	chart_info 
+WHERE
+	chart_classify_id = ? AND chart_type = 1 AND sys_user_id = ?
+ORDER BY
+	sort ASC,
+	chart_classify_id ASC`
+	_, err = o.Raw(sql, parentId, parentId, adminId).QueryRows(&items)
+	return
+}
+
+func GetChartClassifiesById(chartClassifyId int) (items []*ChartClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `
+    SELECT *
+    FROM chart_classify
+    WHERE chart_classify_id = ? 
+    OR parent_id = ?
+    OR parent_id IN (
+        SELECT chart_classify_id
+        FROM chart_classify
+        WHERE parent_id = ?
+    );`
+	_,err = o.Raw(sql, chartClassifyId, chartClassifyId, chartClassifyId).QueryRows(&items)
+	return
+}

+ 32 - 0
models/data_manage/chart_info.go

@@ -1970,6 +1970,8 @@ type ChartInfoView struct {
 	ForumChartInfoId  int             `description:"社区的图表ID"`
 	ChartAlias        string          `description:"图表别名"`
 	DateTypeNum       int             `description:"date_type=25(N月前)时的N值,其他类型N值可复用此字段"`
+	ChartTypeName     string          `description:"图表类型名称"`
+	ChartTypeNameEn   string          `description:"英文图表类型名称"`
 }
 
 type ChartViewButton struct {
@@ -2880,3 +2882,33 @@ func getThsHfEdbDataListMinAndMaxByMongo(source, subSource, edbInfoId int, start
 	maxData = result.MaxValue
 	return
 }
+
+// ModifyChartListReq 批量编辑图表请求参数
+type ModifyChartListReq struct {
+	SelectAll        bool
+	SubClassify      bool `description:"是否关联图表子分类"`
+	ChartClassifyIds string
+	SysUserIds       string
+	KeyWord          string
+	ChartInfoIds     string `description:"图表ID"`
+	ChartClassifyId  int    `description:"新图表分类"`
+	ChartTypeIds     string
+}
+
+func GetChartInfoItemsByCondition(condition string, pars []interface{}) (item []*ChartInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM chart_info WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+// UpdateChartClassifyIdByChartInfoId 根据图表分类ID
+func UpdateChartClassifyIdByChartInfoId(chartInfoIds []int, classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` update chart_info set chart_classify_id = ? WHERE chart_info_id in (` + utils.GetOrmInReplace(len(chartInfoIds)) + `) `
+	_, err = o.Raw(sql, classifyId, chartInfoIds).Exec()
+	return
+}

+ 16 - 0
models/data_manage/chart_info_correlation.go

@@ -398,3 +398,19 @@ type FactorCorrelationEditDetail struct {
 	CorrelationConfig CorrelationConfig                      `description:"相关性基础配置"`
 	CorrelationMatrix []FactorEdbSeriesCorrelationMatrixItem `description:"相关性矩阵"`
 }
+
+func (m *ChartInfoCorrelation) GetChartEdbMappingCount(edbInfoId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count FROM %s WHERE edb_info_id_first=? or edb_info_id_second=?`
+	sql = fmt.Sprintf(sql, m.TableName())
+	err = o.Raw(sql, edbInfoId, edbInfoId).QueryRow(&count)
+	return
+}
+
+func (m *ChartInfoCorrelation) GetChartInfoIdByEdb(edbInfoId int) (chartInfoId int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT correlation_chart_info_id FROM %s WHERE edb_info_id_first=? or edb_info_id_second=?`
+	sql = fmt.Sprintf(sql, m.TableName())
+	err = o.Raw(sql, edbInfoId, edbInfoId).QueryRow(&chartInfoId)
+	return
+}

+ 2 - 0
models/data_manage/edb_data_base.go

@@ -179,6 +179,8 @@ func GetEdbDataTableName(source, subSource int) (tableName string) {
 		tableName = "edb_data_sci99"
 	case utils.DATA_SOURCE_SCI_HQ:
 		tableName = "edb_data_sci_hq"
+	case utils.DATA_SOURCE_PREDICT: // 基础预测指标->30
+		tableName = "edb_data_predict_base"
 	case utils.DATA_SOURCE_LY: // 粮油商务网->86
 		tableName = "edb_data_ly"
 	case utils.DATA_SOURCE_TRADE_ANALYSIS: // 持仓分析->92

+ 4 - 2
models/data_manage/edb_info.go

@@ -66,6 +66,7 @@ type EdbInfo struct {
 	StockCode        string  `description:"证券代码"`
 	Extra            string  `description:"指标额外配置"`
 	IsJoinPermission int     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	IsStaticData     int     `description:"是否是静态指标,0否,1是"`
 }
 
 type EdbInfoFullClassify struct {
@@ -222,8 +223,8 @@ func GetEdbInfoByIdList(edbInfoIdList []int) (items []*EdbInfo, err error) {
 // 	SortRule     int    `form:"SortRule" description:"排序方式: 0-默认; 1-正序; 2-倒序"`
 // }
 
-// MysteelChemicalDataBatchAddCheckReq 钢联化工指标批量添加校验
-type MysteelChemicalDataBatchAddCheckReq struct {
+// BatchAddCheckReq 指标批量添加校验
+type BatchAddCheckReq struct {
 	// MysteelChemicalDataListReq
 	IndexCodes []string `form:"IndexCodes" description:"全选为false时, 该数组为选中; 全选为true时, 该数组为不选的指标"`
 }
@@ -453,6 +454,7 @@ type EdbInfoList struct {
 	NoUpdate         int8                    `description:"是否停止更新,0:继续更新;1:停止更新"`
 	IsJoinPermission int                     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
 	HaveOperaAuth    bool                    `description:"是否有数据权限,默认:false"`
+	IsStaticData     int                     `description:"是否是静态指标,0否,1是"`
 	IsSupplierStop   int                     `description:"是否供应商停更:1:停更,0:未停更"`
 }
 

+ 2 - 2
models/data_manage/excel/request/mixed_table.go

@@ -137,8 +137,8 @@ type MixCellShowStyle struct {
 	Nt              string      `description:"变换类型:number 小数点位数改变,percent百分比," json:"nt"`
 	GlObj           interface{} `description:"公式对象:1:数值,2:百分比,3:文本" json:"glObj"`
 	Width           float64     `description:"单元格宽度" json:"width"`
-	Decimal         *int        `description:"小数点位数"`
-	Last            string      `description:"起始操作:nt|decimal"`
+	Decimal         *int        `description:"小数点位数" json:"decimal"`
+	Last            string      `description:"起始操作:nt|decimal" json:"last"`
 	Color           string      `description:"颜色值,#RRG" json:"color"`
 	BackgroundColor string      `description:"背景颜色值,#RRG" json:"background-color"`
 	Align           string      `description:"对齐方式:left|center|right" json:"align"`

+ 30 - 0
models/data_manage/my_chart.go

@@ -971,3 +971,33 @@ func GetMyChartClassifyIdAndNum(cond string, pars []interface{}) (items []*MyCha
 	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }
+
+func GetChartClassifyByIds(chartClassifyIds []string) (chart_classify_ids string, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT GROUP_CONCAT(DISTINCT t.chart_classify_id) AS chart_classify_ids
+FROM (
+    SELECT chart_classify_id
+    FROM chart_classify
+    WHERE chart_classify_id IN (` + utils.GetOrmInReplace(len(chartClassifyIds)) + `)
+    OR parent_id IN (` + utils.GetOrmInReplace(len(chartClassifyIds)) + `)
+    OR parent_id IN (
+        SELECT chart_classify_id
+        FROM chart_classify
+        WHERE parent_id IN (` + utils.GetOrmInReplace(len(chartClassifyIds)) + `)
+    )
+) AS t;`
+	err = o.Raw(sql, chartClassifyIds, chartClassifyIds, chartClassifyIds).QueryRow(&chart_classify_ids)
+	return
+}
+
+func GetChartClassifyByIdsNoSubClassify(chartClassifyIds []string) (chart_classify_ids string, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT GROUP_CONCAT(DISTINCT t.chart_classify_id) AS chart_classify_ids
+FROM (
+    SELECT chart_classify_id
+    FROM chart_classify
+    WHERE chart_classify_id IN (` + utils.GetOrmInReplace(len(chartClassifyIds)) + `)
+) AS t;`
+	err = o.Raw(sql, chartClassifyIds).QueryRow(&chart_classify_ids)
+	return
+}

+ 11 - 0
models/data_manage/mysteel_chemical_index.go

@@ -316,6 +316,17 @@ func GetBaseFromMysteelChemicalDataMaxCount(classifyId int) (count int, err erro
 	return
 }
 
+// GetBaseFromMysteelChemicalDataTimeByIndexId 根据指标id获取指标数据的日期列表
+func GetBaseFromMysteelChemicalDataTimeByIndexId(indexIdList []int) (items []string, err error) {
+	if len(indexIdList) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT DISTINCT data_time FROM base_from_mysteel_chemical_data WHERE base_from_mysteel_chemical_index_id IN (` + utils.GetOrmInReplace(len(indexIdList)) + `) ORDER BY data_time DESC`
+	_, err = o.Raw(sql, indexIdList).QueryRows(&items)
+	return
+}
+
 // GetMysteelChemicalIndexDataByCode 通过钢联化工指标code获取所有数据列表
 func GetMysteelChemicalIndexDataByCode(indexCode string) (items []*MysteelChemicalData, err error) {
 	sql := ` SELECT * FROM (

+ 11 - 0
models/data_manage/request/predict_edb_info.go

@@ -65,3 +65,14 @@ type ModifyPredictEdbInfoReq struct {
 	MaxValue  float64 `description:"最大值"`
 	MinValue  float64 `description:"最小值"`
 }
+
+// AddStaticPredictEdbInfoReq 添加预测指标静态指标请求
+type AddStaticPredictEdbInfoReq struct {
+	ClassifyId      int    `description:"分类id"`
+	SourceEdbInfoId int    `description:"来源指标id"`
+	EdbName         string `description:"指标名称"`
+	Frequency       string `description:"频率"`
+	Unit            string `description:"单位"`
+	AdminId         int    `description:"添加人id"`
+	AdminName       string `description:"添加人名称"`
+}

+ 11 - 0
models/data_manage/request/yongyi.go

@@ -0,0 +1,11 @@
+package request
+
+type YongyiIndexSource2EdbReq struct {
+	EdbCode       string
+	EdbName       string
+	Frequency     string
+	Unit          string
+	ClassifyId    int
+	AdminId       int
+	AdminRealName string
+}

+ 5 - 2
models/document_manage_model/outside_report.go

@@ -52,7 +52,7 @@ func init() {
 // GetOutsideReportListByConditionCount 根据条件查询列表条数
 func GetOutsideReportListByConditionCount(condition string, pars []interface{}) (count int, err error) {
 	o := orm.NewOrmUsingDB("rddp")
-	sql := `select count(distinct t1.outside_report_id) from outside_report t1 left join chart_permission_search_key_word_mapping t2 on t1.classify_id = t2.classify_id  where 1 = 1 `
+	sql := `select count(DISTINCT t1.outside_report_id) from outside_report t1 left join chart_permission_search_key_word_mapping t2 on t1.classify_id = t2.classify_id  where 1 = 1 `
 	sql += condition
 	err = o.Raw(sql, pars).QueryRow(&count)
 	if err != nil {
@@ -65,7 +65,10 @@ func GetOutsideReportListByConditionCount(condition string, pars []interface{})
 // GetOutsideReportListByCondition 根据条件查询列表
 func GetOutsideReportListByCondition(condition string, pars []interface{}, currentIndex int, pageSize int) (list []OutsideReport, err error) {
 	o := orm.NewOrmUsingDB("rddp")
-	sql := `select distinct t1.* from outside_report t1 left join chart_permission_search_key_word_mapping t2 on t1.classify_id = t2.classify_id  where 1 = 1 `
+	sql := `select DISTINCT t1.outside_report_id, t1.source, t1.title, t1.abstract, t1.classify_id, 
+t1.classify_name, t1.sys_user_id, t1.sys_user_name, t1.email_message_uid, t1.report_update_time, 
+t1.modify_time, t1.create_time, t1.report_code from outside_report t1 
+left join chart_permission_search_key_word_mapping t2 on t1.classify_id = t2.classify_id  where 1 = 1 `
 	sql += condition
 	sql += ` limit ?, ?`
 	_, err = o.Raw(sql, pars, (currentIndex-1)*pageSize, pageSize).QueryRows(&list)

+ 11 - 1
models/permission.go

@@ -1,6 +1,9 @@
 package models
 
-import "github.com/beego/beego/v2/client/orm"
+import (
+	"eta/eta_api/utils"
+	"github.com/beego/beego/v2/client/orm"
+)
 
 // ChartPermissionSearchKeyWordMapping 权限相关
 type ChartPermissionSearchKeyWordMapping struct {
@@ -124,3 +127,10 @@ func GetPermissionByClassifyId(classifyId int) (items []*ChartPermissionSearchKe
 	_, err = o.Raw(sql, classifyId).QueryRows(&items)
 	return
 }
+
+func GetClassifyIdsByPermissionId(chartPermissionIdList []string) (classifyIds []string, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := "SELECT classify_id FROM chart_permission_search_key_word_mapping WHERE `from` =  'rddp' and chart_permission_id IN (" + utils.GetOrmInReplace(len(chartPermissionIdList)) + ") and classify_id <> 0; "
+	_, err = o.Raw(sql, chartPermissionIdList).QueryRows(&classifyIds)
+	return
+}

+ 17 - 2
models/report.go

@@ -166,7 +166,7 @@ type ReportListResp struct {
 // @return err error
 func GetReportListCountV1(condition string, pars []interface{}) (count int, err error) {
 	o := orm.NewOrmUsingDB("rddp")
-	sql := `SELECT COUNT(1) AS count  FROM report as a WHERE 1=1 `
+	sql := `SELECT COUNT(DISTINCT a.id) AS count  FROM report as a WHERE 1=1 `
 	if condition != "" {
 		sql += condition
 	}
@@ -201,7 +201,9 @@ func GetReportListV1(condition string, pars []interface{}, startSize, pageSize i
 func GetReportListByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*ReportList, err error) {
 	o := orm.NewOrmUsingDB("rddp")
 
-	sql := `SELECT * FROM report as a WHERE 1=1  `
+	sql := `SELECT DISTINCT a.id, a.title, a.author, a.modify_time, a.publish_time,a.classify_id_first,
+a.classify_name_first,a.classify_id_second,a.classify_name_second,a.classify_id_third,
+a.classify_name_third,a.abstract,a.admin_id,a.admin_real_name,a.last_modify_admin_id,a.last_modify_admin_name FROM report as a WHERE 1=1  `
 	if condition != "" {
 		sql += condition
 	}
@@ -1537,3 +1539,16 @@ func UpdateReportInfo(reports *Report) (err error) {
 
 	return
 }
+
+func FindReportListByCondition(condition string, pars []interface{}) (items []*Report, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM report WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	if err != nil {
+		return nil, err
+	}
+	return
+}

+ 7 - 3
models/report_approve/report_approve.go

@@ -3,10 +3,11 @@ package report_approve
 import (
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/beego/beego/v2/client/orm"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"strings"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // ReportApprove 报告审批表
@@ -186,6 +187,7 @@ type ReportApproveItem struct {
 	ReportClassify        string `description:"报告分类"`
 	ClassifyFirstId       int    `description:"一级分类ID"`
 	ClassifySecondId      int    `description:"二级分类ID"`
+	ClassifyThirdId       int    `description:"三级分类ID"`
 	State                 int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
 	RecordState           int    `description:"审批记录状态:1-待审批;2-已通过;3-已驳回"`
 	FlowId                int    `description:"审批流ID"`
@@ -216,6 +218,7 @@ func FormatReportApproveOrm2Item(origin *ReportApproveItemOrm) (item *ReportAppr
 	item.ReportTitle = origin.ReportTitle
 	item.ClassifyFirstId = origin.ClassifyFirstId
 	item.ClassifySecondId = origin.ClassifySecondId
+	item.ClassifyThirdId = origin.ClassifyThirdId
 	item.State = origin.State
 	item.RecordState = origin.RecordState
 	item.FlowId = origin.FlowId
@@ -240,6 +243,7 @@ type ReportApproveListReq struct {
 	ReportType       int    `form:"ReportType" description:"报告类型:1-中文研报;2-英文研报;3-智能研报"`
 	ClassifyFirstId  int    `form:"ClassifyFirstId" description:"一级分类ID"`
 	ClassifySecondId int    `form:"ClassifySecondId" description:"二级分类ID"`
+	ClassifyThirdId  int    `form:"ClassifyThirdId" description:"三级级分类ID"`
 	Keyword          string `form:"Keyword" description:"关键词:报告标题"`
 	ApproveState     int    `form:"ApproveState" description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
 	TimeType         int    `form:"TimeType" description:"时间类型:1-提交时间;2-处理时间;3-审批时间"`
@@ -263,7 +267,7 @@ type ReportApproveItemOrm struct {
 	ReportTitle           string    `description:"报告标题"`
 	ClassifyFirstId       int       `description:"一级分类ID"`
 	ClassifySecondId      int       `description:"二级分类ID"`
-	ClassifyThirdId       int       `description:"级分类ID"`
+	ClassifyThirdId       int       `description:"级分类ID"`
 	State                 int       `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
 	RecordState           int       `description:"审批记录状态:1-待审批;2-已通过;3-已驳回"`
 	FlowId                int       `description:"审批流ID"`

+ 31 - 21
models/target.go

@@ -427,28 +427,34 @@ func GetEdbdataClassify(userId int64) (items []*EdbdataClassifyList, err error)
 	}
 	classifyLen := len(newItems)
 
+	// 获取子集分类
+	var allChildItems []*EdbdataClassify
+	if userId > 0 {
+		userClassifyList, _ := GetManualUserClassify(int(userId))
+		var userIdArr []int
+		for _, v := range userClassifyList {
+			userIdArr = append(userIdArr, v.ClassifyId)
+		}
+		num := len(userClassifyList)
+		if num > 0 {
+			childSql := "SELECT a.classify_id,a.classify_name,a.parent_id FROM edbdata_classify AS a WHERE a.is_show=1 and a.classify_id IN(" + utils.GetOrmInReplace(num) + ") ORDER BY a.create_time ASC "
+			_, err = o.Raw(childSql, userIdArr).QueryRows(&allChildItems)
+		}
+	} else {
+		childSql := "SELECT classify_id,classify_name,parent_id FROM edbdata_classify WHERE is_show=1 ORDER BY create_time ASC "
+		_, err = o.Raw(childSql).QueryRows(&allChildItems)
+	}
+	if err != nil {
+		return
+	}
+
 	for i := 0; i < classifyLen; i++ {
 		var childItems []*EdbdataClassify
 		parentId := newItems[i].ClassifyId
-		childSql := ``
-		if userId > 0 {
-			userClassifyList, _ := GetManualUserClassify(int(userId))
-			var userIdArr []string
-			for _, v := range userClassifyList {
-				userIdArr = append(userIdArr, strconv.Itoa(v.ClassifyId))
-			}
-
-			userIdStr := strings.Join(userIdArr, ",")
-			if userIdStr != "" {
-				childSql = "SELECT a.classify_id,a.classify_name,a.parent_id FROM edbdata_classify AS a WHERE a.is_show=1 and a.classify_id IN(" + userIdStr + ") AND parent_id=? ORDER BY a.create_time ASC "
-				_, err = o.Raw(childSql, parentId).QueryRows(&childItems)
+		for _, v := range allChildItems {
+			if v.ParentId == parentId {
+				childItems = append(childItems, v)
 			}
-		} else {
-			childSql = "SELECT classify_id,classify_name,parent_id FROM edbdata_classify WHERE is_show=1 and parent_id=? ORDER BY create_time ASC "
-			_, err = o.Raw(childSql, parentId).QueryRows(&childItems)
-		}
-		if err != nil {
-			return
 		}
 		newItems[i].Child = childItems
 	}
@@ -1473,13 +1479,17 @@ type EdbInfoGroupCount struct {
 }
 
 // GetEdbInfoGroupCountByClassifyIds 根据指标分类id获取当前分类下的指标数量
-func GetEdbInfoGroupCountByClassifyIds(classifyIds string) (list []*EdbInfoGroupCount, err error) {
+func GetEdbInfoGroupCountByClassifyIds(classifyIdList []int) (list []*EdbInfoGroupCount, err error) {
+	num := len(classifyIdList)
+	if num <= 0 {
+		return
+	}
 	o := orm.NewOrmUsingDB("edb")
 	sql := `SELECT COUNT(1) AS count,classify_id FROM ( SELECT a.*,b.CLOSE FROM edbinfo AS a 
              INNER JOIN edbdata AS b ON a.TRADE_CODE=b.TRADE_CODE
-             WHERE a.classify_id in (` + classifyIds + `) group by a.TRADE_CODE) d 
+             WHERE a.classify_id in (` + utils.GetOrmInReplace(num) + `) group by a.TRADE_CODE) d 
 						 GROUP BY classify_id `
-	_, err = o.Raw(sql).QueryRows(&list)
+	_, err = o.Raw(sql, classifyIdList).QueryRows(&list)
 	return
 }
 

+ 68 - 0
models/user_collect_classify.go

@@ -0,0 +1,68 @@
+// @Author gmy 2024/9/21 14:47:00
+package models
+
+import "github.com/beego/beego/v2/client/orm"
+
+/**
+CREATE TABLE `user_collect_classify` (
+  `user_collect_classify_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `classify_id` int(9) unsigned NOT NULL DEFAULT '0' COMMENT '分类id',
+  `sys_user_id` int(9) unsigned DEFAULT '0' COMMENT '收藏人用户id',
+  `create_time` datetime DEFAULT NULL COMMENT '收藏时间',
+  PRIMARY KEY (`user_collect_classify_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户收藏的分类id';
+*/
+
+type UserCollectClassify struct {
+	UserCollectClassifyId int    `orm:"column(user_collect_classify_id);pk" description:"用户收藏的分类id"`
+	ClassifyId            int    `orm:"column(classify_id)" description:"分类id"`
+	SysUserId             int    `orm:"column(sys_user_id)" description:"收藏人用户id"`
+	CreateTime            string `orm:"column(create_time)" description:"收藏时间"`
+}
+
+// GetUserCollectClassifyList 查询用户收藏的分类列表
+func GetUserCollectClassifyList(sysUserId, classifyId int) (list []*UserCollectClassify, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM user_collect_classify WHERE 1=1`
+	var params []interface{}
+
+	// 处理 sysUserId 参数
+	if sysUserId > 0 {
+		sql += ` AND sys_user_id=?`
+		params = append(params, sysUserId)
+	}
+
+	// 处理 classifyId 参数
+	if classifyId > 0 {
+		sql += ` AND classify_id=?`
+		params = append(params, classifyId)
+	}
+
+	_, err = o.Raw(sql, params...).QueryRows(&list)
+
+	return
+}
+
+// InsertUserCollectClassify 新增用户收藏的分类
+func InsertUserCollectClassify(item UserCollectClassify) (err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `INSERT INTO user_collect_classify(classify_id, sys_user_id, create_time) VALUES(?, ?, ?)`
+	_, err = o.Raw(sql, item.ClassifyId, item.SysUserId, item.CreateTime).Exec()
+	return
+}
+
+// DeleteUserCollectClassify 删除分类
+func DeleteUserCollectClassify(sysUserId, classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `DELETE FROM user_collect_classify WHERE sys_user_id=? AND classify_id=?`
+	_, err = o.Raw(sql, sysUserId, classifyId).Exec()
+	return
+}
+
+// DeleteUserCollectClassify 删除分类
+func DeleteCollectByClassifyId(classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `DELETE FROM user_collect_classify WHERE classify_id=?`
+	_, err = o.Raw(sql, classifyId).Exec()
+	return
+}

+ 99 - 0
routers/commentsRouter.go

@@ -2815,6 +2815,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartClassifyController"],
+        beego.ControllerComments{
+            Method: "ChartClassifyChartListV3",
+            Router: `/chart_classify/chart/listV2`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartClassifyController"],
         beego.ControllerComments{
             Method: "DeleteChartClassify",
@@ -2977,6 +2986,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"],
+        beego.ControllerComments{
+            Method: "ChartList",
+            Router: `/chart/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"],
         beego.ControllerComments{
             Method: "ChartInfoAdd",
@@ -3436,6 +3454,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"],
+        beego.ControllerComments{
+            Method: "ModifyChartList",
+            Router: `/modify/chartList`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"],
         beego.ControllerComments{
             Method: "MultipleGraphConfigSaveChart",
@@ -5236,6 +5263,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "YongyiBatchAdd",
+            Router: `/yongyi/batch_add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "YongyiBatchSearch",
+            Router: `/yongyi/batch_search`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
         beego.ControllerComments{
             Method: "YongyiClassify",
@@ -5245,6 +5290,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "YongyiIndexList",
+            Router: `/yongyi/classify/index/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "YongyiEdbInfoAdd",
+            Router: `/yongyi/edb_info/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "YongyiAddCheck",
+            Router: `/yongyi/edb_info/add_check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "YongyiNameCheck",
+            Router: `/yongyi/edb_info/name_check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
         beego.ControllerComments{
             Method: "ExportYongyiList",
@@ -5830,6 +5911,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:PredictEdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:PredictEdbInfoController"],
+        beego.ControllerComments{
+            Method: "EdbInfoBaseEdit",
+            Router: `/predict_edb_info/base/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:PredictEdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:PredictEdbInfoController"],
         beego.ControllerComments{
             Method: "CalculateBatchSave",
@@ -6001,6 +6091,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:PredictEdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:PredictEdbInfoController"],
+        beego.ControllerComments{
+            Method: "AddStaticEdb",
+            Router: `/predict_edb_info/static_edb/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
         beego.ControllerComments{
             Method: "ExportSciHqList",

+ 84 - 35
services/classify.go

@@ -7,6 +7,7 @@ import (
 	"eta/eta_api/models/report_approve"
 	"eta/eta_api/utils"
 	"fmt"
+	"github.com/beego/beego/v2/core/logs"
 	"sort"
 	"time"
 )
@@ -249,6 +250,13 @@ func AddReportClassify(classifyName string, parentId int, chartPermissionIdList
 			return
 		}
 
+		// 清除父级分类的收藏 战研2.1
+		err = models.DeleteCollectByClassifyId(parentId)
+		if err != nil {
+			errMsg = "清除父级分类的收藏失败"
+			return
+		}
+
 	}
 
 	nowTime := time.Now().Local()
@@ -276,47 +284,54 @@ func AddReportClassify(classifyName string, parentId int, chartPermissionIdList
 		return
 	}
 
-	// 如果父级分类下有报告,修改报告到子级分类下
-	reports, err := models.GetReportListByClassifyId(parentId)
+	// 如果当前分类下,没有其他分类,则将当前分类下的所有报告放入新分类下
+	count, err := models.GetClassifySubCountByParentId(parentId)
 	if err != nil {
-		return err, "查询报告列表失败", false
-	}
-	if len(reports) > 0 {
-		for _, report := range reports {
-			if report.ClassifyIdFirst == 0 {
-				report.ClassifyIdFirst = classify.Id
-				report.ClassifyNameFirst = classifyName
-			} else if report.ClassifyIdSecond == 0 {
-				report.ClassifyIdSecond = classify.Id
-				report.ClassifyNameSecond = classifyName
-			} else {
-				report.ClassifyIdThird = classify.Id
-				report.ClassifyNameThird = classifyName
-			}
+		return err, "查询分类下所有的分类记录数失败", false
+	}
 
-			// beego orm 不支持批量修改,所以只能一个一个修改
-			err := models.UpdateReportInfo(report)
-			if err != nil {
-				return err, "修改报告分类失败", false
+	if count == 1 {
+		// 如果父级分类下 无其他子分类 并且有报告,修改报告到子级分类下
+		reports, err := models.GetReportListByClassifyId(parentId)
+		if err != nil {
+			return err, "查询报告列表失败", false
+		}
+		if len(reports) > 0 {
+			for _, report := range reports {
+				// 一级分类不用判断,有报告一定有分类,二级分类如果等于0,就不用判断三级了
+				if report.ClassifyIdSecond == 0 {
+					report.ClassifyIdSecond = classify.Id
+					report.ClassifyNameSecond = classifyName
+				} else if report.ClassifyIdThird == 0 {
+					report.ClassifyIdThird = classify.Id
+					report.ClassifyNameThird = classifyName
+				}
+
+				// beego orm 不支持批量修改,所以只能一个一个修改
+				err := models.UpdateReportInfo(report)
+				if err != nil {
+					return err, "修改报告分类失败", false
+				}
 			}
 		}
-	}
-	outsideReports, err := document_manage_model.GetOutsideReportListByClassifyId(parentId)
-	if err != nil {
-		return err, "查询外部报告列表失败", false
-	}
-	if len(outsideReports) > 0 {
-		for _, report := range outsideReports {
-			tempReport := report
-
-			tempReport.ClassifyId = classify.Id
-			tempReport.ClassifyName = classifyName
-			// 修改报告
-			err := document_manage_model.UpdateOutsideReport(&tempReport)
-			if err != nil {
-				return err, "修改外部报告分类失败", false
+		outsideReports, err := document_manage_model.GetOutsideReportListByClassifyId(parentId)
+		if err != nil {
+			return err, "查询外部报告列表失败", false
+		}
+		if len(outsideReports) > 0 {
+			for _, report := range outsideReports {
+				tempReport := report
+
+				tempReport.ClassifyId = classify.Id
+				tempReport.ClassifyName = classifyName
+				// 修改报告
+				err := document_manage_model.UpdateOutsideReport(&tempReport)
+				if err != nil {
+					return err, "修改外部报告分类失败", false
+				}
 			}
 		}
+
 	}
 
 	//获取报告分类权限列表
@@ -819,3 +834,37 @@ func (a BySortAndCreateTime) Less(i, j int) bool {
 func SortClassifyListBySortAndCreateTime(classifyList []*models.ClassifyList) {
 	sort.Sort(BySortAndCreateTime(classifyList))
 }
+
+// DealBug6445 处理禅道bug6445,对数据进行补偿刷新
+func DealBug6445() error {
+	var condition string
+	var pars []interface{}
+	reportList, err := models.FindReportListByCondition(condition, pars)
+	if err != nil {
+		return err
+	}
+
+	for _, report := range reportList {
+		oldClassifyIdThird := report.ClassifyIdThird
+		oldClassifyNameThird := report.ClassifyNameThird
+		classifyIdList := []int{report.ClassifyIdSecond, report.ClassifyIdThird}
+
+		// 判断当前分类id的父id是否一样,如果系统则将3级分类置为0
+		classifies, err := models.GetClassifyListByIdList(classifyIdList)
+		if err != nil {
+			return err
+		}
+		if len(classifies) >= 2 {
+			if classifies[0].ParentId == classifies[1].ParentId && classifies[0].ParentId != 0 {
+				report.ClassifyIdThird = 0
+				report.ClassifyNameThird = ""
+				err := report.UpdateReport([]string{"classify_id_third", "classify_name_third"})
+				if err != nil {
+					return err
+				}
+				logs.Info("update report id: %d, classify_id_third: %d, classify_name_third: %s", report.Id, oldClassifyIdThird, oldClassifyNameThird)
+			}
+		}
+	}
+	return nil
+}

+ 10 - 0
services/data/base_edb_lib.go

@@ -582,3 +582,13 @@ func BaseStepCalculate(param, lang string) (resp *BaseCalculateResp, err error)
 	}
 	return
 }
+
+// SavePredictStaticEdbData 新增预测指标-静态指标
+func SavePredictStaticEdbData(edbInfoCalculateBatchSaveReqStr, lang string) (resp *AddPredictEdbDataResponse, err error) {
+	_, resultByte, err := postAddEdbData(edbInfoCalculateBatchSaveReqStr, "predict/static_edb/add", lang)
+	err = json.Unmarshal(resultByte, &resp)
+	if err != nil {
+		return
+	}
+	return
+}

+ 176 - 10
services/data/chart_classify.go

@@ -23,18 +23,25 @@ func chartClassifyHaveChild(allNode []*data_manage.ChartClassifyItems, node *dat
 	return
 }
 
-func ChartClassifyItemsMakeTree(sysUser *system.Admin, allNode []*data_manage.ChartClassifyItems, node *data_manage.ChartClassifyItems, permissionClassifyIdList []int) {
+func ChartClassifyItemsMakeTree(sysUser *system.Admin, allNode []*data_manage.ChartClassifyItems, node *data_manage.ChartClassifyItems, permissionClassifyIdList []int, level int) {
 	node.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(node.IsJoinPermission, node.ChartClassifyId, permissionClassifyIdList)
 	button := GetChartClassifyOpButton(sysUser, node.SysUserId, node.HaveOperaAuth)
 	node.Button = button
-
+	node.Disable = true
+	if node.Level == level {
+		node.Disable = false
+	}
 	childs, _ := chartClassifyHaveChild(allNode, node) //判断节点是否有子节点并返回
 	if len(childs) > 0 {
 		for _, child := range childs {
 			child.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(child.IsJoinPermission, child.ChartClassifyId, permissionClassifyIdList)
 			childButton := GetChartClassifyOpButton(sysUser, child.SysUserId, child.HaveOperaAuth)
-			if child.Level == 3 {
-				childButton.AddButton = false //第三级的话,默认图表都是没有添加按钮的
+			if child.Level == 6 {
+				childButton.AddButton = false //第六级的话,默认图表都是没有添加按钮的
+			}
+			child.Disable = true
+			if child.Level == level {
+				child.Disable = false
 			}
 			child.Button = childButton
 			//node.Children = append(node.Children, child)
@@ -45,15 +52,23 @@ func ChartClassifyItemsMakeTree(sysUser *system.Admin, allNode []*data_manage.Ch
 			//查询子节点的子节点,并添加到子节点
 			_, has := chartClassifyHaveChild(allNode, v)
 			if has {
-				ChartClassifyItemsMakeTree(sysUser, allNode, v, permissionClassifyIdList) //递归添加节点
+				ChartClassifyItemsMakeTree(sysUser, allNode, v, permissionClassifyIdList, level) //递归添加节点
 			} else {
-				childrenArr := make([]*data_manage.ChartClassifyItems, 0)
-				v.Children = childrenArr
+				if level > 0 {
+					v.Children = nil
+				} else {
+					childrenArr := make([]*data_manage.ChartClassifyItems, 0)
+					v.Children = childrenArr
+				}
 			}
 		}
 	} else {
-		childrenArr := make([]*data_manage.ChartClassifyItems, 0)
-		node.Children = childrenArr
+		if level > 0 {
+			node.Children = nil
+		} else {
+			childrenArr := make([]*data_manage.ChartClassifyItems, 0)
+			node.Children = childrenArr
+		}
 	}
 }
 
@@ -261,7 +276,7 @@ func AddChartClassify(chartClassifyName string, parentId, level, source int, lan
 		}
 	}
 
-	if level > 6 {
+	if level > 5 {
 		errMsg = `最高只支持添加6级分类`
 		return
 	}
@@ -962,3 +977,154 @@ func GetChartClassifyParentRecursive(list []*data_manage.ChartClassifyItems, cla
 	}
 	return res
 }
+
+// 修改图表分类,可以修改父级
+func EditChartClassifyV2(chartClassifyId, praentId, source int, chartClassifyName, lang string) (classifyInfo *data_manage.ChartClassify, err error, errMsg string, isSendEmail bool) {
+	isSendEmail = true
+	errMsg = "保存失败"
+
+	// 获取分类信息
+	classifyInfo, err = data_manage.GetChartClassifyById(chartClassifyId)
+	if err != nil {
+		return
+	}
+
+	if praentId != classifyInfo.ParentId {
+		parentClassifyInfo, e := data_manage.GetChartClassifyById(praentId)
+		if e != nil {
+			err = e
+			return
+		}
+		if classifyInfo.Level != parentClassifyInfo.Level - 1 {
+			err = errors.New("父级分类层级异常")
+		}
+	}
+
+	// 分类来源校验
+	if classifyInfo.Source != source {
+		errMsg = "图表分类异常"
+		err = errors.New(fmt.Sprintf("图表分类来源异常,修改来源:%d,分类来源:%d", source, classifyInfo.Source))
+		isSendEmail = false
+		return
+	}
+
+
+	// 需要变更的字段
+	updateCols := make([]string, 0)
+
+	if praentId != classifyInfo.ParentId {
+		classifyInfo.ParentId = praentId
+		classifyInfo.ModifyTime = time.Now()
+		updateCols = append(updateCols, "ParentId")
+	}
+
+	// 语言版本校验
+	switch lang {
+	case utils.EnLangVersion:
+		if classifyInfo.ChartClassifyNameEn != chartClassifyName {
+			count, tmpErr := data_manage.GetChartClassifyEnCount(chartClassifyName, classifyInfo.ParentId, source)
+			if tmpErr != nil {
+				errMsg = "判断名称是否已存在失败"
+				err = errors.New("判断名称是否已存在失败,Err:" + tmpErr.Error())
+				return
+			}
+			if count > 0 {
+				errMsg = "分类名称已存在,请重新输入"
+				err = errors.New(errMsg)
+				isSendEmail = false
+				return
+			}
+
+			classifyInfo.ChartClassifyNameEn = chartClassifyName
+			classifyInfo.ModifyTime = time.Now()
+			updateCols = append(updateCols, "ChartClassifyNameEn", "ModifyTime")
+		}
+	default:
+		if classifyInfo.ChartClassifyName != chartClassifyName {
+			count, tmpErr := data_manage.GetChartClassifyCount(chartClassifyName, classifyInfo.ParentId, source)
+			if tmpErr != nil {
+				errMsg = "判断名称是否已存在失败"
+				err = errors.New("判断名称是否已存在失败,Err:" + tmpErr.Error())
+				return
+			}
+			if count > 0 {
+				errMsg = "分类名称已存在,请重新输入"
+				err = errors.New(errMsg)
+				isSendEmail = false
+				return
+			}
+
+			classifyInfo.ChartClassifyName = chartClassifyName
+			classifyInfo.ModifyTime = time.Now()
+			updateCols = append(updateCols, "ChartClassifyName", "ModifyTime")
+		}
+	}
+
+	if len(updateCols) > 0 {
+		err = classifyInfo.Update(updateCols)
+	}
+
+	return
+}
+
+// RemoveNotChartClassifyItemsMakeTree
+// @Description: 过滤名下没有自己图表的分类,并生成树形结构
+// @author: Roc
+// @datetime 2024-09-11 16:59:39
+// @param node *data_manage.ChartClassifyItems
+// @param selfChartClassifyIdList []int
+// @return isSelf bool
+func RemoveNotChartClassifyItemsMakeTree(node *data_manage.ChartClassifyItems, selfChartClassifyIdList []int) (isSelf bool) {
+	if utils.InArrayByInt(selfChartClassifyIdList, node.ChartClassifyId) {
+		return true
+	}
+
+	childrenList := make([]*data_manage.ChartClassifyItems, 0)
+	for _, child := range node.Children {
+		if tmpIsSelf := RemoveNotChartClassifyItemsMakeTree(child, selfChartClassifyIdList); tmpIsSelf {
+			childrenList = append(childrenList, child)
+			isSelf = tmpIsSelf
+		}
+	}
+	node.Children = childrenList
+
+	return
+}
+
+// GetChartClassifyChildrenRecursive 根据父目录递归子级目录
+func GetChartClassifyChildrenRecursive(list []*data_manage.ChartClassifyItems, parentId int) []*data_manage.ChartClassifyItems {
+	var res []*data_manage.ChartClassifyItems
+
+	for _, v := range list {
+		if v.ParentId == parentId {
+			// 递归调用以获取更深层次的子级
+			children := GetChartClassifyChildrenRecursive(list, v.ChartClassifyId)
+			// 将当前节点和所有子节点添加到结果中
+			res = append(res, v)
+			res = append(res, children...)
+		} else if v.ChartClassifyId == parentId {
+			// 将当前节点添加到结果中
+			res = append(res, v)
+		}
+	}
+	return res
+}
+
+// GetChartClassifyChildrenRecursiveByParentIds 根据父目录递归子级目录
+func GetChartClassifyChildrenRecursiveByParentIds(list []*data_manage.ChartClassifyItems, parentIds []string) []*data_manage.ChartClassifyItems {
+	var res []*data_manage.ChartClassifyItems
+
+	for _, v := range list {
+		for _, id := range parentIds {
+			parentId, _ := strconv.Atoi(id)
+			if v.ParentId == parentId || v.ChartClassifyId == parentId {
+				// 递归调用以获取更深层次的子级
+				children := GetChartClassifyChildrenRecursive(list, v.ChartClassifyId)
+				// 将当前节点和所有子节点添加到结果中
+				res = append(res, v)
+				res = append(res, children...)
+			}
+		}
+	}
+	return res
+}

+ 4 - 0
services/data/chart_info.go

@@ -1637,6 +1637,8 @@ func BatchChartInfoRefreshV2(chartInfoList []*data_manage.ChartInfo, redisKey st
 		for _, v := range chartInfoList {
 			key := utils.HZ_CHART_LIB_DETAIL + v.UniqueCode
 			refreshItem.ItemRefreshKeys = append(refreshItem.ItemRefreshKeys, key)
+			// eta平台的缓存,用于Ppt等地方的展示
+			refreshItem.ItemRefreshKeys = append(refreshItem.ItemRefreshKeys, GetChartInfoDataKey(v.ChartInfoId))
 		}
 		refreshItem.BaseEdbInfoArr = newBaseEdbInfoArr
 		refreshItem.BasePredictEdbInfoArr = newBasePredictEdbInfoArr
@@ -1652,6 +1654,8 @@ func BatchChartInfoRefreshV2(chartInfoList []*data_manage.ChartInfo, redisKey st
 		for _, v := range chartInfoList {
 			key := utils.HZ_CHART_LIB_DETAIL + v.UniqueCode
 			_ = utils.Rc.Delete(key)
+			// eta平台的缓存,用于Ppt等地方的展示
+			_ = utils.Rc.Delete(GetChartInfoDataKey(v.ChartInfoId))
 		}
 	}
 

+ 25 - 0
services/data/edb_classify.go

@@ -593,6 +593,19 @@ func DeleteCheck(classifyId, edbInfoId int, sysUser *system.Admin) (deleteStatus
 			tipsMsg = "当前指标已用作画图,不可删除"
 			return
 		}
+		// 查询是否用于相关性图表
+		correlationChart := new(data_manage.ChartInfoCorrelation)
+		correlationChartCount, tmpErr := correlationChart.GetChartEdbMappingCount(edbInfoId)
+		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+			errMsg = "删除失败"
+			err = errors.New("判断指标是否被用于相关性图表失败,Err:" + tmpErr.Error())
+			return
+		}
+		if correlationChartCount > 0 {
+			deleteStatus = 3
+			tipsMsg = "当前指标已用作画图,不可删除"
+			return
+		}
 		//判断指标是否用于计算
 		{
 			calculateCount, tmpErr := data_manage.GetEdbInfoCalculateMappingCount(edbInfoId)
@@ -811,6 +824,18 @@ func Delete(classifyId, edbInfoId int, sysUser *system.Admin, requestBody, reque
 			errMsg = "当前指标已用作画图,不可删除"
 			return
 		}
+		// 查询是否用于相关性图表
+		correlationChart := new(data_manage.ChartInfoCorrelation)
+		correlationChartCount, tmpErr := correlationChart.GetChartEdbMappingCount(edbInfoId)
+		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
+			errMsg = "删除失败"
+			err = errors.New("判断指标是否被用于相关性图表失败,Err:" + tmpErr.Error())
+			return
+		}
+		if correlationChartCount > 0 {
+			errMsg = "当前指标已用作画图,不可删除"
+			return
+		}
 
 		//如果是普通指标,那么还需要判断是否被预测指标作为源指标
 		if edbInfo.EdbInfoType == 0 {

+ 200 - 1
services/data/edb_info.go

@@ -7,6 +7,7 @@ import (
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/data_manage/excel"
+	"eta/eta_api/models/system"
 	"eta/eta_api/services/alarm_msg"
 	"eta/eta_api/services/data/data_manage_permission"
 	"eta/eta_api/services/elastic"
@@ -2969,6 +2970,139 @@ func handleByDelEdbInfo(edbInfo *data_manage.EdbInfo) {
 	}
 }
 
+func EditBaseEdbInfo(req data_manage.EditEdbInfoReq, sysUser *system.Admin, lang, requestBody, uri string) (isSendEmail bool, err error, errMsg string) {
+	isSendEmail = true
+	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
+	if err != nil {
+		errMsg = "修改失败"
+		err = fmt.Errorf("获取指标信息失败,Err:" + err.Error())
+		return
+	}
+
+	// 记录旧的指标基本信息
+	oldEdbName := edbInfo.EdbName
+	oldFrequency := edbInfo.Frequency
+	oldUnit := edbInfo.Unit
+
+	var haveOperaAuth bool
+	// 权限校验
+	{
+		haveOperaAuth, err = data_manage_permission.CheckEdbPermissionByEdbInfoId(edbInfo.EdbInfoId, edbInfo.ClassifyId, edbInfo.IsJoinPermission, sysUser.AdminId)
+		if err != nil {
+			errMsg = err.Error()
+			err = fmt.Errorf("校验指标权限失败,err:" + err.Error())
+			return
+		}
+	}
+
+	// 编辑权限校验
+	button := GetEdbOpButton(sysUser, edbInfo.SysUserId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth)
+	if !button.OpButton {
+		errMsg = "无权限操作"
+		isSendEmail = false
+		return
+	}
+
+	//判断指标名称是否存在
+	var condition string
+	var pars []interface{}
+
+	condition += " AND edb_info_id<>? "
+	pars = append(pars, req.EdbInfoId)
+
+	//condition += " AND source=? "
+	//pars = append(pars, edbInfo.Source)
+
+	updateCols := make([]string, 0)
+	switch lang {
+	case utils.EnLangVersion:
+		condition += " AND edb_name_en = ? "
+		edbInfo.EdbNameEn = req.EdbName
+		edbInfo.Frequency = req.Frequency
+		edbInfo.UnitEn = req.Unit
+		edbInfo.ClassifyId = req.ClassifyId
+		updateCols = append(updateCols, "EdbNameEn", "Frequency", "UnitEn", "ClassifyId")
+	default:
+		condition += " AND edb_name=? "
+		edbInfo.EdbName = req.EdbName
+		edbInfo.EdbNameSource = req.EdbName
+		edbInfo.Frequency = req.Frequency
+		edbInfo.Unit = req.Unit
+		edbInfo.ClassifyId = req.ClassifyId
+		updateCols = append(updateCols, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId")
+	}
+	pars = append(pars, req.EdbName)
+
+	count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
+	if err != nil {
+		errMsg = "判断指标名称是否存在失败"
+		err = fmt.Errorf("判断指标名称是否存在失败,Err:" + err.Error())
+		return
+	}
+
+	if count > 0 {
+		errMsg = "指标名称已存在,请重新填写"
+		err = fmt.Errorf("指标名称已存在,请重新填写")
+		isSendEmail = false
+		return
+	}
+
+	if len(updateCols) > 0 {
+		err = edbInfo.Update(updateCols)
+		if err != nil {
+			errMsg = "保存失败"
+			err = fmt.Errorf("修改失败,Err:" + err.Error())
+			return
+		}
+	}
+
+	// 新增保存记录日志
+	oldEdbInfo := new(data_manage.EdbInfo)
+	oldEdbInfo.EdbInfoId = edbInfo.EdbInfoId
+	oldEdbInfo.EdbName = oldEdbName
+	oldEdbInfo.Frequency = oldFrequency
+	oldEdbInfo.Unit = oldUnit
+	newEdbInfoRecord := new(data_manage.EdbInfoEditRecord)
+	newEdbInfoRecord.EdbName = req.EdbName
+	newEdbInfoRecord.Frequency = req.Frequency
+	newEdbInfoRecord.Unit = req.Unit
+	newEdbInfoRecord.OperateUserId = sysUser.AdminId
+	newEdbInfoRecord.OperateUserRealName = sysUser.RealName
+	go AddEditEdbInfoRcord(oldEdbInfo, newEdbInfoRecord)
+
+	//新增操作日志
+	{
+		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 = requestBody
+		edbLog.Status = "编辑指标"
+		edbLog.Method = uri
+		go data_manage.AddEdbInfoLog(edbLog)
+	}
+
+	//添加es
+	AddOrEditEdbInfoToEs(req.EdbInfoId)
+
+	switch lang {
+	case utils.EnLangVersion:
+		// 修改关联的预测指标基础信息
+		go ModifyPredictEdbEnBaseInfoBySourceEdb(edbInfo, req.Unit)
+	default:
+		// 修改关联的预测指标基础信息
+		go ModifyPredictEdbBaseInfoBySourceEdb(edbInfo, req.Frequency, req.Unit)
+	}
+
+	return
+}
+
 // GetIsSupplierStop
 // @Description: 获取是否供应商停更
 // @author: Roc
@@ -2989,4 +3123,69 @@ func GetIsSupplierStop(source int, edbCode string) (isSupplierStop int) {
 	return
 }
 
-//IsSupplierStop  int    `description:"是否供应商停更:1:停更,0:未停更"`
+// GetMySteelSourceByEdbCode
+// @Description: 根据钢联的指标编码,获取该数据应该从哪个数据源查询
+// @author: Roc
+// @datetime 2024-09-10 13:25:07
+// @param edbCode string
+// @return source int
+// @return item *data_manage.EdbInfo
+// @return err error
+func GetMySteelSourceByEdbCode(edbCode string) (source int, item *data_manage.EdbInfo, err error) {
+	// 先判断在指标库的“上海钢联”中是否存在,存在就直接返回
+	source = utils.DATA_SOURCE_MYSTEEL_CHEMICAL
+	item, err = data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_MYSTEEL_CHEMICAL, edbCode)
+	if err != nil {
+		if err.Error() != utils.ErrNoRow() {
+			return
+		}
+		err = nil
+	}
+	if item != nil {
+		source = utils.DATA_SOURCE_MYSTEEL_CHEMICAL
+		return
+	}
+
+	// 再判断在指标库的“钢联原始”中是否存在,存在就直接返回
+	item, err = data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_GL, edbCode)
+	if err != nil {
+		if err.Error() != utils.ErrNoRow() {
+			return
+		}
+		err = nil
+	}
+	if item != nil {
+		source = utils.DATA_SOURCE_GL
+		return
+	}
+
+	// 再没有就判断下是否处于 《上海钢联》 数据源里面
+	{
+		tmpInfo, tmpErr := data_manage.GetBaseFromMysteelChemicalIndexByCode(edbCode)
+		if tmpErr != nil {
+			if tmpErr.Error() != utils.ErrNoRow() {
+				err = tmpErr
+				return
+			}
+		}
+		if tmpInfo != nil {
+			source = utils.DATA_SOURCE_MYSTEEL_CHEMICAL
+		}
+	}
+
+	// 再没有就判断下是否处于 《钢联原始》 数据源里面
+	{
+		tmpInfo, tmpErr := data_manage.GetGlIndexByCode(edbCode)
+		if tmpErr != nil {
+			if tmpErr.Error() != utils.ErrNoRow() {
+				err = tmpErr
+				return
+			}
+		}
+		if tmpInfo != nil {
+			source = utils.DATA_SOURCE_GL
+		}
+	}
+
+	return
+}

+ 2 - 1
services/data/edb_info_relation.go

@@ -370,7 +370,8 @@ func GetEdbRelationList(source, edbType int, classifyId, sysUserId, frequency, k
 	var addFieldStr, joinTableStr string
 
 	switch source {
-	case utils.DATA_SOURCE_MYSTEEL_CHEMICAL, utils.DATA_SOURCE_WIND:
+	case 0: // 计算指标,不校验source
+	default:
 		condition += ` AND e.source = ? `
 		pars = append(pars, source)
 	}

+ 1 - 1
services/data/excel/excel_info.go

@@ -148,7 +148,7 @@ func formatExcelInfo2Detail(excelInfo *excel.ExcelInfo, sysUserId int, lang stri
 
 			// 获取所有有权限的指标和分类
 			permissionEdbIdList, permissionClassifyIdList, tmpErr := data_manage_permission.GetUserEdbAndClassifyPermissionList(sysUserId, 0, 0)
-			if err != nil {
+			if tmpErr != nil {
 				err = errors.New("获取所有有权限的指标和分类失败,Err:" + tmpErr.Error())
 				return
 			}

+ 57 - 9
services/data/excel/mixed_table.go

@@ -1215,10 +1215,19 @@ func handleMixCellShowStyle(showStyleList []string, calculateCellMap map[string]
 
 			cell := config[cellPosition.Column][cellPosition.Row]
 			val := cell.ShowValue
-			isPercent := false
-			if strings.Contains(val, "%") {
-				isPercent = true
-				val = strings.Trim(val, "%")
+			// 前端不支持手动输入的%数
+			// isPercent := false
+			// if strings.Contains(val, "%") {
+			// 	isPercent = true
+			// 	val = strings.Trim(val, "%")
+			// }
+			// 如果没有showValue, 则使用value
+			if cell.ShowValue == "" {
+				_, err := strconv.ParseFloat(cell.Value, 64)
+				if err == nil {
+					val = cell.Value
+					cell.ShowValue = cell.Value
+				}
 			}
 			_, e := strconv.ParseFloat(val, 64) // 将字符串转换成float类型
 			if e != nil {                       // 如果没有错误发生则返回true,说明该字符串是一个合法的数字
@@ -1246,16 +1255,42 @@ func handleMixCellShowStyle(showStyleList []string, calculateCellMap map[string]
 				err = fmt.Errorf("日期计算配置json解析失败失败: %s, Err:%s", config, err.Error())
 				return
 			}
+			hasPercent := false
+			if styleConf.Nt == "percent" {
+				hasPercent = true
+			}
 			if styleConf.Pn != 0 || styleConf.Nt != "" {
-				val = changePointDecimalPlaces(val, styleConf.Pn, styleConf.Nt, isPercent)
-				cell.ShowFormatValue = val
+				// val = changePointDecimalPlaces(val, styleConf.Pn, styleConf.Nt, hasPercent)
+				// cell.ShowFormatValue = val
+				// 修复历史数据,没有保存小数位数,重置小数位数
+				if styleConf.Pn != 0 {
+					if styleConf.Decimal == nil {
+						styleConf.Decimal = new(int)
+					}
+					*styleConf.Decimal += styleConf.Pn
+					if *styleConf.Decimal < 0 {
+						*styleConf.Decimal = 0
+					}
+					cell.ShowFormatValue = utils.RoundNumber(cell.ShowValue, *styleConf.Decimal, hasPercent)
+					styleConf.Pn = 0
+				} else if styleConf.Decimal != nil {
+					cell.ShowFormatValue = utils.RoundNumber(cell.ShowValue, *styleConf.Decimal, hasPercent)
+				} else {
+					if hasPercent {
+						numDecimal, _ := decimal.NewFromString(cell.ShowValue)
+						tmpStr := numDecimal.Mul(decimal.NewFromInt(100)).String()
+						cell.ShowFormatValue = tmpStr + "%"
+					} else {
+						cell.ShowFormatValue = cell.ShowValue
+					}
+				}
+			} else if styleConf.Decimal != nil {
+				cell.ShowFormatValue = utils.RoundNumber(cell.ShowValue, *styleConf.Decimal, hasPercent)
 			} else {
 				cell.ShowFormatValue = cell.ShowValue
 			}
 			// 前端传过来的json中有可能有glObj,需要去掉
-			if styleConf.GlObj != nil {
-				styleConf.GlObj = nil
-			}
+			styleConf.GlObj = nil
 			tmpStyleConf, err := json.Marshal(styleConf)
 			if err == nil {
 				cell.ShowStyle = string(tmpStyleConf)
@@ -1266,6 +1301,19 @@ func handleMixCellShowStyle(showStyleList []string, calculateCellMap map[string]
 	return
 }
 
+func getDecimalLen(str string, isPercent bool) (decimalPlaces int) {
+	dotIndex := strings.Index(str, ".") // 查找小数点的位置
+	if dotIndex == -1 {
+		decimalPlaces = 0
+	} else {
+		decimalPlaces = len(str) - dotIndex - 1
+	}
+	if isPercent && decimalPlaces >= 1 {
+		decimalPlaces -= 1
+	}
+	return
+}
+
 // changePointDecimalPlaces 小数点位数加减和百分比格式
 func changePointDecimalPlaces(str string, changeNum int, numberType string, isPercent bool) (newStr string) {
 	newStr = str

+ 3 - 91
services/data/predict_edb_info.go

@@ -914,98 +914,10 @@ func GetPredictDataListByPredictEdbInfoId(edbInfoId int, startDate, endDate stri
 
 // GetPredictDataListByPredictEdbInfo 根据预测指标信息获取预测指标的数据
 func GetPredictDataListByPredictEdbInfo(edbInfo *data_manage.EdbInfo, startDate, endDate string, isTimeBetween bool) (dataList []*data_manage.EdbDataList, sourceEdbInfoItem *data_manage.EdbInfo, predictEdbConf *data_manage.PredictEdbConf, err error, errMsg string) {
-	// 非计算指标,直接从表里获取数据
-	if edbInfo.EdbType != 1 {
-		if !isTimeBetween { //如果不是区间数据,那么就结束日期为空
-			endDate = ``
-		}
-		return GetPredictCalculateDataListByPredictEdbInfo(edbInfo, startDate, endDate)
-	}
-	// 查找该预测指标配置
-	predictEdbConfList, err := data_manage.GetPredictEdbConfListById(edbInfo.EdbInfoId)
-	if err != nil && err.Error() != utils.ErrNoRow() {
-		errMsg = "获取预测指标配置信息失败"
-		return
-	}
-	if len(predictEdbConfList) == 0 {
-		errMsg = "获取预测指标配置信息失败"
-		err = errors.New(errMsg)
-		return
+	if !isTimeBetween { //如果不是区间数据,那么就结束日期为空
+		endDate = ``
 	}
-	predictEdbConf = predictEdbConfList[0]
-
-	// 来源指标
-	sourceEdbInfoItem, err = data_manage.GetEdbInfoById(predictEdbConf.SourceEdbInfoId)
-	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
-			errMsg = "找不到来源指标信息"
-			err = errors.New(errMsg)
-		}
-		return
-	}
-
-	allDataList := make([]*data_manage.EdbDataList, 0)
-	//获取指标数据(实际已生成)
-	dataList, err = data_manage.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, startDate, endDate)
-	if err != nil {
-		return
-	}
-	// 如果选择了日期,那么需要筛选所有的数据,用于未来指标的生成
-	if startDate != `` {
-		allDataList, err = data_manage.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, "", "")
-		if err != nil {
-			return
-		}
-	} else {
-		allDataList = dataList
-	}
-	// 获取预测指标未来的数据
-	predictDataList := make([]*data_manage.EdbDataList, 0)
-
-	endDateStr := edbInfo.EndDate //预测指标的结束日期
-
-	if isTimeBetween && endDate != `` { //如果是时间区间,同时截止日期不为空的情况,那么
-		reqEndDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
-		endDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.EndDate, time.Local)
-		// 如果选择的时间区间结束日期 晚于 当天,那么预测数据截止到当天
-		if reqEndDateTime.Before(endDateTime) {
-			endDateStr = endDate
-		}
-	}
-	//predictDataList, err = GetChartPredictEdbInfoDataList(*predictEdbConf, startDate, sourceEdbInfoItem.LatestDate, sourceEdbInfoItem.LatestValue, endDateStr, edbInfo.Frequency)
-	predictEdbConfDataList := make([]data_manage.PredictEdbConfAndData, 0)
-	for _, v := range predictEdbConfList {
-		predictEdbConfDataList = append(predictEdbConfDataList, data_manage.PredictEdbConfAndData{
-			ConfigId:         v.ConfigId,
-			PredictEdbInfoId: v.PredictEdbInfoId,
-			SourceEdbInfoId:  v.SourceEdbInfoId,
-			RuleType:         v.RuleType,
-			FixedValue:       v.FixedValue,
-			Value:            v.Value,
-			EndDate:          v.EndDate,
-			ModifyTime:       v.ModifyTime,
-			CreateTime:       v.CreateTime,
-			DataList:         make([]*data_manage.EdbDataList, 0),
-		})
-	}
-	//var predictMinValue, predictMaxValue float64
-	predictDataList, _, _, err, _ = GetChartPredictEdbInfoDataListByConfList(predictEdbConfDataList, startDate, sourceEdbInfoItem.LatestDate, endDateStr, edbInfo.Frequency, edbInfo.DataDateType, allDataList)
-	if err != nil {
-		return
-	}
-	dataList = append(dataList, predictDataList...)
-	//if len(predictDataList) > 0 {
-	//	// 如果最小值 大于 预测值,那么将预测值作为最小值数据返回
-	//	if edbInfo.MinValue > predictMinValue {
-	//		edbInfo.MinValue = predictMinValue
-	//	}
-	//
-	//	// 如果最大值 小于 预测值,那么将预测值作为最大值数据返回
-	//	if edbInfo.MaxValue < predictMaxValue {
-	//		edbInfo.MaxValue = predictMaxValue
-	//	}
-	//}
-	return
+	return GetPredictCalculateDataListByPredictEdbInfo(edbInfo, startDate, endDate)
 }
 
 // GetChartDataList 通过完整的预测数据 进行 季节性图、公历、农历处理

+ 165 - 103
services/data/predict_edb_info_rule.go

@@ -1525,21 +1525,24 @@ func GetChartPredictEdbInfoDataListByRuleNAnnualAverage(edbInfoId int, configVal
 
 // AnnualValueInversionConf 年度值倒推规则
 type AnnualValueInversionConf struct {
-	Value float64 `description:"年度值"`
-	Type  int     `description:"分配方式,1:均值法;2:同比法"`
-	Year  int     `description:"同比年份"`
+	Value    float64 `description:"年度值"`
+	Type     int     `description:"分配方式,1:均值法;2:同比法"`
+	Year     int     `description:"同比年份"`
+	YearList []int   `description:"指定年份列表"`
 }
 
 // GetChartPredictEdbInfoDataListByRuleAnnualValueInversion 根据 年度值倒推 规则获取预测数据
-// ETA预测规则:年度值倒推:设定年度值,余额=年度值-年初至今累计值(算法参考累计值),进行余额分配,均值法分配时保证每期数值相等(日度/周度:剩余期数=剩余自然日历天数/今年指标最新日期自然日历天数*今年至今指标数据期数;旬度/月度/季度/半年度:剩余期数=全年期数(36\12\4\2)-今年至今自然日历期数),同比法保证每期同比相等(同比增速=余额/同比年份相应日期的余额,预测值等于同比年份同期值*同比增速)
-// 举例:
-// 指标A 日度 最新日期 2023-05-19 年初至今累计值100
-// 设置年度值1000
-// 则余额=1000-100=900
-// 均值法分配:剩余期数=226/139*120=195.11
-// 今年之后的每一期预测值=900/195.11=4.6128
-// 同比法分配:同比增速=900/同比年份5.19的余额
-// 预测值=同比年份5-20的值*(1+同比增速)
+// 预测指标-年度值倒推
+// 1、年度值倒推,选择同比法,支持选择多个年份(当前只可选择一个年份)。选择多个年份时,计算多个年份的余额平均,和同期平均。
+// 2、年度值倒推,同比法的算法优化:旬度,月度,季度,半年度的算法,同原先算法。
+// 日度、周度值算法更新(假设指标实际值最新日期月2024/3/1):
+// 1、设定年度值
+// 2、计算余额:年度值-年初至今累计值
+// 3、年初至今累计值计算方法:用后置填充变频成连续自然日日度数据。计算1/1至指标最新日期(2024/3/3/1)的累计值。
+// 4、计算同比年份全年累计值,年初至指标最新值同期(2023/3/1)累计值,两者相减得到同比年份同期余额,再取平均值,作为最终的同期余额
+// 5、用今年余额/去年同期余额得到同比增速。
+// 6、每一期预测值,为同比年份的同期值,乘以(1+同比)。去年同期,用变频后的序列对应。
+// 7、如果选择的同比年份是多个。则计算多个年份的平均余额。今年余额/平均余额=同比增速。同比基数为多个年份的同期平均值
 func GetChartPredictEdbInfoDataListByRuleAnnualValueInversion(edbInfoId int, configValue string, dayList []time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*data_manage.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*data_manage.EdbDataList, minValue, maxValue float64, err error) {
 	if frequency == "年度" {
 		err = errors.New("当前指标频度是年度,不允许配置年度值倒推")
@@ -1560,6 +1563,11 @@ func GetChartPredictEdbInfoDataListByRuleAnnualValueInversion(edbInfoId int, con
 	newPredictEdbInfoData = predictEdbInfoData
 	index := len(allDataList)
 
+	// 没有数据,直接返回
+	if index <= 0 {
+		return
+	}
+
 	// 配置的年度值
 	yearValueConfig := annualValueInversionConf.Value
 
@@ -1708,112 +1716,166 @@ func GetChartPredictEdbInfoDataListByRuleAnnualValueInversion(edbInfoId int, con
 	// 同比法分配
 	// 同比法保证每期同比相等(同比增速=余额/同比年份相应日期的余额,预测值等于同比年份同期值*同比增速);
 	// 同比法分配:同比增速=900/同比年份5.19的余额
-
+	yearList := annualValueInversionConf.YearList
+	if len(yearList) == 0 {
+		//兼容历史数据
+		yearList = append(yearList, annualValueInversionConf.Year)
+	}
 	// 每年截止到当前日期的累计值
 	dateTotalMap := make(map[time.Time]float64)
+
+	//把每一期的期数和日期绑定
+	dateIndexMap := make(map[time.Time]int)
+	indexDateMap := make(map[int]time.Time)
 	// 每年的累计值(计算使用)
 	yearTotalMap := make(map[int]float64)
-	for _, v := range allDataList {
-		currTime, tmpErr := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
-		if tmpErr != nil {
-			err = tmpErr
-			return
+	//数据按找后值填充的方式处理成连续自然日日度数据
+	allDataListMap := make(map[string]float64)
+	// todo 如果是日度和周度,用后置填充变频成连续自然日日度数据。计算1/1至指标最新日期(2024/3/3/1)的累计值
+	switch frequency {
+	case "日度", "周度":
+		for _, v := range allDataList {
+			allDataListMap[v.DataTime] = v.Value
+		}
+		//找到最早日期的的年份的1月1日,转成time格式
+		earliestYear := allDataList[0].DataTime[:4]
+		earliestYearFirstDay, _ := time.ParseInLocation(utils.FormatDate, earliestYear+"-01-01", time.Local)
+		days := int(currDayTime.Sub(earliestYearFirstDay).Hours() / float64(24))
+		//循环累加日期,直到循环到最新日期
+		for i := 0; i <= days; i++ {
+			currentDate := earliestYearFirstDay.AddDate(0, 0, i)
+			currentDateStr := currentDate.Format(utils.FormatDate)
+			val, ok := allDataListMap[currentDateStr]
+			if !ok { //如果不存在,则填充后值
+				//循环向后查找数据,直到找到
+				for j := i + 1; j <= days; j++ {
+					//循环往后取值
+					currentDateTmp := earliestYearFirstDay.AddDate(0, 0, j)
+					currentDateTmpStr := currentDateTmp.Format(utils.FormatDate)
+					if tmpVal, ok1 := allDataListMap[currentDateTmpStr]; ok1 {
+						allDataListMap[currentDateStr] = tmpVal
+						val = tmpVal
+						break
+					}
+				}
+			}
+			//计算每一天的年初至今累计值
+			yearVal := yearTotalMap[currentDate.Year()]
+			if frequency == "周度" {
+				// 每日累计值需要当前值除7
+				yearVal = yearVal + val/7
+			} else {
+				yearVal = yearVal + val
+			}
+			yearTotalMap[currentDate.Year()] = yearVal
+			dateTotalMap[currentDate] = yearVal
+			dateIndexMap[currentDate] = i
+			indexDateMap[i] = currentDate
 		}
-		yearVal := yearTotalMap[currTime.Year()]
-		yearVal = yearVal + v.Value
-		yearTotalMap[currTime.Year()] = yearVal
-		dateTotalMap[currTime] = yearVal
-	}
-
-	//(同比增速=余额/同比年份相应日期的余额,预测值等于同比年份同期值*同比增速);
-	for k, currentDate := range dayList {
-		currYearBalance := yearValueConfig - yearTotalMap[currentDate.Year()] // 当年的余额
-
-		// 上一期的日期
-		prevDateStr := allDataList[len(allDataList)-1].DataTime
-		prevDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, prevDateStr, time.Local)
-		if tmpErr != nil {
-			err = tmpErr
-			return
+	default:
+		for k, v := range allDataList {
+			currTime, tmpErr := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			allDataListMap[v.DataTime] = v.Value
+			yearVal := yearTotalMap[currTime.Year()]
+			yearVal = yearVal + v.Value
+			yearTotalMap[currTime.Year()] = yearVal
+			dateTotalMap[currTime] = yearVal
+			dateIndexMap[currTime] = k
+			indexDateMap[k] = currTime
 		}
-
-		//同比年份相应日期
-		lastYear := annualValueInversionConf.Year + (currentDate.Year() - currDayTime.Year())
-
-		// 前N年的上一期时间;前N年的当期时间;
-		var lastPrevDateTime, lastDateTime time.Time
-
-		switch frequency {
-		case "半年度", "季度":
-			lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
-			lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
-		case "月度":
-			lastDateTime = time.Date(lastYear, currentDate.Month()+1, 1, 0, 0, 0, 0, currentDate.Location()).AddDate(0, 0, -1)
-			lastPrevDateTime = time.Date(lastYear, prevDateTime.Month()+1, 1, 0, 0, 0, 0, prevDateTime.Location()).AddDate(0, 0, -1)
-		case "旬度":
-			if prevDateTime.Day() == 10 || prevDateTime.Day() == 20 {
-				lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
-				lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
-			} else {
-				lastDateTime = time.Date(lastYear, currentDate.Month()+1, 1, 0, 0, 0, 0, currentDate.Location()).AddDate(0, 0, -1)
-				lastPrevDateTime = time.Date(lastYear, prevDateTime.Month()+1, 1, 0, 0, 0, 0, prevDateTime.Location()).AddDate(0, 0, -1)
+	}
+	// 当年的余额
+	currYearBalance := yearValueConfig - yearTotalMap[currDayTime.Year()]
+	//fmt.Printf("当年的余额%.4f=给定额度%.4f-当年累计值%.4f\n", currYearBalance, yearValueConfig, yearTotalMap[currDayTime.Year()])
+	// 循环统计同比年份同期余额
+	var sum, avg float64
+	for _, year := range yearList {
+		yearTotal := yearTotalMap[year]
+		//fmt.Printf("同比年份的累计值%.4f\n", yearTotal)
+		tmpDate := time.Date(year, currDayTime.Month(), currDayTime.Day(), 0, 0, 0, 0, currDayTime.Location())
+		//fmt.Printf("同比年份的同期%s\n", tmpDate)
+		dateTotal, ok := dateTotalMap[tmpDate]
+		//fmt.Printf("同比年份的同期累计值%.4f\n", dateTotal)
+		if ok {
+			sum = sum + (yearTotal - dateTotal)
+		} else {
+			// 查找下一期的余额
+			tmpIndex, ok1 := dateIndexMap[tmpDate]
+			if ok1 {
+				for tmpDateTime := indexDateMap[tmpIndex+1]; tmpDateTime.Year() == year; tmpDateTime = indexDateMap[tmpIndex+1] {
+					dateTotal, ok = dateTotalMap[tmpDateTime]
+					if ok {
+						//fmt.Printf("同比年份的同期累计值%.4f\n", dateTotal)
+						sum = sum + (yearTotal - dateTotal)
+						break
+					}
+					tmpIndex += 1
+				}
 			}
-		case "周度", "日度":
-			lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
-			lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
 		}
-
-		// 同比年份相应日期的累计值
-		var dateTotal float64
-
-		dateTotal, ok := dateTotalMap[lastPrevDateTime]
-		if !ok { //如果没有找到这个日期,那么就往前面找,一直到找到这个累计值,或者找完这一年
-			yearFirstDayTime := time.Date(lastPrevDateTime.Year(), 1, 1, 0, 0, 0, 0, lastDateTime.Location())
-			for tmpDateTime := lastPrevDateTime.AddDate(0, 0, -1); tmpDateTime.After(yearFirstDayTime) || tmpDateTime.Equal(yearFirstDayTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
-				dateTotal, ok = dateTotalMap[tmpDateTime]
-				if ok {
-					break
+	}
+	//fmt.Printf("同比年份的余额%.4f\n", sum)
+	avg = sum / float64(len(yearList))
+	//fmt.Printf("同比年份的余额%.4f\n", avg)
+	// 同比增速=当年余额/同比年份上一期日期的余额
+	tbVal := decimal.NewFromFloat(currYearBalance).Div(decimal.NewFromFloat(avg))
+	/*tbVal11, _ := tbVal.Round(4).Float64()
+	fmt.Printf("同比增速%.4f\n", tbVal11)*/
+	//(同比增速=余额/同比年份相应日期的余额的平均值,预测值等于同比年份同期值*同比增速);
+	for k, currentDate := range dayList {
+		// 循环遍历多个同比年份
+		var valSum float64
+		for _, year := range yearList {
+			//多个同比年份的同期值的平均值
+			tmpCurrentDate := time.Date(year, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
+			if tmpVal, ok := allDataListMap[tmpCurrentDate.Format(utils.FormatDate)]; ok {
+				valSum += tmpVal
+			} else {
+				// 查找下一期的余额
+				tmpIndex, ok1 := dateIndexMap[tmpCurrentDate]
+				if ok1 {
+					for tmpDateTime := indexDateMap[tmpIndex+1]; tmpDateTime.Year() == year; tmpDateTime = indexDateMap[tmpIndex+1] {
+						tmpVal, ok = allDataListMap[tmpDateTime.Format(utils.FormatDate)]
+						if ok {
+							valSum += tmpVal
+							break
+						}
+						tmpIndex += 1
+					}
 				}
 			}
 		}
+		lastDateVal := valSum / float64(len(yearList))
 
-		//同比年份相应的上一期日期的余额
-		lastYearDateBalance := yearTotalMap[lastPrevDateTime.Year()] - dateTotal
-		if lastYearDateBalance == 0 {
-			continue
+		//预测值 = 同比年份同期值*同比增速
+		tmpVal, _ := decimal.NewFromFloat(lastDateVal).Mul(tbVal).Round(4).Float64()
+		currentDateStr := currentDate.Format(utils.FormatDate)
+		tmpData := &data_manage.EdbDataList{
+			EdbDataId:     edbInfoId + 100000 + index + k,
+			EdbInfoId:     edbInfoId,
+			DataTime:      currentDateStr,
+			Value:         tmpVal,
+			DataTimestamp: currentDate.UnixNano() / 1e6,
 		}
+		newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
+		allDataList = append(allDataList, tmpData)
+		existMap[currentDateStr] = tmpVal
 
-		// 同比增速=当年余额/同比年份上一期日期的余额
-		tbVal := decimal.NewFromFloat(currYearBalance).Div(decimal.NewFromFloat(lastYearDateBalance))
-
-		// 获取同比年份同期值,获取失败的话,就不处理
-		if lastDateVal, ok := existMap[lastDateTime.Format(utils.FormatDate)]; ok {
-			//预测值 = 同比年份同期值*同比增速
-			tmpVal, _ := decimal.NewFromFloat(lastDateVal).Mul(tbVal).Round(4).Float64()
-			currentDateStr := currentDate.Format(utils.FormatDate)
-			tmpData := &data_manage.EdbDataList{
-				EdbDataId:     edbInfoId + 100000 + index + k,
-				EdbInfoId:     edbInfoId,
-				DataTime:      currentDateStr,
-				Value:         tmpVal,
-				DataTimestamp: currentDate.UnixNano() / 1e6,
-			}
-			newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
-			allDataList = append(allDataList, tmpData)
-			existMap[currentDateStr] = tmpVal
-
-			yearVal := yearTotalMap[currentDate.Year()]
-			yearVal = yearVal + tmpVal
-			yearTotalMap[currentDate.Year()] = yearVal
-			dateTotalMap[currentDate] = yearVal
+		yearVal := yearTotalMap[currentDate.Year()]
+		yearVal = yearVal + tmpVal
+		yearTotalMap[currentDate.Year()] = yearVal
+		dateTotalMap[currentDate] = yearVal
 
-			// 最大最小值
-			if tmpVal < minValue {
-				minValue = tmpVal
-			}
-			if tmpVal > maxValue {
-				maxValue = tmpVal
-			}
+		// 最大最小值
+		if tmpVal < minValue {
+			minValue = tmpVal
+		}
+		if tmpVal > maxValue {
+			maxValue = tmpVal
 		}
 	}
 

+ 14 - 0
services/data/range_analysis/chart_info.go

@@ -424,6 +424,13 @@ func GetChartDataByEdbInfoList(chartInfoId int, dateType, startYear int, startDa
 			edbInfoMapping.ConvertUnit = req.DataConvertConf.Unit
 			edbInfoMapping.ConvertEnUnit = req.DataConvertConf.Unit
 		}
+		if edbInfoMapping.ConvertUnit == "无" {
+			edbInfoMapping.ConvertUnit = ""
+		}
+		if edbInfoMapping.ConvertEnUnit == "无" {
+			edbInfoMapping.ConvertEnUnit = ""
+		}
+
 		dataList := edbInfoMapping.DataList.([]*data_manage.EdbDataList)
 		// 处理上下限
 		var maxData, minData float64
@@ -570,6 +577,12 @@ func GetChartDataByEdbInfoListBySeries(chartInfoId int, dateType, startYear int,
 			edbInfoMapping.ConvertUnit = req.DataConvertConf.Unit
 			edbInfoMapping.ConvertEnUnit = req.DataConvertConf.Unit
 		}
+		if edbInfoMapping.ConvertUnit == "无" {
+			edbInfoMapping.ConvertUnit = ""
+		}
+		if edbInfoMapping.ConvertEnUnit == "无" {
+			edbInfoMapping.ConvertEnUnit = ""
+		}
 		edbInfoMapping.DataList = dataList
 		// 处理上下限
 		var maxData, minData float64
@@ -824,6 +837,7 @@ func getChartDataByEdbInfo(edbInfoMapping *data_manage.ChartEdbInfoMapping, req
 					dealDataList = append(dealDataList, v)
 				}
 			}
+			newDataList = dealDataList
 		case 2:
 			for i, v := range newDataList {
 				if utils.CompareFloatByOpStrings(req.UnNormalDataConf.Formula, v.Value, req.UnNormalDataConf.Value) {

+ 50 - 0
services/data/yongyi.go

@@ -0,0 +1,50 @@
+package data
+
+import (
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/data_manage/request"
+	"eta/eta_api/utils"
+	"fmt"
+)
+
+// YongyiIndexSource2Edb 新增涌益咨询数据源到指标库
+func YongyiIndexSource2Edb(req request.YongyiIndexSource2EdbReq, lang string) (edb *data_manage.EdbInfo, err error, errMsg string, skip bool) {
+	if req.EdbCode == "" {
+		err = fmt.Errorf("指标ID为空")
+		return
+	}
+	defer func() {
+		if err != nil {
+			tips := fmt.Sprintf("YongyiIndexSource2Edb新增失败, Err: %s", err.Error())
+			fmt.Println(tips)
+			utils.FileLog.Info(tips)
+		}
+	}()
+	source := utils.DATA_SOURCE_YONYI
+
+	// 是否新增过指标
+	exist, e := data_manage.GetEdbInfoByEdbCode(source, req.EdbCode)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = fmt.Errorf("获取指标是否存在失败, err: %s", e.Error())
+		return
+	}
+	if exist != nil {
+		skip = true
+		return
+	}
+
+	// 开始结束时间
+	var startDate, endDate string
+
+	// 新增指标库
+	edbInfo, e, msg, _ := EdbInfoAdd(source, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, startDate, endDate, req.AdminId, req.AdminRealName, lang)
+	if e != nil {
+		errMsg = msg
+		err = fmt.Errorf("EdbInfo: 新增指标失败, err: %s", e.Error())
+		return
+	}
+
+	edb = edbInfo
+
+	return
+}

+ 28 - 6
services/document_manage_service/document_manage_service.go

@@ -176,7 +176,7 @@ func DocumentReportList(documentType int, chartPermissionIdList []string, classi
 	if orderField != "" && orderType != "" {
 		condition += ` order by t1.` + orderField + ` ` + orderType
 	} else {
-		condition += ` order by t1.modify_time desc`
+		condition += ` order by t1.report_update_time desc`
 	}
 
 	outsideReportList, err := document_manage_model.GetOutsideReportListByCondition(condition, pars, startSize, pageSize)
@@ -213,7 +213,7 @@ func GetAllClassifyIdsByParentId(parentId int) ([]string, error) {
 	return classifyIdList, nil
 }
 
-func RuiSiReportList(classifyIdFirst, classifyIdSecond, classifyIdThird int, keyword string, orderField, orderType string, startSize, pageSize int) (*models.ReportListResp, error) {
+func RuiSiReportList(classifyIdFirst, classifyIdSecond, classifyIdThird int, chartPermissionIdList []string, keyword string, orderField, orderType string, startSize, pageSize int) (*models.ReportListResp, error) {
 	logs.Info("RuiSiReportList")
 
 	var condition string
@@ -241,6 +241,28 @@ func RuiSiReportList(classifyIdFirst, classifyIdSecond, classifyIdThird int, key
 	// 已发布的报告
 	condition += ` and a.state = 2`
 
+	if len(chartPermissionIdList) > 0 {
+		classifyIds, err := models.GetClassifyIdsByPermissionId(chartPermissionIdList)
+		if err != nil {
+			return nil, err
+		}
+
+		if len(classifyIds) > 0 {
+			condition += ` AND ( (a.classify_id_first IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) AND a.classify_id_second = 0) 
+			OR (a.classify_id_second IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) AND a.classify_id_third = 0) 
+			OR a.classify_id_third IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) )`
+			for _, classifyId := range classifyIds {
+				pars = append(pars, classifyId)
+			}
+			for _, classifyId := range classifyIds {
+				pars = append(pars, classifyId)
+			}
+			for _, classifyId := range classifyIds {
+				pars = append(pars, classifyId)
+			}
+		}
+	}
+
 	count, err := models.GetReportListCountV1(condition, pars)
 	if err != nil {
 		return nil, err
@@ -371,9 +393,9 @@ func DocumentUpdate(outsideReport *document_manage_model.OutsideReportBO) error
 	if outsideReport.Title != "" {
 		report.Title = outsideReport.Title
 	}
-	if outsideReport.Abstract != "" {
-		report.Abstract = outsideReport.Abstract
-	}
+
+	report.Abstract = outsideReport.Abstract
+
 	if outsideReport.ClassifyId > 0 {
 		report.ClassifyId = outsideReport.ClassifyId
 	}
@@ -384,7 +406,7 @@ func DocumentUpdate(outsideReport *document_manage_model.OutsideReportBO) error
 		report.Content = outsideReport.Content
 	}
 	report.ModifyTime = utils.GetCurrentTime()
-	report.ReportUpdateTime = utils.GetCurrentTime()
+	//report.ReportUpdateTime = utils.GetCurrentTime()
 	err = document_manage_model.UpdateOutsideReport(report)
 	if err != nil {
 		return fmt.Errorf("更新报告失败, Err: %s", err.Error())

+ 65 - 27
services/excel/lucky_sheet.go

@@ -6,13 +6,13 @@ import (
 	"eta/eta_api/models/data_manage/excel/request"
 	"eta/eta_api/utils"
 	"fmt"
-	"math"
 	"os"
 	"reflect"
 	"strconv"
 	"strings"
 	"time"
 
+	"github.com/shopspring/decimal"
 	"github.com/tealeg/xlsx"
 	"github.com/xuri/excelize/v2"
 )
@@ -1768,40 +1768,78 @@ func GetTableDataByMixedTableData(config [][]request.MixedTableCellDataReq, hide
 					}
 					showFormatValue := fmt.Sprintf("%v", cell.ShowFormatValue)
 					tmp.Monitor = showFormatValue
-					tmpShowValue, err := strconv.ParseFloat(cell.Value, 64)
+					// 如果没有showValue, 则使用value
+					if cell.ShowValue == "" {
+						_, err := strconv.ParseFloat(cell.Value, 64)
+						if err == nil {
+							cell.ShowValue = cell.Value
+						}
+					}
+					_, err := strconv.ParseFloat(cell.Value, 64)
 					if err == nil {
-						switch styleConfig.Last {
-						case "nt":
-							// 先进行数字的百分比计算,然后保留小数点位数
-							percent := tmpShowValue * 100
+						hasPercent := false
+						if styleConfig.Nt == "percent" {
+							hasPercent = true
+						}
+						// 修复历史数据
+						if styleConfig.Pn != 0 {
 							if styleConfig.Decimal == nil {
-								continue
+								styleConfig.Decimal = new(int)
 							}
-							factor := math.Pow(10, float64(*styleConfig.Decimal))
-							rounded := math.Round(percent*factor) / factor
-							tmp.Monitor = fmt.Sprintf("%g%%", rounded)
-						case "decimal":
-							// 先保留小数点位数,再进行百分比计算
-							if styleConfig.Decimal == nil {
-								continue
+							*styleConfig.Decimal += styleConfig.Pn
+							if *styleConfig.Decimal < 0 {
+								*styleConfig.Decimal = 0
 							}
-							factor := math.Pow(10, float64(*styleConfig.Decimal))
-							rounded := math.Round(tmpShowValue*factor) / factor
-							if styleConfig.Nt == "percent" {
-								percent := rounded * 100
-								var precisionStr string
-								if *styleConfig.Decimal > 2 {
-									precision := *styleConfig.Decimal - 2
-									precisionStr = strconv.FormatFloat(rounded, 'f', precision, 64)
-								} else {
-									precisionStr = strconv.FormatFloat(math.Round(percent), 'f', -1, 64)
-								}
-								tmp.Monitor = fmt.Sprintf("%s%%", precisionStr)
+						}
+
+						if styleConfig.Decimal != nil {
+							tmp.Monitor = utils.RoundNumber(cell.ShowValue, *styleConfig.Decimal, hasPercent)
+						} else {
+							if hasPercent {
+								numDecimal, _ := decimal.NewFromString(cell.ShowValue)
+								tmpStr := numDecimal.Mul(decimal.NewFromInt(100)).String()
+								tmp.Monitor = tmpStr + "%"
 							} else {
-								tmp.Monitor = fmt.Sprintf("%g", rounded)
+								tmp.Monitor = cell.ShowValue
 							}
 						}
+					} else {
+						if cell.DataType == request.CustomTextDT {
+							tmp.Monitor = cell.Value
+						}
 					}
+					// 	switch styleConfig.Last {
+					// 	case "nt":
+					// 		// 先进行数字的百分比计算,然后保留小数点位数
+					// 		percent := tmpShowValue * 100
+					// 		if styleConfig.Decimal == nil {
+					// 			continue
+					// 		}
+					// 		factor := math.Pow(10, float64(*styleConfig.Decimal))
+					// 		rounded := math.Round(percent*factor) / factor
+					// 		tmp.Monitor = fmt.Sprintf("%g%%", rounded)
+					// 	case "decimal":
+					// 		// 先保留小数点位数,再进行百分比计算
+					// 		if styleConfig.Decimal == nil {
+					// 			continue
+					// 		}
+					// 		factor := math.Pow(10, float64(*styleConfig.Decimal))
+					// 		rounded := math.Round(tmpShowValue*factor) / factor
+					// 		if styleConfig.Nt == "percent" {
+					// 			percent := rounded * 100
+					// 			var precisionStr string
+					// 			if *styleConfig.Decimal > 2 {
+					// 				precision := *styleConfig.Decimal - 2
+					// 				precisionStr = strconv.FormatFloat(rounded, 'f', precision, 64)
+					// 			} else {
+					// 				precisionStr = strconv.FormatFloat(math.Round(percent), 'f', -1, 64)
+					// 			}
+					// 			tmp.Monitor = fmt.Sprintf("%s%%", precisionStr)
+					// 		} else {
+					// 			tmp.Monitor = fmt.Sprintf("%g", rounded)
+					// 		}
+					// 	}
+					// }
 
 				}
 				dataCol = append(dataCol, tmp)

+ 1 - 1
services/ppt.go

@@ -144,7 +144,7 @@ func SavePPTReport(pptId, classifyId int, title string, adminInfo *system.Admin)
 		ClassifyNameThird:  classifyNameThird,
 		Title:              title,
 		Abstract:           "",
-		Author:             "FICC团队",
+		Author:             "",
 		Frequency:          utils.ReportFrequencyDefault,
 		State:              1,
 		Content:            htm,

+ 26 - 5
services/report_v2.go

@@ -4,6 +4,7 @@ import (
 	"archive/zip"
 	"errors"
 	"eta/eta_api/models"
+	"eta/eta_api/models/company"
 	"eta/eta_api/models/report"
 	"eta/eta_api/models/report_approve"
 	"eta/eta_api/models/system"
@@ -1412,6 +1413,17 @@ func UpdateReportVideo(reportInfo *models.Report) {
 			if reportInfo.VideoUrl != "" && reportInfo.VideoName != "" && reportInfo.VideoSize != "" && reportInfo.VideoPlaySeconds != "" {
 				return
 			}
+
+			weekClassifyId, err := company.GetReportClassifyIdByConfigKey("report_week_classify_id")
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				msg := "获取周报ID配置失败:" + err.Error()
+				utils.FileLog.Info(msg)
+				return
+			}
+
+			if reportInfo.ClassifyIdFirst == weekClassifyId {
+				return
+			}
 			videoUrl, videoName, videoSize, videoPlaySeconds, e := CreateReportVideo(reportInfo.Title, html.UnescapeString(reportContent), time.Now().Format(utils.FormatDateTime))
 			if e != nil {
 				err = e
@@ -1443,18 +1455,27 @@ func GetGeneralPdfUrl(reportCode, classifyFirstName string, reportLayout int8) (
 		return
 	}
 
-	conf, e := models.GetBusinessConfByKey("ReportViewUrl")
-	if e != nil {
-		return
+	// 优先取Report2ImgUrl(用于兼容内外网环境的), 没有的话取报告详情地址
+	var reportUrl string
+	conf, _ := models.GetBusinessConfByKey(models.BusinessConfReport2ImgUrl)
+	if conf != nil && conf.ConfVal != "" {
+		reportUrl = conf.ConfVal
+	}
+	if reportUrl == "" {
+		conf, e := models.GetBusinessConfByKey(models.BusinessConfReportViewUrl)
+		if e != nil {
+			return
+		}
+		reportUrl = conf.ConfVal
 	}
 
 	switch reportLayout {
 	case 1:
 		// 普通布局
-		pdfUrl = fmt.Sprintf("%s/reportshare_pdf?code=%s", conf.ConfVal, reportCode)
+		pdfUrl = fmt.Sprintf("%s/reportshare_pdf?code=%s", reportUrl, reportCode)
 	case 2:
 		// 智能布局
-		pdfUrl = fmt.Sprintf("%s/reportshare_smart_pdf?code=%s", conf.ConfVal, reportCode)
+		pdfUrl = fmt.Sprintf("%s/reportshare_smart_pdf?code=%s", reportUrl, reportCode)
 	}
 
 	return

+ 1 - 1
services/smart_report.go

@@ -160,7 +160,7 @@ async def main():
     })
 
     # 在生成PDF之前等待2秒
-    await asyncio.sleep(10)
+    await asyncio.sleep(15)
 
     await page.pdf({
         'path': "%s",

+ 13 - 0
utils/common.go

@@ -2752,3 +2752,16 @@ func GenerateEdbCode(num int, pre string) (edbCode string, err error) {
 func GetCurrentTime() string {
 	return time.Now().Format("2006-01-02 15:04:05")
 }
+
+// RoundNumber 保留小数位数
+func RoundNumber(num string, decimalPlaces int, hasPercent bool) string {
+	numDecimal, _ := decimal.NewFromString(num)
+	if hasPercent {
+		numDecimal = numDecimal.Mul(decimal.NewFromInt(100))
+	}
+	numStr := numDecimal.Round(int32(decimalPlaces)).StringFixed(int32(decimalPlaces))
+	if hasPercent {
+		numStr += "%"
+	}
+	return numStr
+}

+ 2 - 0
utils/config.go

@@ -224,6 +224,7 @@ var (
 	MinIoUseSSL           string
 	MinIoPort             string
 	MinIoRegion           string
+	MinIoFileDownloadHost string
 )
 
 // PythonUrlReport2Img 生成长图服务地址
@@ -563,6 +564,7 @@ func init() {
 		MinIoUseSSL = config["minio_use_ssl"]
 		MinIoPort = config["minio_port"]
 		MinIoRegion = config["minio_region"]
+		MinIoFileDownloadHost = config["minio_file_download_host"]
 	}
 
 	// S3-OSS相关

+ 1 - 0
utils/constants.go

@@ -170,6 +170,7 @@ const (
 	DATA_SOURCE_PREDICT_CALCULATE_ZSXY                          // 预测指数修匀->73
 	DATA_SOURCE_CALCULATE_ZDYFX                                 // 自定义分析->74
 	DATA_SOURCE_CALCULATE_RJZ                                   // 日均值计算->75
+	DATA_SOURCE_YONYI                                = 76       //涌益咨询
 	DATA_SOURCE_GFEX                                 = 78       // 广州期货交易所->78
 	DATA_SOURCE_ICPI                                 = 79       // ICPI消费价格指数->79
 	DATA_SOURCE_BLOOMBERG                            = 83       // bloomberg彭博数据

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