Browse Source

fix:新增跨品种分析图表

Roc 1 year ago
parent
commit
cc0ac5d85f

+ 44 - 0
controllers/chart_common.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"eta/eta_chart_lib/models"
 	"eta/eta_chart_lib/models/data_manage"
+	cross_varietyReq "eta/eta_chart_lib/models/data_manage/cross_variety/request"
 	"eta/eta_chart_lib/models/data_manage/future_good"
 	"eta/eta_chart_lib/models/data_manage/future_good/request"
 	"eta/eta_chart_lib/models/data_manage/future_good/response"
@@ -11,6 +12,7 @@ import (
 	line_featureReq "eta/eta_chart_lib/models/data_manage/line_feature/request"
 	"eta/eta_chart_lib/services/data"
 	correlationServ "eta/eta_chart_lib/services/data/correlation"
+	"eta/eta_chart_lib/services/data/cross_variety"
 	future_goodServ "eta/eta_chart_lib/services/data/future_good"
 	"eta/eta_chart_lib/services/data/line_equation"
 	lineFeatureServ "eta/eta_chart_lib/services/data/line_feature"
@@ -100,6 +102,8 @@ func (this *ChartController) CommonChartInfoDetailFromUniqueCode() {
 		resp, isOk, msg, errMsg = GetLineEquationChartInfoDetailFromUniqueCode(chartInfo, key)
 	case utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY:
 		resp, isOk, msg, errMsg = GetLineFeatureChartInfoDetailFromUniqueCode(chartInfo, key)
+	case utils.CHART_SOURCE_CROSS_HEDGING:
+		resp, isOk, msg, errMsg = GetCrossVarietyChartInfoDetailFromUniqueCode(chartInfo, key)
 	default:
 		br.Msg = "错误的图表"
 		br.ErrMsg = "错误的图表"
@@ -468,6 +472,46 @@ func GetLineFeatureChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, ke
 	return
 }
 
+// GetCrossVarietyChartInfoDetailFromUniqueCode 根据编码获取图表详情
+func GetCrossVarietyChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, key string) (resp *models.ChartInfoDetailResp, isOk bool, msg, errMsg string) {
+	resp = new(models.ChartInfoDetailResp)
+
+	if chartInfo.ExtraConfig == `` {
+		msg = "图表配置信息异常"
+		errMsg = "图表配置信息异常"
+		return
+	}
+	var config cross_varietyReq.ChartConfigReq
+	err := json.Unmarshal([]byte(chartInfo.ExtraConfig), &config)
+	if err != nil {
+		msg = "解析跨品种分析配置失败"
+		errMsg = "解析跨品种分析配置失败,Err:" + err.Error()
+		return
+	}
+	// 获取图表x轴y轴
+	edbList, dataResp, err, msg, _ := cross_variety.GetChartData(0, config)
+	if err != nil {
+		errMsg = "获取图表,指标信息失败,Err:" + err.Error()
+		return
+	}
+	//判断是否需要展示英文标识
+	//chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList[0:1], chartInfo.Source, chartInfo.ChartType)
+	//chartInfo.UnitEn = edbInfoMappingA.UnitEn
+
+	// 另存为
+	resp.ChartInfo = chartInfo
+	resp.DataResp = dataResp
+	resp.EdbInfoList = edbList
+
+	// 将数据加入缓存
+	if utils.Re == nil {
+		d, _ := json.Marshal(resp)
+		_ = utils.Rc.Put(key, d, 2*time.Hour)
+	}
+	isOk = true
+	return
+}
+
 // FutureGoodChartInfoRefresh
 // @Title 商品价格图表刷新接口
 // @Description 商品价格图表刷新接口

+ 58 - 0
models/data_manage/cross_variety/chart_tag.go

