Browse Source

fix:恢复

Roc 1 year ago
parent
commit
da0d652c6c
1 changed files with 946 additions and 37 deletions
  1. 946 37
      services/data/future_good/future_edb_info.go

+ 946 - 37
services/data/future_good/future_edb_info.go

@@ -1,65 +1,974 @@
 package future_good
 
 import (
+	"errors"
 	"fmt"
+	"github.com/shopspring/decimal"
+	"hongze/hongze_chart_lib/models"
+	"hongze/hongze_chart_lib/models/data_manage"
 	"hongze/hongze_chart_lib/models/data_manage/future_good"
 	"hongze/hongze_chart_lib/services/alarm_msg"
+	"hongze/hongze_chart_lib/services/data"
 	"hongze/hongze_chart_lib/utils"
+	"sort"
+	"strconv"
 	"time"
 )
 
-// FutureGoodEdbInfoRefreshAllFromBase 批量刷新商品期货指标
+// GetChartEdbData 获取图表的指标数据
+func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping, futureGoodEdbInfoMapping *models.ChartEdbInfoMapping, barChartInfoDateList []data_manage.BarChartInfoDateReq) (barConfigEdbInfoIdList []data_manage.BarChartInfoEdbItemReq, edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, xDataList []models.XData, yDataList []models.YData, err error) {
+	edbList = make([]*models.ChartEdbInfoMapping, 0)
+
+	if futureGoodEdbInfoMapping == nil {
+		err = errors.New("商品指标未选取")
+		return
+	}
+	if edbInfoMapping == nil {
+		err = errors.New("ETA指标未选取")
+		return
+	}
+	// 指标对应的所有数据
+	edbDataListMap := make(map[int][]*models.EdbDataList)
+
+	item := new(data_manage.ChartEdbInfoMapping)
+	edbInfoMapping.FrequencyEn = data.GetFrequencyEn(edbInfoMapping.Frequency)
+
+	if edbInfoMapping.Unit == `无` {
+		edbInfoMapping.Unit = ``
+	}
+	if futureGoodEdbInfoMapping.Unit == `无` {
+		futureGoodEdbInfoMapping.Unit = ``
+	}
+
+	if chartInfoId <= 0 {
+		edbInfoMapping.IsAxis = 1
+		edbInfoMapping.LeadValue = 0
+		edbInfoMapping.LeadUnit = ""
+		edbInfoMapping.ChartEdbMappingId = 0
+		edbInfoMapping.ChartInfoId = 0
+		edbInfoMapping.IsOrder = false
+		edbInfoMapping.EdbInfoType = 1
+		edbInfoMapping.ChartStyle = ""
+		edbInfoMapping.ChartColor = ""
+		edbInfoMapping.ChartWidth = 0
+
+		futureGoodEdbInfoMapping.IsAxis = 1
+		futureGoodEdbInfoMapping.LeadValue = 0
+		futureGoodEdbInfoMapping.LeadUnit = ""
+		futureGoodEdbInfoMapping.ChartEdbMappingId = 0
+		futureGoodEdbInfoMapping.ChartInfoId = 0
+		futureGoodEdbInfoMapping.IsOrder = false
+		futureGoodEdbInfoMapping.EdbInfoType = 1
+		futureGoodEdbInfoMapping.ChartStyle = ""
+		futureGoodEdbInfoMapping.ChartColor = ""
+		futureGoodEdbInfoMapping.ChartWidth = 0
+	} else {
+		edbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(edbInfoMapping.LeadUnit)
+		futureGoodEdbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(futureGoodEdbInfoMapping.LeadUnit)
+	}
+
+	// 普通的指标数据
+	{
+		dataList := make([]*models.EdbDataList, 0)
+
+		dataList, err = models.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.EdbInfoId, startDate, endDate)
+		edbDataListMap[edbInfoMapping.EdbInfoId] = dataList
+		item.DataList = dataList
+
+		edbList = append(edbList, edbInfoMapping)
+
+		barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
+			EdbInfoId: edbInfoMapping.EdbInfoId,
+			//Name:      edbInfoMapping.EdbName,
+			Name:   "现货价",
+			NameEn: "Spot Price",
+			Source: edbInfoMapping.Source,
+		})
+	}
+
+	// 获取主力合约和最新日期
+	var zlFutureGoodEdbInfo *future_good.FutureGoodEdbInfo
+	var latestDate string // 最新日期是这个
+	var regionType string // 交易所来源:“国内”,“海外”
+	{
+		// 寻找主力合约
+		zlFutureGoodEdbInfo, err = future_good.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId)
+		if err != nil {
+			return
+		}
+		regionType = zlFutureGoodEdbInfo.RegionType
+
+		// 如果当前合约配置的 "画图时,日期来源的指标id" 并不是自己的话,那么就去查找对应配置的合约
+		if zlFutureGoodEdbInfo.DateSourceId != zlFutureGoodEdbInfo.FutureGoodEdbInfoId {
+			sourceDateFutureGoodEdbInfo, tmpErr := future_good.GetFutureGoodEdbInfo(zlFutureGoodEdbInfo.DateSourceId)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			latestDate = sourceDateFutureGoodEdbInfo.EndDate // 最新日期是这个
+		} else {
+			latestDate = zlFutureGoodEdbInfo.EndDate // 最新日期是这个
+		}
+		if latestDate == `0000-00-00` {
+			err = errors.New("日期异常")
+			return
+		}
+	}
+
+	// 获取期货指标以及期货数据
+	tmpFutureGoodEdbInfoList, err := future_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
+	if err != nil {
+		return
+	}
+
+	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
+	_, futureGoodEdbInfoList, err := getFutureGoodEdbInfoList(latestDateTime, tmpFutureGoodEdbInfoList, barChartInfoDateList)
+	if err != nil {
+		return
+	}
+
+	futureGoodMappingList := make([]*models.ChartEdbInfoMapping, 0)
+	for k, v := range futureGoodEdbInfoList {
+		newMappingInfo := &models.ChartEdbInfoMapping{
+			EdbInfoId:           v.FutureGoodEdbInfoId,
+			SourceName:          v.Exchange,
+			Source:              0,
+			EdbCode:             v.FutureGoodEdbCode,
+			EdbName:             v.FutureGoodEdbName,
+			EdbAliasName:        v.FutureGoodEdbName,
+			EdbNameEn:           v.FutureGoodEdbNameEn,
+			EdbType:             edbInfoMapping.EdbType,
+			Frequency:           edbInfoMapping.Frequency,
+			FrequencyEn:         edbInfoMapping.FrequencyEn,
+			Unit:                edbInfoMapping.Unit,
+			UnitEn:              edbInfoMapping.UnitEn,
+			StartDate:           v.StartDate,
+			EndDate:             v.EndDate,
+			ModifyTime:          v.ModifyTime.Format(utils.FormatDateTime),
+			ChartEdbMappingId:   v.FutureGoodEdbInfoId,
+			ChartInfoId:         edbInfoMapping.ChartInfoId,
+			MaxData:             v.MaxValue,
+			MinData:             v.MinValue,
+			IsOrder:             edbInfoMapping.IsOrder,
+			IsAxis:              edbInfoMapping.IsAxis,
+			EdbInfoType:         edbInfoMapping.EdbInfoType,
+			EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType,
+			LeadValue:           edbInfoMapping.LeadValue,
+			LeadUnit:            edbInfoMapping.LeadUnit,
+			LeadUnitEn:          edbInfoMapping.LeadUnitEn,
+			ChartStyle:          edbInfoMapping.ChartStyle,
+			ChartColor:          edbInfoMapping.ChartColor,
+			PredictChartColor:   edbInfoMapping.PredictChartColor,
+			ChartWidth:          edbInfoMapping.ChartWidth,
+			ChartType:           edbInfoMapping.ChartType,
+			LatestDate:          v.LatestDate.Format(utils.FormatDateTime),
+			LatestValue:         v.LatestValue,
+			UniqueCode:          futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(k),
+			MinValue:            v.MinValue,
+			MaxValue:            v.MaxValue,
+			DataList:            nil,
+			IsNullData:          false,
+		}
+		futureGoodMappingList = append(futureGoodMappingList, newMappingInfo)
+
+		barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
+			EdbInfoId: newMappingInfo.EdbInfoId,
+			Name:      fmt.Sprint("M+", v.Month),
+			NameEn:    fmt.Sprint("M+", v.Month),
+			Source:    newMappingInfo.Source,
+		})
+	}
+
+	// 获取数据
+	for _, v := range futureGoodMappingList {
+		dataList := make([]*models.EdbDataList, 0)
+
+		tmpDataList, tmpErr := future_good.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate)
+		if tmpErr != nil {
+			return
+		}
+		for _, tmpData := range tmpDataList {
+			dataList = append(dataList, &models.EdbDataList{
+				EdbDataId:     tmpData.FutureGoodEdbDataId,
+				EdbInfoId:     tmpData.FutureGoodEdbInfoId,
+				DataTime:      tmpData.DataTime.Format(utils.FormatDate),
+				DataTimestamp: tmpData.DataTimestamp,
+				Value:         tmpData.Close,
+			})
+		}
+		edbDataListMap[v.EdbInfoId] = dataList
+		v.DataList = dataList
+	}
+
+	edbList = append(edbList, futureGoodMappingList...)
+
+	xEdbIdValue, yDataList, err = BarChartData(edbList[0], futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, latestDate)
+
+	xDataList = []models.XData{
+		{
+			Name:   "现货价",
+			NameEn: "Spot Price",
+		},
+	}
+	//yDataList =make([]data_manage.YData,0)
+	//data_manage.YData{
+	//	Date:           "",
+	//	Color:          "",
+	//	Name:           "",
+	//	NameEn:         "",
+	//	Value:          nil,
+	//	NoDataEdbList:  nil,
+	//	XEdbInfoIdList: nil,
+	//}
+	futureGoodEdbInfoIndexMap := make(map[int]int)
+	for index, v := range futureGoodEdbInfoList {
+		futureGoodEdbInfoIndexMap[v.FutureGoodEdbInfoId] = index
+	}
+	nMap := make(map[int]int)
+	maxIndex := 0 // 最大x轴的下标
+	for k, tmpYData := range yDataList {
+		yDataMap := tmpYData.EdbValMap
+		edbInfoIdList := make([]int, 0)
+		noDataEdbInfoIdList := make([]int, 0)
+		valueList := make([]float64, 0)
+		noDataEdbIdMap := make(map[int]int)
+
+		// 所有的N值
+		for _, n := range tmpYData.M {
+			nMap[n] = n
+		}
+
+		// 基础指标
+		{
+			baseEdbInfId := edbList[0].EdbInfoId
+			edbInfoIdList = append(edbInfoIdList, baseEdbInfId)
+			tmpVal, ok := yDataMap[baseEdbInfId]
+			valueList = append(valueList, tmpVal)
+			if !ok || tmpVal == 0 {
+				noDataEdbInfoIdList = append(noDataEdbInfoIdList, baseEdbInfId)
+				noDataEdbIdMap[baseEdbInfId] = baseEdbInfId
+			}
+		}
+
+		for _, futureGoodEdbInfo := range futureGoodEdbInfoList {
+			tmpEdbInfId := futureGoodEdbInfo.FutureGoodEdbInfoId
+			edbInfoIdList = append(edbInfoIdList, tmpEdbInfId)
+			tmpVal, ok := yDataMap[tmpEdbInfId]
+			valueList = append(valueList, tmpVal)
+			if !ok || tmpVal == 0 {
+				noDataEdbInfoIdList = append(noDataEdbInfoIdList, tmpEdbInfId)
+				noDataEdbIdMap[tmpEdbInfId] = tmpEdbInfId
+			}
+		}
+		//tmpYData.Value = valueList
+		tmpYData.NoDataEdbList = noDataEdbInfoIdList
+		yDataList[k] = tmpYData
+
+		lenEdbId := len(edbInfoIdList)
+		tmpMaxIndex := lenEdbId - 1 // 当前数据的最大x轴的下标
+
+		for i := lenEdbId - 1; i >= 0; i-- {
+			// 如果没有在无数据的指标列表中找到,那么就找到了最大x轴的下标
+			if _, ok := noDataEdbIdMap[edbInfoIdList[i]]; !ok {
+				// 如果最大x轴的下标 小于 当前下标,那么就重新赋值
+				if maxIndex < i-1 {
+					maxIndex = i - 1
+				}
+				break
+			}
+
+			tmpMaxIndex = i - 1
+		}
+
+		// 如果最大x轴的下标 小于 当前下标,那么就重新赋值
+		if maxIndex < tmpMaxIndex {
+			maxIndex = tmpMaxIndex
+		}
+	}
+
+	//xEdbIdValue = xEdbIdValue[0:maxIndex]
+
+	// 找出所有的N值,并进行正序排列
+	nList := make([]int, 0)
+	for _, n := range nMap {
+		nList = append(nList, n)
+	}
+	sort.Slice(nList, func(i, j int) bool {
+		return nList[i] < nList[j]
+	})
+
+	for k, v := range yDataList {
+		if len(v.XEdbInfoIdList) >= maxIndex+1 {
+			yDataList[k].XEdbInfoIdList = v.XEdbInfoIdList[0 : maxIndex+1]
+		}
+		if len(v.Value) >= maxIndex+1 {
+			yDataList[k].Value = v.Value[0 : maxIndex+1]
+		}
+	}
+
+	tmpXDataList, newYDataList, err := handleResultData(regionType, yDataList, futureGoodEdbInfoList, maxIndex)
+	if err != nil {
+		return
+	}
+	xDataList = append(xDataList, tmpXDataList...)
+	yDataList = newYDataList
+
+	return
+}
+
+// BarChartData 柱方图的数据处理
+//func BarChartData(edbInfoMapping *models.ChartEdbInfoMapping, futureGoodMappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (edbIdList []int, yDataList []models.YData, err error) {
+//	// 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
+//	edbDataMap := make(map[int]map[string]float64)
+//	for edbInfoId, edbDataList := range edbDataListMap {
+//		edbDateData := make(map[string]float64)
+//		for _, edbData := range edbDataList {
+//			edbDateData[edbData.DataTime] = edbData.Value
+//		}
+//		edbDataMap[edbInfoId] = edbDateData
+//	}
+//
+//	// edbIdList 指标展示顺序;x轴的指标顺序
+//	edbIdList = make([]int, 0)
+//	edbIdList = append(edbIdList, edbInfoMapping.EdbInfoId)
+//	if barChartInfoSort.Sort == 0 {
+//		for _, v := range futureGoodMappingList {
+//			edbIdList = append(edbIdList, v.EdbInfoId)
+//		}
+//	}
+//
+//	//固定取螺纹期货主力合约的时间序列,最新值为该合约最新日期、N天前为该合约最新日期N天前
+//	rbzlInfo, err := future_good.GetFutureGoodEdbInfoByCode("RBZL.SHF")
+//	if err != nil {
+//		return
+//	}
+//	latestDate := rbzlInfo.EndDate // 最新日期是这个
+//	if rbzlInfo.EndDate == `0000-00-00` {
+//		err = errors.New("日期异常")
+//		return
+//	}
+//	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
+//
+//	yDataList = make([]models.YData, 0) //y轴的数据列表
+//
+//	for _, barChartInfoDate := range barChartInfoDateList {
+//		var maxDate time.Time
+//		var findDateTime time.Time
+//		switch barChartInfoDate.Type {
+//		case 1: //最新值
+//			findDateTime = latestDateTime
+//		case 2: //近期几天
+//			findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value)
+//		case 3: // 固定日期
+//			//寻找固定日期的数据
+//			tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
+//			if tmpErr != nil {
+//				err = tmpErr
+//				return
+//			}
+//			findDateTime = tmpFindDateTime
+//		default:
+//			err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
+//			return
+//		}
+//		if findDateTime.IsZero() {
+//			err = errors.New("错误的日期")
+//			return
+//		}
+//
+//		findDataList := make([]float64, 0)  // 当前日期的数据值
+//		noDataIdList := make([]int, 0)      // 没有数据的指标id
+//		noDataIdMap := make(map[int]int, 0) // 没有数据的指标map
+//		xEdbInfoIdList := make([]int, 0)    // 当前数据的指标id列表
+//
+//		// 现货指标
+//		realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[edbInfoMapping.EdbInfoId], edbDataMap[edbInfoMapping.EdbInfoId])
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//		findDataList = append(findDataList, findDataValue)
+//		if isFind {
+//			maxDate = realDateTime
+//		} else {
+//			noDataIdList = append(noDataIdList, edbInfoMapping.EdbInfoId)
+//			noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId
+//		}
+//		currMonth := findDateTime.Month() // 当前月份
+//		xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId)
+//
+//		// 当前月的后面月份合约的数据
+//		for i := currMonth; i < 12; i++ {
+//			futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标
+//			tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.EdbInfoId], edbDataMap[futureGoodMapping.EdbInfoId])
+//			if tmpErr != nil {
+//				err = tmpErr
+//				return
+//			}
+//			findDataList = append(findDataList, tmpFindDataValue)
+//			if tmpIsFind {
+//				if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
+//					maxDate = tmpRealDateTime
+//				}
+//			} else {
+//				noDataIdList = append(noDataIdList, futureGoodMapping.EdbInfoId)
+//				noDataIdMap[futureGoodMapping.EdbInfoId] = futureGoodMapping.EdbInfoId
+//			}
+//			// 当前期货合约的指标
+//			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.EdbInfoId)
+//		}
+//
+//		// 当前月的前面月份合约的数据
+//		for i := 1; i < int(currMonth); i++ {
+//			futureGoodMapping := futureGoodMappingList[i-1] // 当前的期货指标
+//			tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.EdbInfoId], edbDataMap[futureGoodMapping.EdbInfoId])
+//			if tmpErr != nil {
+//				err = tmpErr
+//				return
+//			}
+//			findDataList = append(findDataList, tmpFindDataValue)
+//			if tmpIsFind {
+//				if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
+//					maxDate = tmpRealDateTime
+//				}
+//			} else {
+//				noDataIdList = append(noDataIdList, futureGoodMapping.EdbInfoId)
+//				noDataIdMap[futureGoodMapping.EdbInfoId] = futureGoodMapping.EdbInfoId
+//			}
+//			// 当前期货合约的指标
+//			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.EdbInfoId)
+//		}
+//
+//		yName := barChartInfoDate.Name
+//		yNameEn := barChartInfoDate.Name
+//		if yName == `` {
+//			if barChartInfoDate.Type == 2 {
+//				yName = strconv.Itoa(barChartInfoDate.Value) + "天前"
+//				if barChartInfoDate.Value == 1 {
+//					yNameEn = strconv.Itoa(barChartInfoDate.Value) + "day ago"
+//				} else {
+//					yNameEn = strconv.Itoa(barChartInfoDate.Value) + " days ago"
+//				}
+//			} else {
+//				yName = maxDate.Format(utils.FormatDate)
+//				yNameEn = maxDate.Format(utils.FormatDate)
+//			}
+//		}
+//		yDate := "0000-00-00"
+//		if !maxDate.IsZero() {
+//			yDate = maxDate.Format(utils.FormatDate)
+//		}
+//
+//		// 数据处理,将没有数据的下标,赋值平均值
+//		{
+//			hasDataIndexList := make([]int, 0)
+//			for dataK, edbInfoId := range xEdbInfoIdList {
+//				if _, ok := noDataIdMap[edbInfoId]; !ok { // 如果是没有数据的指标id
+//					hasDataIndexList = append(hasDataIndexList, dataK)
+//				}
+//			}
+//			lenHasDataIndex := len(hasDataIndexList)
+//			if lenHasDataIndex > 0 {
+//				for lenHasDataI := 1; lenHasDataI < lenHasDataIndex; lenHasDataI++ {
+//					perK := hasDataIndexList[lenHasDataI-1] //上一个有数据的指标下标
+//					currK := hasDataIndexList[lenHasDataI]  //当前有数据的指标下标
+//					preVal := findDataList[perK]            //上一个有数据的坐标的值
+//					currVal := findDataList[currK]          //当前有数据的指标的值
+//
+//					// 环差值
+//					hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(currK - perK)))
+//					var tmpI int64
+//					// 将两个中间的数据做平均值补全
+//					for hcI := perK + 1; hcI < currK; hcI++ {
+//						tmpI++
+//						findDataList[hcI], _ = decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(tmpI))).RoundCeil(4).Float64()
+//					}
+//				}
+//			}
+//		}
+//
+//		yDataList = append(yDataList, models.YData{
+//			Date:           yDate,
+//			Value:          findDataList,
+//			NoDataEdbList:  noDataIdList,
+//			XEdbInfoIdList: xEdbInfoIdList,
+//			Color:          barChartInfoDate.Color,
+//			Name:           yName,
+//			NameEn:         yNameEn,
+//		})
+//	}
+//
+//	return
+//}
+
+// BarChartData 柱方图的数据处理
+func BarChartData(edbInfoMapping *models.ChartEdbInfoMapping, futureGoodMappingList []*future_good.FutureGoodEdbInfo, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, regionType, latestDate string) (edbIdList []int, yDataList []models.YData, err error) {
+	// 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
+	edbDataMap := make(map[int]map[string]float64)
+	for edbInfoId, edbDataList := range edbDataListMap {
+		edbDateData := make(map[string]float64)
+		for _, edbData := range edbDataList {
+			edbDateData[edbData.DataTime] = edbData.Value
+		}
+		edbDataMap[edbInfoId] = edbDateData
+	}
+
+	// edbIdList 指标展示顺序;x轴的指标顺序
+	edbIdList = make([]int, 0)
+	edbIdList = append(edbIdList, edbInfoMapping.EdbInfoId)
+	for _, v := range futureGoodMappingList {
+		edbIdList = append(edbIdList, v.FutureGoodEdbInfoId)
+	}
+
+	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
+
+	yDataList = make([]models.YData, 0) //y轴的数据列表
+
+	for _, barChartInfoDate := range barChartInfoDateList {
+		yDataMap := make(map[int]float64)
+		var maxDate time.Time
+
+		var findDateTime time.Time
+		switch barChartInfoDate.Type {
+		case 1: //最新值
+			findDateTime = latestDateTime
+		case 2: //近期几天
+			findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value)
+		case 3: // 固定日期
+			//寻找固定日期的数据
+			tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			findDateTime = tmpFindDateTime
+		default:
+			err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
+			return
+		}
+		if findDateTime.IsZero() {
+			err = errors.New("错误的日期")
+			return
+		}
+
+		findDataList := make([]float64, 0)  // 当前日期的数据值
+		noDataIdList := make([]int, 0)      // 没有数据的指标id
+		noDataIdMap := make(map[int]int, 0) // 没有数据的指标map
+		xEdbInfoIdList := make([]int, 0)    // 当前数据的指标id列表
+
+		// 现货指标
+		realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[edbInfoMapping.EdbInfoId], edbDataMap[edbInfoMapping.EdbInfoId])
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		findDataList = append(findDataList, findDataValue)
+		yDataMap[edbInfoMapping.EdbInfoId] = findDataValue
+		if isFind {
+			maxDate = realDateTime
+		} else {
+			noDataIdList = append(noDataIdList, edbInfoMapping.EdbInfoId)
+			noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId
+		}
+		currMonth := findDateTime.Month() // 当前月份
+		currYear := findDateTime.Year()   // 当前年份
+		xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId)
+		mList := make([]int, 0) // 间隔月份
+		indexList := make([]int, 0)
+		if regionType == `国内` {
+			for i := currMonth + 1; i <= 12; i++ {
+				indexList = append(indexList, int(i))
+				mList = append(mList, int(i-currMonth))
+			}
+			for i := 1; i < int(currMonth); i++ {
+				indexList = append(indexList, i)
+				mList = append(mList, 12+i-int(currMonth))
+			}
+		} else {
+			for i, v := range futureGoodMappingList {
+				if v.Year > currYear || (v.Year == currYear && v.Month > int(currMonth)) {
+					indexList = append(indexList, i)
+					mList = append(mList, (v.Year-currYear)*12+v.Month-int(currMonth))
+				}
+			}
+		}
+
+		for _, i := range indexList {
+			futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标
+			//tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.FutureGoodEdbInfoId], edbDataMap[futureGoodMapping.FutureGoodEdbInfoId])
+			//if tmpErr != nil {
+			//	err = tmpErr
+			//	return
+			//}
+			tmpRealDateTime := findDateTime
+			tmpFindDataValue, tmpIsFind := edbDataMap[futureGoodMapping.FutureGoodEdbInfoId][findDateTime.Format(utils.FormatDate)]
+			yDataMap[futureGoodMapping.FutureGoodEdbInfoId] = tmpFindDataValue
+
+			findDataList = append(findDataList, tmpFindDataValue)
+			if tmpIsFind {
+				if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
+					maxDate = tmpRealDateTime
+				}
+			} else {
+				noDataIdList = append(noDataIdList, futureGoodMapping.FutureGoodEdbInfoId)
+				noDataIdMap[futureGoodMapping.FutureGoodEdbInfoId] = futureGoodMapping.FutureGoodEdbInfoId
+			}
+			// 当前期货合约的指标
+			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.FutureGoodEdbInfoId)
+		}
+
+		yName := barChartInfoDate.Name
+		yNameEn := barChartInfoDate.Name
+		if yName == `` {
+			if barChartInfoDate.Type == 2 {
+				yName = strconv.Itoa(barChartInfoDate.Value) + "天前"
+				if barChartInfoDate.Value == 1 {
+					yNameEn = strconv.Itoa(barChartInfoDate.Value) + "day ago"
+				} else {
+					yNameEn = strconv.Itoa(barChartInfoDate.Value) + " days ago"
+				}
+			} else {
+				yName = maxDate.Format(utils.FormatDate)
+				yNameEn = maxDate.Format(utils.FormatDate)
+			}
+		}
+		yDate := "0000-00-00"
+		if !maxDate.IsZero() {
+			yDate = maxDate.Format(utils.FormatDate)
+		}
+
+		// 数据处理,将没有数据的下标,赋值平均值
+		{
+			hasDataIndexList := make([]int, 0)
+			for dataK, edbInfoId := range xEdbInfoIdList {
+				if _, ok := noDataIdMap[edbInfoId]; !ok { // 如果是没有数据的指标id
+					hasDataIndexList = append(hasDataIndexList, dataK)
+				}
+			}
+			lenHasDataIndex := len(hasDataIndexList)
+			if lenHasDataIndex > 0 {
+				for lenHasDataI := 1; lenHasDataI < lenHasDataIndex; lenHasDataI++ {
+					perK := hasDataIndexList[lenHasDataI-1] //上一个有数据的指标下标
+					currK := hasDataIndexList[lenHasDataI]  //当前有数据的指标下标
+					preVal := findDataList[perK]            //上一个有数据的坐标的值
+					currVal := findDataList[currK]          //当前有数据的指标的值
+
+					// 环差值
+					hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(currK - perK)))
+					var tmpI int64
+					// 将两个中间的数据做平均值补全
+					for hcI := perK + 1; hcI < currK; hcI++ {
+						tmpI++
+						findDataList[hcI], _ = decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(tmpI))).RoundCeil(4).Float64()
+					}
+				}
+			}
+		}
+
+		yDataList = append(yDataList, models.YData{
+			Date:           yDate,
+			ConfigDate:     findDateTime,
+			Value:          findDataList,
+			NoDataEdbList:  noDataIdList,
+			XEdbInfoIdList: xEdbInfoIdList,
+			Color:          barChartInfoDate.Color,
+			Name:           yName,
+			NameEn:         yNameEn,
+			EdbValMap:      yDataMap,
+			M:              mList,
+		})
+	}
+
+	return
+}
+
+// GetNeedDateData 获取合约内需要的日期数据
+func GetNeedDateData(needDateTime time.Time, dataList []*models.EdbDataList, edbDataMap map[string]float64) (findDateTime time.Time, findDataValue float64, isFind bool, err error) {
+	//dataList := edbDataListMap[edbInfoId] //指标的所有数据值
+	if len(dataList) <= 0 {
+		// 没有数据的指标id
+		return
+	}
+
+	//最早的日期
+	minDateTime, err := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
+	if err != nil {
+		return
+	}
+
+	for tmpDateTime := needDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
+		tmpDate := tmpDateTime.Format(utils.FormatDate)
+		if tmpValue, ok := edbDataMap[tmpDate]; ok { //如果能找到数据,那么就返回
+			// 数据为0,也直接返回,做无值处理
+			if tmpValue == 0 {
+				return
+			}
+			findDateTime, _ = time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
+			findDataValue = tmpValue
+			isFind = true
+			return
+		}
+	}
+
+	return
+}
+
+// FutureGoodChartInfoRefresh
 // @author Roc
