package data_manage

import (
	"encoding/json"
	"fmt"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/data_manage"
	"hongze/hz_crm_api/models/data_manage/request"
	"hongze/hz_crm_api/models/data_manage/response"
	"hongze/hz_crm_api/models/system"
	"hongze/hz_crm_api/services/data"
	correlationServ "hongze/hz_crm_api/services/data/correlation"
	"hongze/hz_crm_api/utils"
	"math"
	"strconv"
	"strings"
	"time"
)

//多图配置

// MultipleGraphConfigSave
// @Title 保存配置接口
// @Description 保存配置接口
// @Param	request	body request.SaveMultipleGraphConfigReq true "type json string"
// @Success Ret=200 返回图表id
// @router /multiple_graph/config/save [post]
func (this *ChartInfoController) MultipleGraphConfigSave() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req request.SaveMultipleGraphConfigReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.EdbInfoIdA <= 0 {
		br.Msg = "指标A未选择"
		br.IsSendEmail = false
		return
	}
	_, err = data_manage.GetEdbInfoById(req.EdbInfoIdA)
	if err != nil {
		br.Msg = "指标A异常"
		br.ErrMsg = "指标A异常,err:" + err.Error()
		if err.Error() == utils.ErrNoRow() {
			br.Msg = `指标A不存在`
			br.IsSendEmail = false
		}
		return
	}

	if req.EdbInfoIdB <= 0 {
		br.Msg = "指标B未选择"
		br.IsSendEmail = false
		return
	}
	_, err = data_manage.GetEdbInfoById(req.EdbInfoIdB)
	if err != nil {
		br.Msg = "指标B异常"
		br.ErrMsg = "指标B异常,err:" + err.Error()
		if err.Error() == utils.ErrNoRow() {
			br.Msg = `指标B不存在`
			br.IsSendEmail = false
		}
		return
	}

	curveStrByte, err := json.Marshal(req.Curve)
	if err != nil {
		br.Msg = `曲线图配置异常`
		br.ErrMsg = `曲线图配置异常,ERR:` + err.Error()
		return
	}

	if req.Correlation.LeadValue <= 0 {
		br.Msg = `分析周期不允许设置为负数或0`
		br.IsSendEmail = false
		return
	}
	correlationStrByte, err := json.Marshal(req.Correlation)
	if err != nil {
		br.Msg = `相关性配置异常`
		br.ErrMsg = `相关性配置异常,ERR:` + err.Error()
		return
	}
	rollingCorrelationStrByte, err := json.Marshal(req.RollingCorrelation)
	if err != nil {
		br.Msg = `滚动相关性配置异常`
		br.ErrMsg = `滚动相关性配置异常,ERR:` + err.Error()
		return
	}

	var multipleGraphConfig *data_manage.MultipleGraphConfig
	if req.MultipleGraphConfigId > 0 {
		multipleGraphConfig, err = data_manage.GetMultipleGraphConfigById(req.MultipleGraphConfigId)
		if err != nil {
			br.Msg = `不存在该配置`
			br.ErrMsg = `不存在该配置`
			return
		}
		multipleGraphConfig.EdbInfoIdA = req.EdbInfoIdA
		multipleGraphConfig.EdbInfoIdB = req.EdbInfoIdB
		multipleGraphConfig.Curve = string(curveStrByte)
		multipleGraphConfig.Correlation = string(correlationStrByte)
		multipleGraphConfig.RollingCorrelation = string(rollingCorrelationStrByte)
		multipleGraphConfig.ModifyTime = time.Now()
		err = multipleGraphConfig.Update([]string{"EdbInfoIdA", "EdbInfoIdB", "Curve", "Correlation", "RollingCorrelation", "ModifyTime"})
	} else {
		multipleGraphConfig = &data_manage.MultipleGraphConfig{
			//MultipleGraphConfigId: 0,
			EdbInfoIdA:         req.EdbInfoIdA,
			EdbInfoIdB:         req.EdbInfoIdB,
			Curve:              string(curveStrByte),
			Correlation:        string(correlationStrByte),
			RollingCorrelation: string(rollingCorrelationStrByte),
			SysUserId:          this.SysUser.AdminId,
			SysUserRealName:    this.SysUser.RealName,
			ModifyTime:         time.Now(),
			CreateTime:         time.Now(),
		}
		err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
	}
	if err != nil {
		br.Msg = `保存失败`
		br.ErrMsg = `保存失败，Err:` + err.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = multipleGraphConfig
	br.IsAddLog = true
}

