Ver Fonte

Merge branch 'chart/14.2'

Roc há 1 ano atrás
pai
commit
ecef3b04a4

+ 140 - 2
controller/chart/chart_common.go

@@ -13,6 +13,7 @@ import (
 	chartEdbMappingModel "hongze/hongze_yb/models/tables/chart_edb_mapping"
 	chartInfoModel "hongze/hongze_yb/models/tables/chart_info"
 	"hongze/hongze_yb/models/tables/chart_info_correlation"
+	"hongze/hongze_yb/models/tables/chart_info_future_good_profit"
 	"hongze/hongze_yb/models/tables/chart_info_log"
 	"hongze/hongze_yb/models/tables/yb_my_chart"
 	"hongze/hongze_yb/services/alarm_msg"
@@ -79,6 +80,14 @@ func CommonChartInfoDetailFromUniqueCode(c *gin.Context) {
 		}
 		response.OkData("获取成功", resp, c)
 		return
+	case utils.CHART_SOURCE_FUTURE_GOOD_PROFIT:
+		resp, isOk, msg, errMsg := getFutureGoodProfitChartInfoDetail(chartInfo, myChartClassifyId, user.GetInfoByClaims(c))
+		if !isOk {
+			response.FailMsg(msg, errMsg, c)
+			return
+		}
+		response.OkData("获取成功", resp, c)
+		return
 	case utils.CHART_SOURCE_CORRELATION, utils.CHART_SOURCE_ROLLING_CORRELATION:
 		resp, isOk, msg, errMsg := getCorrelationChartInfoDetail(chartInfo, myChartClassifyId, user.GetInfoByClaims(c))
 		if !isOk {
@@ -225,6 +234,134 @@ func getFutureGoodChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myCha
 	return
 }
 
+// getFutureGoodProfitChartInfoDetail 获取商品利润曲线图表详情
+func getFutureGoodProfitChartInfoDetail(chartInfo *chartInfoModel.ChartInfoView, myChartClassifyId int, userInfo user.UserInfo) (resp *chart_info.ChartInfoDetailResp, isOk bool, msg, errMsg string) {
+	resp = new(chart_info.ChartInfoDetailResp)
+	// 获取图表信息
+	var err error
+	chartInfoId := chartInfo.ChartInfoId
+
+	// 商品利润曲线图的一些配置
+	var extraConf request.ChartInfoReq
+	err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &extraConf)
+	if err != nil {
+		msg = "商品利润曲线图配置异常"
+		errMsg = "商品利润曲线图配置异常,Err:" + err.Error()
+		return
+	}
+
+	edbList := make([]*chartEdbMappingModel.ChartEdbInfoMappingList, 0)
+	edbInfoMapping, err := chartEdbMappingModel.GetEtaEdbChartEdbMapping(chartInfoId)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取图表,现货指标信息失败,Err:" + err.Error()
+		return
+	}
+	edbList = append(edbList, edbInfoMapping)
+	futureGoodEdbInfoMappingList, err := chartEdbMappingModel.GetFutureGoodEdbChartEdbMappingList(chartInfoId)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取图表的期货商品指标信息失败,Err:" + err.Error()
+		return
+	}
+	edbList = append(edbList, futureGoodEdbInfoMappingList...)
+	if len(edbList) <= 0 {
+		msg = "商品利润曲线图表指标异常"
+		errMsg = "商品利润曲线图表指标异常"
+		return
+	}
+
+	xDataList := make([]chart_info.XData, 0)
+	yDataList := make([]chart_info.YData, 0)
+
+	// 查找商品利润图表的扩展信息
+	chartInfoFutureGoodProfit := new(chart_info_future_good_profit.ChartInfoFutureGoodProfit)
+	if err = chartInfoFutureGoodProfit.GetItemById(chartInfoId); err != nil {
+		errMsg = "获取相关性图表失败, Err: " + err.Error()
+		return
+	}
+
+	err = json.Unmarshal([]byte(chartInfoFutureGoodProfit.XValue), &xDataList)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "转换X轴数据失败, Err: " + err.Error()
+		return
+	}
+
+	err = json.Unmarshal([]byte(chartInfoFutureGoodProfit.YValue), &yDataList)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "转换Y轴数据失败, Err: " + err.Error()
+		return
+	}
+
+	baseEdbInfo := edbList[0] //现货指标
+	chartInfo.UnitEn = baseEdbInfo.UnitEn
+
+	sourceArr := []string{"同花顺"}
+	if baseEdbInfo.SourceName != "同花顺" {
+		sourceArr = append(sourceArr, baseEdbInfo.SourceName)
+	}
+	sourceArr = append(sourceArr, "弘则研究")
+	chartInfo.ChartSource = strings.Join(sourceArr, ",")
+
+	warnEdbList := make([]string, 0)
+	for _, v := range edbList {
+		if v.IsNullData {
+			warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
+		}
+	}
+
+	// 访问记录-仅普通用户记录
+	ok, _, _ := user.GetAdminByUserInfo(userInfo)
+	if !ok {
+		go chart.SaveChartVisitLog(userInfo, chartInfo, myChartClassifyId)
+	}
+
+	// 用户是否有收藏该图表
+	{
+		ob := new(yb_my_chart.YbMyChart)
+		cond := `user_id = ? AND chart_info_id = ?`
+		pars := make([]interface{}, 0)
+		pars = append(pars, userInfo.UserID, chartInfo.ChartInfoId)
+		exists, e := ob.FetchByCondition(cond, pars)
+		if e != nil && e != utils.ErrNoRow {
+			msg = `操作失败`
+			errMsg = "获取用户图表失败, Err: " + e.Error()
+			return
+		}
+		myChartInfo := new(responseModel.MyChartItem)
+		if exists != nil && exists.MyChartID > 0 {
+			myChartInfo.MyChartID = exists.MyChartID
+			myChartInfo.MyChartClassifyID = exists.MyChartClassifyID
+			myChartInfo.ChartInfoID = exists.ChartInfoID
+			myChartInfo.ChartName = exists.ChartName
+			myChartInfo.UniqueCode = exists.UniqueCode
+			myChartInfo.ChartImage = exists.ChartImage
+			myChartInfo.UserID = exists.UserID
+			myChartInfo.ReportID = exists.ReportID
+			myChartInfo.ReportChapterID = exists.ReportChapterID
+			myChartInfo.CreateTime = utils.TimeTransferString(utils.FormatDateTime, exists.CreateTime)
+		}
+
+		resp.MyChartInfo = myChartInfo
+	}
+
+	resp.ChartInfo = chartInfo
+	resp.EdbInfoList = edbList
+	resp.DataResp = chart_info.ProfitFutureGoodChartResp{
+		YDataList:    yDataList,
+		XDataList:    xDataList,
+		ProfitName:   chartInfoFutureGoodProfit.ProfitName,
+		ProfitNameEn: chartInfoFutureGoodProfit.ProfitNameEn,
+		Extra:        extraConf,
+	}
+
+	isOk = true
+
+	return
+}
+
 // RefreshFutureGoodChartInfo 刷新商品价格曲线图表信息
 // @Tags 图库模块
 // @Summary  刷新图表信息