-// @datetime 2022-09-16 11:04:44
-// @description 将原有的单个指标刷新,调整为批量多个指标刷新
-func FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList []*future_good.FutureGoodEdbInfo, refreshAll bool) (err error) {
+// @datetime 2023-2-2 18:44:46
+// @description 商品价格曲线图表刷新
+func FutureGoodChartInfoRefresh(chartInfoId int) (err error) {
 	var errMsg string
 	defer func() {
 		if err != nil {
-			fmt.Println("FutureGoodEdbInfoRefreshAllFromBase Err:" + err.Error() + ";errMsg:" + errMsg)
-			go alarm_msg.SendAlarmMsg("FutureGoodEdbInfoRefreshAllFromBase,Err"+err.Error()+";errMsg:"+errMsg, 3)
+			go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errMsg, 3)
+			fmt.Println("ChartInfoRefresh Err:" + errMsg)
 		}
 	}()
-	var startDate string
-	for _, bv := range futureGoodEdbInfoList {
-		if bv.StartDate == "0000-00-00" {
-			continue
+
+	edbInfoMapping, err := models.GetEtaEdbChartEdbMapping(chartInfoId)
+	if err != nil {
+		errMsg = "获取需要刷新的ETA指标失败:Err:" + err.Error()
+		return
+	}
+	// 获取期货指标
+	futureGoodEdbInfoMapping, err := models.GetFutureGoodEdbChartEdbMapping(chartInfoId)
+	if err != nil {
+		errMsg = "获取需要刷新的商品期货指标失败:Err:" + err.Error()
+		return
+	}
+
+	// 获取期货指标以及期货数据
+	futureGoodEdbInfoList, err := future_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
+	if err != nil {
+		return
+	}
+
+	// 批量刷新ETA指标
+	err, _ = data.EdbInfoRefreshAllFromBase([]int{edbInfoMapping.EdbInfoId}, false)
+	if err != nil {
+		return
+	}
+
+	// 批量刷新期货指标
+	err = FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList, false)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// handleResultData 处理成最终的结果数据
+func handleResultData(regionType string, yDataList []models.YData, futureGoodEdbInfoList []*future_good.FutureGoodEdbInfo, maxIndex int) (xDataList []models.XData, newYDataList []models.YData, err error) {
+	xDataList = make([]models.XData, 0)
+	newYDataList = yDataList
+
+	if regionType == `国内` {
+		for i := 1; i < 12; i++ {
+			if i > maxIndex {
+				break
+			}
+			xDataList = append(xDataList, models.XData{
+				Name:   fmt.Sprint("M+", i),
+				NameEn: fmt.Sprint("M+", i),
+			})
+		}
+		return
+	}
+
+	futureGoodEdbInfoMap := make(map[int]*future_good.FutureGoodEdbInfo)
+	for _, v := range futureGoodEdbInfoList {
+		futureGoodEdbInfoMap[v.FutureGoodEdbInfoId] = v
+	}
+
+	nMap := make(map[int]int)
+
+	for _, v := range yDataList {
+		findDateTime := v.ConfigDate
+		currMonth := findDateTime.Month() // 当前月份
+		currYear := findDateTime.Year()   // 当前年份
+		//v.XEdbInfoIdList
+		for edbInfoIndex, edbInfoId := range v.XEdbInfoIdList {
+			// 第一个不处理
+			if edbInfoIndex == 0 {
+				continue
+			}
+
+			futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId]
+			if !ok {
+				err = errors.New("找不到指标")
+				return
+			}
+			n := (futureGoodEdbInfo.Year-currYear)*12 + futureGoodEdbInfo.Month - int(currMonth)
+			nMap[n] = n
 		}
-		//开始时间
-		startDate = ``
-		if refreshAll { //刷新所有数据,用开始时间作为起始日期去刷新
-			sTime, err := time.Parse(utils.FormatDate, bv.StartDate)
-			if err != nil {
-				return err
+
+	}
+
+	// 找出所有的N值,并进行正序排列
+	nList := make([]int, 0)
+	for _, n := range nMap {
+		nList = append(nList, n)
+	}
+	sort.Slice(nList, func(i, j int) bool {
+		return nList[i] < nList[j]
+	})
+
+	//prevMonth := 1
+
+	for _, n := range nList {
+		xDataList = append(xDataList, models.XData{
+			Name:   fmt.Sprint("M+", n),
+			NameEn: fmt.Sprint("M+", n),
+		})
+	}
+
+	for yIndex, yData := range yDataList {
+		newYDataList[yIndex].XEdbInfoIdList = []int{}
+		newYDataList[yIndex].Value = []float64{}
+		tmpNList := nList
+
+		//当前的主力合约
+		newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0])
+		newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0])
+
+		xEdbInfoIdList := yData.XEdbInfoIdList[1:]
+		currDataTime := yData.ConfigDate
+		valIndex := 1
+		needNum := 0
+		for _, n := range tmpNList {
+			if len(xEdbInfoIdList) > 0 {
+				edbInfoId := xEdbInfoIdList[0]
+				futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId]
+				if !ok {
+					err = errors.New("找不到指标")
+					return
+				}
+				// 当前距离最早的日期相差的N数
+				divMonth := (futureGoodEdbInfo.Year-currDataTime.Year())*12 + (futureGoodEdbInfo.Month - int(currDataTime.Month()))
+				if divMonth == n {
+					if needNum > 0 {
+						currVal := yData.Value[valIndex]
+						preVal := yData.Value[valIndex-1]
+						hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(needNum + 1)))
+
+						for tmpNum := 0; tmpNum < needNum; tmpNum++ {
+							newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, 0)
+
+							// 赋值平均值
+							tmpVal, _ := decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(int64(tmpNum + 1)))).RoundCeil(4).Float64()
+							newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, tmpVal)
+						}
+					}
+
+					newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, edbInfoId)
+					newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[valIndex])
+					valIndex++
+					needNum = 0
+					if len(xEdbInfoIdList) > 0 {
+						xEdbInfoIdList = xEdbInfoIdList[1:]
+					}
+				} else {
+					needNum++
+				}
 			}