// MultipleGraphPreview
// @Title 批量添加图表的预览接口
// @Description 批量添加图表的预览接口
// @Param	request	body request.SaveMultipleGraphConfigReq true "type json string"
// @Success Ret=200 返回图表id
// @router /multiple_graph/preview [post]
func (this *ChartInfoController) MultipleGraphPreview() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req request.SaveMultipleGraphConfigReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList([]int{req.EdbInfoIdA, req.EdbInfoIdB})
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表，指标信息失败，Err:" + err.Error()
		return
	}
	var edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping
	for _, v := range mappingList {
		if v.EdbInfoId == req.EdbInfoIdA {
			edbInfoMappingA = v
		}
		if v.EdbInfoId == req.EdbInfoIdB {
			edbInfoMappingB = v
		}
	}
	if edbInfoMappingA == nil {
		br.Msg = "指标A不存在"
		br.IsSendEmail = false
		return
	}
	if edbInfoMappingB == nil {
		br.Msg = "指标B不存在"
		br.IsSendEmail = false
		return
	}

	resp := response.PreviewMultipleGraphConfigResp{}

	chartInfo := new(data_manage.ChartInfoView)
	chartInfo.Calendar = `公历`
	chartInfo.ChartName = edbInfoMappingA.EdbName + "与" + edbInfoMappingB.EdbName

	// 曲线图表信息
	{
		tmpChartInfo := *chartInfo

		curveConf := req.Curve
		startDate, endDate := utils.GetDateByDateType(curveConf.DateType, curveConf.StartDate, curveConf.EndDate)
		edbInfoType := 0
		if curveConf.EdbInfoType {
			edbInfoType = 1
		}
		for _, v := range mappingList {
			v.EdbInfoType = 1
			v.IsOrder = false
			if v.EdbInfoId == req.EdbInfoIdB {
				v.LeadValue = curveConf.LeadValue
				v.LeadUnit = curveConf.LeadUnit
				v.EdbInfoType = edbInfoType
				v.IsOrder = curveConf.IsOrder
			}
		}

		// 获取图表中的指标数据
		edbList, _, _, _, err, errMsg := data.GetChartEdbData(tmpChartInfo.ChartInfoId, tmpChartInfo.ChartType, tmpChartInfo.Calendar, startDate, endDate, mappingList, tmpChartInfo.ExtraConfig)
		if err != nil {
			br.Msg = "获取失败"
			if errMsg != `` {
				br.Msg = errMsg
			}
			br.ErrMsg = "获取图表，指标信息失败，Err:" + err.Error()
			return
		}
		warnEdbList := make([]string, 0)

		tmpEdbList := make([]data_manage.ChartEdbInfoMapping, 0)
		for _, v := range edbList {
			if v.IsNullData {
				warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
			}

			chartEdbInfoMapping := *v
			chartEdbInfoMapping.IsOrder = false

			if v.EdbInfoId == req.EdbInfoIdA {
				chartEdbInfoMapping.IsAxis = 1
				chartEdbInfoMapping.MinData = curveConf.LeftMin
				chartEdbInfoMapping.MaxData = curveConf.LeftMax
				chartEdbInfoMapping.ChartColor = `#00F`
				chartEdbInfoMapping.LeadValue = curveConf.LeadValue
				chartEdbInfoMapping.LeadUnit = curveConf.LeadUnit
				chartEdbInfoMapping.ChartWidth = 3
				chartEdbInfoMapping.EdbInfoType = edbInfoType
			} else {
				chartEdbInfoMapping.IsAxis = 0
				chartEdbInfoMapping.MinData = curveConf.RightMin
				chartEdbInfoMapping.MaxData = curveConf.RightMax
				chartEdbInfoMapping.ChartColor = `#F00`
				chartEdbInfoMapping.LeadValue = curveConf.LeadValue
				chartEdbInfoMapping.LeadUnit = curveConf.LeadUnit
				chartEdbInfoMapping.ChartWidth = 1
				chartEdbInfoMapping.IsOrder = curveConf.IsOrder
				chartEdbInfoMapping.EdbInfoType = edbInfoType
			}

			tmpEdbList = append(tmpEdbList, chartEdbInfoMapping)
		}
		if len(warnEdbList) > 0 {
			tmpChartInfo.WarnMsg = `图表引用指标异常，异常指标：` + strings.Join(warnEdbList, "，")
		}

		tmpChartInfo.Source = utils.CHART_SOURCE_DEFAULT
		tmpChartInfo.DateType = curveConf.DateType
		tmpChartInfo.StartDate = startDate
		tmpChartInfo.EndDate = endDate
		tmpChartInfo.ChartType = utils.CHART_TYPE_CURVE

		resp.CurveData = response.CurveResp{
			ChartInfo:   tmpChartInfo,
			EdbInfoList: tmpEdbList,
		}
	}

	// 相关性图表信息
	{
		correlationConf := req.Correlation
		// 配置了数据才有返回
		if correlationConf.LeadValue > 0 {
			moveUnitDays, ok := utils.FrequencyDaysMap[correlationConf.CalculateUnit]
			if !ok {
				br.Msg = "错误的分析周期"
				br.IsSendEmail = false
				return
			}
			startDate := time.Now().AddDate(0, 0, -correlationConf.CalculateValue*moveUnitDays).Format(utils.FormatDate)
			endDate := time.Now().Format(utils.FormatDate)
			xEdbIdValue, yDataList, e := correlationServ.GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationConf.LeadValue, correlationConf.LeadUnit, startDate, endDate)
			if e != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取相关性图表, 图表计算值失败, Err:" + e.Error()
				return
			}

			tmpChartInfo := *chartInfo
			tmpChartInfo.Source = utils.CHART_SOURCE_CORRELATION
			resp.CorrelationData = response.CorrelationResp{
				ChartInfo:   tmpChartInfo,
				EdbInfoList: mappingList,
				XEdbIdValue: xEdbIdValue,
				YDataList:   yDataList,
				CorrelationChartInfo: data_manage.CorrelationInfo{
					LeadValue:       correlationConf.LeadValue,
					LeadUnit:        correlationConf.LeadUnit,
					StartDate:       startDate,
					EndDate:         endDate,
					EdbInfoIdFirst:  edbInfoMappingA.EdbInfoId,
					EdbInfoIdSecond: edbInfoMappingB.EdbInfoId,
				},
			}
		}

	}

	// 滚动相关性图表信息
	{
		correlationConf := req.Correlation
		rollingCorrelationConfList := req.RollingCorrelation
		// 配置了数据才有返回
		if correlationConf.LeadValue > 0 {
			//moveUnitDays, ok := utils.FrequencyDaysMap[correlationConf.CalculateUnit]
			//if !ok {
			//	br.Msg = "错误的分析周期"
			//	br.IsSendEmail = false
			//	return
			//}
			//startDate := time.Now().AddDate(0, 0, -correlationConf.CalculateValue*moveUnitDays).Format(utils.FormatDate)
			//endDate := time.Now().Format(utils.FormatDate)

			// 数据的开始/结束日期
			curveConf := req.Curve
			startDate, endDate := utils.GetDateByDateType(curveConf.DateType, curveConf.StartDate, curveConf.EndDate)

			rollingCorrelationData := make([]interface{}, 0)
			for _, rollingCorrelationConf := range rollingCorrelationConfList {
				if rollingCorrelationConf.CalculateValue > 0 && rollingCorrelationConf.CalculateUnit != `` {
					xDateTimeValue, yDataList, e := correlationServ.GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, rollingCorrelationConf.LeadValue, rollingCorrelationConf.LeadUnit, rollingCorrelationConf.CalculateValue, rollingCorrelationConf.CalculateUnit, startDate, endDate)
					if e != nil {
						br.Msg = "获取失败"
						br.ErrMsg = "获取滚动相关性图表, 图表计算值失败, Err:" + e.Error()
						return
					}
					tmpChartInfo := *chartInfo
					tmpChartInfo.Source = utils.CHART_SOURCE_ROLLING_CORRELATION
					// ”指标A名称“+”指标B名称“+"滚动相关性"+”滚动相关性计算窗口值“+”滚动相关性计算窗口单位“
					// 若滚动相关性的计算周期为30天
					// 1、B即不领先也不滞后时：“指标A名称”与“指标B名称"30天滚动相关性;
					// 2、B有领先时：“指标A名称”与“指标B名称(领先15天)"30天滚动相关性；
					// 3、B滞后时：“指标A名称”与“指标B名称(滞后15天)"30天滚动相关性
					if rollingCorrelationConf.LeadValue == 0 {
						tmpChartInfo.ChartName = fmt.Sprintf(`%s与%s%d%s滚动相关性`, edbInfoMappingA.EdbName, edbInfoMappingB.EdbName, rollingCorrelationConf.CalculateValue, rollingCorrelationConf.CalculateUnit)
					} else if rollingCorrelationConf.LeadValue < 0 {
						tmpChartInfo.ChartName = fmt.Sprintf(`%s与%s(滞后%d%s)%d%s滚动相关性`, edbInfoMappingA.EdbName, edbInfoMappingB.EdbName, int(math.Abs(float64(rollingCorrelationConf.LeadValue))), rollingCorrelationConf.LeadUnit, rollingCorrelationConf.CalculateValue, rollingCorrelationConf.CalculateUnit)
					} else {
						tmpChartInfo.ChartName = fmt.Sprintf(`%s与%s(领先%d%s)%d%s滚动相关性`, edbInfoMappingA.EdbName, edbInfoMappingB.EdbName, int(math.Abs(float64(rollingCorrelationConf.LeadValue))), rollingCorrelationConf.LeadUnit, rollingCorrelationConf.CalculateValue, rollingCorrelationConf.CalculateUnit)
					}
					rollingCorrelationData = append(rollingCorrelationData, response.RollingCorrelationResp{
						ChartInfo:      tmpChartInfo,
						EdbInfoList:    mappingList,
						XDateTimeValue: xDateTimeValue,
						YDataList:      yDataList,
						CorrelationChartInfo: data_manage.CorrelationInfo{
							LeadValue:       rollingCorrelationConf.LeadValue,
							LeadUnit:        rollingCorrelationConf.LeadUnit,
							CalculateValue:  rollingCorrelationConf.CalculateValue,
							CalculateUnit:   rollingCorrelationConf.CalculateUnit,
							StartDate:       startDate,
							EndDate:         endDate,
							EdbInfoIdFirst:  edbInfoMappingA.EdbInfoId,
							EdbInfoIdSecond: edbInfoMappingB.EdbInfoId,
						},
					})
				} else {
					rollingCorrelationData = append(rollingCorrelationData, nil)
				}

			}

			resp.RollingCorrelationData = rollingCorrelationData

		} else {
			resp.RollingCorrelationData = []interface{}{nil, nil}
		}

	}

	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// MultipleGraphPreviewCurve