@@ -0,0 +1,58 @@
+package cross_variety
+
+import (
+	"eta/eta_chart_lib/utils"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ChartTag
+// @Description: chart_tag 图表标签表
+type ChartTag struct {
+	ChartTagId      int       `orm:"column(chart_tag_id);pk"`
+	ChartTagName    string    `description:"标签名称"`
+	SysUserId       int       `description:"创建人id"`
+	SysUserRealName string    `description:"创建人姓名"`
+	ModifyTime      time.Time `description:"修改时间"`
+	CreateTime      time.Time `description:"创建时间"`
+}
+
+// Update
+// @Description: 更新标签
+// @author: Roc
+// @receiver item
+// @datetime 2023-11-21 15:15:17
+// @param updateColList []string
+// @return err error
+func (item *ChartTag) Update(updateColList []string) (err error) {
+	to := orm.NewOrmUsingDB("data")
+	_, err = to.Update(item, updateColList...)
+
+	return
+}
+
+// Delete 删除
+func (item *ChartTag) Delete() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Delete(item)
+	return
+}
+
+// GetTagListByIdList
+// @Description: 根据ID列表获取标签列表
+// @author: Roc
+// @datetime 2023-11-23 17:56:39
+// @param idList []int
+// @return items []*ChartTag
+// @return err error
+func GetTagListByIdList(idList []int) (items []*ChartTag, err error) {
+	num := len(idList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_tag WHERE 1 = 1 AND chart_tag_id in (` + utils.GetOrmInReplace(num) + `)`
+	_, err = o.Raw(sql, idList).QueryRows(&items)
+
+	return
+}

+ 40 - 0
models/data_manage/cross_variety/chart_tag_variety.go

@@ -0,0 +1,40 @@
+package cross_variety
+
+import (
+	"eta/eta_chart_lib/utils"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ChartTagVariety
+// @Description: chart_tag_variety 图表标签品种关系表
+type ChartTagVariety struct {
+	Id                        int       `orm:"column(id);pk"`
+	ChartTagId                int       `description:"标签id"`
+	ChartVarietyId            int       `description:"品种id"`
+	EdbInfoId                 int       `description:"指标id"`
+	LastUpdateSysUserId       int       `description:"最后一次操作人"`
+	LastUpdateSysUserRealName string    `description:"最后一次操作人真实姓名"`
+	ModifyTime                time.Time `description:"修改时间"`
+	CreateTime                time.Time `description:"创建时间"`
+}
+
+// GetChartTagVarietyListByTagAndVariety
+// @Description: 根据标签id和品种id列表获取所绑定的品种列表
+// @author: Roc
+// @datetime 2023-11-23 15:04:20
+// @param chartTagId int
+// @param varietyIdList []int
+// @return items []*ChartTagVariety
+// @return err error
+func GetChartTagVarietyListByTagAndVariety(chartTagId int, varietyIdList []int) (items []*ChartTagVariety, err error) {
+	num := len(varietyIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_tag_variety WHERE chart_tag_id = ? AND chart_variety_id in (` + utils.GetOrmInReplace(num) + `) `
+	_, err = o.Raw(sql, chartTagId, varietyIdList).QueryRows(&items)
+
+	return
+}

+ 120 - 0
models/data_manage/cross_variety/chart_variety.go

@@ -0,0 +1,120 @@
+package cross_variety
+
+import (
+	"eta/eta_chart_lib/utils"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ChartVariety
+// @Description: chart_variety 图表品种表
+type ChartVariety struct {
+	ChartVarietyId   int       `orm:"column(chart_variety_id);pk"`
+	ChartVarietyName string    `description:"品种名称"`
+	SysUserId        int       `description:"创建人id"`
+	SysUserRealName  string    `description:"创建人姓名"`
+	ModifyTime       time.Time `description:"修改时间"`
+	CreateTime       time.Time `description:"创建时间"`
+}
+
+// GetVarietyById
+// @Description: 根据品种id获取品种详情
+// @author: Roc
+// @datetime 2023-11-21 14:55:31
+// @param id int
+// @return item *ChartVariety
+// @return err error
+func GetVarietyById(id int) (item *ChartVariety, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_variety WHERE chart_variety_id = ?`
+	err = o.Raw(sql, id).QueryRow(&item)
+
+	return
+}
+
+// GetVarietyByName
+// @Description: 根据品种名称获取品种详情
+// @author: Roc
+// @datetime 2023-11-21 14:55:20
+// @param name string
+// @return item *ChartVariety
+// @return err error
+func GetVarietyByName(name string) (item *ChartVariety, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_variety WHERE chart_variety_name = ?`
+	err = o.Raw(sql, name).QueryRow(&item)
+
+	return
+}
+
+// AddVariety
+// @Description: 添加品种
+// @author: Roc
+// @datetime 2023-11-21 14:52:56
+// @param item *ChartVariety
+// @return err error
+func AddVariety(item *ChartVariety) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	lastId, err := o.Insert(item)
+	if err != nil {
+		return
+	}
+
+	item.ChartVarietyId = int(lastId)
+
+	return
+}
+
+// Update
+// @Description: 更新品种
+// @author: Roc
+// @receiver item
+// @datetime 2023-11-21 15:15:17
+// @param updateColList []string
+// @return err error
+func (item *ChartVariety) Update(updateColList []string) (err error) {
+	to := orm.NewOrmUsingDB("data")
+	_, err = to.Update(item, updateColList...)
+
+	return
+}
+
+// Delete 删除
+func (item *ChartVariety) Delete() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Delete(item)
+	return
+}
+
+// GetVarietyList
+// @Description: 获取所有品种列表
+// @author: Roc
+// @datetime 2023-11-22 10:44:35
+// @return items []*ChartVariety
+// @return err error
+func GetVarietyList() (items []*ChartVariety, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_variety WHERE 1 = 1 `
+	_, err = o.Raw(sql).QueryRows(&items)
+
+	return
+}
+
+// GetVarietyListByIdList
+// @Description: 根据ID列表获取品种列表
+// @author: Roc
+// @datetime 2023-11-23 17:56:39
+// @param idList []int
+// @return items []*ChartVariety
+// @return err error
+func GetVarietyListByIdList(idList []int) (items []*ChartVariety, err error) {
+	num := len(idList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_variety WHERE 1 = 1 AND chart_variety_id in (` + utils.GetOrmInReplace(num) + `)`
+	_, err = o.Raw(sql, idList).QueryRows(&items)
+
+	return
+}

