Browse Source

图库接口补充

hsun 2 năm trước cách đây
mục cha
commit
33c7708bb3

+ 467 - 0
controllers/data_manage/chart_classify.go

@@ -0,0 +1,467 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"fmt"
+	"hongze/hongze_ETA_mobile_api/controllers"
+	"hongze/hongze_ETA_mobile_api/models"
+	"hongze/hongze_ETA_mobile_api/models/data_manage"
+	"hongze/hongze_ETA_mobile_api/models/system"
+	"hongze/hongze_ETA_mobile_api/services/data"
+	"hongze/hongze_ETA_mobile_api/utils"
+	"time"
+)
+
+// ChartClassifyController 数据管理-分类模块
+type ChartClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// ChartClassifyListV2
+// @Title 图表分类列表
+// @Description 图表分类列表接口
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /chart_classify/list [get]
+func (this *ChartClassifyController) ChartClassifyListV2() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	resp := new(data_manage.ChartClassifyListResp)
+
+	// 获取当前账号的不可见指标
+	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 {
+		errMsg, err := getChartClassifyListForMe(*this.SysUser, resp)
+		if err != nil {
+			br.Msg = errMsg
+			br.ErrMsg = err.Error()
+			return
+		}
+		// 移除没有权限的图表
+		allNodes := handleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
+		resp.AllNodes = allNodes
+
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = resp
+		fmt.Println("source my classify")
+		return
+	}
+
+	//判断是否存在缓存,如果存在缓存,那么直接从缓存中获取
+	key := utils.CACHE_CHART_CLASSIFY
+	if utils.Re == nil {
+		if utils.Re == nil && utils.Rc.IsExist(key) {
+			if data, err1 := utils.Rc.RedisBytes(key); err1 == nil {
+				err := json.Unmarshal(data, &resp)
+				if err == nil && resp != nil {
+					// 移除没有权限的图表
+					allNodes := handleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
+					resp.AllNodes = allNodes
+
+					br.Ret = 200
+					br.Success = true
+					br.Msg = "获取成功"
+					br.Data = resp
+					fmt.Println("source redis")
+					return
+				}
+			}
+		}
+	}
+
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	allChartInfo, err := data_manage.GetChartInfoAll(utils.CHART_SOURCE_DEFAULT)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		return
+	}
+
+	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range allChartInfo {
+		chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
+	}
+	rootChildMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range classifyAll {
+		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
+		if existItems, ok := chartInfoMap[v.ChartClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.ChartClassifyItems, 0)
+			v.Children = items
+		}
+	}
+	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
+	for _, v := range rootList {
+		if existItems, ok := rootChildMap[v.ChartClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.ChartClassifyItems, 0)
+			v.Children = items
+		}
+		nodeAll = append(nodeAll, v)
+	}
+	//
+	//
+	//nodeAll := make([]*data_manage.ChartClassifyItems, 0)
+	//for k := range rootList {
+	//	rootNode := rootList[k]
+	//	data.ChartClassifyListMakeTree(classifyAll, rootNode)
+	//	nodeAll = append(nodeAll, rootNode)
+	//}
+	resp.AllNodes = nodeAll
+
+	// 将数据加入缓存
+	if utils.Re == nil {
+		data, _ := json.Marshal(resp)
+		utils.Rc.Put(key, data, 2*time.Hour)
+	}
+
+	// 移除没有权限的图表
+	allNodes := handleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
+	resp.AllNodes = allNodes
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// getChartClassifyListForMe 获取我创建的图表
+func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "获取失败"
+		return
+	}
+
+	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "获取失败"
+		return
+	}
+
+	allChartInfo, err := data_manage.GetChartInfoByAdminId(utils.CHART_SOURCE_DEFAULT, adminInfo.AdminId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "获取失败"
+		return
+	}
+
+	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range allChartInfo {
+		chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
+	}
+	rootChildMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range classifyAll {
+		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
+		if existItems, ok := chartInfoMap[v.ChartClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.ChartClassifyItems, 0)
+			v.Children = items
+		}
+	}
+	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
+	for _, v := range rootList {
+		if existItems, ok := rootChildMap[v.ChartClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.ChartClassifyItems, 0)
+			v.Children = items
+		}
+		nodeAll = append(nodeAll, v)
+	}
+	resp.AllNodes = nodeAll
+
+	return
+}
+
+// handleNoPermissionChart 图表列表返回,将没有权限的图表移除
+func handleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
+	// 移除没有权限的图表
+	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
+	for _, node := range allNodes {
+		// 二级分类
+		tmpNodeInfo := *node
+		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
+		if node.Children != nil {
+			for _, chartList := range node.Children {
+				tmpInfo := *chartList
+				tmpList := make([]*data_manage.ChartClassifyItems, 0)
+
+				if chartList.Children != nil {
+					for _, chartInfo := range chartList.Children {
+						// 如果指标不可见,那么就不返回该指标
+						if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
+							continue
+						}
+						tmpList = append(tmpList, chartInfo)
+					}
+				}
+				tmpInfo.Children = tmpList
+				tmpNodeList = append(tmpNodeList, &tmpInfo)
+			}
+		}
+		tmpNodeInfo.Children = tmpNodeList
+		newAllNodes = append(newAllNodes, &tmpNodeInfo)
+	}
+
+	return
+}
+
+// ChartClassifyItems
+// @Title 获取所有图表分类接口-不包含图表
+// @Description 获取所有图表分类接口-不包含图表
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /chart_classify/items [get]
+func (this *ChartClassifyController) ChartClassifyItems() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_DEFAULT)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	classifyAll, err := data_manage.GetChartClassifyAll(utils.CHART_SOURCE_DEFAULT)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	nodeAll := make([]*data_manage.ChartClassifyItems, 0)
+	for k := range rootList {
+		rootNode := rootList[k]
+		data.ChartClassifyItemsMakeTree(classifyAll, rootNode)
+		nodeAll = append(nodeAll, rootNode)
+	}
+
+	language := `CN`
+	// 指标显示的语言
+	{
+		configDetail, _ := system.GetConfigDetailByCode(this.SysUser.AdminId, system.ChartLanguageVar)
+		if configDetail != nil {
+			language = configDetail.ConfigValue
+		} else {
+			configDetail, _ = system.GetDefaultConfigDetailByCode(system.ChartLanguageVar)
+			if configDetail != nil {
+				language = configDetail.ConfigValue
+			}
+		}
+	}
+
+	resp := new(data_manage.ChartClassifyListResp)
+	resp.AllNodes = nodeAll
+	resp.Language = language
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// DeleteChartClassify
+// @Title 删除图表分类/图表
+// @Description 删除图表分类/图表接口
+// @Param	request	body data_manage.DeleteChartClassifyReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /chart_classify/delete [post]
+func (this *ChartClassifyController) DeleteChartClassify() {
+	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.DeleteChartClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartClassifyId < 0 && req.ChartInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	//删除分类
+	if req.ChartClassifyId > 0 && req.ChartInfoId == 0 {
+		//判断是否含有指标
+		count, err := data_manage.GetChartInfoCountByClassifyId(req.ChartClassifyId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "删除失败"
+			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
+			return
+		}
+
+		if count > 0 {
+			br.Msg = "该目录下存在关联指标,不可删除"
+			br.IsSendEmail = false
+			return
+		}
+
+		err = data_manage.DeleteChartClassify(req.ChartClassifyId)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "删除失败,Err:" + err.Error()
+			return
+		}
+	}
+	resp := new(data_manage.AddChartInfoResp)
+	//删除图表
+	if req.ChartInfoId > 0 {
+		chartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				br.Msg = "图表已删除,请刷新页面"
+				br.ErrMsg = "指标不存在,Err:" + err.Error()
+				return
+			} else {
+				br.Msg = "删除失败"
+				br.ErrMsg = "删除失败,获取指标信息失败,Err:" + err.Error()
+				return
+			}
+		}
+		if chartInfo == nil {
+			br.Msg = "图表已删除,请刷新页面"
+			return
+		}
+		//图表操作权限
+		ok := data.CheckOpChartPermission(sysUser, chartInfo.SysUserId)
+		if !ok {
+			br.Msg = "没有该图表的操作权限"
+			br.ErrMsg = "没有该图表的操作权限"
+			return
+		}
+
+		//删除图表及关联指标
+		err = data_manage.DeleteChartInfoAndData(req.ChartInfoId)
+		if err != nil {
+			br.Msg = "删除失败"
+			br.ErrMsg = "删除失败,Err:" + err.Error()
+			return
+		}
+		//删除ES
+		{
+			go data.EsDeleteChartInfo(req.ChartInfoId)
+			// 删除MY ETA 图表 es数据
+			go data.EsDeleteMyChartInfoByChartInfoId(req.ChartInfoId)
+		}
+
+		var condition string
+		var pars []interface{}
+		condition += " AND chart_classify_id=? AND source = ?  "
+		pars = append(pars, chartInfo.ChartClassifyId, utils.CHART_SOURCE_DEFAULT)
+
+		condition += " AND chart_info_id>? ORDER BY create_time ASC LIMIT 1 "
+		pars = append(pars, req.ChartInfoId)
+
+		nextItem, err := data_manage.GetChartInfoByCondition(condition, pars)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "删除失败"
+			br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
+			return
+		}
+
+		if nextItem != nil {
+			resp.UniqueCode = nextItem.UniqueCode
+			resp.ChartInfoId = nextItem.ChartInfoId
+		} else {
+			var condition string
+			var pars []interface{}
+
+			condition += " AND level=3 "
+			//pars = append(pars, chartInfo.ChartClassifyId)
+
+			condition += " AND chart_classify_id>? ORDER BY chart_classify_id ASC LIMIT 1 "
+			pars = append(pars, chartInfo.ChartClassifyId)
+
+			classifyItem, err := data_manage.GetChartClassifyByCondition(condition, pars)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "删除失败"
+				br.ErrMsg = "获取下一级图库分类信息失败,Err:" + err.Error()
+				return
+			}
+			if classifyItem != nil {
+				nextItem, err = data_manage.GetNextChartInfo(chartInfo.ChartClassifyId)
+				if err != nil && err.Error() != utils.ErrNoRow() {
+					br.Msg = "删除失败"
+					br.ErrMsg = "获取下一级图库信息失败,Err:" + err.Error()
+					return
+				}
+				if nextItem != nil {
+					resp.UniqueCode = nextItem.UniqueCode
+					resp.ChartInfoId = nextItem.ChartInfoId
+				}
+			}
+		}
+		//新增操作日志
+		{
+			chartLog := new(data_manage.ChartInfoLog)
+			chartLog.ChartName = chartInfo.ChartName
+			chartLog.ChartInfoId = req.ChartInfoId
+			chartLog.ChartClassifyId = chartInfo.ChartClassifyId
+			chartLog.SysUserId = sysUser.AdminId
+			chartLog.SysUserRealName = sysUser.RealName
+			chartLog.UniqueCode = chartInfo.UniqueCode
+			chartLog.CreateTime = time.Now()
+			chartLog.Content = string(this.Ctx.Input.RequestBody)
+			chartLog.Status = "删除图表"
+			chartLog.Method = this.Ctx.Input.URI()
+			go data_manage.AddChartInfoLog(chartLog)
+		}
+	}
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.Data = resp
+	br.IsAddLog = true
+}