// @Title 批量添加图表的预览曲线图接口（只返回曲线图的数据）
// @Description 批量添加图表的预览曲线图接口
// @Param	request	body request.SaveMultipleGraphConfigReq true "type json string"
// @Success Ret=200 返回图表id
// @router /multiple_graph/preview_cure [post]
func (this *ChartInfoController) MultipleGraphPreviewCurve() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req request.SaveMultipleGraphConfigReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList([]int{req.EdbInfoIdA, req.EdbInfoIdB})
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表，指标信息失败，Err:" + err.Error()
		return
	}
	var edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping
	for _, v := range mappingList {
		if v.EdbInfoId == req.EdbInfoIdA {
			edbInfoMappingA = v
		}
		if v.EdbInfoId == req.EdbInfoIdB {
			edbInfoMappingB = v
		}
	}
	if edbInfoMappingA == nil {
		br.Msg = "指标A不存在"
		br.IsSendEmail = false
		return
	}
	if edbInfoMappingB == nil {
		br.Msg = "指标B不存在"
		br.IsSendEmail = false
		return
	}

	resp := response.PreviewMultipleGraphConfigResp{}

	chartInfo := new(data_manage.ChartInfoView)
	chartInfo.Calendar = `公历`
	chartInfo.ChartName = edbInfoMappingA.EdbName + "与" + edbInfoMappingB.EdbName

	// 曲线图表信息
	{
		tmpChartInfo := *chartInfo

		curveConf := req.Curve
		startDate := curveConf.StartDate
		endDate := curveConf.EndDate
		switch curveConf.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"
		}

		edbInfoType := 0
		if curveConf.EdbInfoType {
			edbInfoType = 1
		}
		for _, v := range mappingList {
			v.EdbInfoType = 1
			v.IsOrder = false
			if v.EdbInfoId == req.EdbInfoIdB {
				v.LeadValue = curveConf.LeadValue
				v.LeadUnit = curveConf.LeadUnit
				v.EdbInfoType = edbInfoType
				v.IsOrder = curveConf.IsOrder
			}
		}

		// 获取图表中的指标数据
		edbList, _, _, _, err, errMsg := data.GetChartEdbData(tmpChartInfo.ChartInfoId, tmpChartInfo.ChartType, tmpChartInfo.Calendar, startDate, endDate, mappingList, tmpChartInfo.ExtraConfig)
		if err != nil {
			br.Msg = "获取失败"
			if errMsg != `` {
				br.Msg = errMsg
			}
			br.ErrMsg = "获取图表，指标信息失败，Err:" + err.Error()
			return
		}
		warnEdbList := make([]string, 0)

		tmpEdbList := make([]data_manage.ChartEdbInfoMapping, 0)
		for _, v := range edbList {
			if v.IsNullData {
				warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
			}

			chartEdbInfoMapping := *v
			chartEdbInfoMapping.IsOrder = false
			chartEdbInfoMapping.EdbInfoType = 1

			if v.EdbInfoId == req.EdbInfoIdA {
				chartEdbInfoMapping.IsAxis = 1
				chartEdbInfoMapping.MinData = curveConf.LeftMin
				chartEdbInfoMapping.MaxData = curveConf.LeftMax
				chartEdbInfoMapping.ChartColor = `#00F`
				//chartEdbInfoMapping.LeadValue = curveConf.LeadValue
				//chartEdbInfoMapping.LeadUnit = curveConf.LeadUnit
				chartEdbInfoMapping.ChartWidth = 3
			} else {
				chartEdbInfoMapping.IsAxis = 0
				chartEdbInfoMapping.MinData = curveConf.RightMin
				chartEdbInfoMapping.MaxData = curveConf.RightMax
				chartEdbInfoMapping.ChartColor = `#F00`
				chartEdbInfoMapping.LeadValue = curveConf.LeadValue
				chartEdbInfoMapping.LeadUnit = curveConf.LeadUnit
				chartEdbInfoMapping.ChartWidth = 1
				chartEdbInfoMapping.IsOrder = curveConf.IsOrder
				chartEdbInfoMapping.EdbInfoType = edbInfoType
			}

			tmpEdbList = append(tmpEdbList, chartEdbInfoMapping)
		}
		if len(warnEdbList) > 0 {
			tmpChartInfo.WarnMsg = `图表引用指标异常，异常指标：` + strings.Join(warnEdbList, "，")
		}

		tmpChartInfo.Source = utils.CHART_SOURCE_DEFAULT
		tmpChartInfo.DateType = curveConf.DateType
		tmpChartInfo.StartDate = startDate
		tmpChartInfo.EndDate = endDate
		tmpChartInfo.ChartType = utils.CHART_TYPE_CURVE

		resp.CurveData = response.CurveResp{
			ChartInfo:   tmpChartInfo,
			EdbInfoList: tmpEdbList,
		}
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// MultipleGraphConfigSaveChart
// @Title 保存图表接口
// @Description 保存图表接口
// @Param	request	body request.SaveMultipleGraphChartReq true "type json string"
// @Success Ret=200 返回图表id
// @router /multiple_graph/chart/save [post]
func (this *ChartInfoController) MultipleGraphConfigSaveChart() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req request.SaveMultipleGraphChartReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	cacheKey := "CACHE_CHART_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
		br.Msg = "系统处理中，请稍后重试！"
		br.ErrMsg = "系统处理中，请稍后重试！" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
		return
	}
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()

	if req.IsSaveAs {
		CopyMultipleGraphConfigSaveChart(req, this, br, sysUser)
		return
	}

	mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList([]int{req.EdbInfoIdA, req.EdbInfoIdB})
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表，指标信息失败，Err:" + err.Error()
		return
	}
	var edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping
	for _, v := range mappingList {
		if v.EdbInfoId == req.EdbInfoIdA {
			edbInfoMappingA = v
		}
		if v.EdbInfoId == req.EdbInfoIdB {
			edbInfoMappingB = v
		}
	}
	if edbInfoMappingA == nil {
		br.Msg = "指标A不存在"
		br.IsSendEmail = false
		return
	}
	if edbInfoMappingB == nil {
		br.Msg = "指标B不存在"
		br.IsSendEmail = false
		return
	}

	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = `保存失败`
		br.ErrMsg = "获取配置与图表的关联关系失败，ERR:" + err.Error()
		return
	}

	err = nil
	var isAdd bool
	var chartInfoId int
	if multipleGraphConfigChartMapping == nil {
		isAdd = true
	} else {
		chartInfo, err := data_manage.GetChartInfoById(multipleGraphConfigChartMapping.ChartInfoId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = `保存失败`
			br.ErrMsg = "获取图表信息失败，ERR:" + err.Error()
			return
		}
		// 说明图还在，没有被删除
		if chartInfo != nil {
			chartInfoId = multipleGraphConfigChartMapping.ChartInfoId
			req.ChartName = chartInfo.ChartName
			req.ClassifyId = chartInfo.ChartClassifyId
		}
	}

	var chartInfo *data_manage.ChartInfo
	var errMsg string
	isSendEmail := true
	switch req.Source {
	case 1: // 曲线图
		curveConf := req.Curve
		edbInfoType := 1 //1:标准指标,0:领先指标
		if !curveConf.EdbInfoType {
			edbInfoType = 0
		}

		chartSaveItemList := []*data_manage.ChartSaveItem{
			{
				EdbInfoId:   edbInfoMappingA.EdbInfoId,
				MaxData:     curveConf.LeftMax,
				MinData:     curveConf.LeftMin,
				IsOrder:     false,
				IsAxis:      1,
				EdbInfoType: 1,
				//LeadValue:         curveConf.LeadValue,
				//LeadUnit:          curveConf.LeadUnit,
				ChartStyle:        "spline",
				ChartColor:        `#00F`,
				PredictChartColor: "",
				ChartWidth:        3,
				Source:            utils.CHART_SOURCE_DEFAULT,
			}, {
				EdbInfoId:         edbInfoMappingB.EdbInfoId,
				MaxData:           curveConf.RightMax,
				MinData:           curveConf.RightMin,
				IsOrder:           curveConf.IsOrder,
				IsAxis:            0,
				EdbInfoType:       edbInfoType,
				LeadValue:         curveConf.LeadValue,
				LeadUnit:          curveConf.LeadUnit,
				ChartStyle:        "spline",
				ChartColor:        `#F00`,
				PredictChartColor: "",
				ChartWidth:        1,
				Source:            utils.CHART_SOURCE_DEFAULT,
			},
		}

		if chartInfoId <= 0 {
			addChartReq := data_manage.AddChartInfoReq{
				ChartEdbInfoList: chartSaveItemList,
				ChartClassifyId:  req.ClassifyId,
				ChartName:        req.ChartName,
				ChartType:        utils.CHART_TYPE_CURVE,
				DateType:         curveConf.DateType,
				StartDate:        curveConf.StartDate,
				EndDate:          curveConf.EndDate,
				Calendar:         "公历",
				SeasonStartDate:  curveConf.StartDate,
				SeasonEndDate:    curveConf.EndDate,
				LeftMin:          fmt.Sprint(curveConf.LeftMin),
				LeftMax:          fmt.Sprint(curveConf.LeftMax),
				RightMin:         fmt.Sprint(curveConf.RightMin),
				RightMax:         fmt.Sprint(curveConf.RightMax),
			}
			chartInfo, err, errMsg, isSendEmail = data.AddChartInfo(addChartReq, sysUser.AdminId, sysUser.RealName)
		} else {
			editChartReq := data_manage.EditChartInfoReq{
				ChartInfoId:      multipleGraphConfigChartMapping.ChartInfoId,
				ChartName:        req.ChartName,
				ChartClassifyId:  req.ClassifyId,
				ChartEdbInfoList: chartSaveItemList,
				ChartType:        utils.CHART_TYPE_CURVE,
				DateType:         curveConf.DateType,
				StartDate:        curveConf.StartDate,
				EndDate:          curveConf.EndDate,
				Calendar:         "公历",
				SeasonStartDate:  curveConf.StartDate,
				SeasonEndDate:    curveConf.EndDate,
				LeftMin:          fmt.Sprint(curveConf.LeftMin),
				LeftMax:          fmt.Sprint(curveConf.LeftMax),
				RightMin:         fmt.Sprint(curveConf.RightMin),
				RightMax:         fmt.Sprint(curveConf.RightMax),
			}
			chartInfo, err, errMsg, isSendEmail = data.EditChartInfo(editChartReq, sysUser)
			if err != nil {
				br.Msg = "保存失败"
				if errMsg != `` {
					br.Msg = errMsg
				}
				br.ErrMsg = err.Error()
				br.IsSendEmail = isSendEmail
				return
			}
		}

	case 2, 3, 4: // 相关性图（滚动相关性）
		correlationConf := req.Correlation
		// 配置了数据才有返回
		if correlationConf.LeadValue > 0 {
			leadValue := correlationConf.LeadValue
			leadUnit := correlationConf.LeadUnit
			baseCalculateValue := correlationConf.CalculateValue
			baseCalculateUnit := correlationConf.CalculateUnit
			calculateValue := baseCalculateValue
			calculateUnit := baseCalculateUnit

			chartSource := utils.CHART_SOURCE_CORRELATION // 默认是相关性图

			moveUnitDays, ok := utils.FrequencyDaysMap[calculateUnit]
			if !ok {
				br.Msg = "错误的分析周期"
				br.IsSendEmail = false
				return
			}
			startDate := time.Now().AddDate(0, 0, -correlationConf.CalculateValue*moveUnitDays).Format(utils.FormatDate)
			endDate := time.Now().Format(utils.FormatDate)
			// 日期类型
			var dateType int

			if req.Source != 2 {
				chartSource = utils.CHART_SOURCE_ROLLING_CORRELATION
				var rollingCorrelation data_manage.RollingCorrelationConfig
				if req.Source == 3 {
					rollingCorrelation = req.RollingCorrelation[0]
				} else {
					rollingCorrelation = req.RollingCorrelation[1]
				}

				leadValue = rollingCorrelation.LeadValue
				leadUnit = rollingCorrelation.LeadUnit
				calculateValue = rollingCorrelation.CalculateValue
				calculateUnit = rollingCorrelation.CalculateUnit

				// 开始日期，结束日期
				dateType = req.Curve.DateType
				startDate, endDate = utils.GetDateByDateType(req.Curve.DateType, req.Curve.StartDate, req.Curve.EndDate)
			}

			correlationChartInfoReq := data_manage.CorrelationChartInfoReq{
				LeadValue:          leadValue,
				LeadUnit:           leadUnit,
				CalculateValue:     calculateValue,
				CalculateUnit:      calculateUnit,
				BaseCalculateValue: baseCalculateValue,
				BaseCalculateUnit:  baseCalculateUnit,
				DateType:           dateType,
				StartDate:          startDate,
				EndDate:            endDate,
				EdbInfoIdList: []data_manage.CorrelationChartInfoEdbItemReq{
					{
						EdbInfoId: edbInfoMappingA.EdbInfoId,
						Name:      "",
						NameEn:    "",
					}, {
						EdbInfoId: edbInfoMappingB.EdbInfoId,
						Name:      "",
						NameEn:    "",
					},
				},
			}

			if chartInfoId <= 0 {
				addChartReq := data_manage.AddChartInfoReq{
					ChartClassifyId:      req.ClassifyId,
					ChartName:            req.ChartName,
					ChartType:            utils.CHART_TYPE_CURVE,
					Calendar:             "公历",
					CorrelationChartInfo: correlationChartInfoReq,
				}
				chartInfo, err, errMsg, isSendEmail = correlationServ.AddChartInfo(addChartReq, chartSource, sysUser)
			} else {
				editChartReq := data_manage.EditChartInfoReq{
					ChartInfoId:          multipleGraphConfigChartMapping.ChartInfoId,
					ChartName:            req.ChartName,
					ChartClassifyId:      req.ClassifyId,
					ChartType:            utils.CHART_TYPE_CURVE,
					Calendar:             "公历",
					CorrelationChartInfo: correlationChartInfoReq,
				}
				chartInfo, err, errMsg, isSendEmail = correlationServ.EditChartInfo(editChartReq, sysUser)
				if err != nil {
					br.Msg = "保存失败"
					if errMsg != `` {
						br.Msg = errMsg
					}
					br.ErrMsg = err.Error()
					br.IsSendEmail = isSendEmail
					return
				}
			}
		}
	default:
		br.Msg = "错误的来源"
		br.ErrMsg = "错误的来源,source:" + strconv.Itoa(req.Source)
		br.IsSendEmail = false
		return

	}

	if err != nil {
		br.Msg = "保存失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = err.Error()
		br.IsSendEmail = isSendEmail
		return
	}

	// 如果图没有建立关联关系，那么就需要添加关系
	if isAdd {
		multipleGraphConfigChartMapping = &data_manage.MultipleGraphConfigChartMapping{
			//Id:                    0,
			MultipleGraphConfigId: req.MultipleGraphConfigId,
			ChartInfoId:           chartInfo.ChartInfoId,
			Source:                req.Source,
			ModifyTime:            time.Now(),
			CreateTime:            time.Now(),
		}
		err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
		if err != nil {
			br.Msg = "保存失败"
			br.ErrMsg = "保存配置与图表的关联关系失败，ERR:" + err.Error()
			return
		}
	} else if multipleGraphConfigChartMapping != nil {
		multipleGraphConfigChartMapping.ChartInfoId = chartInfo.ChartInfoId
		multipleGraphConfigChartMapping.ModifyTime = time.Now()
		err = multipleGraphConfigChartMapping.Update([]string{"ChartInfoId", "ModifyTime"})
		if err != nil {
			br.Msg = "保存失败"
			br.ErrMsg = "保存配置与图表的关联关系失败，ERR:" + err.Error()
			return
		}
	}

	//新增操作日志
	{
		chartLog := new(data_manage.ChartInfoLog)
		chartLog.ChartInfoId = chartInfo.ChartInfoId
		chartLog.ChartName = req.ChartName
		chartLog.ChartClassifyId = req.ClassifyId
		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)
	}

	resp := new(data_manage.AddChartInfoResp)
	resp.ChartInfoId = chartInfo.ChartInfoId
	resp.UniqueCode = chartInfo.UniqueCode
	resp.ChartType = chartInfo.ChartType

	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

