package line_equation

import (
	"encoding/json"
	"errors"
	"eta/eta_mobile/models/data_manage"
	"eta/eta_mobile/models/data_manage/line_equation"
	"eta/eta_mobile/models/data_manage/line_equation/request"
	"eta/eta_mobile/models/system"
	"eta/eta_mobile/services/data"
	"eta/eta_mobile/utils"
	"fmt"
	"github.com/shopspring/decimal"
	"math"
	"sort"
	"strconv"
	"strings"
	"time"
)

type LineEquationResp struct {
	AData  LineEquationDataResp
	BData  LineEquationDataResp
	R2Data LineEquationDataResp
}

type LineEquationDataResp struct {
	MaxData             float64
	MinData             float64
	LatestDate          string `description:"真实数据的最后日期"`
	EdbInfoCategoryType int
	ChartColor          string
	ChartStyle          string
	PredictChartColor   string
	ChartType           int
	ChartWidth          int
	EdbName             string
	EdbNameEn           string
	Unit                string
	UnitEn              string
	IsAxis              int
	DataList            []data_manage.EdbDataList
}

// GetChartEdbData 获取图表数据
func GetChartEdbData(chartInfoId int, lineChartInfoConfig request.LineChartInfoReq, getAData, getBData, getR2Data bool) (edbList []*data_manage.ChartEdbInfoMapping, dataResp LineEquationResp, err error, errMsg string) {
	// 获取基本信息
	mappingList, startDate, endDate, err, errMsg := getConfigData(lineChartInfoConfig)
	if err != nil {
		return
	}
	xEdbInfoIdList := lineChartInfoConfig.XEdbInfoIdList
	yEdbInfoIdList := lineChartInfoConfig.YEdbInfoIdList

	aLineEquationDataResp := LineEquationDataResp{
		DataList:          make([]data_manage.EdbDataList, 0),
		MaxData:           0,
		MinData:           0,
		ChartColor:        "#00f",
		ChartStyle:        `spline`,
		PredictChartColor: `#00f`,
		ChartType:         0,
		ChartWidth:        3,
		EdbName:           `弹性系数`,
		EdbNameEn:         `elastic coefficient`,
		IsAxis:            1,
	}
	bLineEquationDataResp := LineEquationDataResp{
		DataList:          make([]data_manage.EdbDataList, 0),
		MaxData:           0,
		MinData:           0,
		ChartColor:        "#00f",
		ChartStyle:        `spline`,
		PredictChartColor: `#00f`,
		ChartType:         0,
		ChartWidth:        3,
		EdbName:           `截距`,
		EdbNameEn:         `intercept`,
		IsAxis:            1,
	}
	r2LineEquationDataResp := LineEquationDataResp{
		DataList:          make([]data_manage.EdbDataList, 0),
		MaxData:           0,
		MinData:           0,
		ChartColor:        "#00f",
		ChartStyle:        `spline`,
		PredictChartColor: `#00f`,
		ChartType:         0,
		ChartWidth:        3,
		EdbName:           `相关系数`,
		EdbNameEn:         `coefficient of association`,
		IsAxis:            1,
	}
	edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
	dataResp = LineEquationResp{
		AData:  aLineEquationDataResp,
		BData:  bLineEquationDataResp,
		R2Data: r2LineEquationDataResp,
	}

	var baseEdbInfo *data_manage.ChartEdbInfoMapping
	// 获取确定以哪个指标的日期作为基准日期
	{
		var xEdbInfo, yEdbInfo *data_manage.ChartEdbInfoMapping
		for _, v := range mappingList {
			if v.EdbInfoId == xEdbInfoIdList[0] {
				xEdbInfo = v
			}
			if v.EdbInfoId == yEdbInfoIdList[0] {
				yEdbInfo = v
			}
		}
		if xEdbInfo == nil {
			errMsg = `X轴第一个指标异常`
			err = errors.New(errMsg)
			return
		}
		if yEdbInfo == nil {
			errMsg = `Y轴第一个指标异常`
			err = errors.New(errMsg)
			return
		}

		// 时间截面规则：按照什么频率来取不同的截面的问题。原则是：按照X轴和Y轴所选择的第一个指标（X和Y分别有一个第一个指标），两个指标中，以低频的那个作为基准。如果X轴和Y轴是同频的，那以Y轴第一个指标的为准。
		frequencyIntMap := map[string]int{
			"日度": 1,
			"周度": 2,
			"旬度": 3,
			"月度": 4,
			"季度": 5,
			"年度": 6,
		}
		// 如果x是高频 或者 x与y是同频的，那么就是Y轴的第一个指标为主
		if frequencyIntMap[xEdbInfo.Frequency] <= frequencyIntMap[yEdbInfo.Frequency] {
			baseEdbInfo = yEdbInfo
		} else {
			// 否则是X轴的第一个指标是低频
			baseEdbInfo = xEdbInfo
		}
	}

	// 指标对应的所有数据
	chartType := 1 //1：普通图，2：季节性图
	calendar := "公历"
	edbDataListMap, edbList, err := data.GetEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, "")
	if err != nil {
		return
	}

	// 获取所有的日期
	dateList := make([]string, 0)
	for _, v := range edbDataListMap[baseEdbInfo.EdbInfoId] {
		dateList = append(dateList, v.DataTime)
	}

	// 数据整理
	// [日期][A指标id:值，B指标id:值]
	dateEdbMap, err := handleData(baseEdbInfo.EdbInfoId, edbDataListMap)
	if err != nil {
		return
	}

	lenX := len(xEdbInfoIdList)

	var isNotAFirst, isNotBFirst, isNotR2First bool
	for i, date := range dateList {
		coordinateData := make([]utils.Coordinate, 0)
		for k := 0; k < lenX; k++ {
			xVal, ok1 := dateEdbMap[date][xEdbInfoIdList[k]]
			yVal, ok2 := dateEdbMap[date][yEdbInfoIdList[k]]
			if !ok1 || !ok2 {
				continue
			}
			tmpCoordinate1 := utils.Coordinate{
				X: xVal,
				Y: yVal,
			}
			coordinateData = append(coordinateData, tmpCoordinate1)
		}
		dataTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
		timestamp := dataTime.UnixNano() / 1e6

		// 只有存在两个坐标点的时候,才能去计算线性方程和R平方
		if len(coordinateData) >= 2 {
			a, b := utils.GetLinearResult(coordinateData)
			if !math.IsNaN(a) && !math.IsNaN(b) && !math.IsInf(a, 0) && !math.IsInf(b, 0) {
				if getAData {
					a, _ = decimal.NewFromFloat(a).Round(4).Float64()
					dataResp.AData.DataList = append(dataResp.AData.DataList, data_manage.EdbDataList{
						EdbDataId:     i,
						EdbInfoId:     0,
						DataTime:      date,
						DataTimestamp: timestamp,
						Value:         a,
					})
					if !isNotAFirst {
						dataResp.AData.MinData = a
						dataResp.AData.MaxData = a
						isNotAFirst = true
					}
					if dataResp.AData.MinData > a {
						dataResp.AData.MinData = a
					}
					if dataResp.AData.MaxData < a {
						dataResp.AData.MaxData = a
					}
				}
				if getBData {
					b, _ = decimal.NewFromFloat(b).Round(4).Float64()
					dataResp.BData.DataList = append(dataResp.BData.DataList, data_manage.EdbDataList{
						EdbDataId:     i,
						EdbInfoId:     0,
						DataTime:      date,
						DataTimestamp: timestamp,
						Value:         b,
					})
					if !isNotBFirst {
						dataResp.BData.MinData = b
						dataResp.BData.MaxData = b
						isNotBFirst = true
					}
					if dataResp.BData.MinData > b {
						dataResp.BData.MinData = b
					}
					if dataResp.BData.MaxData < b {
						dataResp.BData.MaxData = b
					}
				}
			}

			// 计算R平方
			if getR2Data {
				tmpVal := utils.CalculationDecisive(coordinateData)
				if math.IsNaN(tmpVal) || math.IsInf(tmpVal, 0) {
					continue
				}

				tmpVal, _ = decimal.NewFromFloat(tmpVal).Round(4).Float64()
				dataResp.R2Data.DataList = append(dataResp.R2Data.DataList, data_manage.EdbDataList{
					EdbDataId:     i,
					EdbInfoId:     0,
					DataTime:      date,
					DataTimestamp: timestamp,
					Value:         tmpVal,
				})
				if !isNotR2First {
					dataResp.R2Data.MinData = tmpVal
					dataResp.R2Data.MaxData = tmpVal
					isNotR2First = true
				}
				if dataResp.R2Data.MinData > tmpVal {
					dataResp.R2Data.MinData = tmpVal
				}
				if dataResp.R2Data.MaxData < tmpVal {
					dataResp.R2Data.MaxData = tmpVal
				}
			}
		}
	}
	dataResp.AData.LatestDate = baseEdbInfo.LatestDate
	dataResp.AData.EdbInfoCategoryType = baseEdbInfo.EdbInfoCategoryType
	dataResp.BData.LatestDate = baseEdbInfo.LatestDate
	dataResp.BData.EdbInfoCategoryType = baseEdbInfo.EdbInfoCategoryType
	dataResp.R2Data.LatestDate = baseEdbInfo.LatestDate
	dataResp.R2Data.EdbInfoCategoryType = baseEdbInfo.EdbInfoCategoryType

	return
}