+ 678 - 0
controllers/data_manage/chart_info.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"hongze/hongze_ETA_mobile_api/controllers"
+	"hongze/hongze_ETA_mobile_api/models"
 	"hongze/hongze_ETA_mobile_api/models/data_manage"
 	"hongze/hongze_ETA_mobile_api/models/system"
 	"hongze/hongze_ETA_mobile_api/services/data"
@@ -236,3 +237,680 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 
 	return
 }
+
+// ChartInfoDetail
+// @Title 获取图表详情
+// @Description 获取图表详情接口
+// @Param   ChartInfoId   query   int  true       "图表id"
+// @Param   DateType   query   int  true       "日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"
+// @Param   StartDate   query   string  true       "自定义开始日期"
+// @Param   EndDate   query   string  true       "自定义结束日期"
+// @Param   Calendar   query   string  true       "公历/农历"
+// @Param   SeasonStartDate   query   string  true       "季节性图开始日期"
+// @Param   SeasonEndDate   query   string  true       "季节性图结束日期"
+// @Param   EdbInfoId   query   string  true       "指标ID,多个用英文逗号隔开"
+// @Param   ChartType   query   int  true       "生成样式:1:曲线图,2:季节性图"
+// @Success 200 {object} data_manage.ChartInfoDetailResp
+// @router /chart_info/detail [get]
+func (this *ChartInfoController) ChartInfoDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	chartInfoId, _ := this.GetInt("ChartInfoId")
+
+	dateType, _ := this.GetInt("DateType")
+	fmt.Println("dateType:", dateType)
+	if dateType <= 0 {
+		dateType = 3
+	}
+
+	startDate := this.GetString("StartDate")
+	endDate := this.GetString("EndDate")
+	seasonStartDate := this.GetString("SeasonStartDate")
+	seasonEndDate := this.GetString("SeasonEndDate")
+
+	edbInfoId := this.GetString("EdbInfoId")
+	chartType, _ := this.GetInt("ChartType")
+
+	fmt.Println("seasonStartDate:", seasonStartDate)
+	fmt.Println("seasonEndDate:", seasonEndDate)
+
+	calendar := this.GetString("Calendar")
+	if calendar == "" {
+		calendar = "公历"
+	}
+	switch dateType {
+	case 1:
+		startDate = "2000-01-01"
+	case 2:
+		startDate = "2010-01-01"
+	case 3:
+		startDate = "2015-01-01"
+	case 4:
+		//startDate = strconv.Itoa(time.Now().Year()) + "-01-01"
+		startDate = "2021-01-01"
+	case 5:
+		startDate = startDate + "-01"
+		endDate = endDate + "-01"
+	case 6:
+		startDate = startDate + "-01"
+	case 7:
+		startDate = "2018-01-01"
+	case 8:
+		startDate = "2019-01-01"
+	case 9:
+		startDate = "2020-01-01"
+	case 11:
+		startDate = "2022-01-01"
+	}
+
+	var err error
+	chartInfo := new(data_manage.ChartInfoView)
+	if chartInfoId > 0 {
+		chartInfo, err = data_manage.GetChartInfoViewById(chartInfoId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				br.Msg = "图被删除,请刷新页面"
+				br.ErrMsg = "图被删除,请刷新页面,Err:" + err.Error()
+				return
+			}
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+			return
+		}
+		chartType = chartInfo.ChartType
+	}
+
+	if chartType == 2 {
+		if seasonStartDate != "" {
+			startDate = seasonStartDate + "-01-01"
+		} else {
+			fivePre := time.Now().AddDate(-4, 0, 0).Year()
+			startDate = strconv.Itoa(fivePre) + "-01-01"
+		}
+		if seasonEndDate != "" {
+			endDate = seasonEndDate + "-12-31"
+		} else {
+			endDate = "" //time.Now().AddDate(2, 0, 0).Format(utils.FormatDate)
+		}
+	}
+
+	mappingList := make([]*data_manage.ChartEdbInfoMapping, 0)
+	if chartInfoId > 0 {
+		mappingList, err = data_manage.GetChartEdbMappingList(chartInfoId)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
+			return
+		}
+	} else {
+		if edbInfoId != "" {
+			mappingList, err = data_manage.GetChartEdbMappingListByEdbInfoId(edbInfoId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
+				return
+			}
+		}
+	}
+
+	// 图表额外数据参数
+	extraConfigStr := chartInfo.ExtraConfig
+	// 柱方图的一些配置
+	var barConfig data_manage.BarChartInfoReq
+	if chartInfo != nil && chartInfo.ChartType == 7 {
+		if chartInfo.BarConfig == `` {
+			br.Msg = "柱方图未配置"
+			br.ErrMsg = "柱方图未配置"
+			return
+		}
+		err := json.Unmarshal([]byte(chartInfo.BarConfig), &barConfig)
+		if err != nil {
+			br.Msg = "柱方图配置异常"
+			br.ErrMsg = "柱方图配置异常"
+			return
+		}
+		extraConfigStr = chartInfo.BarConfig
+	}
+
+	// 获取图表中的指标数据
+	edbList, xEdbIdValue, yDataList, dataResp, err, errMsg := data.GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr)
+	if err != nil {
+		br.Msg = "获取失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
+		return
+	}
+	warnEdbList := make([]string, 0)
+	for _, v := range edbList {
+		if v.IsNullData {
+			warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
+		}
+	}
+	if len(warnEdbList) > 0 {
+		chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
+	}
+	if chartInfoId > 0 && chartInfo != nil {
+		//判断是否加入我的图库
+		{
+			var myChartCondition string
+			var myChartPars []interface{}
+			myChartCondition += ` AND a.admin_id=? `
+			myChartPars = append(myChartPars, sysUser.AdminId)
+			myChartCondition += ` AND a.chart_info_id=? `
+			myChartPars = append(myChartPars, chartInfo.ChartInfoId)
+
+			myChartList, err := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取我的图表信息失败,GetMyChartByCondition,Err:" + err.Error()
+				return
+			}
+			if myChartList != nil && len(myChartList) > 0 {
+				chartInfo.IsAdd = true
+				chartInfo.MyChartId = myChartList[0].MyChartId
+				chartInfo.MyChartClassifyId = myChartList[0].MyChartClassifyId
+			}
+		}
+	}
+
+	//图表操作权限
+	chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId)
+	//判断是否需要展示英文标识
+	chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList, chartInfo.Source, chartInfo.ChartType)
+
+	resp := new(data_manage.ChartInfoDetailResp)
+	resp.ChartInfo = chartInfo
+	resp.EdbInfoList = edbList
+	resp.XEdbIdValue = xEdbIdValue
+	resp.YDataList = yDataList
+	resp.BarChartInfo = barConfig
+	resp.DataResp = dataResp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// ChartInfoEdbInfoDetail
+// @Title 图表-获取指标详情
+// @Description 图表-获取指标详情接口
+// @Param   EdbInfoId   query   int  true       "指标ID"
+// @Param   DateType   query   int  true       "日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间,6:自定义起始时间至今,7:18年至今,8:19年至今,9:20年至今"
+// @Param   StartDate   query   string  true       "自定义开始日期"
+// @Param   EndDate   query   string  true       "自定义结束日期"
+// @Param   EdbInfoType  query int  true     "1:标准指标,0:领先指标,默认为标准指标"
+// @Param   LeadValue    query   int  true       "领先值"
+// @Param   LeadUnit     query   string  true        "领先单位:天,月,季,周"
+// @Success 200 {object} data_manage.ChartEdbInfoDetailResp
+// @router /chart_info/edb_info/detail [get]
+func (this *ChartInfoController) ChartInfoEdbInfoDetail() {
+	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
+	}
+	edbInfoId, _ := this.GetInt("EdbInfoId")
+	if edbInfoId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	dateType, _ := this.GetInt("DateType")
+	if dateType <= 0 {
+		dateType = 3
+	}
+
+	edbInfoType, _ := this.GetInt("EdbInfoType")
+	if edbInfoType < 0 {
+		edbInfoType = 1
+	}
+
+	leadValue, _ := this.GetInt("LeadValue")
+	if leadValue < 0 {
+		leadValue = 0
+	}
+
+	leadUnit := this.GetString("LeadUnit")
+
+	startDate := this.GetString("StartDate")
+	endDate := this.GetString("EndDate")
+
+	isTimeBetween := false //是否是时间区间
+	switch dateType {
+	case 1:
+		startDate = "2000-01-01"
+		endDate = ""
+	case 2:
+		startDate = "2010-01-01"
+		endDate = ""
+	case 3:
+		startDate = "2015-01-01"
+		endDate = ""
+	case 4:
+		//startDate = strconv.Itoa(time.Now().Year()) + "-01-01"
+		startDate = "2021-01-01"
+		endDate = ""
+	case 5:
+		startDate = startDate + "-01"
+		endDate = endDate + "-01"
+		isTimeBetween = true
+	case 6:
+		//startDate = startDate + "-01"
+		endDate = ""
+	case 7:
+		startDate = "2018-01-01"
+		endDate = ""
+	case 8:
+		startDate = "2019-01-01"
+		endDate = ""
+	case 9:
+		startDate = "2020-01-01"
+		endDate = ""
+	case 11:
+		startDate = "2022-01-01"
+		endDate = ""
+	default:
+		startDate = startDate + "-01"
+		endDate = endDate + "-01"
+	}
+
+	// 兼容日期错误
+	{
+		if strings.Count(startDate, "-") == 1 {
+			startDate = startDate + "-01"
+		}
+		if strings.Count(endDate, "-") == 1 {
+			endDate = endDate + "-01"
+		}
+	}
+
+	if startDate == "" {
+		br.Msg = "参数错误"
+		br.Msg = "参数错误,无效的查询日期"
+		return
+	}
+
+	var startDateReal string
+	var diffSeconds int64
+	if leadValue > 0 && leadUnit != "" {
+		var startTimeRealTemp time.Time
+		startDateParse, err := time.Parse(utils.FormatDate, startDate)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取数据失败,日期格式错误:startDate:" + startDate
+			return
+		}
+		switch leadUnit {
+		case "天":
+			startTimeRealTemp = startDateParse.AddDate(0, 0, -leadValue)
+		case "月":
+			startTimeRealTemp = startDateParse.AddDate(0, -leadValue, 0)
+		case "季":
+			startTimeRealTemp = startDateParse.AddDate(0, -3*leadValue, 0)
+		case "周":
+			startTimeRealTemp = startDateParse.AddDate(0, 0, -7*leadValue)
+		case "年":
+			startTimeRealTemp = startDateParse.AddDate(-leadValue, 0, 0)
+		}
+
+		if startTimeRealTemp.Before(startDateParse) {
+			startDateReal = startTimeRealTemp.Format(utils.FormatDate)
+			diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
+		} else {
+			startDateReal = startDate
+			diffSeconds = 0
+		}
+	} else {
+		startDateReal = startDate
+	}
+
+	edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.Msg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	var dataList []*data_manage.EdbDataList
+	var minData, maxData float64
+
+	switch edbInfo.EdbInfoType {
+	case 0: //普通源指标
+		dataList, err = data_manage.GetEdbDataList(edbInfo.Source, edbInfoId, startDateReal, endDate)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.Msg = "获取失败,Err:" + err.Error()
+			return
+		}
+		//查询区间内最大最小值
+		minData, maxData, err = data_manage.GetEdbDataListMinAndMax(edbInfo.Source, edbInfoId, startDateReal, endDate)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.Msg = "获取指标最新的最大最小值失败,Err:" + err.Error()
+			return
+		}
+	case 1: //预测指标
+		tmpDataList, sourceEdbInfoItem, _, err, _ := data.GetPredictDataListByPredictEdbInfo(edbInfo, startDateReal, endDate, isTimeBetween)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.Msg = "获取失败,Err:" + err.Error()
+			return
+		}
+		dataList = tmpDataList
+		// 有预测数据,且为普通的预测指标
+		if len(dataList) > 0 && edbInfo.EdbInfoType == 0 {
+			//查询区间内最大最小值
+			minData, maxData, err = data_manage.GetEdbDataListMinAndMax(sourceEdbInfoItem.Source, sourceEdbInfoItem.EdbInfoId, startDateReal, endDate)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.Msg = "获取指标最新的最大最小值失败,Err:" + err.Error()
+				return
+			}
+
+			tmpValue := dataList[len(dataList)-1]
+
+			// 如果最大值 小于 预测值,那么将预测值作为最大值数据返回
+			if edbInfo.MaxValue < tmpValue.Value {
+				maxData = tmpValue.Value
+			}
+
+			// 如果最小值 大于 预测值,那么将预测值作为最小值数据返回
+			if edbInfo.MinValue > tmpValue.Value {
+				minData = tmpValue.Value
+			}
+		}
+	}
+
+	if diffSeconds != 0 {
+		dataListLen := len(dataList)
+		for i := 0; i < dataListLen; i++ {
+			dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
+		}
+
+		day, err := utils.GetDaysBetween2Date(utils.FormatDate, startDate, startDateReal)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.Msg = "获取领先滞后的的日期间隔失败,Err:" + err.Error()
+			return
+		}
+		latestDateTime, err := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.Msg = "指标日期转换失败,Err:" + err.Error()
+			return
+		}
+		edbInfo.LatestDate = latestDateTime.AddDate(0, 0, day).Format(utils.FormatDate)
+	}
+	mapping := new(data_manage.ChartEdbInfoMapping)
+	mapping.EdbInfoId = edbInfo.EdbInfoId
+	mapping.EdbInfoCategoryType = edbInfo.EdbInfoType
+	mapping.SourceName = edbInfo.SourceName
+	mapping.Source = edbInfo.Source
+	mapping.EdbCode = edbInfo.EdbCode
+	mapping.EdbName = edbInfo.EdbName
+	mapping.EdbType = edbInfo.EdbType
+	mapping.Frequency = edbInfo.Frequency
+	mapping.Unit = edbInfo.Unit
+	mapping.StartDate = edbInfo.StartDate
+	mapping.EndDate = edbInfo.EndDate
+	mapping.ChartEdbMappingId = 0
+	mapping.ChartInfoId = 0
+	mapping.MaxData = maxData
+	mapping.MinData = minData
+	mapping.IsOrder = false
+	mapping.IsAxis = 1
+	mapping.EdbInfoType = 1
+	mapping.LeadValue = 0
+	mapping.LeadUnit = ""
+	mapping.LeadUnitEn = ""
+	mapping.ChartStyle = ""
+	mapping.ChartColor = ""
+	mapping.PredictChartColor = ""
+	mapping.ChartWidth = 0
+	mapping.LatestDate = edbInfo.LatestDate
+	mapping.DataList = dataList
+
+	resp := new(data_manage.ChartEdbInfoDetailResp)
+	resp.EdbInfo = mapping
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// CopyChartInfo
+// @Title 复制并新增图表接口
+// @Description 新增图表接口
+// @Param	request	body data_manage.CopyAddChartInfoReq true "type json string"
+// @Success 200 {object} data_manage.AddChartInfoResp
+// @router /chart_info/copy [post]
+func (this *ChartInfoController) CopyChartInfo() {
+	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_CHART_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req data_manage.CopyAddChartInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	// 获取原图表信息
+	oldChartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
+	if err != nil {
+		br.Msg = "获取原图表信息失败"
+		br.ErrMsg = "获取原图表信息失败,Err:" + err.Error()
+		return
+	}
+
+	//校验图表名称是否重复
+	req.ChartName = strings.Trim(req.ChartName, " ")
+	if req.ChartName == "" {
+		br.Msg = "请填写图表名称!"
+		return
+	}
+	if req.ChartClassifyId <= 0 {
+		br.Msg = "分类参数错误!"
+		return
+	}
+	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "分类不存在"
+			br.ErrMsg = "分类不存在"
+			return
+		}
+		br.Msg = "获取分类信息失败"
+		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+		return
+	}
+	if chartClassify == nil {
+		br.Msg = "分类不存在"
+		br.ErrMsg = "分类不存在"
+		return
+	}
+	//count, err := data_manage.ChartInfoExist("", edbInfoIdStr)
+	//if err != nil && err.Error() != utils.ErrNoRow() {
+	//	br.Msg = "保存失败"
+	//	br.ErrMsg = "判断图表名称是否存在失败,Err:" + err.Error()
+	//	return
+	//}
+	//if count > 0 {
+	//	br.Msg = "所选指标已存在相同指标"
+	//	return
+	//}
+	//判断图表是否存在
+	var condition string
+	var pars []interface{}
+	condition += " AND chart_classify_id=? "
+	pars = append(pars, req.ChartClassifyId)
+
+	condition += " AND chart_name=? AND source = ? "
+	pars = append(pars, req.ChartName, utils.CHART_SOURCE_DEFAULT)
+
+	count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
+	if err != nil {
+		br.Msg = "判断图表名称是否存在失败"
+		br.ErrMsg = "判断图表名称是否存在失败,Err:" + err.Error()
+		return
+	}
+
+	if count > 0 {
+		br.Msg = "图表已存在,请重新填写"
+		br.IsSendEmail = false
+		return
+	}
+
+	//获取原图表关联的指标信息列表
+	edbMappingList, err := data_manage.GetChartEdbMappingList(req.ChartInfoId)
+	if err != nil {
+		br.Msg = "获取图表关联的指标信息失败!"
+		return
+	}
+
+	//添加图表
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	chartInfo := &data_manage.ChartInfo{
+		ChartInfoId:     0,
+		ChartName:       req.ChartName,
+		ChartClassifyId: req.ChartClassifyId,
+		SysUserId:       sysUser.AdminId,
+		SysUserRealName: sysUser.RealName,
+		UniqueCode:      utils.MD5(utils.CHART_PREFIX + "_" + timestamp),
+		CreateTime:      time.Now(),
+		ModifyTime:      time.Now(),
+		DateType:        oldChartInfo.DateType,
+		StartDate:       oldChartInfo.StartDate,
+		EndDate:         oldChartInfo.EndDate,
+		IsSetName:       oldChartInfo.IsSetName,
+		EdbInfoIds:      oldChartInfo.EdbInfoIds,
+		ChartType:       oldChartInfo.ChartType,
+		Calendar:        oldChartInfo.Calendar,
+		SeasonStartDate: oldChartInfo.SeasonStartDate,
+		SeasonEndDate:   oldChartInfo.SeasonEndDate,
+		ChartImage:      oldChartInfo.ChartImage,
+		BarConfig:       oldChartInfo.BarConfig,
+		//Sort:     sort,
+		LeftMin:     oldChartInfo.LeftMin,
+		LeftMax:     oldChartInfo.LeftMax,
+		RightMin:    oldChartInfo.RightMin,
+		RightMax:    oldChartInfo.RightMax,
+		Disabled:    oldChartInfo.Disabled,
+		Source:      oldChartInfo.Source,
+		ExtraConfig: oldChartInfo.ExtraConfig,
+	}
+	newId, err := data_manage.AddChartInfo(chartInfo)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartInfoId = int(newId)
+
+	// 添加图表与指标的关联关系
+	{
+		mapList := make([]*data_manage.ChartEdbMapping, 0)
+		for _, v := range edbMappingList {
+			timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+			mapItem := &data_manage.ChartEdbMapping{
+				//ChartEdbMappingId: 0,
+				ChartInfoId: chartInfo.ChartInfoId,
+				EdbInfoId:   v.EdbInfoId,
+				CreateTime:  time.Now(),
+				ModifyTime:  time.Now(),
+				UniqueCode:  utils.MD5(utils.CHART_PREFIX + "_" + timestamp),
+				MaxData:     v.MaxData,
+				MinData:     v.MinData,
+				IsOrder:     v.IsOrder,
+				IsAxis:      v.IsAxis,
+				EdbInfoType: v.EdbInfoType,
+				LeadValue:   v.LeadValue,
+				LeadUnit:    v.LeadUnit,
+				ChartStyle:  v.ChartStyle,
+				ChartColor:  v.ChartColor,
+				ChartWidth:  v.ChartWidth,
+				Source:      v.Source,
+			}
+			mapList = append(mapList, mapItem)
+		}
+		err = data_manage.AddChartEdbMapping(mapList)
+		if err != nil {
+			br.Msg = "保存失败"
+			br.ErrMsg = "保存失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	//添加es数据
+	go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	//修改my eta es数据
+	go data.EsAddOrEditMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
+
+	//新增操作日志
+	{
+		chartLog := new(data_manage.ChartInfoLog)
+		chartLog.ChartInfoId = chartInfo.ChartInfoId
+		chartLog.ChartName = req.ChartName
+		chartLog.ChartClassifyId = req.ChartClassifyId
+		chartLog.SysUserId = sysUser.AdminId
+		chartLog.SysUserRealName = sysUser.RealName
+		chartLog.UniqueCode = chartInfo.UniqueCode
+		chartLog.CreateTime = time.Now()
+		chartLog.Content = string(this.Ctx.Input.RequestBody)
+		chartLog.Status = "新增图表"
+		chartLog.Method = this.Ctx.Input.URI()
+		go data_manage.AddChartInfoLog(chartLog)
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = data_manage.AddChartInfoResp{
+		ChartInfoId: chartInfo.ChartInfoId,
+		UniqueCode:  chartInfo.UniqueCode,
+		ChartType:   chartInfo.ChartType,
+	}
+	br.IsAddLog = true
+}

+ 135 - 0
controllers/data_manage/correlation/correlation_chart_classify.go

@@ -0,0 +1,135 @@
+package correlation
+
+import (
+	"hongze/hongze_ETA_mobile_api/controllers"
+	"hongze/hongze_ETA_mobile_api/models"
+	"hongze/hongze_ETA_mobile_api/models/data_manage"
+	"hongze/hongze_ETA_mobile_api/utils"
+)
+
+// CorrelationChartClassifyController 相关性图表分类
+type CorrelationChartClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// ChartClassifyList
+// @Title 相关性图表分类列表
+// @Description 相关性图表分类列表接口
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Param   Source   query   int  true       "图表类型,3:相关性,4:滚动相关性"
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /chart_classify/list [get]
+func (this *CorrelationChartClassifyController) ChartClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	resp := new(data_manage.ChartClassifyListResp)
+
+	// 获取当前账号的不可见指标
+	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 {
+	//	errMsg, err := getChartClassifyListForMe(*this.SysUser, resp)
+	//	if err != nil {
+	//		br.Msg = errMsg
+	//		br.ErrMsg = err.Error()
+	//		return
+	//	}
+	//	br.Ret = 200
+	//	br.Success = true
+	//	br.Msg = "获取成功"
+	//	br.Data = resp
+	//	return
+	//}
+
+	source, _ := this.GetInt("Source")
+	if source <= 0 {
+		source = utils.CHART_SOURCE_CORRELATION
+	}
+
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_CORRELATION)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	allChartInfo, err := data_manage.GetChartInfoAll(source)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		return
+	}
+
+	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range allChartInfo {
+		if !isShowMe {
+			chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
+			continue
+		}
+		if v.SysUserId != this.SysUser.AdminId {
+			continue
+		}
+		chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
+	}
+	rootChildMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range rootList {
+		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
+		if existItems, ok := chartInfoMap[v.ChartClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.ChartClassifyItems, 0)
+			v.Children = items
+		}
+	}
+
+	// 移除没有权限的图表
+	allNodes := handleNoPermissionChart(rootList, noPermissionChartIdMap)
+	resp.AllNodes = allNodes
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// handleNoPermissionChart 图表列表返回,将没有权限的图表移除
+func handleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
+	// 移除没有权限的图表
+	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
+	for _, node := range allNodes {
+		// 二级分类
+		tmpNodeInfo := *node
+		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
+
+		if node.Children != nil {
+			for _, chartInfo := range node.Children {
+				// 如果指标不可见,那么就不返回该指标
+				if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
+					continue
+				}
+				tmpNodeList = append(tmpNodeList, chartInfo)
+			}
+		}
+
+		tmpNodeInfo.Children = tmpNodeList
+		newAllNodes = append(newAllNodes, &tmpNodeInfo)
+	}
+
+	return
+}