// CopyMultipleGraphConfigSaveChart 图表另存为
func CopyMultipleGraphConfigSaveChart(req request.SaveMultipleGraphChartReq, this *ChartInfoController, br *models.BaseResponse, sysUser *system.Admin) {
	mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList([]int{req.EdbInfoIdA, req.EdbInfoIdB})
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表，指标信息失败，Err:" + err.Error()
		return
	}
	var edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping
	for _, v := range mappingList {
		if v.EdbInfoId == req.EdbInfoIdA {
			edbInfoMappingA = v
		}
		if v.EdbInfoId == req.EdbInfoIdB {
			edbInfoMappingB = v
		}
	}
	if edbInfoMappingA == nil {
		br.Msg = "指标A不存在"
		br.IsSendEmail = false
		return
	}
	if edbInfoMappingB == nil {
		br.Msg = "指标B不存在"
		br.IsSendEmail = false
		return
	}

	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = `保存失败`
		br.ErrMsg = "获取配置与图表的关联关系失败，ERR:" + err.Error()
		return
	}

	// 原图
	oldChartInfo, err := data_manage.GetChartInfoById(multipleGraphConfigChartMapping.ChartInfoId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = `保存失败`
		br.ErrMsg = "获取图表信息失败，ERR:" + err.Error()
		return
	}
	// 说明图还在，没有被删除
	if oldChartInfo == nil {
		br.Msg = "原图不存在"
		br.IsSendEmail = false
	}

	var chartInfo *data_manage.ChartInfo
	var errMsg string
	isSendEmail := true
	switch req.Source {
	case 1: // 曲线图
		curveConf := req.Curve
		edbInfoType := 1 //1:标准指标,0:领先指标
		if !curveConf.EdbInfoType {
			edbInfoType = 0
		}
		chartSaveItemList := []*data_manage.ChartSaveItem{
			{
				EdbInfoId:   edbInfoMappingA.EdbInfoId,
				MaxData:     curveConf.LeftMax,
				MinData:     curveConf.LeftMin,
				IsOrder:     false,
				IsAxis:      1,
				EdbInfoType: 1,
				//LeadValue:         curveConf.LeadValue,
				//LeadUnit:          curveConf.LeadUnit,
				ChartStyle:        "spline",
				ChartColor:        `#00F`,
				PredictChartColor: "",
				ChartWidth:        3,
				Source:            utils.CHART_SOURCE_DEFAULT,
			}, {
				EdbInfoId:         edbInfoMappingB.EdbInfoId,
				MaxData:           curveConf.RightMax,
				MinData:           curveConf.RightMin,
				IsOrder:           curveConf.IsOrder,
				IsAxis:            0,
				EdbInfoType:       edbInfoType,
				LeadValue:         curveConf.LeadValue,
				LeadUnit:          curveConf.LeadUnit,
				ChartStyle:        "spline",
				ChartColor:        `#F00`,
				PredictChartColor: "",
				ChartWidth:        1,
				Source:            utils.CHART_SOURCE_DEFAULT,
			},
		}

		addChartReq := data_manage.AddChartInfoReq{
			ChartEdbInfoList: chartSaveItemList,
			ChartClassifyId:  req.ClassifyId,
			ChartName:        req.ChartName,
			ChartType:        utils.CHART_TYPE_CURVE,
			DateType:         curveConf.DateType,
			StartDate:        curveConf.StartDate,
			EndDate:          curveConf.EndDate,
			Calendar:         "公历",
			SeasonStartDate:  curveConf.StartDate,
			SeasonEndDate:    curveConf.EndDate,
			LeftMin:          fmt.Sprint(curveConf.LeftMin),
			LeftMax:          fmt.Sprint(curveConf.LeftMax),
			RightMin:         fmt.Sprint(curveConf.RightMin),
			RightMax:         fmt.Sprint(curveConf.RightMax),
		}
		chartInfo, err, errMsg, isSendEmail = data.AddChartInfo(addChartReq, sysUser.AdminId, sysUser.RealName)

	case 2: // 相关性图
		correlationConf := req.Correlation
		// 配置了数据才有返回
		if correlationConf.LeadValue > 0 {
			leadValue := correlationConf.LeadValue
			leadUnit := correlationConf.LeadUnit
			calculateValue := correlationConf.CalculateValue
			calculateUnit := correlationConf.CalculateUnit

			moveUnitDays, ok := utils.FrequencyDaysMap[calculateUnit]
			if !ok {
				br.Msg = "错误的分析周期"
				br.IsSendEmail = false
				return
			}
			startDate := time.Now().AddDate(0, 0, -correlationConf.CalculateValue*moveUnitDays).Format(utils.FormatDate)

			endDate := time.Now().Format(utils.FormatDate)

			correlationChartInfoReq := data_manage.CorrelationChartInfoReq{
				LeadValue:      leadValue,
				LeadUnit:       leadUnit,
				CalculateValue: calculateValue,
				CalculateUnit:  calculateUnit,
				StartDate:      startDate,
				EndDate:        endDate,
				EdbInfoIdList: []data_manage.CorrelationChartInfoEdbItemReq{
					{
						EdbInfoId: edbInfoMappingA.EdbInfoId,
						Name:      "",
						NameEn:    "",
					}, {
						EdbInfoId: edbInfoMappingB.EdbInfoId,
						Name:      "",
						NameEn:    "",
					},
				},
			}

			chartInfo, err, errMsg, isSendEmail = correlationServ.CopyChartInfo(multipleGraphConfigChartMapping.MultipleGraphConfigId, req.ClassifyId, req.ChartName, correlationChartInfoReq, sysUser)
		}
	default:
		br.Msg = "错误的来源"
		br.ErrMsg = "错误的来源,source:" + strconv.Itoa(req.Source)
		br.IsSendEmail = false
		return

	}

	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.ClassifyId
		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)
	}

	resp := new(data_manage.AddChartInfoResp)
	resp.ChartInfoId = chartInfo.ChartInfoId
	resp.UniqueCode = chartInfo.UniqueCode
	resp.ChartType = chartInfo.ChartType

	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