+ 19 - 0
models/data_manage/cross_variety/request/chart.go

@@ -0,0 +1,19 @@
+package request
+
+// ChartConfigReq
+// @Description: 跨品种分析的图表配置
+type ChartConfigReq struct {
+	TagX           int               `description:"X轴的标签ID"`
+	TagY           int               `description:"Y轴的标签ID"`
+	CalculateValue int               `description:"计算窗口"`
+	CalculateUnit  string            `description:"计算频度"`
+	DateConfigList []ChartConfigDate `description:"日期配置列表"`
+	VarietyList    []int             `description:"品种id列表"`
+}
+
+// ChartConfigDate
+// @Description: 跨品种分析的日期配置
+type ChartConfigDate struct {
+	DateType int `description:"日期类型,,1:最新日期;2:N天前"`
+	Num      int
+}

+ 426 - 0
services/data/cross_variety/chart.go

@@ -0,0 +1,426 @@
+package cross_variety
+
+import (
+	"errors"
+	"eta/eta_chart_lib/models"
+	cross_varietyModel "eta/eta_chart_lib/models/data_manage/cross_variety"
+	"eta/eta_chart_lib/models/data_manage/cross_variety/request"
+	"eta/eta_chart_lib/services/data"
+	"eta/eta_chart_lib/utils"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"time"
+)
+
+// ChartInfoResp 截面散点图数据
+type ChartInfoResp struct {
+	XName       string                         `description:"x轴名称"`
+	XNameEn     string                         `description:"x轴名称(英文)"`
+	XUnitName   string                         `description:"x轴单位名称"`
+	XUnitNameEn string                         `description:"x轴单位名称(英文)"`
+	YName       string                         `description:"y轴名称"`
+	YNameEn     string                         `description:"y轴名称(英文)"`
+	YUnitName   string                         `description:"y轴单位名称"`
+	YUnitNameEn string                         `description:"y轴单位名称(英文)"`
+	XMinValue   string                         `description:"X轴的最小值"`
+	XMaxValue   string                         `description:"X轴的最大值"`
+	YMinValue   string                         `description:"Y轴的最小值"`
+	YMaxValue   string                         `description:"Y轴的最大值"`
+	DataList    []SectionScatterSeriesItemResp `description:"数据列"`
+}
+
+// SectionScatterSeriesItemResp 系列的返回
+type SectionScatterSeriesItemResp struct {
+	Name                string            `description:"系列名"`
+	NameEn              string            `description:"系列名(英文)"`
+	Color               string            `description:"颜色"`
+	CoordinatePointData []CoordinatePoint `description:"趋势线的前后坐标点"`
+}
+
+// SectionScatterEdbItemResp 截面散点的返回参数
+type SectionScatterEdbItemResp struct {
+	XEdbInfoId int     `description:"X轴指标id"`
+	XDate      string  `description:"X轴指标实际日期"`
+	XName      string  `description:"X轴指标名称"`
+	XNameEn    string  `description:"X轴指标英文名称"`
+	XValue     float64 `description:"X轴实际值"`
+	YEdbInfoId int     `description:"Y轴指标id"`
+	YDate      string  `description:"Y轴指标实际日期"`
+	YName      string  `description:"Y轴指标名称"`
+	YNameEn    string  `description:"Y轴指标英文名称"`
+	YValue     float64 `description:"Y轴实际值"`
+	IsShow     bool    `description:"是否展示"`
+	Name       string  `description:"标签名称"`
+	NameEn     string  `description:"英文标签名称"`
+}
+
+// CoordinatePoint 坐标点
+type CoordinatePoint struct {
+	X          float64
+	Y          float64
+	XEdbInfoId int
+	YEdbInfoId int
+	XDate      string
+	YDate      string
+}
+
+// GetChartData
+// @Description: 获取跨品种分析图表数据
+// @author: Roc
+// @datetime 2023-11-24 09:42:59
+// @param chartInfoId int
+// @param config request.ChartConfigReq
+// @return edbList []*data_manage.ChartEdbInfoMapping
+// @return dataResp ChartInfoResp
+// @return err error
+// @return errMsg string
+// @return isSendEmail bool
+func GetChartData(chartInfoId int, config request.ChartConfigReq) (edbList []*models.ChartEdbInfoMapping, dataResp ChartInfoResp, err error, errMsg string, isSendEmail bool) {
+	moveUnitDays, ok := utils.FrequencyDaysMap[config.CalculateUnit]
+	if !ok {
+		errMsg = "错误的分析周期"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+
+	isSendEmail = true
+
+	// 品种map
+	varietyMap := make(map[int]*cross_varietyModel.ChartVariety)
+	{
+		varietyList, tmpErr := cross_varietyModel.GetVarietyListByIdList(config.VarietyList)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		for _, v := range varietyList {
+			varietyMap[v.ChartVarietyId] = v
+		}
+	}
+
+	// 标签m
+	var xTagInfo, yTagInfo *cross_varietyModel.ChartTag
+	{
+		tagList, tmpErr := cross_varietyModel.GetTagListByIdList([]int{config.TagX, config.TagY})
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		for _, v := range tagList {
+			if v.ChartTagId == config.TagX {
+				xTagInfo = v
+			} else if v.ChartTagId == config.TagY {
+				yTagInfo = v
+			}
+		}
+	}
+	if xTagInfo == nil {
+		errMsg = "找不到对应的X轴标签"
+		err = errors.New(errMsg)
+		return
+	}
+	if yTagInfo == nil {
+		errMsg = "找不到对应的Y轴标签"
+		err = errors.New(errMsg)
+		return
+	}
+
+	xVarietyEdbMap, yVarietyEdbMap, edbInfoIdList, err := GetXYEdbIdList(config.TagX, config.TagY, config.VarietyList)
+	if err != nil {
+		return
+	}
+
+	if len(edbInfoIdList) <= 0 {
+		errMsg = "品种未配置指标"
+		err = errors.New(errMsg)
+		isSendEmail = false
+		return
+	}
+	mappingList, err := models.GetChartEdbMappingListByEdbInfoIdList(edbInfoIdList)
+	if err != nil {
+		errMsg = "获取指标信息失败"
+		err = errors.New("获取指标信息失败,ERR:" + err.Error())
+		return
+	}
+
+	// 指标对应的所有数据
+	chartType := 1 //1:普通图,2:季节性图
+	calendar := "公历"
+	edbDataListMap, edbList, err := data.GetEdbDataMapList(chartInfoId, chartType, calendar, "", "", mappingList, "")
+	if err != nil {
+		return
+	}
+
+	currDay := time.Now()
+	currDay = time.Date(currDay.Year(), currDay.Month(), currDay.Day(), 0, 0, 0, 0, time.Local)
+
+	dataMap := make(map[string]float64)
+	dateMap := make(map[string]string)
+	for dateIndex, dateConfig := range config.DateConfigList {
+		for _, edbInfoMapping := range mappingList {
+			// 数据会是正序的
+			dataList, ok := edbDataListMap[edbInfoMapping.EdbInfoId]
+			if !ok {
+				continue
+			}
+
+			lenData := len(dataList)
+			if lenData <= 0 {
+				continue
+			}
+
+			// 数据开始日期
+			endDateStr := ``
+			var endDate time.Time
+			// 数据的开始索引
+			k := lenData - 1
+			var currVal float64
+			switch dateConfig.DateType {
+			case 1: // 1:最新日期;
+				endDateStr = dataList[k].DataTime
+				tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, endDateStr, time.Local)
+				if tmpErr != nil {
+					err = tmpErr
+					return
+				}
+				endDate = tmpDate
+				currVal = dataList[k].Value
+			case 2: // 2:N天前
+				tmpEndDate := currDay.AddDate(0, 0, -dateConfig.Num)
+				tmpEndDateStr := tmpEndDate.Format(utils.FormatDate)
+
+				for i := k; i >= 0; i-- {
+					tmpDateStr := dataList[i].DataTime
+					// 如果正好是这一天,那么就直接break了
+					if tmpEndDateStr == tmpDateStr {
+						k = i
+						endDateStr = tmpDateStr
+						currVal = dataList[i].Value
+						break
+					}
+					tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					// 如果这期的日期晚于选择的日期,那么继续遍历
+					if tmpDate.After(tmpEndDate) {
+						continue
+					}
+					k = i
+					endDateStr = tmpDateStr
+					endDate = tmpDate
+					currVal = dataList[i].Value
+					break
+				}
+			}
+
+			// 没有找到日期,那么就不处理
+			if endDateStr == `` || endDate.IsZero() {
+				continue
+			}
+
+			// 最早的日期
+			earliestDate := endDate.AddDate(0, 0, -config.CalculateValue*moveUnitDays)
+			earliestDateStr := earliestDate.Format(utils.FormatDate)
+
+			var minVal, maxVal float64
+			var isNotFirst bool // 是否是第一条数据
+			for i := k; i >= 0; i-- {
+				tmpData := dataList[i]
+				if !isNotFirst {
+					maxVal = tmpData.Value
+					minVal = tmpData.Value
+					isNotFirst = true
+					continue
+				}
+
+				tmpDateStr := dataList[i].DataTime
+				// 如果正好是这一天,那么就直接break了
+				if earliestDateStr == tmpDateStr {
+					break
+				}
+				tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
+				if tmpErr != nil {
+					err = tmpErr
+					return
+				}
+				// 如果这期的日期早于选择的日期,那么继续停止遍历
+				if tmpDate.Before(earliestDate) {
+					continue
+				}
+
+				if tmpData.Value > maxVal {
+					maxVal = tmpData.Value
+				}
+				if tmpData.Value < minVal {
+					minVal = tmpData.Value
+				}
+			}
+
+			// 最大值等于最小值,说明计算结果无效
+			if maxVal == minVal {
+				continue
+			}
+			//百分位=(现值-Min)/(Max-Min)
+			tmpV := (currVal - minVal) / (maxVal - minVal) * 100
+			tmpV, _ = decimal.NewFromFloat(tmpV).Round(4).Float64()
+
+			// key的生成(日期配置下标+指标id)
+			key := fmt.Sprint(dateIndex, "_", edbInfoMapping.EdbInfoId)
+			dataMap[key] = tmpV
+			dateMap[key] = endDateStr
+		}
+	}
+
+	// 返回数据处理
+	dataList := make([]SectionScatterSeriesItemResp, 0)
+	var xMinVal, xMaxVal, yMinVal, yMaxVal float64
+	var isNotFirst bool
+
+	for _, varietyId := range config.VarietyList {
+		xEdbInfoId, ok1 := xVarietyEdbMap[varietyId]
+		if !ok1 {
+			continue
+		}
+		yEdbInfoId, ok2 := yVarietyEdbMap[varietyId]
+		if !ok2 {
+			continue
+		}
+		variety, ok := varietyMap[varietyId]
+		if !ok {
+			continue
+		}
+
+		coordinatePointList := make([]CoordinatePoint, 0)
+
+		for dateIndex := range config.DateConfigList {
+			key1 := fmt.Sprint(dateIndex, "_", xEdbInfoId)
+			xVal, ok1 := dataMap[key1]
+			if !ok1 {
+				continue
+			}
+			key2 := fmt.Sprint(dateIndex, "_", yEdbInfoId)
+			yVal, ok2 := dataMap[key2]
+			if !ok2 {
+				continue
+			}
+			if !isNotFirst {
+				xMinVal = xVal
+				xMaxVal = xVal
+				yMinVal = yVal
+				yMaxVal = yVal
+				isNotFirst = true
+			} else {
+				if xVal < xMinVal {
+					xMinVal = xVal
+				}
+				if xVal > xMaxVal {
+					xMaxVal = xVal
+				}
+				if yVal < yMinVal {
+					yMinVal = yVal
+				}
+				if yVal > yMaxVal {
+					yMaxVal = yVal
+				}
+			}
+			coordinatePointList = append(coordinatePointList, CoordinatePoint{
+				X:          xVal,
+				Y:          yVal,
+				XEdbInfoId: xEdbInfoId,
+				YEdbInfoId: yEdbInfoId,
+				XDate:      dateMap[key1],
+				YDate:      dateMap[key2],
+			})
+		}
+
+		dataList = append(dataList, SectionScatterSeriesItemResp{
+			Name:                variety.ChartVarietyName,
+			NameEn:              "",
+			Color:               "",
+			CoordinatePointData: coordinatePointList,
+		})
+	}
+
+	dataResp = ChartInfoResp{
+		XName:       xTagInfo.ChartTagName,
+		XNameEn:     "",
+		XUnitName:   "%",
+		XUnitNameEn: "%",
+		YName:       yTagInfo.ChartTagName,
+		YNameEn:     "",
+		YUnitName:   "%",
+		YUnitNameEn: "%",
+		XMinValue:   fmt.Sprint(xMinVal),
+		XMaxValue:   fmt.Sprint(xMaxVal),
+		YMinValue:   fmt.Sprint(yMinVal),
+		YMaxValue:   fmt.Sprint(yMaxVal),
+		DataList:    dataList,
+	}
+
+	// 去除返回指标中的数据信息,避免没必要的数据传输
+	for k := range edbList {
+		edbList[k].DataList = nil
+	}
+
+	return
+}
+
+// GetXYEdbIdList
+// @Description: 根据标签id和品种获取指标列表信息
+// @author: Roc
+// @datetime 2023-11-27 14:31:23
+// @param tagX int
+// @param tagY int
+// @param varietyList []int
+// @return xVarietyEdbMap map[int]int
+// @return yVarietyEdbMap map[int]int
+// @return edbInfoIdList []int
+// @return errMsg string
+// @return err error
+func GetXYEdbIdList(tagX, tagY int, varietyList []int) (xVarietyEdbMap, yVarietyEdbMap map[int]int, edbInfoIdList []int, err error) {
+	edbInfoIdList = make([]int, 0)
+	xVarietyEdbMap = make(map[int]int)
+	yVarietyEdbMap = make(map[int]int)
+	xList, err := cross_varietyModel.GetChartTagVarietyListByTagAndVariety(tagX, varietyList)
+	if err != nil {
+		err = errors.New("获取X轴的品种指标配置信息失败,Err:" + err.Error())
+		return
+	}
+	yList, err := cross_varietyModel.GetChartTagVarietyListByTagAndVariety(tagY, varietyList)
+	if err != nil {
+		err = errors.New("获取Y轴的品种指标配置信息失败,Err:" + err.Error())
+		return
+	}
+
+	baseVarietyIdMap := make(map[int]int)
+	for _, v := range xList {
+		baseVarietyIdMap[v.ChartVarietyId] = v.ChartVarietyId
+	}
+
+	// 两个标签里面的品种并集
+	needVarietyIdMap := make(map[int]int)
+	for _, v := range yList {
+		if val, ok := baseVarietyIdMap[v.ChartVarietyId]; ok {
+			// 如果在 map2 中存在相同的键,则将键和值添加到结果中
+			needVarietyIdMap[v.ChartVarietyId] = val
+		}
+	}
+
+	for _, v := range xList {
+		if _, ok := needVarietyIdMap[v.ChartVarietyId]; ok {
+			xVarietyEdbMap[v.ChartVarietyId] = v.EdbInfoId
+			edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+		}
+	}
+	for _, v := range yList {
+		if _, ok := needVarietyIdMap[v.ChartVarietyId]; ok {
+			yVarietyEdbMap[v.ChartVarietyId] = v.EdbInfoId
+			edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+		}
+	}
+
+	return
+}