@@ -350,8 +487,9 @@ func FutureGoodChartInfoSave(c *gin.Context) {
 		response.FailMsg("操作失败", "获取图表信息失败, Err:"+err.Error(), c)
 		return
 	}
-	if chartItem.Source != 2 {
-		response.Fail("该图不是商品价格曲线图", c)
+
+	if !utils.InArrayByInt([]int{utils.CHART_SOURCE_FUTURE_GOOD, utils.CHART_SOURCE_FUTURE_GOOD_PROFIT}, chartItem.Source) {
+		response.Fail("该图不是商品价格/利润曲线图!", c)
 		return
 	}
 	chartItem.LeftMin = req.LeftMin

+ 25 - 0
models/request/chart.go

@@ -127,3 +127,28 @@ type CoordinatePoint struct {
 	X float64
 	Y float64
 }
+
+// ChartInfoReq 图表预览请求数据
+type ChartInfoReq struct {
+	FutureGoodEdbInfoIdList []EdbInfoFromTag   `description:"指标信息"`
+	CalculateFormula        string             `description:"计算公式"`
+	BaseEdbInfoId           int                `description:"基础的指标id"`
+	DateList                []ChartInfoDateReq `description:"日期配置"`
+	ProfitNameEn            string             `description:"利润英文名称"`
+}
+
+// EdbInfoFromTag 计算指标的关联指标
+type EdbInfoFromTag struct {
+	EdbInfoId int    `description:"指标id"`
+	FromTag   string `description:"指标对应标签"`
+	MoveValue int    `description:"移动的值"`
+}
+
+// ChartInfoDateReq 图表的日期数据(日期相关)
+type ChartInfoDateReq struct {
+	Type  int    `description:"配置类型"`
+	Date  string `description:"固定日期"`
+	Value int    `description:"N天的值"`
+	Color string `description:"颜色"`
+	Name  string `description:"别名"`
+}

+ 12 - 0
models/response/chart_info/chart_info.go

@@ -1,6 +1,7 @@
 package chart_info
 
 import (
+	"hongze/hongze_yb/models/request"
 	responseModel "hongze/hongze_yb/models/response"
 	"hongze/hongze_yb/models/tables/chart_edb_mapping"
 	"hongze/hongze_yb/models/tables/chart_info"
@@ -36,6 +37,8 @@ type YData struct {
 	XEdbInfoIdList []int           `description:"对应X轴的指标id列表"`
 	EdbValMap      map[int]float64 `description:"指标与值的对应" json:"-"`
 	M              []int           `description:"对应开始日期的间隔值" json:"-"`
+	NameList       []string        `description:"每个值对应的名称"`
+	EnNameList     []string        `description:"每个值对应的英文名称"`
 }
 
 type CorrelationInfo struct {
@@ -54,3 +57,12 @@ type RollingCorrelationChartDataResp struct {
 	XDateTimeValue []string `description:"滚动相关性图的x轴数据,日期数据"`
 	YDataList      []YData  `description:"滚动相关性图的y轴数据"`
 }
+
+// ProfitFutureGoodChartResp 商品利润图
+type ProfitFutureGoodChartResp struct {
+	XDataList    []XData
+	YDataList    []YData
+	ProfitName   string               `description:"利润的名称"`
+	ProfitNameEn string               `description:"利润的英文名称"`
+	Extra        request.ChartInfoReq `description:"柱方图的配置"`
+}

+ 12 - 0
models/tables/chart_edb_mapping/query.go

@@ -99,6 +99,18 @@ func GetFutureGoodEdbChartEdbMapping(chartInfoId int) (item *ChartEdbInfoMapping
 	return
 }
 
+// GetFutureGoodEdbChartEdbMappingList       商品曲线图查询对应的商品指标列表
+func GetFutureGoodEdbChartEdbMappingList(chartInfoId int) (items []*ChartEdbInfoMappingList, err error) {
+	aField := `a.chart_edb_mapping_id,a.chart_info_id,a.edb_info_id,a.create_time,a.modify_time,a.unique_code,a.max_data,a.min_data,a.is_order,a.is_axis,a.edb_info_type,a.lead_value,a.lead_unit,a.chart_style,a.chart_color,a.predict_chart_color,a.chart_width,a.source as mapping_source`
+	sql := ` SELECT ` + aField + `,b.future_good_edb_info_id,b.future_good_edb_code as edb_code,b.future_good_edb_name as edb_name,b.start_date,b.end_date,b.modify_time,b.latest_date,b.latest_value
+             FROM chart_edb_mapping AS a
+			 INNER JOIN future_good_edb_info AS b ON a.edb_info_id=b.future_good_edb_info_id
+			 WHERE a.chart_info_id=? AND a.source = ?
+             ORDER BY chart_edb_mapping_id ASC `
+	err = global.MYSQL["data"].Raw(sql, chartInfoId, utils.CHART_SOURCE_FUTURE_GOOD).Find(&items).Error
+	return
+}
+
 // GetChartEdbMappingByEdbInfoId 根据指标id获取edb_mapping
 func GetChartEdbMappingByEdbInfoId(edbInfoId int) (item *ChartEdbInfoMapping, err error) {
 	sql := ` SELECT edb_info_id,source_name,source,edb_code,edb_name,edb_name_en,frequency,unit,unit_en,start_date,end_date,modify_time,latest_date,latest_value,unique_code,edb_info_type AS edb_info_category_type,max_value,min_value

+ 38 - 0
models/tables/chart_info_future_good_profit/entity.go

@@ -0,0 +1,38 @@
+package chart_info_future_good_profit
+
+import "time"
+
+// ChartInfoFutureGoodProfit 商品利润详情
+type ChartInfoFutureGoodProfit struct {
+	ChartInfoId  int       `gorm:"primaryKey;column:chart_info_id;type:int(10) unsigned;not null" json:"-"`        // 图表ID(chart_info表source=5的)
+	ProfitName   string    `gorm:"column:profit_name;type:varchar(16);not null;default:''" json:"profitName"`      // 领先单位
+	ProfitNameEn string    `gorm:"column:profit_name_en;type:varchar(16);not null;default:''" json:"ProfitNameEn"` // 领先单位
+	XValue       string    `gorm:"column:x_value;type:text" json:"x_value"`                                        // x轴的数据值
+	YValue       string    `gorm:"column:y_value;type:text" json:"y_value"`                                        // y轴的数据值
+	CreateTime   time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`                             // 创建时间
+	ModifyTime   time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`                             // 更新时间
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *ChartInfoFutureGoodProfit) TableName() string {
+	return "chart_info_future_good_profit"
+}
+
+// ChartInfoFutureGoodProfitColumns get sql column name.获取数据库列名
+var ChartInfoFutureGoodProfitColumns = struct {
+	ChartInfoId  string
+	ProfitName   string
+	ProfitNameEn string
+	XValue       string
+	YValue       string
+	CreateTime   string
+	ModifyTime   string
+}{
+	ChartInfoId:  "chart_info_id",
+	ProfitName:   "profit_name",
+	ProfitNameEn: "profit_name_en",
+	XValue:       "x_value",
+	YValue:       "y_value",
+	CreateTime:   "create_time",
+	ModifyTime:   "modify_time",
+}

+ 16 - 0
models/tables/chart_info_future_good_profit/model.go

@@ -0,0 +1,16 @@
+package chart_info_future_good_profit
+
+import "hongze/hongze_yb/global"
+
+// GetItemById 主键获取
+func (m *ChartInfoFutureGoodProfit) GetItemById(primaryId int) (err error) {
+	err = global.MYSQL["data"].Model(m).
+		Where("chart_info_id = ?", primaryId).
+		First(&m).Error
+	return
+}
+
+func (m *ChartInfoFutureGoodProfit) Update(updateCols []string) (err error) {
+	err = global.MYSQL["data"].Model(m).Select(updateCols).Updates(*m).Error
+	return
+}

+ 9 - 0
services/chart/future_good/base_future_good_lib.go

@@ -32,6 +32,15 @@ func RefreshEdbData(futureGoodEdbInfoId int, futureGoodEdbCode, startDate string
 	return
 }
 
+// RefreshEdbRelation 刷新商品期货指标相关的数据
+func RefreshEdbRelation(futureGoodEdbInfoId int) (resp *RefreshResponse, err error) {
+	param := make(map[string]interface{})
+	param["FutureGoodEdbInfoId"] = futureGoodEdbInfoId
+	urlStr := `future_good/relation/refresh`
+	resp, err = postRefreshEdbData(param, urlStr)
+	return
+}
+
 // postRefreshEdbData 刷新指标数据
 func postRefreshEdbData(param map[string]interface{}, urlStr string) (resp *RefreshResponse, err error) {
 	edbLibUrl := ""

+ 104 - 11
services/chart/future_good/chart_info.go

@@ -100,6 +100,7 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 	var zlFutureGoodEdbInfo *future_good_edb_info.FutureGoodEdbInfo
 	var latestDate string // 最新日期是这个
 	var regionType string // 交易所来源:“国内”,“海外”
+	var futureGoodEdbType int
 	{
 		// 寻找主力合约
 		zlFutureGoodEdbInfo, err = future_good_edb_info.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId)
@@ -107,6 +108,7 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 			return
 		}
 		regionType = zlFutureGoodEdbInfo.RegionType
+		futureGoodEdbType = int(zlFutureGoodEdbInfo.FutureGoodEdbType)
 
 		// 如果当前合约配置的 "画图时,日期来源的指标id" 并不是自己的话,那么就去查找对应配置的合约
 		if uint64(zlFutureGoodEdbInfo.DateSourceID) != zlFutureGoodEdbInfo.FutureGoodEdbInfoID {
@@ -318,7 +320,7 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 		}
 	}
 
-	tmpXDataList, newYDataList, err := handleResultData(regionType, yDataList, futureGoodEdbInfoList, maxIndex)
+	tmpXDataList, newYDataList, err := handleResultData(regionType, futureGoodEdbType, yDataList, futureGoodEdbInfoList, maxIndex)
 	if err != nil {
 		return
 	}
@@ -413,9 +415,17 @@ func BarChartData(edbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList,
 			}
 		} else {
 			for i, v := range futureGoodMappingList {
-				if v.Year > currYear || (v.Year == currYear && int(v.Month) > int(currMonth)) {
+				if v.FutureGoodEdbType == 2 {
+					if i == 0 {
+						continue
+					}
 					indexList = append(indexList, i)
-					mList = append(mList, (v.Year-currYear)*12+int(v.Month)-int(currMonth))
+					mList = append(mList, int(v.Month))
+				} else {
+					if v.Year > currYear || (v.Year == currYear && int(v.Month) > int(currMonth)) {
+						indexList = append(indexList, i)
+						mList = append(mList, (v.Year-currYear)*12+int(v.Month)-int(currMonth))
+					}
 				}
 			}
 		}
@@ -587,7 +597,7 @@ func FutureGoodChartInfoRefresh(chartInfoId int) (err error) {
 }
 
 // handleResultData 处理成最终的结果数据
-func handleResultData(regionType string, yDataList []chart_info.YData, futureGoodEdbInfoList []*future_good_edb_info.FutureGoodEdbInfo, maxIndex int) (xDataList []chart_info.XData, newYDataList []chart_info.YData, err error) {
+func handleResultData(regionType string, futureGoodEdbType int, yDataList []chart_info.YData, futureGoodEdbInfoList []*future_good_edb_info.FutureGoodEdbInfo, maxIndex int) (xDataList []chart_info.XData, newYDataList []chart_info.YData, err error) {
 	xDataList = make([]chart_info.XData, 0)
 	newYDataList = yDataList
 
@@ -609,6 +619,89 @@ func handleResultData(regionType string, yDataList []chart_info.YData, futureGoo
 		futureGoodEdbInfoMap[int(v.FutureGoodEdbInfoID)] = v
 	}
 
+	if futureGoodEdbType == 2 { // 	FutureGoodEdbType   int       `description:"指标类型,1:年月是固定的合约;2:只有M+N期的合约,未固定年月"`
+		nList := []int{3, 15, 27}
+		for _, i := range nList {
+			xDataList = append(xDataList, chart_info.XData{
+				Name:   fmt.Sprint("M+", i),
+				NameEn: fmt.Sprint("M+", i),
+			})
+		}
+
+		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:]
+			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数
+					if int(futureGoodEdbInfo.Month) == 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++
+					}
+				}
+			}
+		}
+
+		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
+					}
+				}
+			}
+		}
+
+		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
+	}
+
 	nMap := make(map[int]int)
 
 	for _, v := range yDataList {
@@ -769,13 +862,13 @@ func getFutureGoodEdbInfoList(latestDateTime time.Time, tmpFutureGoodEdbInfoList
 		//海外的连续日期,目前
 		if v.FutureGoodEdbType == 2 {
 			if int(v.Month) <= maxM {
-				addMonth := int(earliestDateTime.Month()) + int(v.Month)
-				v.Year = earliestDateTime.Year() + addMonth/12
-				realMonth := addMonth % 12
-				if realMonth == 0 {
-					realMonth = 12
-				}
-				v.Month = uint32(realMonth)
+				//addMonth := int(earliestDateTime.Month()) + int(v.Month)
+				//v.Year = earliestDateTime.Year() + addMonth/12
+				//realMonth := addMonth % 12
+				//if realMonth == 0 {
+				//	realMonth = 12
+				//}
+				//v.Month = uint32(realMonth)
 				futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
 			}
 			continue

+ 7 - 0
services/chart/future_good/future_good_edb_info.go

@@ -45,5 +45,12 @@ func FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList []*future_good_ed
 			return fmt.Errorf("刷新失败, err:%s", errMsg)
 		}
 	}
+
+	// 刷新商品期货指标相关的数据
+	for _, bv := range futureGoodEdbInfoList {
+		if bv.ParentID == 0 {
+			RefreshEdbRelation(int(bv.FutureGoodEdbInfoID))
+		}
+	}
 	return err
 }

+ 1 - 0
utils/constants.go

@@ -256,6 +256,7 @@ const (
 	CHART_SOURCE_FUTURE_GOOD         = 2
 	CHART_SOURCE_CORRELATION         = 3 // 相关性图表
 	CHART_SOURCE_ROLLING_CORRELATION = 4 // 滚动相关性图表
+	CHART_SOURCE_FUTURE_GOOD_PROFIT  = 5 // 商品利润曲线
 )
 
 // 图表样式类型