+ 129 - 0
controllers/data_manage/correlation/correlation_chart_info.go

@@ -395,3 +395,132 @@ func (this *CorrelationChartInfoController) List() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+// Copy
+// @Title 复制并新增图表接口
+// @Description 新增图表接口
+// @Param	request	body data_manage.CopyAddChartInfoReq true "type json string"
+// @Success 200 {object} data_manage.AddChartInfoResp
+// @router /chart_info/copy [post]
+func (this *CorrelationChartInfoController) Copy() {
+	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_CHART_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req data_manage.CopyAddChartInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	// 获取原图表信息
+	oldChartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
+	if err != nil {
+		br.Msg = "获取原图表信息失败"
+		br.ErrMsg = "获取原图表信息失败,Err:" + err.Error()
+		return
+	}
+	if oldChartInfo.Source == utils.CHART_SOURCE_ROLLING_CORRELATION {
+		br.Msg = `滚动相关性图不支持另存为`
+		br.IsSendEmail = false
+		return
+	}
+
+	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByChartId(req.ChartInfoId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = `保存失败`
+		br.ErrMsg = "获取配置与图表的关联关系失败,ERR:" + err.Error()
+		return
+	}
+
+	correlationChart := new(data_manage.ChartInfoCorrelation)
+	if e := correlationChart.GetItemById(req.ChartInfoId); e != nil {
+		br.Msg = "另存为失败"
+		br.ErrMsg = "获取原图表相关性信息失败, Err:" + e.Error()
+		return
+	}
+
+	correlationChartInfoReq := data_manage.CorrelationChartInfoReq{
+		LeadValue:          correlationChart.LeadValue,
+		LeadUnit:           correlationChart.LeadUnit,
+		CalculateValue:     correlationChart.CalculateValue,
+		CalculateUnit:      correlationChart.CalculateUnit,
+		BaseCalculateUnit:  correlationChart.BaseCalculateUnit,
+		BaseCalculateValue: correlationChart.BaseCalculateValue,
+		StartDate:          correlationChart.StartDate.Format(utils.FormatDate),
+		EndDate:            correlationChart.EndDate.Format(utils.FormatDate),
+		EdbInfoIdList: []data_manage.CorrelationChartInfoEdbItemReq{
+			{
+				EdbInfoId: correlationChart.EdbInfoIdFirst,
+				Name:      "",
+				NameEn:    "",
+			}, {
+				EdbInfoId: correlationChart.EdbInfoIdSecond,
+				Name:      "",
+				NameEn:    "",
+			},
+		},
+	}
+
+	chartInfo, err, errMsg, isSendEmail := correlationServ.CopyChartInfo(multipleGraphConfigChartMapping.MultipleGraphConfigId, req.ChartClassifyId, req.ChartName, correlationChartInfoReq, sysUser)
+
+	if err != nil {
+		br.Msg = "保存失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+
+	//新增操作日志
+	{
+		chartLog := new(data_manage.ChartInfoLog)
+		chartLog.ChartInfoId = chartInfo.ChartInfoId
+		chartLog.ChartName = req.ChartName
+		chartLog.ChartClassifyId = req.ChartClassifyId
+		chartLog.SysUserId = sysUser.AdminId
+		chartLog.SysUserRealName = sysUser.RealName
+		chartLog.UniqueCode = chartInfo.UniqueCode
+		chartLog.CreateTime = time.Now()
+		chartLog.Content = string(this.Ctx.Input.RequestBody)
+		chartLog.Status = "复制相关性图表"
+		chartLog.Method = this.Ctx.Input.URI()
+		go data_manage.AddChartInfoLog(chartLog)
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = data_manage.AddChartInfoResp{
+		ChartInfoId: chartInfo.ChartInfoId,
+		UniqueCode:  chartInfo.UniqueCode,
+		ChartType:   chartInfo.ChartType,
+	}
+	br.IsAddLog = true
+}

+ 162 - 0
controllers/data_manage/future_good/future_good_chart_classify.go

@@ -0,0 +1,162 @@
+package future_good
+
+import (
+	"fmt"
+	"hongze/hongze_ETA_mobile_api/controllers"
+	"hongze/hongze_ETA_mobile_api/models"
+	"hongze/hongze_ETA_mobile_api/models/data_manage"
+	"hongze/hongze_ETA_mobile_api/models/system"
+	"hongze/hongze_ETA_mobile_api/utils"
+)
+
+// FutureGoodChartClassifyController 期货指标分类
+type FutureGoodChartClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// ChartClassifyList
+// @Title 商品价格图表分类列表
+// @Description 商品价格图表分类列表接口
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /chart_classify/list [get]
+func (this *FutureGoodChartClassifyController) ChartClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	resp := new(data_manage.ChartClassifyListResp)
+
+	// 获取当前账号的不可见指标
+	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 {
+		errMsg, err := getChartClassifyListForMe(*this.SysUser, resp)
+		if err != nil {
+			br.Msg = errMsg
+			br.ErrMsg = err.Error()
+			return
+		}
+		// 移除没有权限的图表
+		allNodes := handleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
+		resp.AllNodes = allNodes
+
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = resp
+		fmt.Println("source my classify")
+		return
+	}
+
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	allChartInfo, err := data_manage.GetChartInfoAll(utils.CHART_SOURCE_FUTURE_GOOD)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		return
+	}
+
+	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range allChartInfo {
+		chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
+	}
+	rootChildMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range rootList {
+		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
+		if existItems, ok := chartInfoMap[v.ChartClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.ChartClassifyItems, 0)
+			v.Children = items
+		}
+	}
+
+	// 移除没有权限的图表
+	allNodes := handleNoPermissionChart(rootList, noPermissionChartIdMap)
+	resp.AllNodes = allNodes
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// getChartClassifyListForMe 获取我创建的图表
+func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartClassifyListResp) (errMsg string, err error) {
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_FUTURE_GOOD)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "获取失败"
+		return
+	}
+
+	allChartInfo, err := data_manage.GetChartInfoByAdminId(utils.CHART_SOURCE_FUTURE_GOOD, adminInfo.AdminId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "获取失败"
+		return
+	}
+
+	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range allChartInfo {
+		chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
+	}
+	rootChildMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range rootList {
+		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
+		if existItems, ok := chartInfoMap[v.ChartClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.ChartClassifyItems, 0)
+			v.Children = items
+		}
+	}
+	resp.AllNodes = rootList
+
+	return
+}
+
+// handleNoPermissionChart 图表列表返回,将没有权限的图表移除
+func handleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
+	// 移除没有权限的图表
+	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
+	for _, node := range allNodes {
+		// 二级分类
+		tmpNodeInfo := *node
+		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
+
+		if node.Children != nil {
+			for _, chartInfo := range node.Children {
+				// 如果指标不可见,那么就不返回该指标
+				if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
+					continue
+				}
+				tmpNodeList = append(tmpNodeList, chartInfo)
+			}
+		}
+
+		tmpNodeInfo.Children = tmpNodeList
+		newAllNodes = append(newAllNodes, &tmpNodeInfo)
+	}
+
+	return
+}

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