+ 8 - 7
utils/constants.go

@@ -126,13 +126,14 @@ const (
 const (
 	CHART_SOURCE_DEFAULT                         = 1
 	CHART_SOURCE_FUTURE_GOOD                     = 2
-	CHART_SOURCE_CORRELATION                     = 3 // 相关性图表
-	CHART_SOURCE_ROLLING_CORRELATION             = 4 // 滚动相关性图表
-	CHART_SOURCE_FUTURE_GOOD_PROFIT              = 5 // 商品利润曲线
-	CHART_SOURCE_LINE_EQUATION                   = 6 // 拟合方程图表
-	CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION = 7 // 统计特征-标准差图表
-	CHART_SOURCE_LINE_FEATURE_PERCENTILE         = 8 // 统计特征-百分位图表
-	CHART_SOURCE_LINE_FEATURE_FREQUENCY          = 9 // 统计特征-频率分布图表
+	CHART_SOURCE_CORRELATION                     = 3  // 相关性图表
+	CHART_SOURCE_ROLLING_CORRELATION             = 4  // 滚动相关性图表
+	CHART_SOURCE_FUTURE_GOOD_PROFIT              = 5  // 商品利润曲线
+	CHART_SOURCE_LINE_EQUATION                   = 6  // 拟合方程图表
+	CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION = 7  // 统计特征-标准差图表
+	CHART_SOURCE_LINE_FEATURE_PERCENTILE         = 8  // 统计特征-百分位图表
+	CHART_SOURCE_LINE_FEATURE_FREQUENCY          = 9  // 统计特征-频率分布图表
+	CHART_SOURCE_CROSS_HEDGING                   = 10 // 跨品种分析图表
 )
 
 // ETA表格