// GetConfigData 获取配置数据
func GetConfigData(lineChartInfoConfig request.LineChartInfoReq) (mappingList []*data_manage.ChartEdbInfoMapping, startDate, endDate string, err error, errMsg string) {
	return getConfigData(lineChartInfoConfig)
}

// getConfigData 获取配置数据
func getConfigData(lineChartInfoConfig request.LineChartInfoReq) (mappingList []*data_manage.ChartEdbInfoMapping, startDate, endDate string, err error, errMsg string) {
	dateType := lineChartInfoConfig.DateType
	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 = lineChartInfoConfig.StartDate + "-01"
		endDate = lineChartInfoConfig.EndDate + "-01"
	case 6:
		startDate = lineChartInfoConfig.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"
	}

	//指标数据
	edbInfoIdList := make([]int, 0)
	{
		edbInfoIdMap := make(map[int]int, 0)
		for _, edbInfoId := range lineChartInfoConfig.XEdbInfoIdList {
			edbInfoIdMap[edbInfoId] = edbInfoId
		}
		for _, edbInfoId := range lineChartInfoConfig.YEdbInfoIdList {
			edbInfoIdMap[edbInfoId] = edbInfoId
		}
		for _, edbInfoId := range edbInfoIdMap {
			edbInfoIdList = append(edbInfoIdList, edbInfoId)
		}
	}
	mappingList, err = data_manage.GetChartEdbMappingListByEdbInfoIdList(edbInfoIdList)
	if err != nil {
		errMsg = `获取失败`
		err = errors.New("获取图表，指标信息失败，Err:" + err.Error())
		return
	}

	return
}

