Bläddra i källkod

Merge branch 'debug' of http://8.136.199.33:3000/eta_server/eta_api into bzq1/execl-edit-conflict

zqbao 10 månader sedan
förälder
incheckning
cd3b6c7a00

+ 106 - 0
controllers/data_manage/chart_info.go

@@ -4266,3 +4266,109 @@ func (this *ChartInfoController) ForumDelete() {
 	br.Success = true
 	br.Msg = "操作成功"
 }
+
+// PreviewSeasonChartInfo
+// @Title 图表-获取预览的季节性图
+// @Description 图表-获取预览的季节性图
+// @Param	ExtraConfig	body data_manage.PreviewRadarChartReq true "type json string"
+// @Success 200 {object} data_manage.ChartEdbInfoDetailResp
+// @router /chart_info/preview/season [post]
+func (this *ChartInfoController) PreviewSeasonChartInfo() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req data_manage.PreviewSeasonChartReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	chartInfo := new(data_manage.ChartInfoView)
+
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	chartType := utils.CHART_TYPE_SEASON
+	if len(req.ChartEdbInfoList) <= 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+
+	edbInfoIdArr := make([]int, 0)
+	edbInfoNameMap := make(map[int]string)
+	for _, v := range req.ChartEdbInfoList {
+		edbInfoIdArr = append(edbInfoIdArr, v.EdbInfoId)
+		edbInfoNameMap[v.EdbInfoId] = v.EdbAliasName
+	}
+	mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList(edbInfoIdArr)
+	for _, v := range mappingList {
+		if name, ok := edbInfoNameMap[v.EdbInfoId]; ok {
+			v.EdbAliasName = name
+		}
+	}
+
+	var seasonExtraConfig string
+	seasonExtra, tErr := json.Marshal(req.SeasonExtraConfig)
+	if tErr != nil {
+		br.Msg = "季节性图表配置信息异常"
+		br.ErrMsg = "季节性图表配置信息异常,Err:" + tErr.Error()
+		return
+	}
+	seasonExtraConfig = string(seasonExtra)
+	// 获取图表中的指标数据
+	edbList, xEdbIdValue, yDataList, dataResp, err, errMsg := data.GetChartEdbData(0, chartType, "", "", "", mappingList, "", seasonExtraConfig)
+	if err != nil {
+		br.Msg = "获取失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
+		return
+	}
+	warnEdbList := make([]string, 0)
+	for _, v := range edbList {
+		if v.IsNullData {
+			warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
+		}
+	}
+	if len(warnEdbList) > 0 {
+		chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
+	}
+
+	//图表操作权限
+	chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId, true)
+	//判断是否需要展示英文标识
+	chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList, utils.CHART_SOURCE_DEFAULT, chartType)
+	chartInfo.Button = data_manage.ChartViewButton{
+		IsEdit:    chartInfo.IsEdit,
+		IsEnChart: chartInfo.IsEnChart,
+		IsAdd:     chartInfo.IsAdd,
+		IsCopy:    true,
+		IsSetName: chartInfo.IsSetName,
+	}
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
+	resp := new(data_manage.ChartInfoDetailResp)
+	resp.ChartInfo = chartInfo
+	resp.EdbInfoList = edbList
+	resp.XEdbIdValue = xEdbIdValue
+	resp.YDataList = yDataList
+	resp.DataResp = dataResp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 1 - 1
controllers/data_manage/edb_info.go

@@ -2483,7 +2483,7 @@ func (this *EdbInfoController) EdbInfoEdit() {
 		edbInfo.Frequency = req.Frequency
 		edbInfo.Unit = req.Unit
 		edbInfo.ClassifyId = req.ClassifyId
-		updateCols = append(updateCols, "EdbName", "EdbNameSource", "Frequency", "UnitEn", "ClassifyId")
+		updateCols = append(updateCols, "EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId")
 	}
 	pars = append(pars, req.EdbName)
 

+ 16 - 11
controllers/data_manage/edb_info_refresh.go