// MultipleGraphConfigSaveEdb
// @Title 保存指标接口
// @Description 保存指标接口
// @Param	request	body request.SaveMultipleGraphEdbReq true "type json string"
// @Success Ret=200 返回指标id
// @router /multiple_graph/edb/save [post]
func (this *ChartInfoController) MultipleGraphConfigSaveEdb() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req request.SaveMultipleGraphEdbReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	cacheKey := "CACHE_CHART_EDB_INFO_ADD_" + strconv.Itoa(sysUser.AdminId)
	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
		br.Msg = "系统处理中，请稍后重试！"
		br.ErrMsg = "系统处理中，请稍后重试！" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
		return
	}
	defer func() {
		_ = utils.Rc.Delete(cacheKey)
	}()

	mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList([]int{req.EdbInfoIdA, req.EdbInfoIdB})
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表，指标信息失败，Err:" + err.Error()
		return
	}
	var edbInfoMappingA, edbInfoMappingB *data_manage.ChartEdbInfoMapping
	for _, v := range mappingList {
		if v.EdbInfoId == req.EdbInfoIdA {
			edbInfoMappingA = v
		}
		if v.EdbInfoId == req.EdbInfoIdB {
			edbInfoMappingB = v
		}
	}
	if edbInfoMappingA == nil {
		br.Msg = "指标A不存在"
		br.IsSendEmail = false
		return
	}
	if edbInfoMappingB == nil {
		br.Msg = "指标B不存在"
		br.IsSendEmail = false
		return
	}

	correlationConf := req.Correlation
	// 配置了数据才有返回
	if correlationConf.LeadValue <= 0 {
		br.Msg = "相关性计算窗口必须大于0"
		br.IsSendEmail = false
		return
	}
	// 滚动相关性配置
	var rollingCorrelation data_manage.RollingCorrelationConfig
	switch req.Source {
	case 3:
		rollingCorrelation = req.RollingCorrelation[0]
	case 4:
		rollingCorrelation = req.RollingCorrelation[1]
	default:
		br.Msg = "错误的来源"
		br.ErrMsg = "错误的来源,source:" + strconv.Itoa(req.Source)
		br.IsSendEmail = false
		return
	}
	// 配置了数据才有返回
	if rollingCorrelation.CalculateValue <= 0 {
		br.Msg = "滚动相关性计算窗口必须大于0"
		br.IsSendEmail = false
		return
	}

	multipleGraphConfigEdbMapping, err := data_manage.GetMultipleGraphConfigEdbMappingByIdAndSource(req.MultipleGraphConfigId, req.Source)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = `保存失败`
		br.ErrMsg = "获取配置与图表的关联关系失败，ERR:" + err.Error()
		return
	}
	err = nil
	var isAdd bool
	var edbInfoId int
	if multipleGraphConfigEdbMapping == nil {
		isAdd = true
	} else {
		edbInfo, err := data_manage.GetEdbInfoById(multipleGraphConfigEdbMapping.EdbInfoId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = `保存失败`
			br.ErrMsg = "获取图表信息失败，ERR:" + err.Error()
			return
		}
		// 说明指标还在，没有被删除
		if edbInfo != nil && !req.IsSaveAs {
			edbInfoId = multipleGraphConfigEdbMapping.EdbInfoId
			req.EdbName = edbInfo.EdbName
			req.ClassifyId = edbInfo.ClassifyId
			req.Frequency = edbInfo.Frequency
			req.Unit = edbInfo.Unit
		}
	}

	// 关联指标
	edbInfoIdArr := []data_manage.EdbInfoFromTag{
		{
			EdbInfoId: edbInfoMappingA.EdbInfoId,
			FromTag:   "A",
			MoveValue: 0,
		}, {
			EdbInfoId: edbInfoMappingB.EdbInfoId,
			FromTag:   "B",
			MoveValue: 0,
		},
	}

	calculateFormula := request.EdbCalculateFormula{
		BaseCalculateValue: correlationConf.CalculateValue,
		BaseCalculateUnit:  correlationConf.CalculateUnit,
		LeadValue:          rollingCorrelation.LeadValue,
		LeadUnit:           rollingCorrelation.LeadUnit,
		CalculateValue:     rollingCorrelation.CalculateValue,
		CalculateUnit:      rollingCorrelation.CalculateUnit,
	}
	calculateFormulaByte, err := json.Marshal(calculateFormula)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	var respItem *data.AddPredictEdbDataResponse
	if edbInfoId <= 0 || req.IsSaveAs {
		req2 := &data_manage.EdbInfoCalculateBatchSaveReqByEdbLib{
			AdminId:      sysUser.AdminId,
			AdminName:    sysUser.RealName,
			EdbName:      req.EdbName,
			Frequency:    req.Frequency,
			Unit:         req.Unit,
			ClassifyId:   req.ClassifyId,
			Formula:      string(calculateFormulaByte),
			Source:       utils.DATA_SOURCE_CALCULATE_CORRELATION,
			EdbInfoIdArr: edbInfoIdArr,
			Calendar:     `公历`,
		}

		// 调用指标库去添加
		reqJson, err := json.Marshal(req2)
		if err != nil {
			br.Msg = "参数解析异常！"
			br.ErrMsg = "参数解析失败，Err:" + err.Error()
			return
		}
		respItem, err = data.BatchSaveEdbCalculateData(string(reqJson))
		if err != nil {
			br.Msg = "新增失败"
			br.ErrMsg = "新增失败,Err:" + err.Error()
			return
		}
	} else {
		req2 := &data_manage.EdbInfoCalculateBatchEditReqByEdbLib{
			EdbInfoId:    edbInfoId,
			EdbName:      req.EdbName,
			Frequency:    req.Frequency,
			Unit:         req.Unit,
			ClassifyId:   req.ClassifyId,
			Formula:      string(calculateFormulaByte),
			Source:       utils.DATA_SOURCE_CALCULATE_CORRELATION,
			EdbInfoIdArr: edbInfoIdArr,
			Calendar:     `公历`,
		}

		// 调用指标库去更新
		reqJson, err := json.Marshal(req2)
		if err != nil {
			br.Msg = "参数解析异常！"
			br.ErrMsg = "参数解析失败，Err:" + err.Error()
			return
		}
		respItem, err = data.BatchEditEdbCalculateData(string(reqJson))
		if err != nil {
			br.Msg = "编辑失败"
			br.ErrMsg = "编辑失败,Err:" + err.Error()
			return
		}
	}
	if respItem == nil {
		br.Msg = "保存失败"
		br.ErrMsg = "保存失败"
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	resp := respItem.Data

	//添加es
	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)

	// 如果不是另存为的话，那么需要建立配置与指标的关系
	if !req.IsSaveAs {
		// 如果指标没有建立关联关系，那么就需要添加关系
		if isAdd {
			multipleGraphConfigEdbMapping = &data_manage.MultipleGraphConfigEdbMapping{
				//Id:                    0,
				MultipleGraphConfigId: req.MultipleGraphConfigId,
				EdbInfoId:             resp.EdbInfoId,
				Source:                req.Source,
				ModifyTime:            time.Now(),
				CreateTime:            time.Now(),
			}
			err = data_manage.AddMultipleGraphConfigEdbMapping(multipleGraphConfigEdbMapping)
			if err != nil {
				br.Msg = "保存失败"
				br.ErrMsg = "保存配置与指标的关联关系失败，ERR:" + err.Error()
				return
			}
		} else if multipleGraphConfigEdbMapping != nil {
			multipleGraphConfigEdbMapping.EdbInfoId = resp.EdbInfoId
			multipleGraphConfigEdbMapping.ModifyTime = time.Now()
			err = multipleGraphConfigEdbMapping.Update([]string{"EdbInfoId", "ModifyTime"})
			if err != nil {
				br.Msg = "保存失败"
				br.ErrMsg = "保存配置与指标的关联关系失败，ERR:" + err.Error()
				return
			}
		}
	}

	//新增操作日志
	//{
	//	edbLog := new(data_manage.EdbInfoLog)
	//	edbLog.EdbInfoId = resp.EdbInfoId
	//	edbLog.SourceName = edbInfo.SourceName
	//	edbLog.Source = edbInfo.Source
	//	edbLog.EdbCode = edbInfo.EdbCode
	//	edbLog.EdbName = req2.EdbName
	//	edbLog.ClassifyId = req2.ClassifyId
	//	edbLog.SysUserId = sysUser.AdminId
	//	edbLog.SysUserRealName = sysUser.RealName
	//	edbLog.CreateTime = time.Now()
	//	edbLog.Content = string(this.Ctx.Input.RequestBody)
	//	edbLog.Status = "多图配置保存指标"
	//	edbLog.Method = this.Ctx.Input.URI()
	//	go data_manage.AddEdbInfoLog(edbLog)
	//}

	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