// handleData 数据处理
func handleData(baseEdbInfoId int, edbDataListMap map[int][]*data_manage.EdbDataList) (dateEdbMap map[string]map[int]float64, err error) {
	dateEdbMap = make(map[string]map[int]float64) // [日期][A指标id:值，B指标id:值]
	for edbInfoId, edbDataList := range edbDataListMap {
		if edbInfoId != baseEdbInfoId {
			// 用上期的数据补充当期的数据处理
			handleDataMap := make(map[string]float64)
			err = data_manage.HandleDataByPreviousData(edbDataList, handleDataMap)
			if err != nil {
				return
			}

			for date, val := range handleDataMap {
				item, ok := dateEdbMap[date]
				if ok {
					item[edbInfoId] = val
				} else {
					item = map[int]float64{
						edbInfoId: val,
					}
				}
				dateEdbMap[date] = item
			}
		} else {
			for _, edbData := range edbDataList {
				item, ok := dateEdbMap[edbData.DataTime]
				if ok {
					item[edbInfoId] = edbData.Value
				} else {
					item = map[int]float64{
						edbInfoId: edbData.Value,
					}
				}
				dateEdbMap[edbData.DataTime] = item
			}
		}
	}

	return
}

// BatchAddChartInfo 批量添加图表
func BatchAddChartInfo(batchAddChartReq []request.AddChart, lineChartInfoConfig request.LineChartInfoReq, sysUser *system.Admin, lang string) (batchAddChartList []line_equation.BatchAddChart, err error, errMsg string, isSendEmail bool) {
	source := utils.CHART_SOURCE_LINE_EQUATION
	// 获取需要
	for k, v := range batchAddChartReq {
		v.ChartName = strings.Trim(v.ChartName, " ")
		batchAddChartReq[k] = v

		if v.ChartName == "" {
			errMsg = "请填写图表名称！"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}
		if v.ChartClassifyId <= 0 {
			errMsg = "请填写图表名称！"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}

		chartClassify, tmpErr := data_manage.GetChartClassifyById(v.ChartClassifyId)
		if tmpErr != nil {
			if tmpErr.Error() == utils.ErrNoRow() {
				errMsg = "分类不存在"
				err = errors.New(errMsg)
				isSendEmail = false
				return
			}
			errMsg = "获取分类信息失败"
			err = errors.New("获取分类信息失败，Err:" + tmpErr.Error())
			return
		}
		if chartClassify == nil {
			errMsg = "分类不存在"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}

		// 判断图表是否存在
		{
			var condition string
			var pars []interface{}
			switch lang {
			case utils.EnLangVersion:
				condition += " AND chart_name_en = ? AND source = ? "
			default:
				condition += " AND chart_name = ? AND source = ? "
			}
			pars = append(pars, v.ChartName, source)
			count, tmpErr := data_manage.GetChartInfoCountByCondition(condition, pars)
			if tmpErr != nil {
				errMsg = "判断图表名称是否存在失败"
				err = errors.New("判断图表名称是否存在失败,Err:" + tmpErr.Error())
				return
			}

			if count > 0 {
				errMsg = "图表已存在，请重新填写"
				err = errors.New(errMsg)
				isSendEmail = false
				return
			}

		}
	}

	edbList, _, _, err, errMsg := getConfigData(lineChartInfoConfig)

	var edbInfoIdArr []int
	for _, v := range edbList {
		edbInfoIdArr = append(edbInfoIdArr, v.EdbInfoId)
	}
	disableVal := data.CheckIsDisableChart(edbInfoIdArr)

	sort.Ints(edbInfoIdArr)
	var edbInfoIdArrStr []string
	for _, v := range edbInfoIdArr {
		edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
	}
	edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")

	// 批量配置
	lineChartInfoConfigByte, err := json.Marshal(lineChartInfoConfig)
	if err != nil {
		return
	}
	multipleGraphConfig := &data_manage.MultipleGraphConfig{
		Curve:           string(lineChartInfoConfigByte),
		SysUserId:       sysUser.AdminId,
		SysUserRealName: sysUser.RealName,
		ModifyTime:      time.Now(),
		CreateTime:      time.Now(),
	}

	// 多图
	batchAddChartList = make([]line_equation.BatchAddChart, 0)
	for _, v := range batchAddChartReq {
		tmpLineChartInfoConfig := lineChartInfoConfig
		tmpLineChartInfoConfig.Source = v.Source
		tmpLineChartInfoConfigByte, tmpErr := json.Marshal(tmpLineChartInfoConfig)
		if tmpErr != nil {
			err = tmpErr
			return
		}

		chartInfo := &data_manage.ChartInfo{
			ChartInfoId:     0,
			ChartName:       v.ChartName,
			ChartNameEn:     v.ChartName,
			ChartClassifyId: v.ChartClassifyId,
			SysUserId:       sysUser.AdminId,
			SysUserRealName: sysUser.RealName,
			UniqueCode:      utils.MD5(utils.CHART_PREFIX + "_" + fmt.Sprint(v.Source) + "_" + strconv.FormatInt(time.Now().UnixNano(), 10)),
			CreateTime:      time.Now(),
			ModifyTime:      time.Now(),
			DateType:        lineChartInfoConfig.DateType,
			StartDate:       lineChartInfoConfig.StartDate,
			EndDate:         lineChartInfoConfig.EndDate,
			IsSetName:       0,
			EdbInfoIds:      edbInfoIdStr,
			ChartType:       1,
			Calendar:        "公历",
			SeasonStartDate: "",
			SeasonEndDate:   "",
			ChartImage:      v.ChartImage,
			Sort:            0,
			LeftMin:         v.LeftMin,
			LeftMax:         v.LeftMax,
			RightMin:        "",
			RightMax:        "",
			Disabled:        disableVal,
			BarConfig:       "",
			Source:          source,
			ExtraConfig:     string(tmpLineChartInfoConfigByte),
		}

		// 指标信息
		mapList := make([]*data_manage.ChartEdbMapping, 0)
		for _, edbInfo := range edbList {
			mapItem := new(data_manage.ChartEdbMapping)
			mapItem.EdbInfoId = edbInfo.EdbInfoId
			mapItem.CreateTime = time.Now()
			mapItem.ModifyTime = time.Now()
			timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)

			mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + fmt.Sprint(v.Source) + "_" + timestamp + "_" + strconv.Itoa(edbInfo.EdbInfoId))
			mapItem.IsOrder = true
			mapItem.IsAxis = 1
			mapItem.EdbInfoType = 1
			mapItem.Source = source
			mapList = append(mapList, mapItem)
		}

		// 批量的关系图
		multipleGraphConfigChartMapping := &data_manage.MultipleGraphConfigChartMapping{
			//Id:                    0,
			//MultipleGraphConfigId: 0,
			//ChartInfoId:           0,
			Source:     v.Source,
			ModifyTime: time.Now(),
			CreateTime: time.Now(),
		}

		batchAddChartList = append(batchAddChartList, line_equation.BatchAddChart{
			ChartInfo:                       chartInfo,
			EdbMappingList:                  mapList,
			MultipleGraphConfigChartMapping: multipleGraphConfigChartMapping,
		})
	}

	// 批量创建
	err = line_equation.CreateLineEquationChartAndEdb(multipleGraphConfig, batchAddChartList)

	// 更改es
	for _, v := range batchAddChartList {
		//添加es数据
		go data.EsAddOrEditChartInfo(v.ChartInfo.ChartInfoId)
	}

	return
}