@@ -584,23 +584,27 @@ func (c *EdbInfoController) SaveEdbRefreshStatusSingle() {
 	if req.ModifyStatus == `暂停` {
 		isStop = 1
 	}
-	// 查询相关的计算指标
-	calculateEdb, err := data_manage.GetAllCalculateByEdbInfoId(edbInfo.EdbInfoId)
-	if err != nil {
-		if err.Error() == utils.ErrNoRow() {
-			br.Msg = "指标不存在"
+	calculateEdb := make([]*data_manage.EdbInfoCalculateMapping, 0)
+	if edbInfo.EdbInfoType == 0 && edbInfo.EdbType == 1 { //基础指标
+		// 查询相关的计算指标
+		calculateEdb, err = data_manage.GetAllCalculateByEdbInfoId(edbInfo.EdbInfoId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				br.Msg = "指标不存在"
+				return
+			}
+			br.Msg = "查询计算指标失败"
+			br.ErrMsg = "查询计算指标失败,Err:" + err.Error()
 			return
 		}
-		br.Msg = "查询计算指标失败"
-		br.ErrMsg = "查询计算指标失败,Err:" + err.Error()
 	}
+
 	// 遍历指标列表,把计算指标id整理成数组
 	if len(calculateEdb) > 0 {
 		for _, calculateEdbInfo := range calculateEdb {
 			calculateEdbIdList = append(calculateEdbIdList, calculateEdbInfo.EdbInfoId)
 		}
 	}
-	// todo 查询相关的预测指标
 
 	switch edbInfo.Source {
 	case utils.DATA_SOURCE_MYSTEEL_CHEMICAL: // 钢联
@@ -608,7 +612,8 @@ func (c *EdbInfoController) SaveEdbRefreshStatusSingle() {
 	case utils.DATA_SOURCE_WIND: // wind
 		err = data_manage.WindEdbInfoUpdateStatusByEdbInfoId([]int{edbInfo.EdbInfoId}, isStop, calculateEdbIdList)
 	default:
-		br.Msg = "暂不支持设置其他来源的指标"
+		// todo 支持其他的指标设置
+		err = data_manage.EdbInfoUpdateStatusByEdbInfoId([]int{edbInfo.EdbInfoId}, isStop)
 		return
 	}
 	if err != nil {
@@ -660,7 +665,7 @@ func (c *EdbInfoController) SaveRelationEdbRefreshStatus() {
 	// 指标id列表
 	if req.IsSelectAll {
 		// 如果是列表全选
-		_, edbList, err := data.GetEdbRelationList(req.Source, req.ClassifyId, req.SysUserId, req.Frequency, req.Keyword, req.Status, 0, 100000, "", "")
+		_, edbList, err := data.GetEdbRelationList(req.Source, req.EdbInfoType, req.ClassifyId, req.SysUserId, req.Frequency, req.Keyword, req.Status, 0, 100000, "", "")
 		if err != nil && err.Error() != utils.ErrNoRow() {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -736,7 +741,7 @@ func (c *EdbInfoController) SaveRelationEdbRefreshStatus() {
 	case utils.DATA_SOURCE_WIND: // wind
 		err = data_manage.WindEdbInfoUpdateStatusByEdbInfoId(edbIdList, isStop, calculateEdbIdList)
 	default:
-		br.Msg = "暂不支持设置其他来源的指标"
+		err = data_manage.EdbInfoUpdateStatusByEdbInfoId(edbIdList, isStop)
 		return
 	}
 	if err != nil {

+ 45 - 1
controllers/data_manage/edb_info_relation.go

@@ -4,6 +4,7 @@ import (
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/data_manage/excel"
 	"eta/eta_api/models/fe_calendar"
 	"eta/eta_api/models/sandbox"
 	"eta/eta_api/services/data"
@@ -38,6 +39,7 @@ func (c *EdbInfoRelationController) RelationEdbList() {
 	}()
 
 	source, _ := c.GetInt("Source")
+	edbInfoType, _ := c.GetInt("EdbInfoType")
 	classifyId := c.GetString("ClassifyId")
 	sysUserId := c.GetString("SysUserId")
 	frequency := c.GetString("Frequency")
@@ -73,7 +75,7 @@ func (c *EdbInfoRelationController) RelationEdbList() {
 	}
 	startSize = utils.StartIndex(currentIndex, pageSize)
 
-	total, list, err := data.GetEdbRelationList(source, classifyId, sysUserId, frequency, keyword, status, startSize, pageSize, sortParam, sortType)
+	total, list, err := data.GetEdbRelationList(source, edbInfoType, classifyId, sysUserId, frequency, keyword, status, startSize, pageSize, sortParam, sortType)
 	if err != nil && err.Error() != utils.ErrNoRow() {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -193,6 +195,48 @@ func (c *EdbInfoRelationController) RelationEdbListDetail() {
 		}
 	}
 
+	// 查询表格名称
+	if len(tableInfoIds) > 0 {
+		cond := " AND excel_info_id in (" + utils.GetOrmInReplace(len(tableInfoIds)) + ")"
+		pars := make([]interface{}, 0)
+		pars = append(pars, tableInfoIds)
+		tableList, err := excel.GetNoContentExcelInfoListByConditionNoPage(cond, pars)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取表格数据失败,Err:" + err.Error()
+			return
+		}
+		// 查询父级名称
+		excelParentName := make(map[int]string)
+		parentIds := make([]int, 0)
+		for _, v := range tableList {
+			if v.ParentId > 0 {
+				parentIds = append(parentIds, v.ParentId)
+			}
+		}
+		if len(parentIds) > 0 {
+			cond = " AND excel_info_id in (" + utils.GetOrmInReplace(len(parentIds)) + ")"
+			pars = make([]interface{}, 0)
+			pars = append(pars, tableInfoIds)
+			parentList, err := excel.GetNoContentExcelInfoListByConditionNoPage(cond, pars)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取表格数据失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range parentList {
+				excelParentName[v.ExcelInfoId] = v.ExcelName
+			}
+		}
+		for _, v := range tableList {
+			if v.ParentId > 0 {
+				parentName := excelParentName[v.ParentId]
+				objectNameMap[v.ExcelInfoId] = fmt.Sprintf("%s_%s", parentName, v.ExcelName)
+			} else {
+				objectNameMap[v.ExcelInfoId] = v.ExcelName
+			}
+		}
+	}
 	for _, v := range relationList {
 		referObjectName, _ := objectNameMap[v.ReferObjectId]
 		tmp := &data_manage.EdbInfoRelationDetail{

+ 99 - 4
models/data_manage/chart_info.go

@@ -263,10 +263,30 @@ type EditChartInfoReq struct {
 	UnitEn               string                  `description:"英文单位名称"`
 }
 
+type MarkersLine struct {
+	Axis             int    `json:"axis" description:"1左轴 2右轴 3横轴"`
+	AxisName         string `json:"axisName" description:"轴的名称,例如'左轴'"`
+	MarkLineType     int    `json:"markLineType" description:"1:固定 2:指标计算"`
+	Value            string `json:"value" description:"连线指向的数值,例如'4000'"`
+	From             string `json:"from" description:"连线的起始点,可以为空"`
+	To               string `json:"to" description:"连线的结束点,可以为空"`
+	LineWidth        int    `json:"lineWidth" description:"连线的宽度"`
+	DashStyle        string `json:"dashStyle" description:"连线的虚线样式,例如'ShortDashDot'"`
+	Color            string `json:"color" description:"连线的颜色"`
+	Text             string `json:"text" description:"连线旁边显示的文本"`
+	TextPosition     string `json:"textPosition" description:"文本的显示位置,例如'bottom'"`
+	TextColor        string `json:"textColor" description:"文本颜色"`
+	TextFontSize     int    `json:"textFontSize" description:"文本的字号大小"`
+	IsShow           bool   `json:"isShow" description:"是否显示连线及文本"`
+	Calculation      int    `json:"calculation" description:"计算方式 1区间均值 2区间均值加N倍标准差 3区间个数分位 4区间数值分位"`
+	CalculationValue int    `json:"calculationValue" description:"计算方式对应的值 2就是几倍标准差 3就是分位值 4就是数值值·"`
+}
+
 type EditFutureGoodChartInfoReq struct {
 	EditChartInfoReq
 	BarChartInfo FutureGoodBarChartInfoReq
 }
+
 type EditChartEnInfoReq struct {
 	ChartInfoId      int                       `description:"图表ID"`
 	ChartNameEn      string                    `description:"英文图表名称"`
@@ -1477,16 +1497,85 @@ type PreviewChartInfoReq struct {
 }
 
 type SeasonExtraItem struct {
-	ChartLegend []SeasonChartLegend `description:"自定义的图例名称"`
-	XStartDate  string              `description:"横坐标显示的起始日"`
-	XEndDate    string              `description:"横坐标显示的截止日"`
-	JumpYear    int                 `description:"横坐标日期是否跨年,1跨年,0不跨年"`
+	ChartLegend                 []SeasonChartLegend         `description:"自定义的图例名称"`
+	XStartDate                  string                      `description:"横坐标显示的起始日"`
+	XEndDate                    string                      `description:"横坐标显示的截止日"`
+	JumpYear                    int                         `description:"横坐标日期是否跨年,1跨年,0不跨年"`
+	RightAxis                   []SeasonRightAxis           `description:"自定义右轴指标"`
+	MaxMinLimits                MaxMinLimits                `description:"自定义同期上下限"`
+	SamePeriodAverage           SamePeriodAverage           `description:"自定义同期均线"`
+	SamePeriodStandardDeviation SamePeriodStandardDeviation `description:"自定义同期标准差"`
 }
 
 type SeasonChartLegend struct {
 	Name  string
 	Value string
 }
+
+// 自定义右轴指标
+type SeasonRightAxis struct {
+	IndicatorType int    `description:"右轴指标类型 1:左轴指标同比,2:指标库,3:预测指标 "`
+	Style         string `description:"生成样式"`
+	Shape         string `description:"形状"`
+	ChartColor    string `description:"图表颜色"`
+	Size          int    `description:"大小"`
+	Legend        string `description:"图例名称"`
+	NumFormat     int    `description:"数值格式 1:百分比 2:小数"`
+	IsConnected   int    `description:"是否连接 0不连接 1连接"`
+	LineColor     string `description:"线条颜色"`
+	LineWidth     int    `description:"线条宽度"`
+	LineStyle     string `description:"线条样式"`
+	IsShow        bool   `description:"是否显示"`
+}
+
+// 自定义同期上下限
+type MaxMinLimits struct {
+	Color  string `description:"颜色"`
+	Year   int    `description:"上下限取值范围"`
+	Legend string `description:"图例名称"`
+	IsShow bool   `description:"是否显示"`
+}
+
+// 自定义同期均线
+type SamePeriodAverage struct {
+	Color     string  `description:"颜色"`
+	Year      int     `description:"均线取值范围"`
+	Legend    string  `description:"图例名称"`
+	LineType  string  `description:"线型"`
+	LineWidth int     `description:"线宽"`
+	Value     float64 `description:"均线值"`
+	IsShow    bool    `description:"是否显示"`
+}
+
+// 自定义同期标准差
+type SamePeriodStandardDeviation struct {
+	Color    string  `description:"颜色"`
+	Year     int     `description:"标准差取值范围"`
+	Legend   string  `description:"图例名称"`
+	Multiple int     `description:"标准差倍数"`
+	MaxValue float64 `description:"上限"`
+	MinValue float64 `description:"上限"`
+	IsShow   bool    `description:"是否显示"`
+}
+
+type SeasonChartResp struct {
+	MaxMinLimits                MaxMinLimitsResp            `description:"自定义上下限"`
+	SamePeriodAverage           SamePeriodAverage           `description:"自定义同期均线"`
+	SamePeriodStandardDeviation SamePeriodStandardDeviation `description:"自定义同期标准差线"`
+}
+type MaxMinLimitsResp struct {
+	List   []*MaxMinLimitsData `description:"自定义上下限列表"`
+	Color  string              `description:"颜色"`
+	Value  int                 `description:"上下限取值范围"`
+	Legend string              `description:"图例名称"`
+}
+type MaxMinLimitsData struct {
+	DataTime      string  `description:"数据日期"`
+	DataTimestamp int64   `description:"数据日期时间戳"`
+	MaxValue      float64 `description:"最大值"`
+	MinValue      float64 `description:"最小值"`
+}
+
 type AddChartInfoResp struct {
 	ChartInfoId int    `description:"图表id"`
 	UniqueCode  string `description:"图表唯一编码"`
@@ -2479,3 +2568,9 @@ func GetChartInfoBySourceAndParentId(source, parentId, adminId int) (items []*Ch
 	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }
+
+// PreviewSeasonChartReq 预览季节性图的请求入参
+type PreviewSeasonChartReq struct {
+	ChartEdbInfoList  []*ChartSaveItem `description:"指标及配置信息"`
+	SeasonExtraConfig SeasonExtraItem  `description:"季节图额外配置信息,json字符串"`
+}

+ 30 - 0
models/data_manage/edb_data_wind.go

@@ -104,3 +104,33 @@ func WindEdbInfoUpdateStatusByEdbInfoId(edbInfoIds []int, isStop int, calculateE
 
 	return
 }
+
+func EdbInfoUpdateStatusByEdbInfoId(edbInfoIds []int, isStop int) (err error) {
+	o, err := orm.NewOrmUsingDB("data").Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = o.Rollback()
+			return
+		}
+		_ = o.Commit()
+	}()
+
+	// 更改指标的更新状态
+	if len(edbInfoIds) == 1 {
+		sql := ` UPDATE edb_info SET no_update = ? WHERE edb_info_id=? `
+		_, err = o.Raw(sql, isStop, edbInfoIds[0]).Exec()
+		if err != nil {
+			return
+		}
+	} else {
+		sql := ` UPDATE edb_info SET no_update = ? WHERE edb_info_id IN (` + utils.GetOrmInReplace(len(edbInfoIds)) + `) `
+		_, err = o.Raw(sql, isStop, edbInfoIds).Exec()
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 1 - 0
models/data_manage/edb_refresh/request/edb_info_refresh.go

@@ -66,6 +66,7 @@ type SaveRelationEdbRefreshStatusReq struct {
 	SysUserId       string `description:"操作人id,支持多选,用英文,隔开"`
 	Frequency       string `description:"频度,支持多选,用英文,隔开"`
 	Status          string `description:"状态,枚举值:启用、暂停"`
+	EdbInfoType     int    `description:"1计算指标,2预测指标"`
 	Keyword         string `description:"关键字"`
 	IsSelectAll     bool   `description:"是否选择所有指标"`
 	EdbSelectIdList []int  `description:"选择的指标id列表"`

+ 9 - 0
routers/commentsRouter.go

@@ -2482,6 +2482,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"],
+        beego.ControllerComments{
+            Method: "PreviewSeasonChartInfo",
+            Router: `/chart_info/preview/season`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartInfoController"],
         beego.ControllerComments{
             Method: "PreviewSectionScatterChartInfo",

+ 135 - 0
services/data/chart_info.go

@@ -357,6 +357,10 @@ func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate st
 
 	// 特殊图形数据处理
 	switch chartType {
+	case 2: // 季节性图
+		if seasonExtraConfig != "" {
+			dataResp, err = SeasonChartData(edbList, seasonExtraConfig)
+		}
 	case 7: // 柱形图
 		barChartConf := extraConfig.(data_manage.BarChartInfoReq)
 		xEdbIdValue, yDataList, err = BarChartData(mappingList, edbDataListMap, barChartConf.DateList, barChartConf.Sort)
@@ -3228,3 +3232,134 @@ func GetChartEdbDataV2(chartInfoId, chartType int, calendar, startDate, endDate
 	}
 	return
 }
+
+// SeasonChartData 季节性图的数据处理
+func SeasonChartData(dataList []*data_manage.ChartEdbInfoMapping, seasonExtraConfig string) (dataResp data_manage.SeasonChartResp, err error) {
+	var seasonConfig data_manage.SeasonExtraItem
+	err = json.Unmarshal([]byte(seasonExtraConfig), &seasonConfig)
+	if err != nil {
+		err = errors.New("季节性图配置异常, Err:" + err.Error())
+		return
+	}
+
+	for _, mappingItem := range dataList {
+		quarterDataList := mappingItem.DataList.(data_manage.QuarterDataList)
+		// 上下限区间
+		//if seasonConfig.MaxMinLimits.Year > 0 {
+			dataResp.MaxMinLimits.List = make([]*data_manage.MaxMinLimitsData, 0)
+			dataTimeMap := make(map[time.Time]time.Time)
+			dataTimeList := make([]string, 0)
+			maxValueMap := make(map[time.Time]float64)
+			minValueMap := make(map[time.Time]float64)
+
+			maxMinDataList := make([]*data_manage.MaxMinLimitsData, 0)
+			// 日度 周度插值
+			for _, v := range quarterDataList {
+				if mappingItem.Frequency == "日度" || mappingItem.Frequency == "周度" {
+					handleDataMap := make(map[string]float64)
+					dataTimeList, _, err = HandleDataByLinearRegressionToList(v.DataList, handleDataMap)
+					if err != nil {
+						err = errors.New("插值处理数据异常, Err:" + err.Error())
+						return
+					}
+					for _, date := range dataTimeList {
+						dateTime, e := time.Parse(utils.FormatDate, date)
+						if e != nil {
+							err = errors.New("时间格式化异常, Err:" + e.Error())
+							return
+						}
+						newDate := dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
+						// 处理上下限列表
+						if value, ok := maxValueMap[newDate]; ok {
+							if value < handleDataMap[date] {
+								maxValueMap[newDate] = handleDataMap[date]
+							}
+						} else {
+							maxValueMap[newDate] = handleDataMap[date]
+						}
+
+						if value, ok := minValueMap[newDate]; ok {
+							if value > handleDataMap[date] {
+								minValueMap[newDate] = handleDataMap[date]
+							}
+						} else {
+							minValueMap[newDate] = handleDataMap[date]
+						}
+
+						dataTimeMap[newDate] = newDate
+					}
+				} else {
+					// 旬度、月度、季度、半年度 不插值,需要先把日期列表和数据map取出来
+					for _, vv := range v.DataList {
+						dateTime, e := time.Parse(utils.FormatDate, vv.DataTime)
+						if e != nil {
+							err = errors.New("时间格式化异常, Err:" + e.Error())
+							return
+						}
+						newDate := dateTime.AddDate(time.Now().Year()-dateTime.Year(), 0, 0)
+
+						if value, ok := maxValueMap[newDate]; ok {
+							if value < vv.Value {
+								maxValueMap[newDate] = vv.Value
+							}
+						} else {
+							maxValueMap[newDate] = vv.Value
+						}
+
+						if value, ok := minValueMap[newDate]; ok {
+							if value > vv.Value {
+								minValueMap[newDate] = vv.Value
+							}
+						} else {
+							minValueMap[newDate] = vv.Value
+						}
+						dataTimeMap[newDate] = newDate
+					}
+				}
+			}
+
+			for _, v := range dataTimeMap {
+				maxMinItem := &data_manage.MaxMinLimitsData{}
+				if maxValue, ok := maxValueMap[v]; ok {
+					maxMinItem.MaxValue = maxValue
+				} else {
+					maxMinItem.MaxValue = minValueMap[v]
+				}
+
+				if minValue, ok := minValueMap[v]; ok {
+					maxMinItem.MinValue = minValue
+				} else {
+					maxMinItem.MinValue = maxValueMap[v]
+				}
+				maxMinItem.DataTime = v.Format(utils.FormatDate)
+				maxMinItem.DataTimestamp = v.UnixNano() / 1e6
+
+				maxMinDataList = append(maxMinDataList, maxMinItem)
+
+			}
+
+			// 排序
+			sort.Slice(maxMinDataList, func(i, j int) bool {
+				return maxMinDataList[i].DataTime < maxMinDataList[j].DataTime
+			})
+
+			dataResp.MaxMinLimits.List = maxMinDataList
+			dataResp.MaxMinLimits.Color = seasonConfig.MaxMinLimits.Color
+			dataResp.MaxMinLimits.Legend = seasonConfig.MaxMinLimits.Legend
+		//}
+
+		// 自定义同期均线
+		if seasonConfig.SamePeriodAverage.Year > 0 {
+
+		}
+
+		// 自定义同期标准差
+		if seasonConfig.SamePeriodAverage.Year > 0 {
+
+		}
+
+
+	}
+
+	return
+}

+ 71 - 0
services/data/edb_info_calculate.go

@@ -372,3 +372,74 @@ func GetMaxMinEdbInfo(formula string) string {
 	formula = strings.ReplaceAll(formula, "min", "MIN")
 	return formula
 }
+
+// HandleDataByLinearRegressionToList 插值法补充数据(线性方程式)
+func HandleDataByLinearRegressionToList (edbInfoDataList []*data_manage.EdbDataList, handleDataMap map[string]float64) (dataTimeList []string,valueList []float64, err error) {
+	if len(edbInfoDataList) < 2 {
+		return
+	}
+
+	var startEdbInfoData *data_manage.EdbDataList
+	for _, v := range edbInfoDataList {
+		handleDataMap[v.DataTime] = v.Value
+		dataTimeList = append(dataTimeList, v.DataTime)
+		// 第一个数据就给过滤了,给后面的试用
+		if startEdbInfoData == nil {
+			startEdbInfoData = v
+			continue
+		}
+
+		// 获取两条数据之间相差的天数
+		startDataTime, _ := time.ParseInLocation(utils.FormatDate, startEdbInfoData.DataTime, time.Local)
+		currDataTime, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
+		betweenHour := int(currDataTime.Sub(startDataTime).Hours())
+		betweenDay := betweenHour / 24
+
+		// 如果相差一天,那么过滤
+		if betweenDay <= 1 {
+			startEdbInfoData = v
+			continue
+		}
+
+		// 生成线性方程式
+		var a, b float64
+		{
+			coordinateData := make([]utils.Coordinate, 0)
+			tmpCoordinate1 := utils.Coordinate{
+				X: 1,
+				Y: startEdbInfoData.Value,
+			}
+			coordinateData = append(coordinateData, tmpCoordinate1)
+			tmpCoordinate2 := utils.Coordinate{
+				X: float64(betweenDay) + 1,
+				Y: v.Value,
+			}
+			coordinateData = append(coordinateData, tmpCoordinate2)
+
+			a, b = utils.GetLinearResult(coordinateData)
+			if math.IsNaN(a) || math.IsNaN(b) {
+				err = errors.New("线性方程公式生成失败")
+				return
+			}
+		}
+
+		// 生成对应的值
+		{
+			for i := 1; i < betweenDay; i++ {
+				tmpDataTime := startDataTime.AddDate(0, 0, i)
+				aDecimal := decimal.NewFromFloat(a)
+				xDecimal := decimal.NewFromInt(int64(i) + 1)
+				bDecimal := decimal.NewFromFloat(b)
+
+				val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).Round(4).Float64()
+				handleDataMap[tmpDataTime.Format(utils.FormatDate)] = val
+				dataTimeList = append(dataTimeList, tmpDataTime.Format(utils.FormatDate))
+				valueList = append(valueList, val)
+			}
+		}
+
+		startEdbInfoData = v
+	}
+
+	return
+}

+ 50 - 42
services/data/edb_info_relation.go

@@ -339,7 +339,7 @@ func SaveCalendarEdbInfoRelation(chartPermissionId int, matterDate string, editM
 }
 
 // GetEdbRelationList 获取指标引用列表
-func GetEdbRelationList(source int, classifyId, sysUserId, frequency, keyword, status string, startSize, pageSize int, sortParam, sortType string) (total int, list []*data_manage.BaseRelationEdbInfo, err error) {
+func GetEdbRelationList(source, edbInfoType int, classifyId, sysUserId, frequency, keyword, status string, startSize, pageSize int, sortParam, sortType string) (total int, list []*data_manage.BaseRelationEdbInfo, err error) {
 	var pars []interface{}
 	var condition string
 
@@ -356,57 +356,65 @@ func GetEdbRelationList(source int, classifyId, sysUserId, frequency, keyword, s
 	case utils.DATA_SOURCE_MYSTEEL_CHEMICAL, utils.DATA_SOURCE_WIND:
 		condition += ` AND e.source = ? `
 		pars = append(pars, source)
+	}
 
-		if isStop >= 0 {
-			condition += " AND e.no_update = ? "
-			pars = append(pars, isStop)
-		}
+	if edbInfoType == 1 { //预测指标
+		condition += ` AND e.edb_info_type = ? `
+		pars = append(pars, edbInfoType)
+	} else if edbInfoType == 2 { //计算指标
+		condition += ` AND e.edb_type = ? `
+		pars = append(pars, edbInfoType)
+	}
 
-		if classifyId != `` {
-			classifyIdSlice := strings.Split(classifyId, ",")
-			condition += ` AND e.classify_id IN (` + utils.GetOrmInReplace(len(classifyIdSlice)) + `)`
-			pars = append(pars, classifyIdSlice)
-		}
-		if sysUserId != `` {
-			sysUserIdSlice := strings.Split(sysUserId, ",")
-			condition += ` AND e.sys_user_id IN (` + utils.GetOrmInReplace(len(sysUserIdSlice)) + `)`
-			pars = append(pars, sysUserIdSlice)
-		}
-		if frequency != `` {
-			frequencySlice := strings.Split(frequency, ",")
-			condition += ` AND e.frequency IN (` + utils.GetOrmInReplace(len(frequencySlice)) + `)`
-			pars = append(pars, frequencySlice)
-		}
-		if keyword != `` {
-			keywordSlice := strings.Split(keyword, " ")
-			if len(keywordSlice) > 0 {
-				tmpConditionSlice := make([]string, 0)
-				tmpConditionSlice = append(tmpConditionSlice, ` e.edb_name like ? or e.edb_code like ? `)
-				pars = utils.GetLikeKeywordPars(pars, keyword, 2)
+	if isStop >= 0 {
+		condition += " AND e.no_update = ? "
+		pars = append(pars, isStop)
+	}
 
-				for _, v := range keywordSlice {
-					if v == ` ` || v == `` {
-						continue
-					}
-					tmpConditionSlice = append(tmpConditionSlice, ` e.edb_name like ? or e.edb_code like ? `)
-					pars = utils.GetLikeKeywordPars(pars, v, 2)
-				}
-				condition += ` AND (` + strings.Join(tmpConditionSlice, " or ") + `)`
+	if classifyId != `` {
+		classifyIdSlice := strings.Split(classifyId, ",")
+		condition += ` AND e.classify_id IN (` + utils.GetOrmInReplace(len(classifyIdSlice)) + `)`
+		pars = append(pars, classifyIdSlice)
+	}
+	if sysUserId != `` {
+		sysUserIdSlice := strings.Split(sysUserId, ",")
+		condition += ` AND e.sys_user_id IN (` + utils.GetOrmInReplace(len(sysUserIdSlice)) + `)`
+		pars = append(pars, sysUserIdSlice)
+	}
+	if frequency != `` {
+		frequencySlice := strings.Split(frequency, ",")
+		condition += ` AND e.frequency IN (` + utils.GetOrmInReplace(len(frequencySlice)) + `)`
+		pars = append(pars, frequencySlice)
+	}
+	if keyword != `` {
+		keywordSlice := strings.Split(keyword, " ")
+		if len(keywordSlice) > 0 {
+			tmpConditionSlice := make([]string, 0)
+			tmpConditionSlice = append(tmpConditionSlice, ` e.edb_name like ? or e.edb_code like ? `)
+			pars = utils.GetLikeKeywordPars(pars, keyword, 2)
 
-			} else {
-				condition += ` AND (e.edb_name like ? or e.edb_code like ? )`
-				pars = utils.GetLikeKeywordPars(pars, keyword, 2)
+			for _, v := range keywordSlice {
+				if v == ` ` || v == `` {
+					continue
+				}
+				tmpConditionSlice = append(tmpConditionSlice, ` e.edb_name like ? or e.edb_code like ? `)
+				pars = utils.GetLikeKeywordPars(pars, v, 2)
 			}
-		}
+			condition += ` AND (` + strings.Join(tmpConditionSlice, " or ") + `)`
 
-		sortStr := ``
-		if sortParam != `` {
-			sortStr = fmt.Sprintf("%s %s,e.edb_info_id desc ", sortParam, sortType)
+		} else {
+			condition += ` AND (e.edb_name like ? or e.edb_code like ? )`
+			pars = utils.GetLikeKeywordPars(pars, keyword, 2)
 		}
+	}
 
-		total, list, err = data_manage.GetEdbInfoRelationList(condition, pars, sortStr, startSize, pageSize)
+	sortStr := ``
+	if sortParam != `` {
+		sortStr = fmt.Sprintf("%s %s,e.edb_info_id desc ", sortParam, sortType)
 	}
 
+	total, list, err = data_manage.GetEdbInfoRelationList(condition, pars, sortStr, startSize, pageSize)
+
 	return
 }
 

+ 1 - 0
utils/constants.go

@@ -310,6 +310,7 @@ const (
 // 图表样式类型
 const (
 	CHART_TYPE_CURVE           = 1  //曲线图
+	CHART_TYPE_SEASON          = 2  //季节性图
 	CHART_TYPE_BAR             = 7  //柱形图
 	CHART_TYPE_SECTION_SCATTER = 10 //截面散点图样式
 	CHART_TYPE_RADAR           = 11 //雷达图