@@ -313,3 +313,221 @@ func (this *FutureGoodChartInfoController) ChartInfoSearchByEs() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+// CopyChartInfo
+// @Title 复制并新增图表接口
+// @Description 新增图表接口
+// @Param	request	body data_manage.CopyAddChartInfoReq true "type json string"
+// @Success 200 {object} data_manage.AddChartInfoResp
+// @router /chart_info/copy [post]
+func (this *FutureGoodChartInfoController) CopyChartInfo() {
+	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_CHART_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+	var req data_manage.CopyAddChartInfoReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	// 获取原图表信息
+	oldChartInfo, err := data_manage.GetChartInfoById(req.ChartInfoId)
+	if err != nil {
+		br.Msg = "获取原图表信息失败"
+		br.ErrMsg = "获取原图表信息失败,Err:" + err.Error()
+		return
+	}
+
+	//校验图表名称是否重复
+	req.ChartName = strings.Trim(req.ChartName, " ")
+	if req.ChartName == "" {
+		br.Msg = "请填写图表名称!"
+		return
+	}
+	if req.ChartClassifyId <= 0 {
+		br.Msg = "分类参数错误!"
+		return
+	}
+	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "分类不存在"
+			br.ErrMsg = "分类不存在"
+			return
+		}
+		br.Msg = "获取分类信息失败"
+		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+		return
+	}
+	if chartClassify == nil {
+		br.Msg = "分类不存在"
+		br.ErrMsg = "分类不存在"
+		return
+	}
+	//count, err := data_manage.ChartInfoExist("", edbInfoIdStr)
+	//if err != nil && err.Error() != utils.ErrNoRow() {
+	//	br.Msg = "保存失败"
+	//	br.ErrMsg = "判断图表名称是否存在失败,Err:" + err.Error()
+	//	return
+	//}
+	//if count > 0 {
+	//	br.Msg = "所选指标已存在相同指标"
+	//	return
+	//}
+	//判断图表是否存在
+	var condition string
+	var pars []interface{}
+	condition += " AND chart_classify_id=? "
+	pars = append(pars, req.ChartClassifyId)
+
+	condition += " AND chart_name=? AND source = ? "
+	pars = append(pars, req.ChartName, utils.CHART_SOURCE_FUTURE_GOOD)
+
+	count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
+	if err != nil {
+		br.Msg = "判断图表名称是否存在失败"
+		br.ErrMsg = "判断图表名称是否存在失败,Err:" + err.Error()
+		return
+	}
+
+	if count > 0 {
+		br.Msg = "图表已存在,请重新填写"
+		br.IsSendEmail = false
+		return
+	}
+
+	//获取原图表关联的指标信息列表
+	edbMappingList, err := data_manage.GetChartEdbMappingListV2(req.ChartInfoId)
+	if err != nil {
+		br.Msg = "获取图表关联的指标信息失败!"
+		return
+	}
+
+	//添加图表
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	chartInfo := &data_manage.ChartInfo{
+		ChartInfoId:     0,
+		ChartName:       req.ChartName,
+		ChartClassifyId: req.ChartClassifyId,
+		SysUserId:       sysUser.AdminId,
+		SysUserRealName: sysUser.RealName,
+		UniqueCode:      utils.MD5(utils.CHART_PREFIX + "_" + timestamp),
+		CreateTime:      time.Now(),
+		ModifyTime:      time.Now(),
+		DateType:        oldChartInfo.DateType,
+		StartDate:       oldChartInfo.StartDate,
+		EndDate:         oldChartInfo.EndDate,
+		IsSetName:       oldChartInfo.IsSetName,
+		EdbInfoIds:      oldChartInfo.EdbInfoIds,
+		ChartType:       oldChartInfo.ChartType,
+		Calendar:        oldChartInfo.Calendar,
+		SeasonStartDate: oldChartInfo.SeasonStartDate,
+		SeasonEndDate:   oldChartInfo.SeasonEndDate,
+		ChartImage:      oldChartInfo.ChartImage,
+		BarConfig:       oldChartInfo.BarConfig,
+		//Sort:     sort,
+		LeftMin:  oldChartInfo.LeftMin,
+		LeftMax:  oldChartInfo.LeftMax,
+		RightMin: oldChartInfo.RightMin,
+		RightMax: oldChartInfo.RightMax,
+		Disabled: oldChartInfo.Disabled,
+		Source:   oldChartInfo.Source,
+	}
+	newId, err := data_manage.AddChartInfo(chartInfo)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartInfoId = int(newId)
+
+	// 添加图表与指标的关联关系
+	{
+		mapList := make([]*data_manage.ChartEdbMapping, 0)
+		for _, v := range edbMappingList {
+			timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+			mapItem := &data_manage.ChartEdbMapping{
+				//ChartEdbMappingId: 0,
+				ChartInfoId: chartInfo.ChartInfoId,
+				EdbInfoId:   v.EdbInfoId,
+				CreateTime:  time.Now(),
+				ModifyTime:  time.Now(),
+				UniqueCode:  utils.MD5(utils.CHART_PREFIX + "_" + strconv.Itoa(v.EdbInfoId) + timestamp),
+				MaxData:     v.MaxData,
+				MinData:     v.MinData,
+				IsOrder:     v.IsOrder,
+				IsAxis:      v.IsAxis,
+				EdbInfoType: v.EdbInfoType,
+				LeadValue:   v.LeadValue,
+				LeadUnit:    v.LeadUnit,
+				ChartStyle:  v.ChartStyle,
+				ChartColor:  v.ChartColor,
+				ChartWidth:  v.ChartWidth,
+				Source:      v.Source,
+			}
+			mapList = append(mapList, mapItem)
+		}
+		err = data_manage.AddChartEdbMapping(mapList)
+		if err != nil {
+			br.Msg = "保存失败"
+			br.ErrMsg = "保存失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	//添加es数据
+	go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	//修改my eta es数据
+	go data.EsAddOrEditMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
+
+	//新增操作日志
+	{
+		chartLog := new(data_manage.ChartInfoLog)
+		chartLog.ChartInfoId = chartInfo.ChartInfoId
+		chartLog.ChartName = req.ChartName
+		chartLog.ChartClassifyId = req.ChartClassifyId
+		chartLog.SysUserId = sysUser.AdminId
+		chartLog.SysUserRealName = sysUser.RealName
+		chartLog.UniqueCode = chartInfo.UniqueCode
+		chartLog.CreateTime = time.Now()
+		chartLog.Content = string(this.Ctx.Input.RequestBody)
+		chartLog.Status = "复制商品价格图表"
+		chartLog.Method = this.Ctx.Input.URI()
+		go data_manage.AddChartInfoLog(chartLog)
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = data_manage.AddChartInfoResp{
+		ChartInfoId: chartInfo.ChartInfoId,
+		UniqueCode:  chartInfo.UniqueCode,
+		ChartType:   chartInfo.ChartType,
+	}
+	br.IsAddLog = true
+}

+ 1 - 0
models/data_manage/chart_classify.go

@@ -149,6 +149,7 @@ type ChartClassifyItems struct {
 
 type ChartClassifyListResp struct {
 	AllNodes []*ChartClassifyItems
+	Language string `description:"指标的展示语言,CN:中文,EN:英文"`
 }
 
 type ChartClassifyDeleteCheckResp struct {

+ 3 - 0
models/data_manage/chart_info_correlation.go

@@ -14,6 +14,8 @@ type ChartInfoCorrelation struct {
 	LeadUnit               string    `description:"领先单位"`
 	CalculateValue         int       `description:"计算窗口"`
 	CalculateUnit          string    `description:"计算频度"`
+	BaseCalculateValue     int       `description:"基础计算窗口(滚动相关性的时候用到)"`
+	BaseCalculateUnit      string    `description:"基础计算频度(滚动相关性的时候用到)"`
 	StartDate              time.Time `description:"开始日期"`
 	EndDate                time.Time `description:"结束日期"`
 	EdbInfoIdFirst         int       `description:"A指标ID"`
@@ -23,6 +25,7 @@ type ChartInfoCorrelation struct {
 	CreateTime             time.Time `description:"创建时间"`
 	ModifyTime             time.Time `description:"更新时间"`
 }
+
 type CorrelationInfo struct {
 	LeadValue       int    `description:"领先值"`
 	LeadUnit        string `description:"领先单位"`

+ 26 - 0
models/data_manage/chart_info_log.go

@@ -0,0 +1,26 @@
+package data_manage
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type ChartInfoLog struct {
+	ChartInfoLogId  int    `orm:"column(chart_info_log_id);pk"`
+	ChartInfoId     int    `description:"图表id"`
+	ChartName       string `description:"来源名称"`
+	ChartClassifyId int    `description:"图表分类id"`
+	SysUserId       int
+	SysUserRealName string
+	UniqueCode      string `description:"图表唯一编码"`
+	CreateTime      time.Time
+	Content         string `description:"内容"`
+	Status          string `description:"状态"`
+	Method          string `description:"执行方法"`
+}
+
+func AddChartInfoLog(item *ChartInfoLog) (lastId int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	lastId, err = o.Insert(item)
+	return
+}

+ 79 - 0
models/data_manage/multiple_graph_config.go

@@ -0,0 +1,79 @@
+package data_manage
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// MultipleGraphConfig 多图配置表
+type MultipleGraphConfig struct {
+	MultipleGraphConfigId int       `orm:"column(multiple_graph_config_id);pk"`
+	EdbInfoIdA            int       `description:"指标A"`
+	EdbInfoIdB            int       `description:"指标B"`
+	Curve                 string    `description:"曲线图配置"`
+	Correlation           string    `description:"相关性配置"`
+	RollingCorrelation    string    `description:"滚动相关性配置"`
+	SysUserId             int       `description:"操作人id"`
+	SysUserRealName       string    `description:"操作人真实姓名"`
+	ModifyTime            time.Time `description:"最近一次修改时间"`
+	CreateTime            time.Time `description:"添加时间"`
+}
+
+// AddMultipleGraphConfig 新增多图配置
+func AddMultipleGraphConfig(item *MultipleGraphConfig) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	// 表格信息入库
+	lastId, err := o.Insert(item)
+	if err != nil {
+		return
+	}
+	item.MultipleGraphConfigId = int(lastId)
+	return
+}
+
+// Update 更新 基础信息
+func (item *MultipleGraphConfig) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(item, cols...)
+	return
+}
+
+// GetMultipleGraphConfigById 根据配置id获取配置
+func GetMultipleGraphConfigById(id int) (item *MultipleGraphConfig, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM multiple_graph_config WHERE multiple_graph_config_id = ? `
+	// 表格信息入库
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+// CurveConfig 曲线图配置
+type CurveConfig struct {
+	DateType    int     `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate   string  `description:"自定义开始日期"`
+	EndDate     string  `description:"自定义结束日期"`
+	LeftMin     float64 `description:"图表左侧最小值"`
+	LeftMax     float64 `description:"图表左侧最大值"`
+	RightMin    float64 `description:"图表右侧最小值"`
+	RightMax    float64 `description:"图表右侧最大值"`
+	IsOrder     bool    `description:"true:正序,false:逆序"`
+	EdbInfoType bool    `description:"true:标准指标,false:领先指标"`
+	LeadValue   int     `description:"领先值"`
+	LeadUnit    string  `description:"领先单位"`
+}
+
+// CorrelationConfig 相关性配置
+type CorrelationConfig struct {
+	LeadValue      int    `description:"领先期数"`
+	LeadUnit       string `description:"频度"`
+	CalculateValue int    `description:"计算窗口"`
+	CalculateUnit  string `description:"计算频度"`
+}
+
+// RollingCorrelationConfig 滚动相关性配置
+type RollingCorrelationConfig struct {
+	LeadValue      int    `description:"领先期数"`
+	LeadUnit       string `description:"频度"`
+	CalculateValue int    `description:"计算窗口"`
+	CalculateUnit  string `description:"计算频度"`
+}

+ 15 - 1
models/db.go

@@ -69,6 +69,9 @@ func init() {
 
 	// 英文ppt
 	initPptEnglish()
+
+	//多图配置
+	initMultipleGraphConfig()
 }
 
 // initSystem 系统表 数据表
@@ -77,6 +80,7 @@ func initSystem() {
 		new(system.SysUserLoginRecord),
 		new(system.SysSession),
 		new(system.Admin),
+		new(system.AdminConfig), //系统用户配置表
 	)
 }
 
@@ -97,7 +101,7 @@ func initChart() {
 		new(data_manage.MyChart),
 		new(data_manage.MyChartLog),
 		new(data_manage.MyChartClassifyMapping),
-		//new(data_manage.ChartInfoLog),
+		new(data_manage.ChartInfoLog),
 		new(data_manage.ChartInfoCorrelation),
 	)
 }
@@ -121,3 +125,13 @@ func initPptEnglish() {
 		new(ppt_english.ReportPptEnglishImg), //Ppt转报告的图片记录表
 	)
 }
+
+// initMultipleGraphConfig 多图配置 数据表
+func initMultipleGraphConfig() {
+	//注册对象
+	orm.RegisterModel(
+		new(data_manage.MultipleGraphConfig),             //多图配置表
+		new(data_manage.MultipleGraphConfigChartMapping), //图表与多图配置的关系表
+		//new(data_manage.MultipleGraphConfigEdbMapping),   //指标与多图配置的关系表
+	)
+}

+ 58 - 0
models/system/admin_config.go

@@ -0,0 +1,58 @@
+package system
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type AdminConfig struct {
+	ConfigId    int       `orm:"column(config_id);pk" description:"配置id"`
+	AdminId     int       `description:"系统客户id"`
+	ConfigCode  string    `description:"配置编码"`
+	ConfigValue string    `description:"配置值"`
+	Remark      string    `description:"备注信息"`
+	CreateTime  time.Time `description:"创建时间"`
+}
+
+// Update 更新基础信息
+func (item *AdminConfig) Update(cols []string) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Update(item, cols...)
+	return
+}
+
+func (item *AdminConfig) Create() (err error) {
+	o := orm.NewOrm()
+	id, err := o.Insert(item)
+	if err != nil {
+		return
+	}
+	item.ConfigId = int(id)
+	return
+}
+
+var EdbLanguageVar = `edb_language`
+var PredictEdbLanguageVar = `predict_edb_language`
+var ChartLanguageVar = `chart_language`
+
+// GetConfigDetailByCode 获取详情
+func GetConfigDetailByCode(adminId int, configCode string) (item *AdminConfig, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM admin_config WHERE admin_id = ? AND  config_code=? `
+	err = o.Raw(sql, adminId, configCode).QueryRow(&item)
+	return
+}
+
+// GetDefaultConfigDetailByCode 获取默认配置详情
+func GetDefaultConfigDetailByCode(configCode string) (item *AdminConfig, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM admin_config WHERE admin_id = ? AND  config_code=? `
+	err = o.Raw(sql, 0, configCode).QueryRow(&item)
+	return
+}
+
+// SetAdminConfigReq 设置用户的配置
+type SetAdminConfigReq struct {
+	ConfigCode  string `description:"配置编码"`
+	ConfigValue string `description:"配置值"`
+}