// BatchSaveChartInfo 批量添加编辑图表
func BatchSaveChartInfo(multipleGraphConfigId int, batchAddChartReq []request.AddChart, lineChartInfoConfig request.LineChartInfoReq, sysUser *system.Admin) (batchAddChartList []line_equation.BatchAddChart, err error, errMsg string, isSendEmail bool) {
	// 获取统一配置
	multipleGraphConfig, err := data_manage.GetMultipleGraphConfigById(multipleGraphConfigId)
	if err != nil {
		errMsg = `获取失败`
		err = errors.New(`获取配置失败，ERR：` + err.Error())
		return
	}
	// 获取已经关联的图表
	chartMappingList, err := data_manage.GetMultipleGraphConfigChartMappingListById(multipleGraphConfig.MultipleGraphConfigId)
	if err != nil {
		errMsg = `获取失败`
		err = errors.New(`获取关联图表配置失败，ERR：` + err.Error())
		return
	}

	// 已经存在关联的图表map
	existSourceChartMap := make(map[int]*data_manage.MultipleGraphConfigChartMapping)
	// 已经存在的图表map
	existChartInfoMap := make(map[int]*data_manage.ChartInfo)
	for _, v := range chartMappingList {
		existSourceChartMap[v.Source] = v

		chartInfo, tmpErr := data_manage.GetChartInfoById(v.ChartInfoId)
		if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
			err = tmpErr
			return
		}
		if chartInfo != nil {
			existChartInfoMap[v.Source] = chartInfo
		}
	}

	source := utils.CHART_SOURCE_LINE_EQUATION
	// 获取需要
	for k, v := range batchAddChartReq {
		v.ChartName = strings.Trim(v.ChartName, " ")
		batchAddChartReq[k] = v

		if v.ChartName == "" {
			errMsg = "请填写图表名称！"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}
		if v.ChartClassifyId <= 0 {
			errMsg = "请填写图表名称！"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}

		chartClassify, tmpErr := data_manage.GetChartClassifyById(v.ChartClassifyId)
		if tmpErr != nil {
			if tmpErr.Error() == utils.ErrNoRow() {
				errMsg = "分类不存在"
				err = errors.New(errMsg)
				isSendEmail = false
				return
			}
			errMsg = "获取分类信息失败"
			err = errors.New("获取分类信息失败，Err:" + tmpErr.Error())
			return
		}
		if chartClassify == nil {
			errMsg = "分类不存在"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}

		// 判断图表是否存在
		var condition string
		var pars []interface{}
		condition += " AND chart_name=? AND source = ? "
		pars = append(pars, v.ChartName, source)

		// 已经创建了图表的类型
		if sourceChart, ok := existChartInfoMap[v.Source]; ok {
			condition += " AND chart_info_id != ?  "
			pars = append(pars, sourceChart.ChartInfoId)
		}

		count, tmpErr := data_manage.GetChartInfoCountByCondition(condition, pars)
		if tmpErr != nil {
			errMsg = "判断图表名称是否存在失败"
			err = errors.New("判断图表名称是否存在失败,Err:" + tmpErr.Error())
			return
		}

		if count > 0 {
			errMsg = "图表已存在，请重新填写"
			err = errors.New(errMsg)
			isSendEmail = false
			return
		}
	}

	edbList, _, _, err, errMsg := getConfigData(lineChartInfoConfig)

	var edbInfoIdArr []int
	for _, v := range edbList {
		edbInfoIdArr = append(edbInfoIdArr, v.EdbInfoId)
	}
	disableVal := data.CheckIsDisableChart(edbInfoIdArr)

	sort.Ints(edbInfoIdArr)
	var edbInfoIdArrStr []string
	for _, v := range edbInfoIdArr {
		edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
	}
	edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")

	// 批量配置
	lineChartInfoConfigByte, err := json.Marshal(lineChartInfoConfig)
	if err != nil {
		return
	}
	multipleGraphConfig.Curve = string(lineChartInfoConfigByte)
	multipleGraphConfig.ModifyTime = time.Now()
	updateMultipleGraphConfigCols := []string{"Curve", "ModifyTime"}
	updateChartCols := []string{"ChartName", "DateType", "StartDate", "EndDate", "EdbInfoIds", "LeftMin", "LeftMax", "Disabled", "ExtraConfig"}

	// 多图
	batchAddChartList = make([]line_equation.BatchAddChart, 0)
	for _, v := range batchAddChartReq {
		tmpLineChartInfoConfig := lineChartInfoConfig
		tmpLineChartInfoConfig.Source = v.Source
		tmpLineChartInfoConfigByte, tmpErr := json.Marshal(tmpLineChartInfoConfig)
		if tmpErr != nil {
			err = tmpErr
			return
		}

		var multipleGraphConfigChartMapping *data_manage.MultipleGraphConfigChartMapping
		// 已经创建了图表的类型
		chartInfo, ok := existChartInfoMap[v.Source]
		if ok {
			chartInfo.ChartName = v.ChartName
			chartInfo.DateType = lineChartInfoConfig.DateType
			chartInfo.StartDate = lineChartInfoConfig.StartDate
			chartInfo.EndDate = lineChartInfoConfig.EndDate
			chartInfo.EdbInfoIds = edbInfoIdStr
			chartInfo.LeftMin = v.LeftMin
			chartInfo.LeftMax = v.LeftMax
			chartInfo.Disabled = disableVal
			chartInfo.ExtraConfig = string(tmpLineChartInfoConfigByte)
			//updateChartInfoList

			tmpMultipleGraphConfigChartMapping, ok2 := existSourceChartMap[v.Source]
			if !ok2 {
				err = errors.New("找不到对应的统一配置关系")
				return
			}
			multipleGraphConfigChartMapping = tmpMultipleGraphConfigChartMapping
		} else {
			chartInfo = &data_manage.ChartInfo{
				ChartInfoId: 0,
				ChartName:   v.ChartName,
				//ChartNameEn:     v.ChartName,
				ChartClassifyId: v.ChartClassifyId,
				SysUserId:       sysUser.AdminId,
				SysUserRealName: sysUser.RealName,
				UniqueCode:      utils.MD5(utils.CHART_PREFIX + "_" + fmt.Sprint(v.Source) + "_" + strconv.FormatInt(time.Now().UnixNano(), 10)),
				CreateTime:      time.Now(),
				ModifyTime:      time.Now(),
				DateType:        lineChartInfoConfig.DateType,
				StartDate:       lineChartInfoConfig.StartDate,
				EndDate:         lineChartInfoConfig.EndDate,
				IsSetName:       0,
				EdbInfoIds:      edbInfoIdStr,
				ChartType:       1,
				Calendar:        "公历",
				SeasonStartDate: "",
				SeasonEndDate:   "",
				ChartImage:      "",
				Sort:            0,
				LeftMin:         v.LeftMin,
				LeftMax:         v.LeftMax,
				RightMin:        "",
				RightMax:        "",
				Disabled:        disableVal,
				BarConfig:       "",
				Source:          source,
				ExtraConfig:     string(tmpLineChartInfoConfigByte),
			}

			// 批量配置的关系图
			if tmpMultipleGraphConfigChartMapping, ok2 := existSourceChartMap[v.Source]; ok2 {
				multipleGraphConfigChartMapping = tmpMultipleGraphConfigChartMapping
			} else {
				multipleGraphConfigChartMapping = &data_manage.MultipleGraphConfigChartMapping{
					//Id:                    0,
					//MultipleGraphConfigId: 0,
					//ChartInfoId:           0,
					Source:     v.Source,
					ModifyTime: time.Now(),
					CreateTime: time.Now(),
				}
			}

		}

		// 指标信息
		mapList := make([]*data_manage.ChartEdbMapping, 0)
		for _, edbInfo := range edbList {
			mapItem := new(data_manage.ChartEdbMapping)
			mapItem.EdbInfoId = edbInfo.EdbInfoId
			mapItem.CreateTime = time.Now()
			mapItem.ModifyTime = time.Now()
			timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)

			mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + fmt.Sprint(v.Source) + "_" + timestamp + "_" + strconv.Itoa(edbInfo.EdbInfoId))
			mapItem.IsOrder = true
			mapItem.IsAxis = 1
			mapItem.EdbInfoType = 1
			mapItem.Source = source
			mapList = append(mapList, mapItem)
		}

		batchAddChartList = append(batchAddChartList, line_equation.BatchAddChart{
			ChartInfo:                       chartInfo,
			EdbMappingList:                  mapList,
			MultipleGraphConfigChartMapping: multipleGraphConfigChartMapping,
		})
	}

	// 批量创建
	err = line_equation.CreateAndEditLineEquationChartAndEdb(multipleGraphConfig, batchAddChartList, updateMultipleGraphConfigCols, updateChartCols)

	// 更改es
	for _, v := range batchAddChartList {
		//添加es数据
		go data.EsAddOrEditChartInfo(v.ChartInfo.ChartInfoId)
	}
	return
}