// GetMultipleGraphConfig
// @Title 保存配置接口
// @Description 保存配置接口
// @Param   UniqueCode   query   int  true       "图表唯一编码,如果是管理后台访问，传固定字符串:7c69b590249049942070ae9dcd5bf6dc"
// @Success Ret=200 返回图表id
// @router /multiple_graph/config/detail [get]
func (this *ChartInfoController) GetMultipleGraphConfig() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录，SysUser Is Empty"
		br.Ret = 408
		return
	}
	uniqueCode := this.GetString("UniqueCode")
	if uniqueCode == "" {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误,uniqueCode is empty"
		return
	}

	chartInfo, err := data_manage.GetChartInfoViewByUniqueCode(uniqueCode)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表信息失败，Err:" + err.Error()
		return
	}
	if chartInfo == nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表信息失败，Err:" + err.Error()
		return
	}
	multipleGraphConfigChartMapping, err := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfo.ChartInfoId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取滚动相关性图表的配置信息失败，Err:" + err.Error()
		return
	}

	multipleGraphConfig, err := data_manage.GetMultipleGraphConfigById(multipleGraphConfigChartMapping.MultipleGraphConfigId)
	if err != nil {
		br.Msg = `获取失败`
		br.ErrMsg = `获取配置失败，ERR：` + err.Error()
		return
	}

	// 生成的图表
	multipleGraphConfigChartMappingList := make([]response.MultipleGraphConfigChartMapping, 0)
	{
		chartMappingList, err := data_manage.GetMultipleGraphConfigChartMappingListById(multipleGraphConfigChartMapping.MultipleGraphConfigId)
		if err != nil {
			br.Msg = `获取失败`
			br.ErrMsg = `获取关联图表配置失败，ERR：` + err.Error()
			return
		}
		chartInfoIdList := make([]int, 0)
		chartMappingMap := make(map[int]*data_manage.MultipleGraphConfigChartMapping)
		for _, v := range chartMappingList {
			chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
			chartMappingMap[v.ChartInfoId] = v
		}
		chartList, err := data_manage.GetChartInfoByIdList(chartInfoIdList)
		if err != nil {
			br.Msg = `获取失败`
			br.ErrMsg = `获取关联图表列表失败，ERR：` + err.Error()
			return
		}
		for _, v := range chartList {
			if tmpInfo, ok := chartMappingMap[v.ChartInfoId]; ok {
				multipleGraphConfigChartMappingList = append(multipleGraphConfigChartMappingList, response.MultipleGraphConfigChartMapping{
					ChartInfoId:            tmpInfo.ChartInfoId,
					Source:                 tmpInfo.Source,
					MultipleLocationSource: tmpInfo.Source,
				})
			}
		}
	}

	// 生成的指标
	multipleGraphConfigEdbMappingList := make([]response.MultipleGraphConfigEdbMapping, 0)
	{
		edbMappingList, err := data_manage.GetMultipleGraphConfigEdbMappingListById(multipleGraphConfigChartMapping.MultipleGraphConfigId)
		if err != nil {
			br.Msg = `获取失败`
			br.ErrMsg = `获取关联指标配置失败，ERR：` + err.Error()
			return
		}
		edbInfoIdList := make([]int, 0)
		edbMappingMap := make(map[int]*data_manage.MultipleGraphConfigEdbMapping)
		for _, v := range edbMappingList {
			edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
			edbMappingMap[v.EdbInfoId] = v
		}

		edbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
		if err != nil {
			br.Msg = `获取失败`
			br.ErrMsg = `获取关联图表列表失败，ERR：` + err.Error()
			return
		}
		for _, v := range edbList {
			if tmpInfo, ok := edbMappingMap[v.EdbInfoId]; ok {
				multipleGraphConfigEdbMappingList = append(multipleGraphConfigEdbMappingList, response.MultipleGraphConfigEdbMapping{
					EdbInfoId:              tmpInfo.EdbInfoId,
					Source:                 tmpInfo.Source,
					MultipleLocationSource: tmpInfo.Source,
				})
			}
		}
	}

	// 关联指标
	mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList([]int{multipleGraphConfig.EdbInfoIdA, multipleGraphConfig.EdbInfoIdB})
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表，指标信息失败，Err:" + err.Error()
		return
	}

	resp := response.MultipleGraphConfigDetailResp{
		EdbInfoList:         mappingList,
		MultipleGraphConfig: *multipleGraphConfig,
		ChartMappingList:    multipleGraphConfigChartMappingList,
		EdbMappingList:      multipleGraphConfigEdbMappingList,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

//	func init() {
//		//correlationChart := new(data_manage.ChartInfoCorrelation)
//
//		condition := ` AND source = 3 `
//		list, err := data_manage.GetChartListByCondition(condition, []interface{}{}, 0, 1000)
//		if err != nil {
//			fmt.Println("err:", err)
//			return
//		}
//		timeNowFormat := time.Now().Format(utils.FormatDate)
//		for _, v := range list {
//			item, tmpErr := data_manage.GetMultipleGraphConfigChartMappingByChartIdAndSource(v.ChartInfoId)
//			if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
//				fmt.Println("tmpErr:", tmpErr)
//				continue
//			}
//			if item == nil {
//				correlationChart := new(data_manage.ChartInfoCorrelation)
//				e := correlationChart.GetItemById(v.ChartInfoId)
//				if e != nil {
//					fmt.Println("获取历史配置失败:", e)
//					continue
//				}
//				day, _ := utils.GetDaysBetween2Date(utils.FormatDate, timeNowFormat, correlationChart.StartDate.Format(utils.FormatDate))
//				req := request.SaveMultipleGraphConfigReq{
//					MultipleGraphConfigId: 0,
//					EdbInfoIdA:            correlationChart.EdbInfoIdFirst,
//					EdbInfoIdB:            correlationChart.EdbInfoIdSecond,
//					Curve:                 data_manage.CurveConfig{},
//					Correlation: data_manage.CorrelationConfig{
//						LeadValue:      correlationChart.LeadValue,
//						LeadUnit:       correlationChart.LeadUnit,
//						CalculateValue: day,
//						CalculateUnit:  "天",
//					},
//					RollingCorrelation: []data_manage.RollingCorrelationConfig{
//						{}, {},
//					},
//				}
//				curveStrByte, _ := json.Marshal(req.Curve)
//				correlationStrByte, _ := json.Marshal(req.Correlation)
//				rollingCorrelationStrByte, _ := json.Marshal(req.RollingCorrelation)
//
//				multipleGraphConfig := &data_manage.MultipleGraphConfig{
//					//MultipleGraphConfigId: 0,
//					EdbInfoIdA:         req.EdbInfoIdA,
//					EdbInfoIdB:         req.EdbInfoIdB,
//					Curve:              string(curveStrByte),
//					Correlation:        string(correlationStrByte),
//					RollingCorrelation: string(rollingCorrelationStrByte),
//					SysUserId:          v.SysUserId,
//					SysUserRealName:    v.SysUserRealName,
//					ModifyTime:         v.ModifyTime,
//					CreateTime:         v.CreateTime,
//				}
//				err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
//
//				if err != nil {
//					fmt.Println(v.ChartInfoId, "创建配置失败：", err)
//					continue
//				}
//
//				multipleGraphConfigChartMapping := &data_manage.MultipleGraphConfigChartMapping{
//					//Id:                    0,
//					MultipleGraphConfigId: multipleGraphConfig.MultipleGraphConfigId,
//					ChartInfoId:           v.ChartInfoId,
//					Source:                2,
//					ModifyTime:            time.Now(),
//					CreateTime:            time.Now(),
//				}
//				err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
//				if err != nil {
//					fmt.Println(v.ChartInfoId, "保存配置与图表的关联关系失败：", err)
//				}
//
//				correlationChart.CalculateUnit = "天"
//				correlationChart.CalculateValue = day
//				err = correlationChart.Update([]string{"CalculateUnit", "CalculateValue"})
//				if err != nil {
//					fmt.Println(v.ChartInfoId, "修复历史数据失败：", err)
//				}
//			}
//		}
//	}

// 修复相关性图表与滚动相关性图表的强关联关系
//func init() {
//	condition := ` AND source =  ? `
//	pars := []interface{}{utils.CHART_SOURCE_ROLLING_CORRELATION}
//	list, err := data_manage.GetChartListByCondition(condition, pars, 0, 1000)
//	if err != nil {
//		fmt.Println("err:", err)
//		return
//	}
//	for _, chartInfo := range list {
//		multipleGraphConfigChartMapping, e := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfo.ChartInfoId)
//		if e != nil {
//			fmt.Println(chartInfo.ChartInfoId, ";获取滚动相关性图表的配置信息失败, Err:"+e.Error())
//			continue
//		}
//		baseChartMultipleGraphConfigChartMapping, e := data_manage.GetMultipleGraphConfigChartMappingByIdAndSource(multipleGraphConfigChartMapping.MultipleGraphConfigId, 2)
//		if e != nil {
//			fmt.Println(chartInfo.ChartInfoId, ";获取相关性图表的配置信息失败, Err:"+e.Error())
//			continue
//		}
//		baseChartCorrelationChart := new(data_manage.ChartInfoCorrelation)
//		if e := baseChartCorrelationChart.GetItemById(baseChartMultipleGraphConfigChartMapping.ChartInfoId); e != nil {
//			fmt.Println(chartInfo.ChartInfoId, ";获取基础相关性图表信息失败, Err:"+e.Error())
//			continue
//		}
//
//		// 自己的配置
//		selfChartCorrelationChart := new(data_manage.ChartInfoCorrelation)
//		if e := selfChartCorrelationChart.GetItemById(chartInfo.ChartInfoId); e != nil {
//			fmt.Println(chartInfo.ChartInfoId, ";获取自己的相关性图表信息失败, Err:"+e.Error())
//			continue
//		}
//
//		selfChartCorrelationChart.BaseCalculateUnit = baseChartCorrelationChart.CalculateUnit
//		selfChartCorrelationChart.BaseCalculateValue = baseChartCorrelationChart.CalculateValue
//		err = selfChartCorrelationChart.Update([]string{"BaseCalculateUnit", "BaseCalculateValue"})
//		if err != nil {
//			fmt.Println(chartInfo.ChartInfoId, ";更新相关性图表信息失败, Err:"+err.Error())
//			continue
//		}
//	}
//
//}

// 修复相关性图表与滚动相关性图表的强关联关系
//func init() {
//	{
//		condition := ` AND source =  ? `
//		pars := []interface{}{utils.CHART_SOURCE_ROLLING_CORRELATION}
//		list, err := data_manage.GetChartListByCondition(condition, pars, 0, 1000)
//		if err != nil {
//			fmt.Println("err:", err)
//			return
//		}
//		for _, chartInfo := range list {
//			multipleGraphConfigChartMapping, e := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfo.ChartInfoId)
//			if e != nil {
//				fmt.Println(chartInfo.ChartInfoId, ";获取滚动相关性图表的配置信息失败, Err:"+e.Error())
//				continue
//			}
//			multipleGraphConfig, e := data_manage.GetMultipleGraphConfigById(multipleGraphConfigChartMapping.MultipleGraphConfigId)
//			if e != nil {
//				fmt.Println(chartInfo.ChartInfoId, ";获取相关性图表的配置信息失败, Err:"+e.Error())
//				continue
//			}
//			var curveConf data_manage.CurveConfig
//			e = json.Unmarshal([]byte(multipleGraphConfig.Curve), &curveConf)
//			if e != nil {
//				fmt.Println(chartInfo.ChartInfoId, ";格式化曲线图数据失败, Err:"+e.Error())
//				continue
//			}
//
//			// 自己的配置
//			selfChartCorrelationChart := new(data_manage.ChartInfoCorrelation)
//			if e := selfChartCorrelationChart.GetItemById(chartInfo.ChartInfoId); e != nil {
//				fmt.Println(chartInfo.ChartInfoId, ";获取自己的相关性图表信息失败, Err:"+e.Error())
//				continue
//			}
//
//			selfChartCorrelationChart.DateType = curveConf.DateType
//
//			startDate, endDate := utils.GetDateByDateType(curveConf.DateType, curveConf.StartDate, curveConf.EndDate)
//			if startDate != `` {
//				startDateTime, e := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
//				if e != nil {
//					fmt.Println(chartInfo.ChartInfoId, ";开始日期格式化失败，开始日期：", startDate, ", Err:"+e.Error())
//					continue
//				}
//				selfChartCorrelationChart.StartDate = startDateTime
//			}
//			if endDate != `` {
//				endDateTime, e := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
//				if e != nil {
//					fmt.Println(chartInfo.ChartInfoId, ";开始日期格式化失败，开始日期：", startDate, ", Err:"+e.Error())
//					continue
//				}
//				selfChartCorrelationChart.EndDate = endDateTime
//			}
//			err = selfChartCorrelationChart.Update([]string{"DateType", "StartDate", "EndDate"})
//			if err != nil {
//				fmt.Println(chartInfo.ChartInfoId, ";更新相关性图表信息失败, Err:"+err.Error())
//				continue
//			}
//		}
//
//		fmt.Println("图表更新完成")
//	}
//
//	{
//		// 更新指标
//		condition := ` AND source =  ? `
//		pars := []interface{}{utils.DATA_SOURCE_CALCULATE_CORRELATION}
//		list, err := data_manage.GetEdbInfoListV2ByCondition(condition, pars, 0, 10000)
//		if err != nil {
//			fmt.Println("err:", err)
//			return
//		}
//		for _, edbInfo := range list {
//			multipleGraphConfigEdbMappingInfo, e := data_manage.GetMultipleGraphConfigEdbMappingByEdbInfoId(edbInfo.EdbInfoId)
//			if e != nil {
//				fmt.Println(edbInfo.EdbInfoId, ";获取滚动相关性指标的配置信息失败, Err:"+e.Error())
//				continue
//			}
//			multipleGraphConfig, e := data_manage.GetMultipleGraphConfigById(multipleGraphConfigEdbMappingInfo.MultipleGraphConfigId)
//			if e != nil {
//				fmt.Println(edbInfo.EdbInfoId, ";获取相关性图表的配置信息失败, Err:"+e.Error())
//				continue
//			}
//
//			// 曲线图配置
//			var curveConf data_manage.CurveConfig
//			e = json.Unmarshal([]byte(multipleGraphConfig.Curve), &curveConf)
//			if e != nil {
//				fmt.Println(edbInfo.EdbInfoId, ";格式化曲线图数据失败, Err:"+e.Error())
//				continue
//			}
//
//			var formulaConf request.EdbCalculateFormula
//			e = json.Unmarshal([]byte(edbInfo.CalculateFormula), &formulaConf)
//			if e != nil {
//				fmt.Println(edbInfo.EdbInfoId, ";格式化指标计算配置数据失败, Err:"+e.Error())
//				continue
//			}
//			formulaConf.DateType = curveConf.DateType
//			formulaConf.StartDate = curveConf.StartDate
//			formulaConf.EndDate = curveConf.EndDate
//			calculateFormulaByte, err := json.Marshal(formulaConf)
//			edbInfo.CalculateFormula = string(calculateFormulaByte)
//			err = edbInfo.Update([]string{"CalculateFormula"})
//			if err != nil {
//				fmt.Println(edbInfo.EdbInfoId, ";更新指标信息失败, Err:"+err.Error())
//				continue
//			}
//		}
//
//		fmt.Println("指标更新完成")
//	}
//}