-			startDate = sTime.Format(utils.FormatDate)
-		} else {
-			sTime, err := time.Parse(utils.FormatDate, bv.EndDate)
-			if err != nil {
-				return err
+		}
+	}
+
+	maxI := 0
+	for _, yData := range newYDataList {
+		lenEdb := len(yData.XEdbInfoIdList)
+		for i := 0; i < lenEdb; i++ {
+			if yData.XEdbInfoIdList[i] != 0 && !utils.InArrayByInt(yData.NoDataEdbList, yData.XEdbInfoIdList[i]) {
+				if maxI < i {
+					maxI = i
+				}
 			}
-			limitDay := utils.DATA_REFRESH
-			startDate = sTime.AddDate(0, 0, -limitDay).Format(utils.FormatDate)
 		}
-		result, err := RefreshEdbData(bv.FutureGoodEdbInfoId, bv.FutureGoodEdbCode, startDate)
-		if err != nil {
-			fmt.Println(bv.FutureGoodEdbInfoId, "FutureGoodRefreshBaseEdbData err", time.Now())
-			errMsg = "FutureGoodRefreshBaseEdbData Err:" + err.Error()
-			return err
+	}
+
+	xDataList = xDataList[0:maxI]
+	for yIndex, yData := range newYDataList {
+		if len(yData.XEdbInfoIdList) > maxI+1 {
+			newYDataList[yIndex].XEdbInfoIdList = yData.XEdbInfoIdList[0 : maxI+1]
+		}
+		if len(yData.Value) > maxI+1 {
+			newYDataList[yIndex].Value = yData.Value[0 : maxI+1]
+		}
+	}
+
+	return
+}
+
+// getFutureGoodEdbInfoList 获取适用的指标列表
+func getFutureGoodEdbInfoList(latestDateTime time.Time, tmpFutureGoodEdbInfoList []*future_good.FutureGoodEdbInfo, barChartInfoDateList []data_manage.BarChartInfoDateReq) (earliestDateTime time.Time, futureGoodEdbInfoList []*future_good.FutureGoodEdbInfo, err error) {
+	maxM := 32 //最大32期合约
+	futureGoodEdbInfoList = make([]*future_good.FutureGoodEdbInfo, 0)
+	earliestDateTime = latestDateTime // 数据的最早日期,目的是为了找出最早的合约
+	for _, barChartInfoDate := range barChartInfoDateList {
+		var findDateTime time.Time
+		switch barChartInfoDate.Type {
+		case 1: //最新值
+			findDateTime = latestDateTime
+		case 2: //近期几天
+			findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value)
+		case 3: // 固定日期
+			//寻找固定日期的数据
+			tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			findDateTime = tmpFindDateTime
+		default:
+			err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
+			return
+		}
+		if findDateTime.IsZero() {
+			err = errors.New("错误的日期")
+			return
 		}
-		if result.Ret != 200 {
-			fmt.Println(bv.FutureGoodEdbInfoId, "FutureGoodRefreshBaseEdbData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
-			errMsg = fmt.Sprint(bv.FutureGoodEdbInfoId, "FutureGoodRefreshBaseEdbData err;msg:", result.Msg, ";errMsg:", result.ErrMsg)
-			return fmt.Errorf("刷新失败, err:%s", errMsg)
+		if findDateTime.Before(earliestDateTime) {
+			earliestDateTime = findDateTime
 		}
 	}
 
-	// 刷新商品期货指标相关的数据
-	for _, bv := range futureGoodEdbInfoList {
-		if bv.ParentId == 0 {
-			RefreshEdbRelation(bv.FutureGoodEdbInfoId)
+	for _, v := range tmpFutureGoodEdbInfoList {
+		if v.RegionType == `国内` {
+			futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
+			continue
 		}
+		//海外的连续日期,目前
+		if v.FutureGoodEdbType == 2 {
+			if v.Month <= maxM {
+				addMonth := int(earliestDateTime.Month()) + v.Month
+				v.Year = earliestDateTime.Year() + addMonth/12
+				realMonth := addMonth % 12
+				if realMonth == 0 {
+					realMonth = 12
+				}
+				v.Month = realMonth
+				futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
+			}
+			continue
+		}
+
+		if v.Year < earliestDateTime.Year() {
+			continue
+		}
+		// 小于等于当前年,那么就肯定是ok的
+		if v.Year <= earliestDateTime.Year() {
+			futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
+			continue
+		}
+		// 如果(当前年-最新日期的年份) * 12个月 + (当前月-最新日期的月份) 小于总月份
+		if (v.Year-earliestDateTime.Year())*12+(v.Month-int(earliestDateTime.Month())) <= maxM {
+			futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
+			continue
+		}
+
 	}
 
-	return err
+	return
 }