+ 90 - 0
routers/commentsRouter.go

@@ -7,6 +7,24 @@ import (
 
 func init() {
 
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/correlation:CorrelationChartClassifyController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/correlation:CorrelationChartClassifyController"],
+        beego.ControllerComments{
+            Method: "ChartClassifyList",
+            Router: `/chart_classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/correlation:CorrelationChartInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/correlation:CorrelationChartInfoController"],
+        beego.ControllerComments{
+            Method: "Copy",
+            Router: `/chart_info/copy`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/correlation:CorrelationChartInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/correlation:CorrelationChartInfoController"],
         beego.ControllerComments{
             Method: "List",
@@ -16,6 +34,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/future_good:FutureGoodChartClassifyController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/future_good:FutureGoodChartClassifyController"],
+        beego.ControllerComments{
+            Method: "ChartClassifyList",
+            Router: `/chart_classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/future_good:FutureGoodChartInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/future_good:FutureGoodChartInfoController"],
+        beego.ControllerComments{
+            Method: "CopyChartInfo",
+            Router: `/chart_info/copy`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/future_good:FutureGoodChartInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage/future_good:FutureGoodChartInfoController"],
         beego.ControllerComments{
             Method: "ChartInfoSearchByEs",
@@ -25,6 +61,33 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartClassifyController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartClassifyController"],
+        beego.ControllerComments{
+            Method: "DeleteChartClassify",
+            Router: `/chart_classify/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartClassifyController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartClassifyController"],
+        beego.ControllerComments{
+            Method: "ChartClassifyItems",
+            Router: `/chart_classify/items`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartClassifyController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartClassifyController"],
+        beego.ControllerComments{
+            Method: "ChartClassifyListV2",
+            Router: `/chart_classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartInfoController"],
         beego.ControllerComments{
             Method: "CommonChartInfoDetailFromUniqueCode",
@@ -34,6 +97,33 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartInfoController"],
+        beego.ControllerComments{
+            Method: "CopyChartInfo",
+            Router: `/chart_info/copy`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartInfoController"],
+        beego.ControllerComments{
+            Method: "ChartInfoDetail",
+            Router: `/chart_info/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ChartInfoController"],
+        beego.ControllerComments{
+            Method: "ChartInfoEdbInfoDetail",
+            Router: `/chart_info/edb_info/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ExcelInfoController"] = append(beego.GlobalControllerRouter["hongze/hongze_ETA_mobile_api/controllers/data_manage:ExcelInfoController"],
         beego.ControllerComments{
             Method: "GetExcelTableData",

+ 21 - 0
routers/router.go

@@ -10,6 +10,8 @@ package routers
 import (
 	"hongze/hongze_ETA_mobile_api/controllers"
 	"hongze/hongze_ETA_mobile_api/controllers/data_manage"
+	"hongze/hongze_ETA_mobile_api/controllers/data_manage/correlation"
+	"hongze/hongze_ETA_mobile_api/controllers/data_manage/future_good"
 
 	"github.com/beego/beego/v2/server/web"
 	"github.com/beego/beego/v2/server/web/filter/cors"
@@ -63,6 +65,7 @@ func init() {
 			web.NSInclude(
 				&data_manage.ChartInfoController{},
 				&data_manage.ExcelInfoController{},
+				&data_manage.ChartClassifyController{},
 			),
 		),
 		web.NSNamespace("/resource",
@@ -70,6 +73,24 @@ func init() {
 				&controllers.ResourceController{},
 			),
 		),
+		web.NSNamespace("/my_chart",
+			web.NSInclude(
+				&data_manage.MyChartController{},
+			),
+		),
+		web.NSNamespace("/future_good",
+			web.NSInclude(
+				//&future_good.FutureGoodEdbInfoController{},
+				&future_good.FutureGoodChartClassifyController{},
+				&future_good.FutureGoodChartInfoController{},
+			),
+		),
+		web.NSNamespace("/correlation",
+			web.NSInclude(
+				&correlation.CorrelationChartClassifyController{},
+				&correlation.CorrelationChartInfoController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 36 - 0
services/data/chart_classify.go

@@ -0,0 +1,36 @@
+package data
+
+import (
+	"hongze/hongze_ETA_mobile_api/models/data_manage"
+)
+
+func chartClassifyHaveChild(allNode []*data_manage.ChartClassifyItems, node *data_manage.ChartClassifyItems) (childs []*data_manage.ChartClassifyItems, yes bool) {
+	for _, v := range allNode {
+		if v.ParentId == node.ChartClassifyId {
+			childs = append(childs, v)
+		}
+	}
+	if len(childs) > 0 {
+		yes = true
+	}
+	return
+}
+
+func ChartClassifyItemsMakeTree(allNode []*data_manage.ChartClassifyItems, node *data_manage.ChartClassifyItems) {
+	childs, _ := chartClassifyHaveChild(allNode, node) //判断节点是否有子节点并返回
+	if len(childs) > 0 {
+		node.Children = append(node.Children, childs[0:]...) //添加子节点
+		for _, v := range childs {                           //查询子节点的子节点,并添加到子节点
+			_, has := chartClassifyHaveChild(allNode, v)
+			if has {
+				ChartClassifyItemsMakeTree(allNode, v) //递归添加节点
+			} else {
+				childrenArr := make([]*data_manage.ChartClassifyItems, 0)
+				v.Children = childrenArr
+			}
+		}
+	} else {
+		childrenArr := make([]*data_manage.ChartClassifyItems, 0)
+		node.Children = childrenArr
+	}
+}

+ 294 - 0
services/data/correlation/chart_info.go

@@ -5,9 +5,13 @@ import (
 	"fmt"
 	"github.com/shopspring/decimal"
 	"hongze/hongze_ETA_mobile_api/models/data_manage"
+	"hongze/hongze_ETA_mobile_api/models/system"
 	"hongze/hongze_ETA_mobile_api/services/data"
 	"hongze/hongze_ETA_mobile_api/utils"
 	"math"
+	"sort"
+	"strconv"
+	"strings"
 	"time"
 )
 
@@ -501,3 +505,293 @@ func GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *d
 	})
 	return
 }
+
+// AddChartInfo 添加图表
+func AddChartInfo(req data_manage.AddChartInfoReq, source int, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
+	isSendEmail = true
+
+	req.ChartName = strings.Trim(req.ChartName, " ")
+	if req.ChartName == "" {
+		errMsg = "请填写图表名称!"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+	if req.ChartClassifyId <= 0 {
+		errMsg = "分类参数错误!"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+	// 相关性图表配置
+	if req.CorrelationChartInfo.LeadValue == 0 {
+		errMsg = "请输入领先期数"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+	if req.CorrelationChartInfo.LeadUnit == "" {
+		errMsg = "请填写领先单位"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+	//if req.CorrelationChartInfo.StartDate == "" || req.CorrelationChartInfo.EndDate == "" {
+	//	errMsg = "请填写开始结束日期"
+	//	err = errors.New(errMsg)
+	//	isSendEmail = false
+	//	return
+	//}
+	//startDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.StartDate)
+	//if e != nil {
+	//	errMsg = "开始日期格式有误"
+	//	err = errors.New(errMsg)
+	//	isSendEmail = false
+	//	return
+	//}
+	//endDate, e := time.Parse(utils.FormatDate, req.CorrelationChartInfo.EndDate)
+	//if e != nil {
+	//	errMsg = "结束日期格式有误"
+	//	err = errors.New(errMsg)
+	//	isSendEmail = false
+	//	return
+	//}
+	if len(req.CorrelationChartInfo.EdbInfoIdList) != 2 {
+		errMsg = "请选择AB指标"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+
+	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = "分类不存在"
+			err = errors.New(errMsg)
+			isSendEmail = false
+			return
+		}
+		errMsg = "获取分类信息失败"
+		err = errors.New("获取分类信息失败,Err:" + err.Error())
+		return
+	}
+	if chartClassify == nil {
+		errMsg = "分类不存在"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+
+	var edbInfoIdArr []int
+	for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
+		edbInfoId := v.EdbInfoId
+		edbInfo, tmpErr := data_manage.GetEdbInfoById(edbInfoId)
+		if tmpErr != nil {
+			if tmpErr.Error() == utils.ErrNoRow() {
+				errMsg = "指标不存在!"
+				err = errors.New("指标不存在,edbInfoId:" + strconv.Itoa(edbInfoId))
+				return
+			} else {
+				errMsg = "获取指标信息失败!"
+				err = errors.New("获取图表的指标信息失败,Err:" + tmpErr.Error())
+				return
+			}
+		}
+
+		if edbInfo == nil {
+			errMsg = "指标已被删除,请重新选择!"
+			err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
+			return
+		} else {
+			if edbInfo.EdbInfoId <= 0 {
+				errMsg = "指标已被删除,请重新选择!"
+				err = errors.New("指标不存在,ChartInfoId:" + strconv.Itoa(edbInfoId))
+				return
+			}
+		}
+
+		edbInfoIdArr = append(edbInfoIdArr, edbInfoId)
+		edbInfo.EdbNameSource = edbInfo.EdbName
+	}
+
+	sort.Ints(edbInfoIdArr)
+	var edbInfoIdArrStr []string
+	for _, v := range edbInfoIdArr {
+		edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
+	}
+	edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
+	var chartInfoId int
+	// 判断图表是否存在
+	var condition string
+	var pars []interface{}
+	condition += " AND chart_name=? AND source = ? "
+	pars = append(pars, req.ChartName, source)
+	count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
+	if err != nil {
+		errMsg = "判断图表名称是否存在失败"
+		err = errors.New("判断图表名称是否存在失败,Err:" + err.Error())
+		return
+	}
+
+	if count > 0 {
+		errMsg = "图表已存在,请重新填写"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+
+	disableVal := data.CheckIsDisableChart(edbInfoIdArr)
+
+	chartInfo = new(data_manage.ChartInfo)
+	chartInfo.ChartName = req.ChartName
+	chartInfo.EdbInfoIds = edbInfoIdStr
+	chartInfo.ChartClassifyId = req.ChartClassifyId
+	chartInfo.SysUserId = sysUser.AdminId
+	chartInfo.SysUserRealName = sysUser.RealName
+	chartInfo.CreateTime = time.Now()
+	chartInfo.ModifyTime = time.Now()
+	chartInfo.IsSetName = 0
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
+	chartInfo.ChartType = 9 // 相关性图
+	chartInfo.Calendar = "公历"
+	chartInfo.DateType = 6
+	chartInfo.StartDate = req.StartDate
+	chartInfo.EndDate = req.EndDate
+	chartInfo.SeasonStartDate = req.SeasonStartDate
+	chartInfo.SeasonEndDate = req.SeasonEndDate
+	chartInfo.LeftMin = req.LeftMin
+	chartInfo.LeftMax = req.LeftMax
+	chartInfo.RightMin = req.RightMin
+	chartInfo.RightMax = req.RightMax
+	chartInfo.Disabled = disableVal
+	chartInfo.Source = source
+
+	// 指标信息
+	mapList := make([]*data_manage.ChartEdbMapping, 0)
+	for _, v := range req.CorrelationChartInfo.EdbInfoIdList {
+		mapItem := new(data_manage.ChartEdbMapping)
+		mapItem.EdbInfoId = v.EdbInfoId
+		mapItem.CreateTime = time.Now()
+		mapItem.ModifyTime = time.Now()
+		timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+		mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp + "_" + strconv.Itoa(v.EdbInfoId))
+		mapItem.IsOrder = true
+		mapItem.IsAxis = 1
+		mapItem.EdbInfoType = 1
+		mapItem.Source = utils.CHART_SOURCE_CORRELATION
+		mapList = append(mapList, mapItem)
+	}
+
+	// 相关性图表扩展信息
+	correlationChart := new(data_manage.ChartInfoCorrelation)
+	correlationChart.LeadValue = req.CorrelationChartInfo.LeadValue
+	correlationChart.LeadUnit = req.CorrelationChartInfo.LeadUnit
+	correlationChart.CalculateValue = req.CorrelationChartInfo.CalculateValue
+	correlationChart.CalculateUnit = req.CorrelationChartInfo.CalculateUnit
+	correlationChart.BaseCalculateValue = req.CorrelationChartInfo.BaseCalculateValue
+	correlationChart.BaseCalculateUnit = req.CorrelationChartInfo.BaseCalculateUnit
+	correlationChart.EdbInfoIdFirst = req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId
+	correlationChart.EdbInfoIdSecond = req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId
+	correlationChart.CreateTime = time.Now().Local()
+	correlationChart.ModifyTime = time.Now().Local()
+	//// 生成图表x轴y轴数据
+	//edbInfoMappingA, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[0].EdbInfoId)
+	//if e != nil {
+	//	errMsg = "获取失败"
+	//	err = errors.New("获取相关性图表, A指标mapping信息失败, Err:" + e.Error())
+	//	return
+	//}
+	//edbInfoMappingB, e := data_manage.GetChartEdbMappingByEdbInfoId(req.CorrelationChartInfo.EdbInfoIdList[1].EdbInfoId)
+	//if e != nil {
+	//	errMsg = "获取失败"
+	//	err = errors.New("获取相关性图表, B指标mapping信息失败, Err:" + e.Error())
+	//	return
+	//}
+	//periodData, correlationData, e := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, req.CorrelationChartInfo.LeadValue, req.CorrelationChartInfo.LeadUnit, req.CorrelationChartInfo.StartDate, req.CorrelationChartInfo.EndDate)
+	//if e != nil {
+	//	errMsg = "获取失败"
+	//	err = errors.New("获取相关性图表, 图表计算值失败, Err:" + e.Error())
+	//	return
+	//}
+	//periodDataByte, e := json.Marshal(periodData)
+	//if e != nil {
+	//	errMsg = "获取失败"
+	//	err = errors.New("相关性图表, X轴信息有误, Err:" + e.Error())
+	//	return
+	//}
+	//correlationDataByte, e := json.Marshal(correlationData[0].Value)
+	//if e != nil {
+	//	errMsg = "获取失败"
+	//	err = errors.New("相关性图表, Y轴信息有误, Err:" + e.Error())
+	//	return
+	//}
+	//correlationChart.PeriodData = string(periodDataByte)
+	//correlationChart.CorrelationData = string(correlationDataByte)
+
+	// 新增图表和指标mapping
+	chartInfoId, e := data_manage.CreateCorrelationChartAndEdb(chartInfo, mapList, correlationChart)
+	if e != nil {
+		errMsg = "操作失败"
+		err = errors.New("新增相关性图表失败, Err: " + e.Error())
+		return
+	}
+
+	//添加es数据
+	go data.EsAddOrEditChartInfo(chartInfoId)
+
+	return
+}
+
+// CopyChartInfo 复制图表
+func CopyChartInfo(configId, classifyId int, chartName string, correlationChartInfoReq data_manage.CorrelationChartInfoReq, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
+	configSource := 2
+	isSendEmail = true
+	// 获取相关性图的配置
+	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(configId, configSource)
+	if err != nil {
+		return
+	}
+	multipleGraphConfig, err := data_manage.GetMultipleGraphConfigById(configId)
+	if err != nil {
+		return
+	}
+	multipleGraphConfig.MultipleGraphConfigId = 0
+	err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
+	if err != nil {
+		return
+	}
+
+	// 添加图
+	addChartReq := data_manage.AddChartInfoReq{
+		ChartClassifyId:      classifyId,
+		ChartName:            chartName,
+		ChartType:            utils.CHART_TYPE_CURVE,
+		Calendar:             "公历",
+		CorrelationChartInfo: correlationChartInfoReq,
+	}
+	chartSource := utils.CHART_SOURCE_CORRELATION // 默认是相关性图
+	chartInfo, err, errMsg, isSendEmail = AddChartInfo(addChartReq, chartSource, sysUser)
+	if err != nil {
+		return
+	}
+
+	// 添加关系
+	multipleGraphConfigChartMapping = &data_manage.MultipleGraphConfigChartMapping{
+		//Id:                    0,
+		MultipleGraphConfigId: multipleGraphConfig.MultipleGraphConfigId,
+		ChartInfoId:           chartInfo.ChartInfoId,
+		Source:                configSource,
+		ModifyTime:            time.Now(),
+		CreateTime:            time.Now(),
+	}
+	err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
+	if err != nil {
+		return
+	}
+
+	//添加es数据
+	go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+
+	return
+}

+ 4 - 3
utils/constants.go

@@ -399,14 +399,15 @@ const (
 
 // 图表类型
 const (
-	CHART_SOURCE_DEFAULT     = 1
-	CHART_SOURCE_FUTURE_GOOD = 2
-	CHART_SOURCE_CORRELATION = 3 // 相关性图表
+	CHART_SOURCE_DEFAULT             = 1
+	CHART_SOURCE_FUTURE_GOOD         = 2
+	CHART_SOURCE_CORRELATION         = 3 // 相关性图表
 	CHART_SOURCE_ROLLING_CORRELATION = 4 // 滚动相关性图表
 )
 
 // 图表样式类型
 const (
+	CHART_TYPE_CURVE           = 1  //曲线图
 	CHART_TYPE_BAR             = 7  //柱形图
 	CHART_TYPE_SECTION_SCATTER = 10 //截面散点图样式
 )