Browse Source

Merge branch 'feature/api_v1_edb' into debug

hsun 1 year ago
parent
commit
3a9b9d4cf8

+ 2 - 1
.gitignore

@@ -6,8 +6,9 @@
 /routers/commentsRouter_controllers.go
 /*.tmp
 /eta_hub
-/eta_hub.exe
+/*.exe
 /binlog/*.log
 /static/file/*
 .DS_Store
 /app.conf
+/*.tar.gz

+ 6 - 0
controllers/base_auth.go

@@ -100,6 +100,12 @@ func (c *BaseAuthController) ServeJSON(encoding ...bool) {
 		//if baseRes.Ret != 200 && baseRes.IsSendEmail {
 		//	go utils.SendEmail(utils.APP_NAME_CN+"【"+utils.RunMode+"】"+"失败提醒", "URI:"+c.Ctx.Input.URI()+"<br/> "+"Params"+requestBody+" <br/>"+"ErrMsg:"+baseRes.ErrMsg+";<br/>Msg:"+baseRes.Msg+";<br/> Body:"+string(body)+"<br/>", utils.EmailSendToUsers)
 		//}
+
+		// 记录错误日志, 并清掉错误信息避免暴露给外部
+		if baseRes.ErrMsg != "" {
+			utils.FileLog.Info(baseRes.ErrMsg)
+			baseRes.ErrMsg = ""
+		}
 	}
 	c.JSON(c.Data["json"], hasIndent, hasEncoding)
 }

+ 160 - 0
controllers/chart.go

@@ -0,0 +1,160 @@
+package controllers
+
+import (
+	"eta/eta_hub/models"
+	"eta/eta_hub/models/data_manage"
+	"eta/eta_hub/services"
+	"eta/eta_hub/utils"
+)
+
+// ChartController 图表
+type ChartController struct {
+	BaseAuthController
+}
+
+// ClassifyList
+// @Title 分类列表
+// @Description 分类列表
+// @Success 200 {object} data_manage.ChartClassifyItem
+// @router /classify/list [get]
+func (this *ChartController) ClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	source := utils.CHART_SOURCE_DEFAULT
+	cond := ` AND source = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, source)
+
+	classifyOb := new(data_manage.ChartClassify)
+	classifies, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, "parent_id ASC, sort ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "ChartClassifyList GetItemsByCondition err: " + e.Error()
+		return
+	}
+	resp := make([]*data_manage.ChartClassifyItem, 0)
+	for _, v := range classifies {
+		resp = append(resp, data_manage.FormatChartClassify2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// ClassifyTree
+// @Title 图库分类树
+// @Description 图库分类树
+// @Success 200 {object} data_manage.ChartClassifyItem
+// @router /classify/tree [get]
+func (this *ChartController) ClassifyTree() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	// 获取所有分类
+	classifyOb := new(data_manage.ChartClassify)
+	cond := ` AND source = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, utils.CHART_SOURCE_DEFAULT)
+	classifies, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, "sort ASC, parent_id ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "ChartClassifyTree GetItemsByCondition err: " + e.Error()
+		return
+	}
+
+	// 递归生成分类树
+	classifyTree := services.GetChartClassifyTreeRecursive(classifies, 0)
+
+	br.Data = classifyTree
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// List
+// @Title 图表列表
+// @Description 图表列表
+// @Param   ClassifyId  query  int  true  "图表分类ID"
+// @Success 200 {object} data_manage.ChartInfoItem
+// @router /list [get]
+func (this *ChartController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId <= 0 {
+		br.Msg = "参数有误"
+		return
+	}
+
+	chartOb := new(data_manage.ChartInfo)
+	cond := ` AND chart_classify_id = ? AND source = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, classifyId, utils.CHART_SOURCE_DEFAULT)
+	charts, e := chartOb.GetItemsByCondition(cond, pars, []string{}, "sort ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "ChartList GetItemsByCondition err: " + e.Error()
+		return
+	}
+	resp := make([]*data_manage.ChartInfoItem, 0)
+	for _, v := range charts {
+		resp = append(resp, data_manage.FormatChartInfo2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// Detail
+// @Title 图表详情
+// @Description 图表详情(这个接口的意义不大, 拿到数据也没啥用=_=!)
+// @Success 200 {object} models.Report
+// @router /detail [get]
+//func (this *ChartController) Detail() {
+//	br := new(models.BaseResponse).Init()
+//	defer func() {
+//		this.Data["json"] = br
+//		this.ServeJSON()
+//	}()
+//
+//	unicode := this.GetString("UniqueCode")
+//	if unicode == "" {
+//		br.Msg = "参数有误"
+//		return
+//	}
+//	chartOb := new(data_manage.ChartInfo)
+//	_, e := chartOb.GetItemByCode(unicode)
+//	if e != nil {
+//		if e.Error() == utils.ErrNoRow() {
+//			br.Msg = "图表不存在"
+//			return
+//		}
+//		br.Msg = "获取失败"
+//		br.ErrMsg = "ChartDetail GetItemByCode err: " + e.Error()
+//		return
+//	}
+//
+//	// 从edb_chart_lib中获取图详情, 这边只做部分数据的返回
+//	detail, e := services.GetChartDetailFromChartLibByUnicode(unicode)
+//	if e != nil {
+//		br.Msg = "获取失败"
+//		br.ErrMsg = "ChartDetail GetChartDetailFromChartLibByUnicode err: " + e.Error()
+//		return
+//	}
+//
+//	br.Data = detail
+//	br.Ret = 200
+//	br.Msg = "获取成功"
+//}

+ 200 - 0
controllers/edb.go

@@ -0,0 +1,200 @@
+package controllers
+
+import (
+	"eta/eta_hub/models"
+	"eta/eta_hub/models/data_manage"
+	"eta/eta_hub/services"
+	"eta/eta_hub/utils"
+)
+
+// EdbController 指标
+type EdbController struct {
+	BaseAuthController
+}
+
+// SourceList
+// @Title 指标来源
+// @Description 指标来源
+// @Success 200 {object} data_manage.EdbSourceItem
+// @router /source/list [get]
+func (this *EdbController) SourceList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sources, e := data_manage.GetEdbSourceItemsByCondition(``, make([]interface{}, 0), []string{}, "")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "SourceList GetEdbSourceItemsByCondition err: " + e.Error()
+		return
+	}
+	resp := make([]*data_manage.EdbSourceItem, 0)
+	for _, v := range sources {
+		resp = append(resp, data_manage.FormatEdbSource2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// ClassifyList
+// @Title 指标分类列表
+// @Description 指标分类列表
+// @Param   ClassifyType  query  int  false  "分类类型: 0-普通指标; 1-预测指标"
+// @Success 200 {object} data_manage.EdbClassifyItem
+// @router /classify/list [get]
+func (this *EdbController) ClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	classifyType, _ := this.GetInt("ClassifyType", 0)
+	cond := ` AND classify_type = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, classifyType)
+
+	// 获取所有分类
+	classifyOb := new(data_manage.EdbClassify)
+	classifies, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, "parent_id ASC, sort ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "ClassifyTree GetItemsByCondition err: " + e.Error()
+		return
+	}
+
+	resp := make([]*data_manage.EdbClassifyItem, 0)
+	for _, v := range classifies {
+		resp = append(resp, data_manage.FormatEdbClassify2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// ClassifyTree
+// @Title 指标分类树
+// @Description 指标分类树
+// @Param   ClassifyType  query  int  false  "分类类型: 0-普通指标; 1-预测指标"
+// @Success 200 {object} data_manage.EdbClassifyItem
+// @router /classify/tree [get]
+func (this *EdbController) ClassifyTree() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	classifyType, _ := this.GetInt("ClassifyType", 0)
+	cond := ` AND classify_type = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, classifyType)
+
+	// 获取所有分类
+	classifyOb := new(data_manage.EdbClassify)
+	classifies, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, "sort ASC, parent_id ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "EdbClassifyTree GetItemsByCondition err: " + e.Error()
+		return
+	}
+
+	// 递归生成分类树
+	classifyTree := services.GetEdbClassifyTreeRecursive(classifies, 0)
+
+	br.Data = classifyTree
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// List
+// @Title 指标列表
+// @Description 指标列表
+// @Param   ClassifyId  query  int  true  "指标分类ID"
+// @Success 200 {object} data_manage.EdbInfoItem
+// @router /list [get]
+func (this *EdbController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId <= 0 {
+		br.Msg = "参数有误"
+		return
+	}
+
+	edbOb := new(data_manage.EdbInfo)
+	cond := ` AND classify_id = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, classifyId)
+	edbList, e := edbOb.GetItemsByCondition(cond, pars, []string{}, "sort ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "EdbList GetItemsByCondition err: " + e.Error()
+		return
+	}
+	resp := make([]*data_manage.EdbInfoItem, 0)
+	for _, v := range edbList {
+		resp = append(resp, data_manage.FormatEdbInfo2Item(v, make([]*data_manage.EdbDataItem, 0)))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// Detail
+// @Title 指标详情
+// @Description 指标详情
+// @Success 200 {object} data_manage.EdbInfoItem
+// @router /detail [get]
+func (this *EdbController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	unicode := this.GetString("UniqueCode")
+	if unicode == "" {
+		br.Msg = "参数有误"
+		return
+	}
+	edbOb := new(data_manage.EdbInfo)
+	edb, e := edbOb.GetItemByUniCode(unicode)
+	if e != nil {
+		if e.Error() == utils.ErrNoRow() {
+			br.Msg = "指标不存在"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = "EdbDetail GetItemByCode err: " + e.Error()
+		return
+	}
+
+	// 获取指标数据
+	dataOb := new(data_manage.EdbData)
+	dataList, e := dataOb.GetItemsBySourceAndCode(edb.Source, edb.EdbCode, []string{}, "")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "EdbDetail GetItemsBySourceAndCode err: " + e.Error()
+		return
+	}
+	edbData := make([]*data_manage.EdbDataItem, 0)
+	for _, v := range dataList {
+		edbData = append(edbData, data_manage.FormatEdbData2Item(v))
+	}
+
+	resp := data_manage.FormatEdbInfo2Item(edb, edbData)
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}

+ 126 - 0
controllers/statistic_analysis.go

@@ -0,0 +1,126 @@
+package controllers
+
+import (
+	"eta/eta_hub/models"
+	"eta/eta_hub/models/data_manage"
+	"eta/eta_hub/utils"
+	"fmt"
+)
+
+// StatisticAnalysisController 统计分析
+type StatisticAnalysisController struct {
+	BaseAuthController
+}
+
+// ClassifyList
+// @Title 统计分析-分类列表
+// @Description 统计分析-分类列表
+// @Param   SourceType  query  int  false  "分类类型: 1-相关性分析; 2-拟合方程曲线; 3-统计特征"
+// @Success 200 {object} data_manage.ChartClassifyItem
+// @router /classify/list [get]
+func (this *StatisticAnalysisController) ClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sourceType, _ := this.GetInt("SourceType", 0)
+	if sourceType <= 0 {
+		sourceType = 1
+	}
+	sourceMap := map[int]int{
+		1: utils.CHART_SOURCE_CORRELATION,
+		2: utils.CHART_SOURCE_LINE_EQUATION,
+		3: utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION,
+	}
+	source := sourceMap[sourceType]
+	if source <= 0 {
+		br.Msg = "分类来源有误"
+		return
+	}
+	cond := ` AND source = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, source)
+
+	// 获取所有分类
+	classifyOb := new(data_manage.ChartClassify)
+	classifies, e := classifyOb.GetItemsByCondition(cond, pars, []string{}, "parent_id ASC, sort ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "ChartClassifyList GetItemsByCondition err: " + e.Error()
+		return
+	}
+	resp := make([]*data_manage.ChartClassifyItem, 0)
+	for _, v := range classifies {
+		resp = append(resp, data_manage.FormatChartClassify2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// ChartList
+// @Title 统计分析-图表列表
+// @Description 统计分析-图表列表
+// @Param   ClassifyId  query  int  true  "图表分类ID"
+// @Param   CorrelationType  query  int  false  "相关性图表类型: 1-相关性图表; 2-滚动相关性"
+// @Success 200 {object} data_manage.ChartInfoItem
+// @router /chart/list [get]
+func (this *StatisticAnalysisController) ChartList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	classifyId, _ := this.GetInt("ClassifyId")
+	if classifyId <= 0 {
+		br.Msg = "参数有误"
+		return
+	}
+	cond := ` AND chart_classify_id = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, classifyId)
+
+	// 相关性图表类型
+	correlationType, _ := this.GetInt("CorrelationType")
+	if correlationType > 0 {
+		correlationMap := map[int]int{
+			1: utils.CHART_SOURCE_CORRELATION,
+			2: utils.CHART_SOURCE_ROLLING_CORRELATION,
+		}
+		source := correlationMap[correlationType]
+		if source <= 0 {
+			br.Msg = "相关性图表类型有误"
+			return
+		}
+		cond += ` AND source = ?`
+		pars = append(pars, source)
+	} else {
+		// 默认统计分析的图表
+		sourceArr := []int{
+			utils.CHART_SOURCE_CORRELATION, utils.CHART_SOURCE_ROLLING_CORRELATION, utils.CHART_SOURCE_LINE_EQUATION,
+			utils.CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION, utils.CHART_SOURCE_LINE_FEATURE_PERCENTILE, utils.CHART_SOURCE_LINE_FEATURE_FREQUENCY,
+		}
+		cond += fmt.Sprintf(` AND source IN (%s)`, utils.GetOrmInReplace(len(sourceArr)))
+		pars = append(pars, sourceArr)
+	}
+
+	chartOb := new(data_manage.ChartInfo)
+	charts, e := chartOb.GetItemsByCondition(cond, pars, []string{}, "sort ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "ClassifyChart GetItemsByCondition err: " + e.Error()
+		return
+	}
+	resp := make([]*data_manage.ChartInfoItem, 0)
+	for _, v := range charts {
+		resp = append(resp, data_manage.FormatChartInfo2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}

+ 132 - 0
controllers/supply_analysis.go

@@ -0,0 +1,132 @@
+package controllers
+
+import (
+	"eta/eta_hub/models"
+	"eta/eta_hub/models/data_manage"
+	"eta/eta_hub/utils"
+)
+
+// SupplyAnalysisController 供应分析
+type SupplyAnalysisController struct {
+	BaseAuthController
+}
+
+// StockPlantVarietyList
+// @Title 装置检修-品种分类
+// @Description 装置检修-品种分类
+// @Success 200 {object} data_manage.VarietyItem
+// @router /stock_plant/variety/list [get]
+func (this *SupplyAnalysisController) StockPlantVarietyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	varietyOb := new(data_manage.Variety)
+	cond := ``
+	pars := make([]interface{}, 0)
+	list, e := varietyOb.GetItemsByCondition(cond, pars, []string{}, "create_time ASC")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "StockPlantVarietyList GetItemsByCondition err: " + e.Error()
+		return
+	}
+
+	resp := make([]*data_manage.VarietyItem, 0)
+	for _, v := range list {
+		resp = append(resp, data_manage.FormatVariety2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// StockPlantEdbList
+// @Title 装置检修-指标列表
+// @Description 装置检修-指标列表
+// @Param   VarietyId  query  int  false  "品种ID"
+// @Success 200 {object} data_manage.ChartInfoItem
+// @router /stock_plant/edb/list [get]
+func (this *SupplyAnalysisController) StockPlantEdbList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	varietyId, _ := this.GetInt("VarietyId", 0)
+
+	// 只取加入指标库中的
+	cond := ` AND edb_info_id > 0`
+	pars := make([]interface{}, 0)
+	if varietyId > 0 {
+		cond += ` AND variety_id = ?`
+		pars = append(pars, varietyId)
+	}
+	edbOb := new(data_manage.VarietyEdbInfo)
+	list, e := edbOb.GetItemsByCondition(cond, pars, []string{}, "")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "StockPlantEdbList GetItemsByCondition err: " + e.Error()
+		return
+	}
+
+	resp := make([]*data_manage.VarietyEdbInfoItem, 0)
+	for _, v := range list {
+		resp = append(resp, data_manage.FormatVarietyEdbInfo2Item(v))
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}
+
+// StockPlantEdbDetail
+// @Title 装置检修-指标详情
+// @Description 装置检修-指标详情
+// @Param   EdbCode  query  string  true  "指标编码"
+// @Success 200 {object} data_manage.EdbInfoItem
+// @router /stock_plant/edb/detail [get]
+func (this *SupplyAnalysisController) StockPlantEdbDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	edbCode := this.GetString("EdbCode")
+	if edbCode == "" {
+		br.Msg = "参数有误"
+		return
+	}
+	edbOb := new(data_manage.EdbInfo)
+	edb, e := edbOb.GetItemByEdbCode(edbCode)
+	if e != nil {
+		if e.Error() == utils.ErrNoRow() {
+			br.Msg = "指标不存在"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = "StockPlantEdbDetail GetItemByCode err: " + e.Error()
+		return
+	}
+
+	// 获取指标数据
+	dataOb := new(data_manage.EdbData)
+	dataList, e := dataOb.GetItemsBySourceAndCode(edb.Source, edb.EdbCode, []string{}, "")
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "StockPlantEdbDetail GetItemsBySourceAndCode err: " + e.Error()
+		return
+	}
+	edbData := make([]*data_manage.EdbDataItem, 0)
+	for _, v := range dataList {
+		edbData = append(edbData, data_manage.FormatEdbData2Item(v))
+	}
+
+	resp := data_manage.FormatEdbInfo2Item(edb, edbData)
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "获取成功"
+}

+ 9 - 0
go.mod

@@ -6,6 +6,8 @@ require (
 	github.com/beego/bee/v2 v2.1.0
 	github.com/beego/beego/v2 v2.1.3
 	github.com/go-sql-driver/mysql v1.7.1
+	github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b
+	github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19
 	github.com/olivere/elastic/v7 v7.0.32
 	github.com/rdlucklib/rdluck_tools v1.0.3
 	github.com/shopspring/decimal v1.3.1
@@ -17,7 +19,14 @@ require (
 require (
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/garyburd/redigo v1.6.3 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
+	github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac // indirect
+	github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 // indirect
+	github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2 // indirect
+	github.com/gonum/internal v0.0.0-20181124074243-f884aa714029 // indirect
+	github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9 // indirect
+	github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9 // indirect
 	github.com/hashicorp/golang-lru v0.5.4 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect

+ 17 - 0
go.sum

@@ -36,6 +36,7 @@ github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo
 github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
 github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/garyburd/redigo v1.6.3 h1:HCeeRluvAgMusMomi1+6Y5dmFOdYV/JzoRrrbFlkGIc=
 github.com/garyburd/redigo v1.6.3/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw=
 github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -65,6 +66,20 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
 github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
+github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac h1:Q0Jsdxl5jbxouNs1TQYt0gxesYMU4VXRbsTlgDloZ50=
+github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc=
+github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 h1:EvokxLQsaaQjcWVWSV38221VAK7qc2zhaO17bKys/18=
+github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg=
+github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2 h1:GUSkTcIe1SlregbHNUKbYDhBsS8lNgYfIp4S4cToUyU=
+github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2/go.mod h1:pDgmNM6seYpwvPos3q+zxlXMsbve6mOIPucUnUOrI7Y=
+github.com/gonum/internal v0.0.0-20181124074243-f884aa714029 h1:8jtTdc+Nfj9AR+0soOeia9UZSvYBvETVHZrugUowJ7M=
+github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks=
+github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9 h1:7qnwS9+oeSiOIsiUMajT+0R7HR6hw5NegnKPmn/94oI=
+github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A=
+github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9 h1:V2IgdyerlBa/MxaEFRbV5juy/C3MGdj4ePi+g6ePIp4=
+github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw=
+github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b h1:fbskpz/cPqWH8VqkQ7LJghFkl2KPAiIFUHrTJ2O3RGk=
+github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b/go.mod h1:Z4GIJBJO3Wa4gD4vbwQxXXZ+WHmW6E9ixmNrwvs0iZs=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -105,6 +120,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19 h1:LhWT2dBuNkYexwRSsPpYh67e0ikmH1ebBDaVkGHoMts=
+github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19/go.mod h1:LjhyrWzOLJ9l1azMoNr9iCvfNrHEREqvJHzSLQcD0/o=
 github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=
 github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=

+ 85 - 0
models/data_manage/chart_classify.go

@@ -0,0 +1,85 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// ChartClassify 图表分类表
+type ChartClassify struct {
+	ChartClassifyId   int       `orm:"column(chart_classify_id);pk"`
+	ChartClassifyName string    `description:"分类名称"`
+	ParentId          int       `description:"父级id"`
+	HasData           int       `description:"是否含有指标数据"`
+	SysUserId         int       `description:"创建人id"`
+	SysUserRealName   string    `description:"创建人姓名"`
+	Level             int       `description:"层级"`
+	UniqueCode        string    `description:"唯一编码"`
+	Sort              int       `description:"排序字段,越小越靠前,默认值:10"`
+	Source            int       `description:"1:ETA图库;2:商品价格曲线"`
+	CreateTime        time.Time `description:"创建时间"`
+	ModifyTime        time.Time `description:"修改时间"`
+}
+
+func (m *ChartClassify) GetItemsByCondition(cond string, pars []interface{}, fieldArr []string, orderRule string) (items []*ChartClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM chart_classify WHERE 1=1 %s %s`, fields, cond, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// ChartClassifyItem 指标分类信息
+type ChartClassifyItem struct {
+	ClassifyId   int    `description:"分类ID"`
+	ClassifyName string `description:"分类名称"`
+	UniqueCode   string `description:"唯一编码"`
+	ParentId     int    `description:"父级ID"`
+	Level        int    `description:"层级"`
+	Sort         int    `description:"排序字段,越小越靠前,默认值:10"`
+	//Source       int                  `description:"1-ETA图库; 2-商品价格曲线"`
+	CreateTime string               `description:"创建时间"`
+	UpdateTime string               `description:"修改时间"`
+	Child      []*ChartClassifyItem `description:"子分类"`
+}
+
+func FormatChartClassify2Item(origin *ChartClassify) (item *ChartClassifyItem) {
+	if origin == nil {
+		return
+	}
+	item = new(ChartClassifyItem)
+	item.ClassifyId = origin.ChartClassifyId
+	item.ClassifyName = origin.ChartClassifyName
+	item.UniqueCode = origin.UniqueCode
+	item.ParentId = origin.ParentId
+	item.Level = origin.Level
+	item.Sort = origin.Sort
+	//item.Source = origin.Source
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.UpdateTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	item.Child = make([]*ChartClassifyItem, 0)
+	return
+}
+
+type ChartClassifyView struct {
+	ChartClassifyId   int    `description:"图表分类"`
+	ChartClassifyName string `description:"分类名称"`
+	ParentId          int    `description:"父级ID"`
+}
+
+func GetChartClassifyViewById(classifyId int) (item *ChartClassifyView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_classify WHERE chart_classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}

+ 47 - 0
models/data_manage/chart_edb_mapping.go

@@ -0,0 +1,47 @@
+package data_manage
+
+type ChartEdbInfoMapping struct {
+	EdbInfoId           int     `description:"指标id"`
+	SourceName          string  `description:"来源名称"`
+	Source              int     `description:"来源id"`
+	EdbCode             string  `description:"指标编码"`
+	EdbName             string  `description:"指标名称"`
+	EdbAliasName        string  `description:"指标名称(别名)"`
+	EdbNameEn           string  `description:"英文指标名称"`
+	EdbAliasNameEn      string  `description:"英文指标名称(别名)"`
+	EdbType             int     `description:"指标类型:1:基础指标,2:计算指标"`
+	Frequency           string  `description:"频率"`
+	FrequencyEn         string  `description:"英文频率"`
+	Unit                string  `description:"单位"`
+	UnitEn              string  `description:"英文单位"`
+	StartDate           string  `description:"起始日期"`
+	EndDate             string  `description:"终止日期"`
+	ModifyTime          string  `description:"指标最后更新时间"`
+	ChartEdbMappingId   int     `description:"图表指标id"`
+	ChartInfoId         int     `description:"图表id"`
+	MaxData             float64 `description:"上限"`
+	MinData             float64 `description:"下限"`
+	IsOrder             bool    `description:"true:正序,false:逆序"`
+	IsAxis              int     `description:"1:左轴,0:右轴"`
+	EdbInfoType         int     `description:"1:标准指标,0:领先指标"`
+	EdbInfoCategoryType int     `description:"0:普通指标,1:预测指标"`
+	LeadValue           int     `description:"领先值"`
+	LeadUnit            string  `description:"领先单位"`
+	LeadUnitEn          string  `description:"领先英文单位"`
+	ChartStyle          string  `description:"图表类型"`
+	ChartColor          string  `description:"颜色"`
+	PredictChartColor   string  `description:"预测数据的颜色"`
+	ChartWidth          float64 `description:"线条大小"`
+	ChartType           int     `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图"`
+	LatestDate          string  `description:"数据最新日期"`
+	LatestValue         float64 `description:"数据最新值"`
+	MoveLatestDate      string  `description:"移动后的数据最新日期"`
+	UniqueCode          string  `description:"指标唯一编码"`
+	MinValue            float64 `json:"-" description:"最小值"`
+	MaxValue            float64 `json:"-" description:"最大值"`
+	DataList            interface{}
+	IsNullData          bool   `json:"-" description:"是否空数据"`
+	MappingSource       int    `description:"1:ETA图库;2:商品价格曲线"`
+	RegionType          string `description:"交易所来源,海外还是国内" json:"-"`
+	ClassifyId          int    `description:"分类id"`
+}

+ 451 - 0
models/data_manage/chart_info.go

@@ -0,0 +1,451 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// ChartInfo 图库主表
+type ChartInfo struct {
+	ChartInfoId       int       `orm:"column(chart_info_id);pk"`
+	ChartName         string    `description:"来源名称"`
+	ChartNameEn       string    `description:"英文图表名称"`
+	ChartClassifyId   int       `description:"图表分类id"`
+	SysUserId         int       `description:"创建人ID"`
+	SysUserRealName   string    `description:"创建人姓名"`
+	UniqueCode        string    `description:"图表唯一编码"`
+	DateType          int       `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate         string    `description:"自定义开始日期"`
+	EndDate           string    `description:"自定义结束日期"`
+	IsSetName         int       `description:"设置名称"`
+	EdbInfoIds        string    `description:"指标id"`
+	ChartType         int       `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图"`
+	Calendar          string    `description:"公历/农历"`
+	SeasonStartDate   string    `description:"季节性图开始日期"`
+	SeasonEndDate     string    `description:"季节性图开始日期"`
+	ChartImage        string    `description:"图表图片"`
+	Sort              int       `description:"排序字段,数字越小越排前面"`
+	LeftMin           string    `description:"图表左侧最小值"`
+	LeftMax           string    `description:"图表左侧最大值"`
+	RightMin          string    `description:"图表右侧最小值"`
+	RightMax          string    `description:"图表右侧最大值"`
+	Disabled          int       `description:"是否禁用,0:启用,1:禁用,默认:0"`
+	BarConfig         string    `description:"柱方图的配置,json数据"`
+	Source            int       `description:"1:ETA图库;2:商品价格曲线"`
+	ExtraConfig       string    `description:"图表额外配置,json数据"`
+	SeasonExtraConfig string    `description:"季节性图表中的配置,json数据"`
+	StartYear         int       `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+	CreateTime        time.Time `description:"创建时间"`
+	ModifyTime        time.Time `description:"更新时间"`
+}
+
+func (m *ChartInfo) GetItemsByCondition(cond string, pars []interface{}, fieldArr []string, orderRule string) (items []*ChartInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM chart_info WHERE 1=1 %s %s`, fields, cond, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func (m *ChartInfo) GetItemByCode(code string) (item *ChartInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT * FROM chart_info WHERE unique_code = ? LIMIT 1`)
+	err = o.Raw(sql, code).QueryRow(&item)
+	return
+}
+
+// ChartInfoItem 图表信息
+type ChartInfoItem struct {
+	ChartInfoId       int    `description:"图表ID"`
+	ChartName         string `description:"来源名称"`
+	ChartNameEn       string `description:"英文图表名称"`
+	ChartClassifyId   int    `description:"图表分类id"`
+	UniqueCode        string `description:"图表唯一编码"`
+	DateType          int    `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间" json:"-"`
+	StartDate         string `description:"自定义开始日期"`
+	EndDate           string `description:"自定义结束日期"`
+	ChartType         int    `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图"`
+	Calendar          string `description:"公历/农历"`
+	SeasonStartDate   string `description:"季节性图开始日期" json:"-"`
+	SeasonEndDate     string `description:"季节性图开始日期" json:"-"`
+	ChartImage        string `description:"图表图片"`
+	Sort              int    `description:"排序字段,数字越小越排前面"`
+	LeftMin           string `description:"图表左侧最小值" json:"-"`
+	LeftMax           string `description:"图表左侧最大值" json:"-"`
+	RightMin          string `description:"图表右侧最小值" json:"-"`
+	RightMax          string `description:"图表右侧最大值" json:"-"`
+	BarConfig         string `description:"柱方图的配置,json数据" json:"-"`
+	Source            int    `description:"1:ETA图库;2:商品价格曲线" json:"-"`
+	ExtraConfig       string `description:"图表额外配置,json数据" json:"-"`
+	SeasonExtraConfig string `description:"季节性图表中的配置,json数据" json:"-"`
+	StartYear         int    `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N" json:"-"`
+	CreateTime        string `description:"创建时间"`
+	ModifyTime        string `description:"更新时间"`
+}
+
+func FormatChartInfo2Item(origin *ChartInfo) (item *ChartInfoItem) {
+	if origin == nil {
+		return
+	}
+	item = new(ChartInfoItem)
+	item.ChartInfoId = origin.ChartInfoId
+	item.ChartName = origin.ChartName
+	item.ChartNameEn = origin.ChartNameEn
+	item.ChartClassifyId = origin.ChartClassifyId
+	item.UniqueCode = origin.UniqueCode
+	item.DateType = origin.DateType
+	item.StartDate = origin.StartDate
+	item.EndDate = origin.EndDate
+	item.ChartType = origin.ChartType
+	item.Calendar = origin.Calendar
+	item.SeasonStartDate = origin.SeasonStartDate
+	item.SeasonEndDate = origin.SeasonEndDate
+	item.ChartImage = origin.ChartImage
+	item.Sort = origin.Sort
+	item.LeftMin = origin.LeftMin
+	item.LeftMax = origin.LeftMax
+	item.RightMin = origin.RightMin
+	item.RightMax = origin.RightMax
+	item.BarConfig = origin.BarConfig
+	item.Source = origin.Source
+	item.ExtraConfig = origin.ExtraConfig
+	item.SeasonExtraConfig = origin.SeasonExtraConfig
+	item.StartYear = origin.StartYear
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	return
+}
+
+type ChartInfoDetailResp struct {
+	ChartInfo            *ChartInfo             `description:"图表信息"`
+	Status               bool                   `description:"true:图表存在,false:图表不存在" json:"-"`
+	EdbInfoList          []*ChartEdbInfoMapping `description:"指标信息"`
+	XEdbIdValue          []int                  `description:"柱方图的x轴数据,指标id"`
+	YDataList            []YData                `description:"柱方图的y轴数据"`
+	XDataList            []XData                `description:"商品价格曲线的X轴数据"`
+	BarChartInfo         BarChartInfoReq        `description:"柱方图的配置"`
+	CorrelationChartInfo *CorrelationInfo       `description:"相关性图表信息"`
+	DataResp             interface{}            `description:"图表数据,根据图的类型而定的,没有确定的数据格式"`
+}
+
+// XData 商品价格曲线的的x轴数据
+type XData struct {
+	Name   string `description:"别名"`
+	NameEn string `description:"英文别名"`
+}
+
+// YData 柱方图的y轴数据
+type YData struct {
+	Date           string          `description:"数据日期"`
+	ConfigDate     time.Time       `description:"配置的日期" json:"-"`
+	Color          string          `description:"数据颜色"`
+	Name           string          `description:"别名"`
+	NameEn         string          `description:"英文别名"`
+	Value          []float64       `description:"每个指标的值"`
+	NoDataEdbList  []int           `description:"没有数据的指标列表"`
+	XEdbInfoIdList []int           `description:"对应X轴的指标id列表"`
+	NameList       []string        `description:"每个值对应的名称"`
+	EnNameList     []string        `description:"每个值对应的英文名称"`
+	EdbValMap      map[int]float64 `description:"指标与值的对应" json:"-"`
+	M              []int           `description:"对应开始日期的间隔值" json:"-"`
+	Unit           string          `description:"中文单位名称"`
+	UnitEn         string          `description:"英文单位名称"`
+}
+
+// BarChartInfoReq 柱方图预览请求数据
+type BarChartInfoReq struct {
+	EdbInfoIdList []BarChartInfoEdbItemReq `description:"指标信息"`
+	DateList      []BarChartInfoDateReq    `description:"日期配置"`
+	Sort          BarChartInfoSortReq      `description:"排序"`
+	XEdbList      []BarChartInfoEdbItemReq `description:"X轴选择的指标列表"`
+	YEdbList      []BarChartInfoEdbItemReq `description:"Y轴选择的指标列表"`
+	Unit          string                   `description:"中文单位"`
+	UnitEn        string                   `description:"英文单位"`
+}
+
+// BarChartInfoEdbItemReq 柱方图预览请求数据(指标相关)
+type BarChartInfoEdbItemReq struct {
+	EdbInfoId int    `description:"指标ID"`
+	Name      string `description:"别名"`
+	NameEn    string `description:"英文别名"`
+	Source    int    `description:"1:ETA图库;2:商品价格"`
+}
+
+// BarChartInfoDateReq 柱方图预览请求数据(日期相关)
+type BarChartInfoDateReq struct {
+	Type  int    `description:"配置类型"`
+	Date  string `description:"固定日期"`
+	Value int    `description:"N天的值"`
+	Color string `description:"颜色"`
+	Name  string `description:"别名"`
+}
+
+// BarChartInfoSortReq 柱方图预览请求数据(排序相关)
+type BarChartInfoSortReq struct {
+	Sort      int `description:"排序类型,0:默认,1:升序,2:降序"`
+	DateIndex int `description:"日期数据的下标,从0开始"`
+}
+
+type CorrelationInfo struct {
+	LeadValue       int    `description:"领先值"`
+	LeadUnit        string `description:"领先单位"`
+	CalculateValue  int    `description:"计算窗口"`
+	CalculateUnit   string `description:"计算频度"`
+	StartDate       string `description:"开始日期"`
+	EndDate         string `description:"结束日期"`
+	EdbInfoIdFirst  int    `description:"A指标ID"`
+	EdbInfoIdSecond int    `description:"B指标ID"`
+	PeriodData      string `description:"X轴-期数数据"`
+	CorrelationData string `description:"Y轴-相关性系数"`
+}
+
+type ChartInfoView struct {
+	ChartInfoId       int    `orm:"column(chart_info_id);pk"`
+	ChartName         string `description:"来源名称"`
+	ChartNameEn       string `description:"英文图表名称"`
+	Unit              string `description:"中文单位名称"`
+	UnitEn            string `description:"英文单位名称"`
+	ChartClassifyId   int    `description:"图表分类id"`
+	ChartClassifyName string `description:"图表名称"`
+	SysUserId         int
+	SysUserRealName   string
+	UniqueCode        string `description:"图表唯一编码"`
+	CreateTime        time.Time
+	ModifyTime        time.Time
+	DateType          int    `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate         string `description:"自定义开始日期"`
+	EndDate           string `description:"自定义结束日期"`
+	IsSetName         int    `description:"设置名称"`
+	EdbInfoIds        string `description:"指标id"`
+	ChartType         int    `description:"生成样式:1:曲线图,2:季节性图"`
+	Calendar          string `description:"公历/农历"`
+	SeasonStartDate   string `description:"季节性图开始日期"`
+	SeasonEndDate     string `description:"季节性图开始日期"`
+	ChartImage        string `description:"图表图片"`
+	Sort              int    `description:"排序字段,数字越小越排前面"`
+	IsAdd             bool   `description:"true:已加入我的图库,false:未加入我的图库"`
+	MyChartId         int
+	MyChartClassifyId string `description:"我的图表分类,多个用逗号隔开"`
+	ChartClassify     []*ChartClassifyView
+	EdbEndDate        string `description:"指标最新更新日期"`
+	LeftMin           string `description:"图表左侧最小值"`
+	LeftMax           string `description:"图表左侧最大值"`
+	RightMin          string `description:"图表右侧最小值"`
+	RightMax          string `description:"图表右侧最大值"`
+	IsEdit            bool   `description:"是否有编辑权限"`
+	IsEnChart         bool   `description:"是否展示英文标识"`
+	WarnMsg           string `description:"错误信息"`
+	Disabled          int    `description:"是否禁用,0:启用,1:禁用,默认:0"`
+	BarConfig         string `description:"柱方图的配置,json数据" json:"-"`
+	Source            int    `description:"1:ETA图库;2:商品价格曲线;3:相关性图表"`
+	//CorrelationLeadUnit string `description:"相关性图表-领先单位"`
+	ExtraConfig       string          `description:"图表额外配置,json数据"`
+	Button            ChartViewButton `description:"操作按钮" json:"-"`
+	SeasonExtraConfig string          `description:"季节性图表中的配置,json数据"`
+	StartYear         int             `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+}
+
+type ChartViewButton struct {
+	IsEdit    bool `description:"是否有编辑权限"`
+	IsEnChart bool `description:"是否展示英文标识"`
+	IsAdd     bool `description:"true:已加入我的图库,false:未加入我的图库"`
+	IsCopy    bool `description:"是否有另存为按钮"`
+	IsSetName int  `description:"设置名称"`
+}
+
+// SectionScatterReq 截面散点请求
+//type SectionScatterReq 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轴的最大值"`
+//	//EdbList     []SectionScatterEdbItemReq    `description:"指标数据"`
+//	SeriesList []SectionScatterSeriesItemReq `description:"系列数据"`
+//}
+
+// SectionScatterSeriesItemReq 系列的请求
+//type SectionScatterSeriesItemReq struct {
+//	Name            string `description:"系列名"`
+//	NameEn          string `description:"系列名(英文名)"`
+//	IsNameDefault   bool   `description:"是否使用默认的系列名 false修改过 true默认  影响自动更新"`
+//	Color           string `description:"颜色"`
+//	EdbInfoList     []SectionScatterEdbItemReq
+//	ShowTrendLine   bool `description:"是否展示趋势线"`
+//	ShowFitEquation bool `description:"是否展示方程式"`
+//	ShowRSquare     bool `description:"是否展示R平方"`
+//}
+
+// SectionScatterEdbItemReq 截面散点请求的指标
+//type SectionScatterEdbItemReq struct {
+//	XEdbInfoId int    `description:"X轴的指标ID"`
+//	YEdbInfoId int    `description:"Y轴的指标ID"`
+//	Name       string `description:"别名"`
+//	NameEn     string `description:"英文别名"`
+//	XDateType  int    `description:"X轴的日期配置类型"`
+//	XDate      string `description:"X轴的日期固定日期"`
+//	XDateValue int    `description:"X轴的日期N天的值"`
+//	YDateType  int    `description:"Y轴的日期配置类型"`
+//	YDate      string `description:"Y轴的日期固定日期"`
+//	YDateValue int    `description:"Y轴的日期N天的值"`
+//	IsShow     bool   `description:"是否展示"`
+//}
+
+// SectionScatterInfoResp 截面散点图数据
+//type SectionScatterInfoResp 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:"系列名(英文)"`
+//	IsNameDefault   bool   `description:"是否使用默认的系列名 false修改过 true默认  影响自动更新"`
+//	Color           string `description:"颜色"`
+//	EdbInfoList     []SectionScatterEdbItemResp
+//	ShowTrendLine   bool              `description:"是否展示趋势线"`
+//	ShowFitEquation bool              `description:"是否展示方程式"`
+//	ShowRSquare     bool              `description:"是否展示R平方"`
+//	TrendLine       string            `description:"方程式"`
+//	RSquare         string            `description:"R平方的值(决定系数R2)"`
+//	TrendLimitData  []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
+//}
+
+// RollingCorrelationChartDataResp 滚动相关性图
+//type RollingCorrelationChartDataResp struct {
+//	XDateTimeValue []string `description:"滚动相关性图的x轴数据,日期数据"`
+//	YDataList      []YData  `description:"滚动相关性图的y轴数据"`
+//}
+
+//type EdbDataList struct {
+//	EdbDataId     int     `description:" 指标数据ID"`
+//	EdbInfoId     int     `description:"指标ID"`
+//	DataTime      string  //`json:"-" description:"数据日期"`
+//	DataTimestamp int64   `description:"数据日期"`
+//	Value         float64 `description:"数据值"`
+//}
+
+// EditChartInfoExtraConfig 修改 ETA图库 的 图表额外配置
+//func EditChartInfoExtraConfig(chartId int, extraConfig string) (err error) {
+//	o := orm.NewOrmUsingDB("data")
+//	var pars []interface{}
+//	pars = append(pars, extraConfig)
+//
+//	sql := ` UPDATE  chart_info
+//			SET
+//			  modify_time = NOW(),
+//              extra_config = ?
+//			`
+//	sql += `WHERE chart_info_id = ?`
+//
+//	pars = append(pars, chartId)
+//	_, err = o.Raw(sql, pars).Exec()
+//	if err != nil {
+//		fmt.Println("UPDATE  chart_info Err:", err.Error())
+//		return err
+//	}
+//
+//	return
+//}
+
+//type SeasonExtraItem struct {
+//	ChartLegend []SeasonChartLegend `description:"自定义的图例名称"`
+//	XStartDate  string              `description:"横坐标显示的起始日"`
+//	XEndDate    string              `description:"横坐标显示的截止日"`
+//	JumpYear    int                 `description:"横坐标日期是否跨年,1跨年,0不跨年"`
+//}
+
+//type SeasonChartLegend struct {
+//	Name  string
+//	Value string
+//}
+
+//type QuarterData struct {
+//	Year                 int
+//	DataList             []*EdbDataList
+//	CuttingDataTimestamp int64 `description:"切割的时间戳"`
+//	ChartLegend          string
+//	Years                string
+//}
+
+//type QuarterXDateItem struct {
+//	StartDate            time.Time
+//	EndDate              time.Time
+//	ShowName             string
+//	ChartLegend          string
+//	CuttingDataTimestamp int64 `description:"切割的时间戳"`
+//}
+
+//type QuarterDataList []*QuarterData
+//
+//func (m QuarterDataList) Len() int {
+//	return len(m)
+//}
+//
+//func (m QuarterDataList) Less(i, j int) bool {
+//	return m[i].Years < m[j].Years
+//}
+//
+//func (m QuarterDataList) Swap(i, j int) {
+//	m[i], m[j] = m[j], m[i]
+//}
+
+// ChartDetailApiResponse 图表详情接口响应体
+type ChartDetailApiResponse struct {
+	Ret    int
+	Msg    string
+	ErrMsg string
+	Data   *ChartInfoDetailResp
+}

+ 71 - 0
models/data_manage/edb_classify.go

@@ -0,0 +1,71 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// EdbClassify 指标分类
+type EdbClassify struct {
+	ClassifyId      int       `orm:"column(classify_id);pk"`
+	ClassifyType    uint8     `description:"分类类型,0:普通指标分类,1:预测指标分类"`
+	ClassifyName    string    `description:"分类名称"`
+	ParentId        int       `description:"父级id"`
+	RootId          int       `description:"顶级id"`
+	HasData         int       `description:"是否含有指标数据"`
+	SysUserId       int       `description:"创建人id"`
+	SysUserRealName string    `description:"创建人姓名"`
+	Level           int       `description:"层级"`
+	UniqueCode      string    `description:"唯一编码"`
+	Sort            int       `description:"排序字段,越小越靠前,默认值:10"`
+	CreateTime      time.Time `description:"创建时间"`
+	ModifyTime      time.Time `description:"修改时间"`
+}
+
+func (m *EdbClassify) GetItemsByCondition(cond string, pars []interface{}, fieldArr []string, orderRule string) (items []*EdbClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM edb_classify WHERE 1=1 %s %s`, fields, cond, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// EdbClassifyItem 指标分类信息
+type EdbClassifyItem struct {
+	ClassifyId   int                `description:"分类ID"`
+	ClassifyName string             `description:"分类名称"`
+	UniqueCode   string             `description:"分类唯一编码"`
+	ParentId     int                `description:"父级id"`
+	Level        int                `description:"层级"`
+	Sort         int                `description:"排序"`
+	CreateTime   string             `description:"创建时间"`
+	UpdateTime   string             `description:"更新时间"`
+	Child        []*EdbClassifyItem `description:"子分类"`
+}
+
+func FormatEdbClassify2Item(origin *EdbClassify) (item *EdbClassifyItem) {
+	if origin == nil {
+		return
+	}
+	item = new(EdbClassifyItem)
+	item.ClassifyId = origin.ClassifyId
+	item.ClassifyName = origin.ClassifyName
+	item.UniqueCode = origin.UniqueCode
+	item.ParentId = origin.ParentId
+	item.Level = origin.Level
+	item.Sort = origin.Sort
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.UpdateTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	item.Child = make([]*EdbClassifyItem, 0)
+	return
+}

+ 217 - 0
models/data_manage/edb_data.go

@@ -0,0 +1,217 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// GetEdbDataTableName 指标数据->存储表
+func GetEdbDataTableName(source int) (tableName string) {
+	switch source {
+	case utils.DATA_SOURCE_THS:
+		tableName = "edb_data_ths"
+	case utils.DATA_SOURCE_WIND:
+		tableName = "edb_data_wind"
+	case utils.DATA_SOURCE_PB, utils.DATA_SOURCE_PB_FINANCE: //彭博经济数据、彭博财务数据
+		tableName = "edb_data_pb"
+	case utils.DATA_SOURCE_CALCULATE:
+		tableName = "edb_data_calculate"
+	case utils.DATA_SOURCE_CALCULATE_LJZZY:
+		tableName = "edb_data_calculate_ljzzy"
+	case utils.DATA_SOURCE_CALCULATE_TBZ:
+		tableName = "edb_data_calculate_tbz"
+	case utils.DATA_SOURCE_CALCULATE_TCZ:
+		tableName = "edb_data_calculate_tcz"
+	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS:
+		tableName = "edb_data_calculate_nszydpjjs"
+	case utils.DATA_SOURCE_MANUAL:
+		tableName = "edb_data_manual"
+	case utils.DATA_SOURCE_LZ:
+		tableName = "edb_data_lz"
+	case utils.DATA_SOURCE_YS:
+		tableName = "edb_data_ys"
+	case utils.DATA_SOURCE_CALCULATE_HBZ:
+		tableName = "edb_data_calculate_hbz"
+	case utils.DATA_SOURCE_CALCULATE_HCZ:
+		tableName = "edb_data_calculate_hcz"
+	case utils.DATA_SOURCE_CALCULATE_BP:
+		tableName = "edb_data_calculate_bp"
+	case utils.DATA_SOURCE_GL:
+		tableName = "edb_data_gl"
+	case utils.DATA_SOURCE_ZZ:
+		tableName = "edb_data_zz"
+	case utils.DATA_SOURCE_DL:
+		tableName = "edb_data_dl"
+	case utils.DATA_SOURCE_SH:
+		tableName = "edb_data_sh"
+	case utils.DATA_SOURCE_CFFEX:
+		tableName = "edb_data_cffex"
+	case utils.DATA_SOURCE_SHFE:
+		tableName = "edb_data_ine"
+	case utils.DATA_SOURCE_GIE:
+		tableName = "edb_data_gie"
+	case utils.DATA_SOURCE_CALCULATE_ZJPJ:
+		tableName = "edb_data_calculate_zjpj"
+	case utils.DATA_SOURCE_CALCULATE_TIME_SHIFT:
+		tableName = "edb_data_calculate_time_shift"
+	case utils.DATA_SOURCE_CALCULATE_LJZTBPJ:
+		tableName = "edb_data_calculate_ljztbpj"
+	case utils.DATA_SOURCE_LT:
+		tableName = "edb_data_lt"
+	case utils.DATA_SOURCE_COAL:
+		tableName = "edb_data_coal"
+	case utils.DATA_SOURCE_PYTHON:
+		tableName = "edb_data_python"
+	case utils.DATA_SOURCE_GOOGLE_TRAVEL:
+		tableName = "edb_data_google_travel"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE:
+		tableName = "edb_data_predict_calculate"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_TBZ:
+		tableName = "edb_data_predict_calculate_tbz"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_TCZ:
+		tableName = "edb_data_predict_calculate_tcz"
+	case utils.DATA_SOURCE_MYSTEEL_CHEMICAL:
+		tableName = "edb_data_mysteel_chemical"
+	case utils.DATA_SOURCE_CALCULATE_CJJX:
+		tableName = "edb_data_calculate_cjjx"
+	case utils.DATA_SOURCE_EIA_STEO:
+		tableName = "edb_data_eia_steo"
+	case utils.DATA_SOURCE_CALCULATE_NHCC:
+		tableName = "edb_data_calculate_nhcc"
+	case utils.DATA_SOURCE_COM_TRADE:
+		tableName = "edb_data_com_trade"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS:
+		tableName = "edb_data_predict_calculate_nszydpjjs"
+	case utils.DATA_SOURCE_CALCULATE_ADJUST:
+		tableName = "edb_data_calculate_adjust"
+	case utils.DATA_SOURCE_SCI:
+		tableName = "edb_data_sci"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZZY:
+		tableName = "edb_data_predict_calculate_ljzzy"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_TIME_SHIFT:
+		tableName = "edb_data_predict_calculate_time_shift"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_ZJPJ:
+		tableName = "edb_data_predict_calculate_zjpj"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZTBPJ:
+		tableName = "edb_data_predict_calculate_ljztbpj"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_NHCC:
+		tableName = "edb_data_predict_calculate_nhcc"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_CJJX:
+		tableName = "edb_data_predict_calculate_cjjx"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_HBZ:
+		tableName = "edb_data_predict_calculate_hbz"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_HCZ:
+		tableName = "edb_data_predict_calculate_hcz"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_BP:
+		tableName = "edb_data_predict_calculate_bp"
+	case utils.DATA_SOURCE_CALCULATE_JP:
+		tableName = "edb_data_calculate_jp"
+	case utils.DATA_SOURCE_CALCULATE_NH:
+		tableName = "edb_data_calculate_nh"
+	case utils.DATA_SOURCE_CALCULATE_KSZS:
+		tableName = "edb_data_calculate_kszs"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_JP:
+		tableName = "edb_data_predict_calculate_jp"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_NH:
+		tableName = "edb_data_predict_calculate_nh"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_KSZS:
+		tableName = "edb_data_predict_calculate_kszs"
+	case utils.DATA_SOURCE_BAIINFO:
+		tableName = "edb_data_baiinfo"
+	case utils.DATA_SOURCE_STOCK_PLANT:
+		tableName = "edb_data_stock_plant"
+	case utils.DATA_SOURCE_CALCULATE_CORRELATION:
+		tableName = "edb_data_calculate_correlation"
+	case utils.DATA_SOURCE_NATIONAL_STATISTICS:
+		tableName = "edb_data_national_statistics"
+	case utils.DATA_SOURCE_CALCULATE_LJZZJ: //累计值转季 -> 61
+		tableName = "edb_data_calculate_ljzzj"
+	case utils.DATA_SOURCE_CALCULATE_LJZ: //累计值 -> 62
+		tableName = "edb_data_calculate_ljz"
+	case utils.DATA_SOURCE_CALCULATE_LJZNCZJ: //累计值(年初至今) -> 63
+		tableName = "edb_data_calculate_ljznczj"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZZJ: // 预测指标 - 累计值 -> 65
+		tableName = "edb_data_predict_calculate_ljzzj"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZ: //预测指标 - 累计值转季->64
+		tableName = "edb_data_predict_calculate_ljz"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZNCZJ: //预测指标 - 累计值(年初至今) -> 66
+		tableName = "edb_data_predict_calculate_ljznczj"
+	case utils.DATA_SOURCE_CALCULATE_STANDARD_DEVIATION: //标准差->67
+		tableName = "edb_data_calculate_standard_deviation"
+	case utils.DATA_SOURCE_CALCULATE_PERCENTILE: //百分位->68
+		tableName = "edb_data_calculate_percentile"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_STANDARD_DEVIATION: //预测标准差->69
+		tableName = "edb_data_predict_ccalculate_standard_deviation"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE: //预测百分位->70
+		tableName = "edb_data_predict_ccalculate_percentile"
+	case utils.DATA_SOURCE_FUBAO: //富宝-71
+		tableName = "edb_data_fubao"
+	case utils.DATA_SOURCE_CALCULATE_ZSXY:
+		tableName = "edb_data_calculate_zsxy" // 指数修匀->72
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_ZSXY:
+		tableName = "edb_data_predict_calculate_zsxy" // 预测指数修匀->73
+	case utils.DATA_SOURCE_CALCULATE_ZDYFX:
+		tableName = "edb_data_calculate_zdyfx" // 自定义分析->74
+	case utils.DATA_SOURCE_CALCULATE_RJZ: //日均值->75
+		tableName = "edb_data_calculate_rjz"
+	default:
+		edbSource := EdbSourceIdMap[source]
+		if edbSource != nil {
+			tableName = edbSource.TableName
+		}
+	}
+	return
+}
+
+type EdbData struct {
+	EdbDataId     int       `orm:"column(edb_data_id);pk"`
+	EdbInfoId     int       `description:"指标信息ID"`
+	EdbCode       string    `description:"指标编码"`
+	DataTime      time.Time `description:"数据日期"`
+	Value         float64   `description:"数据值"`
+	CreateTime    time.Time `description:"创建时间"`
+	ModifyTime    time.Time `description:"修改时间"`
+	DataTimestamp int64     `description:"数据日期时间戳"`
+}
+
+// EdbDataItem 指标数据
+type EdbDataItem struct {
+	DataTime   string  `description:"数据日期"`
+	Value      float64 `description:"数据值"`
+	UpdateTime string  `description:"更新时间"`
+}
+
+func (m *EdbData) GetItemsBySourceAndCode(source int, edbCode string, fieldArr []string, orderRule string) (items []*EdbData, err error) {
+	tableName := GetEdbDataTableName(source)
+	if tableName == "" {
+		err = fmt.Errorf("table name empty")
+		return
+	}
+
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY data_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE edb_code = ? %s`, fields, tableName, order)
+	_, err = o.Raw(sql, edbCode).QueryRows(&items)
+	return
+}
+
+func FormatEdbData2Item(origin *EdbData) (item *EdbDataItem) {
+	if origin == nil {
+		return
+	}
+	item = new(EdbDataItem)
+	item.DataTime = utils.TimeTransferString(utils.FormatDate, origin.DataTime)
+	item.Value = origin.Value
+	item.UpdateTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	return
+}

+ 137 - 0
models/data_manage/edb_info.go

@@ -0,0 +1,137 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+type EdbInfo struct {
+	EdbInfoId        int       `orm:"column(edb_info_id);pk"`
+	EdbInfoType      int       `description:"指标类型,0:普通指标,1:预测指标"`
+	SourceName       string    `description:"来源名称"`
+	Source           int       `description:"来源ID"`
+	EdbCode          string    `description:"指标编码"`
+	EdbName          string    `description:"指标名称"`
+	EdbNameEn        string    `description:"英文指标名称"`
+	EdbNameSource    string    `description:"指标名称来源"`
+	Frequency        string    `description:"频率"`
+	Unit             string    `description:"单位"`
+	UnitEn           string    `description:"英文单位"`
+	StartDate        string    `description:"起始日期"`
+	EndDate          string    `description:"终止日期"`
+	ClassifyId       int       `description:"分类ID"`
+	SysUserId        int       `description:"创建人ID"`
+	SysUserRealName  string    `description:"创建人姓名"`
+	UniqueCode       string    `description:"指标唯一编码"`
+	CreateTime       time.Time `description:"创建时间"`
+	ModifyTime       time.Time `description:"更新时间"`
+	MinValue         float64   `description:"指标最小值"`
+	MaxValue         float64   `description:"指标最大值"`
+	CalculateFormula string    `description:"计算公式"`
+	EdbType          int       `description:"指标类型:1:基础指标,2:计算指标"`
+	Sort             int       `description:"排序字段"`
+	LatestDate       string    `description:"数据最新日期"`
+	LatestValue      float64   `description:"数据最新值"`
+	MoveType         int       `description:"移动方式:1:领先(默认),2:滞后"`
+	MoveFrequency    string    `description:"移动频度"`
+	NoUpdate         int8      `description:"是否停止更新,0:继续更新;1:停止更新"`
+	ServerUrl        string    `description:"服务器地址"`
+	ChartImage       string    `description:"图表图片"`
+	Calendar         string    `description:"公历/农历" orm:"default(公历);"`
+	DataDateType     string    `orm:"column(data_date_type);size(255);null;default(交易日)"`
+	ManualSave       int       `description:"是否有手动保存过上下限: 0-否; 1-是"`
+}
+
+func (m *EdbInfo) GetItemsByCondition(cond string, pars []interface{}, fieldArr []string, orderRule string) (items []*EdbInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM edb_info WHERE 1=1 %s %s`, fields, cond, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func (m *EdbInfo) GetItemByUniCode(code string) (item *EdbInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT * FROM edb_info WHERE unique_code = ? LIMIT 1`)
+	err = o.Raw(sql, code).QueryRow(&item)
+	return
+}
+
+func (m *EdbInfo) GetItemByEdbCode(code string) (item *EdbInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT * FROM edb_info WHERE edb_code = ? LIMIT 1`)
+	err = o.Raw(sql, code).QueryRow(&item)
+	return
+}
+
+// EdbInfoItem 指标信息
+type EdbInfoItem struct {
+	EdbInfoId    int            `description:"指标信息ID"`
+	UniqueCode   string         `description:"指标唯一编码"`
+	EdbCode      string         `description:"指标编码"`
+	EdbInfoType  int            `description:"指标类型: 0-普通指标; 1-预测指标"`
+	EdbType      int            `description:"指标类型: 1-基础指标; 2-计算指标"`
+	EdbName      string         `description:"指标名称"`
+	ClassifyId   int            `description:"分类ID"`
+	Source       int            `description:"来源ID"`
+	SourceName   string         `description:"来源名称"`
+	Frequency    string         `description:"频率"`
+	Unit         string         `description:"单位"`
+	StartDate    string         `description:"起始日期"`
+	EndDate      string         `description:"终止日期"`
+	MinValue     float64        `description:"指标最小值"`
+	MaxValue     float64        `description:"指标最大值"`
+	LatestDate   string         `description:"数据最新日期"`
+	LatestValue  float64        `description:"数据最新值"`
+	ChartImage   string         `description:"图表图片"`
+	Calendar     string         `description:"公历/农历"`
+	DataDateType string         `description:"数据日期类型: 交易日/自然日"`
+	Sort         int            `description:"排序"`
+	NoUpdate     int            `description:"是否停更: 0-继续更新; 1-停止更新"`
+	CreateTime   string         `description:"创建时间"`
+	ModifyTime   string         `description:"更新时间"`
+	EdbData      []*EdbDataItem `description:"指标数据"`
+}
+
+func FormatEdbInfo2Item(origin *EdbInfo, edbData []*EdbDataItem) (item *EdbInfoItem) {
+	if origin == nil {
+		return
+	}
+	item = new(EdbInfoItem)
+	item.EdbInfoId = origin.EdbInfoId
+	item.EdbInfoType = origin.EdbInfoType
+	item.SourceName = origin.SourceName
+	item.Source = origin.Source
+	item.EdbCode = origin.EdbCode
+	item.EdbName = origin.EdbName
+	item.Frequency = origin.Frequency
+	item.Unit = origin.Unit
+	item.StartDate = origin.StartDate
+	item.EndDate = origin.EndDate
+	item.ClassifyId = origin.ClassifyId
+	item.UniqueCode = origin.UniqueCode
+	item.MinValue = origin.MinValue
+	item.MaxValue = origin.MaxValue
+	item.EdbType = origin.EdbType
+	item.Sort = origin.Sort
+	item.LatestDate = origin.LatestDate
+	item.LatestValue = origin.LatestValue
+	item.NoUpdate = int(origin.NoUpdate)
+	item.ChartImage = origin.ChartImage
+	item.Calendar = origin.Calendar
+	item.DataDateType = origin.DataDateType
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	item.EdbData = edbData
+	return
+}

+ 84 - 0
models/data_manage/edb_source.go

@@ -0,0 +1,84 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+)
+
+var (
+	EdbSourceIdMap map[int]*EdbSource // 指标来源ID映射
+)
+
+// EdbSource 指标来源表
+type EdbSource struct {
+	EdbSourceId      int    `orm:"column(edb_source_id);pk"`
+	SourceName       string `description:"指标来源名称"`
+	TableName        string `description:"数据表名"`
+	EdbAddMethod     string `description:"指标新增接口"`
+	EdbRefreshMethod string `description:"指标刷新接口"`
+	IsBase           int    `description:"是否为基础指标: 0-否; 1-是"`
+	FromBridge       int    `description:"是否来源于桥接服务: 0-否; 1-是"`
+	BridgeFlag       string `description:"桥接服务对象标识"`
+	SourceExtend     string `description:"扩展字段做查询用"`
+	EdbCodeRequired  int    `description:"指标编码是否必填: 0-否; 1-是"`
+}
+
+// GetEdbSourceItemsByCondition 获取指标来源列表
+func GetEdbSourceItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*EdbSource, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY edb_source_id ASC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM edb_source WHERE 1=1 %s %s`, fields, condition, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// GetEdbSourceItemByCondition 获取指标来源
+func GetEdbSourceItemByCondition(condition string, pars []interface{}) (item *EdbSource, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := fmt.Sprintf(`SELECT * FROM edb_source WHERE 1=1 %s`, condition)
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+// EdbSourceItem 指标来源信息
+type EdbSourceItem struct {
+	SourceId   int    `description:"指标来源ID"`
+	SourceName string `description:"指标来源名称"`
+	//TableName  string `description:"数据表名"`
+	SourceType int `description:"来源类型: 1-基础指标; 2-计算指标"`
+}
+
+// FormatEdbSource2Item 格式化指标来源信息
+func FormatEdbSource2Item(origin *EdbSource) (item *EdbSourceItem) {
+	if origin == nil {
+		return
+	}
+	item = new(EdbSourceItem)
+	item.SourceId = origin.EdbSourceId
+	item.SourceName = origin.SourceName
+	//item.TableName = origin.TableName
+	item.SourceType = origin.IsBase
+	return
+}
+
+// InitEdbSource 初始化时加载指标来源
+func InitEdbSource() {
+	EdbSourceIdMap = make(map[int]*EdbSource)
+	sources, e := GetEdbSourceItemsByCondition(``, make([]interface{}, 0), []string{}, "")
+	if e != nil {
+		utils.FileLog.Info("init source table err: %s", e.Error())
+		return
+	}
+	for _, v := range sources {
+		EdbSourceIdMap[v.EdbSourceId] = v
+	}
+}

+ 59 - 0
models/data_manage/variety.go

@@ -0,0 +1,59 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// Variety variety 装置检修-品种表
+type Variety struct {
+	VarietyId                 int       `orm:"column(variety_id);pk"`
+	VarietyName               string    `description:"品种名称"`
+	LastUpdateSysUserId       int       `description:"最后更新人id"`
+	LastUpdateSysUserRealName string    `description:"最后更新人名称"`
+	ProductionDay             int       `description:"生产天数"`
+	SysUserId                 int       `description:"创建人id"`
+	SysUserRealName           string    `description:"创建人姓名"`
+	CreateTime                time.Time `description:"创建时间"`
+	ModifyTime                time.Time `description:"修改时间"`
+}
+
+func (m *Variety) GetItemsByCondition(cond string, pars []interface{}, fieldArr []string, orderRule string) (items []*Variety, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM variety WHERE 1=1 %s %s`, fields, cond, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// VarietyItem 品种信息
+type VarietyItem struct {
+	VarietyId     int    `description:"品种ID"`
+	VarietyName   string `description:"品种名称"`
+	ProductionDay int    `description:"生产天数"`
+	CreateTime    string `description:"创建时间"`
+	UpdateTime    string `description:"更新时间"`
+}
+
+func FormatVariety2Item(origin *Variety) (item *VarietyItem) {
+	if origin == nil {
+		return
+	}
+	item = new(VarietyItem)
+	item.VarietyId = origin.VarietyId
+	item.VarietyName = origin.VarietyName
+	item.ProductionDay = origin.ProductionDay
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.UpdateTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	return
+}

+ 72 - 0
models/data_manage/variety_edb_info.go

@@ -0,0 +1,72 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// VarietyEdbInfo 品种指标表
+type VarietyEdbInfo struct {
+	VarietyEdbId int       `orm:"column(variety_edb_id);pk"`
+	VarietyId    int       `description:"品种id"`
+	EdbName      string    `description:"品种指标名称"`
+	Frequency    string    `description:"频度"`
+	StartDate    time.Time `description:"开始日期"`
+	EndDate      time.Time `description:"结束日期"`
+	LatestValue  float64   `description:"最新值"`
+	EdbInfoId    int       `description:"指标id"`
+	EdbCode      string    `description:"品种编码"`
+	Source       int       `description:"来源,1:影响周度产量;2:周度产量变动;3:影响月度产量;4:月度产量变动"`
+	ModifyTime   time.Time `description:"更新时间"`
+	CreateTime   time.Time `description:"添加时间"`
+}
+
+func (m *VarietyEdbInfo) GetItemsByCondition(cond string, pars []interface{}, fieldArr []string, orderRule string) (items []*VarietyEdbInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM variety_edb_info WHERE 1=1 %s %s`, fields, cond, order)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// VarietyEdbInfoItem 品种指标信息
+type VarietyEdbInfoItem struct {
+	EdbInfoId   int     `description:"指标ID"`
+	EdbName     string  `description:"指标名称"`
+	EdbCode     string  `description:"指标编码"`
+	VarietyId   int     `description:"品种ID"`
+	StartDate   string  `description:"开始日期"`
+	EndDate     string  `description:"结束日期"`
+	Frequency   string  `description:"频度"`
+	LatestValue float64 `description:"最新值"`
+	CreateTime  string  `description:"创建时间"`
+	UpdateTime  string  `description:"更新时间"`
+}
+
+func FormatVarietyEdbInfo2Item(origin *VarietyEdbInfo) (item *VarietyEdbInfoItem) {
+	if origin == nil {
+		return
+	}
+	item = new(VarietyEdbInfoItem)
+	item.EdbInfoId = origin.EdbInfoId
+	item.EdbName = origin.EdbName
+	item.EdbCode = origin.EdbCode
+	item.VarietyId = origin.VarietyId
+	item.StartDate = utils.TimeTransferString(utils.FormatDate, origin.StartDate)
+	item.EndDate = utils.TimeTransferString(utils.FormatDate, origin.EndDate)
+	item.Frequency = origin.Frequency
+	item.LatestValue = origin.LatestValue
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.UpdateTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	return
+}

+ 18 - 5
models/db.go

@@ -1,6 +1,7 @@
 package models
 
 import (
+	"eta/eta_hub/models/data_manage"
 	"eta/eta_hub/utils"
 	"time"
 
@@ -10,28 +11,40 @@ import (
 )
 
 func init() {
-
+	// eta_master
 	_ = orm.RegisterDataBase("default", "mysql", utils.MYSQL_URL)
 	orm.SetMaxIdleConns("default", 50)
 	orm.SetMaxOpenConns("default", 100)
-
 	db, _ := orm.GetDB("default")
 	db.SetConnMaxLifetime(10 * time.Minute)
 
+	// eta_report
 	_ = orm.RegisterDataBase("rddp", "mysql", utils.MYSQL_URL_RDDP)
 	orm.SetMaxIdleConns("rddp", 50)
 	orm.SetMaxOpenConns("rddp", 100)
+	reportDb, _ := orm.GetDB("rddp")
+	reportDb.SetConnMaxLifetime(10 * time.Minute)
 
-	data_db, _ := orm.GetDB("rddp")
-	data_db.SetConnMaxLifetime(10 * time.Minute)
+	// eta_index
+	_ = orm.RegisterDataBase("data", "mysql", utils.MYSQL_URL_DATA)
+	orm.SetMaxIdleConns("data", 50)
+	orm.SetMaxOpenConns("data", 100)
+	indexDb, _ := orm.GetDB("data")
+	indexDb.SetConnMaxLifetime(10 * time.Minute)
 
 	orm.Debug = true
 	orm.DebugLog = orm.NewLog(utils.Binlog)
 
-	//注册对象
+	// 注册对象
 	orm.RegisterModel(
 		new(Report),
 		new(SmartReport),
 		new(ReportStateRecord),
+		new(data_manage.EdbSource),
+		new(data_manage.EdbClassify),
+		new(data_manage.EdbInfo),
 	)
+
+	// 初始化指标来源
+	data_manage.InitEdbSource()
 }

+ 117 - 0
routers/commentsRouter.go

@@ -7,6 +7,78 @@ import (
 
 func init() {
 
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:ChartController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:ChartController"],
+        beego.ControllerComments{
+            Method: "ClassifyList",
+            Router: `/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:ChartController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:ChartController"],
+        beego.ControllerComments{
+            Method: "ClassifyTree",
+            Router: `/classify/tree`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:ChartController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:ChartController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"],
+        beego.ControllerComments{
+            Method: "ClassifyList",
+            Router: `/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"],
+        beego.ControllerComments{
+            Method: "ClassifyTree",
+            Router: `/classify/tree`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"],
+        beego.ControllerComments{
+            Method: "SourceList",
+            Router: `/source/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_hub/controllers:ReportController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:ReportController"],
         beego.ControllerComments{
             Method: "Detail",
@@ -61,4 +133,49 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:StatisticAnalysisController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:StatisticAnalysisController"],
+        beego.ControllerComments{
+            Method: "ChartList",
+            Router: `/chart/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:StatisticAnalysisController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:StatisticAnalysisController"],
+        beego.ControllerComments{
+            Method: "ClassifyList",
+            Router: `/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:SupplyAnalysisController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:SupplyAnalysisController"],
+        beego.ControllerComments{
+            Method: "StockPlantEdbDetail",
+            Router: `/stock_plant/edb/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:SupplyAnalysisController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:SupplyAnalysisController"],
+        beego.ControllerComments{
+            Method: "StockPlantEdbList",
+            Router: `/stock_plant/edb/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:SupplyAnalysisController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:SupplyAnalysisController"],
+        beego.ControllerComments{
+            Method: "StockPlantVarietyList",
+            Router: `/stock_plant/variety/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
 }

+ 20 - 0
routers/router.go

@@ -24,6 +24,26 @@ func init() {
 				&controllers.SmartReportController{},
 			),
 		),
+		web.NSNamespace("/edb",
+			web.NSInclude(
+				&controllers.EdbController{},
+			),
+		),
+		web.NSNamespace("/chart",
+			web.NSInclude(
+				&controllers.ChartController{},
+			),
+		),
+		web.NSNamespace("/statistic_analysis",
+			web.NSInclude(
+				&controllers.StatisticAnalysisController{},
+			),
+		),
+		web.NSNamespace("/supply_analysis",
+			web.NSInclude(
+				&controllers.SupplyAnalysisController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 62 - 0
services/chart.go

@@ -0,0 +1,62 @@
+package services
+
+import (
+	"encoding/json"
+	"eta/eta_hub/models/data_manage"
+	"eta/eta_hub/utils"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+)
+
+// GetChartDetailFromChartLibByUnicode 图库服务获取图表详情
+func GetChartDetailFromChartLibByUnicode(unicode string) (detail *data_manage.ChartInfoDetailResp, err error) {
+	if unicode == "" {
+		err = fmt.Errorf("编码为空")
+		return
+	}
+	defer func() {
+		if err != nil {
+			tips := fmt.Sprintf("获取图表详情失败, GetChartDetailFromChartLibByUnicode Err: %s", err.Error())
+			utils.FileLog.Info(tips)
+		}
+	}()
+
+	apiDetail, e := CurlChartLibChartDetailApi(unicode)
+	if e != nil {
+		err = fmt.Errorf("")
+		return
+	}
+	detail = apiDetail
+	return
+}
+
+// CurlChartLibChartDetailApi 请求图表详情接口
+func CurlChartLibChartDetailApi(unicode string) (detail *data_manage.ChartInfoDetailResp, err error) {
+	apiUrl := fmt.Sprint(utils.EdbChartLibUrl, utils.ChartLibChartDetailFromUnicodeApi, "?UniqueCode=", unicode)
+	ret, e := http.Get(apiUrl)
+	if e != nil {
+		err = fmt.Errorf("http get err: %s", e.Error())
+		return
+	}
+	defer func() {
+		_ = ret.Body.Close()
+	}()
+
+	body, e := ioutil.ReadAll(ret.Body)
+	if e != nil {
+		err = fmt.Errorf("read body err: %s", e.Error())
+		return
+	}
+	result := new(data_manage.ChartDetailApiResponse)
+	if e = json.Unmarshal(body, &result); e != nil {
+		err = fmt.Errorf("json unmarshal err: %s", e.Error())
+		return
+	}
+	if result.Ret != 200 {
+		err = fmt.Errorf("result err: %s", result.ErrMsg)
+		return
+	}
+	detail = result.Data
+	return
+}

+ 24 - 0
services/chart_classify.go

@@ -0,0 +1,24 @@
+package services
+
+import (
+	"eta/eta_hub/models/data_manage"
+)
+
+// GetChartClassifyTreeRecursive 递归图表分类树
+func GetChartClassifyTreeRecursive(list []*data_manage.ChartClassify, parentId int) []*data_manage.ChartClassifyItem {
+	res := make([]*data_manage.ChartClassifyItem, 0)
+	for _, v := range list {
+		t := new(data_manage.ChartClassifyItem)
+		t.ClassifyId = v.ChartClassifyId
+		t.ClassifyName = v.ChartClassifyName
+		t.UniqueCode = v.UniqueCode
+		t.ParentId = v.ParentId
+		t.Level = v.Level
+		t.Sort = v.Sort
+		if v.ParentId == parentId {
+			t.Child = GetChartClassifyTreeRecursive(list, v.ChartClassifyId)
+			res = append(res, t)
+		}
+	}
+	return res
+}

+ 23 - 0
services/edb_classify.go

@@ -0,0 +1,23 @@
+package services
+
+import (
+	"eta/eta_hub/models/data_manage"
+)
+
+// GetEdbClassifyTreeRecursive 递归指标分类树
+func GetEdbClassifyTreeRecursive(list []*data_manage.EdbClassify, parentId int) []*data_manage.EdbClassifyItem {
+	res := make([]*data_manage.EdbClassifyItem, 0)
+	for _, v := range list {
+		t := new(data_manage.EdbClassifyItem)
+		t.ClassifyId = v.ClassifyId
+		t.ClassifyName = v.ClassifyName
+		t.UniqueCode = v.UniqueCode
+		t.ParentId = v.ParentId
+		t.Sort = v.Sort
+		if v.ParentId == parentId {
+			t.Child = GetEdbClassifyTreeRecursive(list, v.ClassifyId)
+			res = append(res, t)
+		}
+	}
+	return res
+}

+ 0 - 8
services/task.go

@@ -1,13 +1,5 @@
 package services
 
-import (
-	"fmt"
-)
-
 func Task() {
-	fmt.Println("start crawler")
-
-	//task.StartTask()
 
-	fmt.Println("end crawler")
 }

+ 92 - 2
utils/common.go

@@ -1000,7 +1000,7 @@ func HmacSha256(key string, data string) []byte {
 	return mac.Sum(nil)
 }
 
-// HmacSha256ToHex 将加密后的二进制转Base64字符串
+// HmacSha256ToBase64 将加密后的二进制转Base64字符串
 func HmacSha256ToBase64(key string, data string) string {
 	return base64.URLEncoding.EncodeToString(HmacSha256(key, data))
 }
@@ -1050,4 +1050,94 @@ func TimeTransferString(format string, t time.Time) string {
 		return ""
 	}
 	return str
-}
+}
+
+func GetDateByDateTypeV2(dateType int, tmpStartDate, tmpEndDate string, startYear, yearMax int) (startDate, endDate string) {
+	startDate = tmpStartDate
+	endDate = tmpEndDate
+	switch dateType {
+	case 1:
+		startDate = "2000-01-01"
+		endDate = ""
+	case 2:
+		startDate = "2010-01-01"
+		endDate = ""
+	case 3:
+		startDate = "2015-01-01"
+		endDate = ""
+	case 4:
+		//startDate = strconv.Itoa(time.Now().Year()) + "-01-01"
+		startDate = "2021-01-01"
+		endDate = ""
+	case 5:
+		//startDate = startDate + "-01"
+		//endDate = endDate + "-01"
+	case 6:
+		//startDate = startDate + "-01"
+		endDate = ""
+	case 7:
+		startDate = "2018-01-01"
+		endDate = ""
+	case 8:
+		startDate = "2019-01-01"
+		endDate = ""
+	case 9:
+		startDate = "2020-01-01"
+		endDate = ""
+	case 11:
+		startDate = "2022-01-01"
+		endDate = ""
+	case DateTypeNYears:
+		if startYear == 0 { //默认取最近5年
+			startYear = 5
+		}
+		if yearMax == 0 {
+			return
+		}
+		startYear = startYear - 1
+		baseDate, _ := time.Parse(FormatDate, fmt.Sprintf("%d-01-01", yearMax))
+		startDate = baseDate.AddDate(-startYear, 0, 0).Format(FormatDate)
+		endDate = ""
+	}
+
+	// 兼容日期错误
+	{
+		if strings.Count(startDate, "-") == 1 {
+			startDate = startDate + "-01"
+		}
+		if strings.Count(endDate, "-") == 1 {
+			endDate = endDate + "-01"
+		}
+	}
+
+	return
+}
+
+// MapSorter 对于map 排序
+type MapSorter []Item
+
+type Item struct {
+	Key int
+	Val float64
+}
+
+func NewMapSorter(m map[int]float64) MapSorter {
+	ms := make(MapSorter, 0, len(m))
+	for k, v := range m {
+		ms = append(ms, Item{k, v})
+	}
+	return ms
+}
+
+func (ms MapSorter) Len() int {
+	return len(ms)
+}
+
+func (ms MapSorter) Less(i, j int) bool {
+	return ms[i].Val > ms[j].Val // 按值排序
+	//return ms[i].Key < ms[j].Key // 按键排序
+}
+
+func (ms MapSorter) Swap(i, j int) {
+	ms[i], ms[j] = ms[j], ms[i]
+}

+ 25 - 5
utils/config.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 	beeLogger "github.com/beego/bee/v2/logger"
 	"github.com/beego/beego/v2/server/web"
+	"github.com/rdlucklib/rdluck_tools/cache"
 	"strconv"
 )
 
@@ -12,6 +13,10 @@ var (
 	MYSQL_URL      string //数据库连接
 	MYSQL_URL_DATA string
 	MYSQL_URL_RDDP string
+
+	REDIS_CACHE string       //缓存地址
+	Rc          *cache.Cache //redis缓存
+	Re          error        //redis错误
 )
 
 // 日志配置
@@ -33,8 +38,8 @@ var (
 
 // ES索引配置
 var (
-	EsReportIndexName              string //研报ES索引
-	SmartReportIndexName           string //智能研报ES索引
+	EsReportIndexName    string //研报ES索引
+	SmartReportIndexName string //智能研报ES索引
 )
 
 // ES配置
@@ -44,6 +49,11 @@ var (
 	ES_PASSWORD string // ES密码
 )
 
+// 内部配置
+var (
+	EdbChartLibUrl string // 图库服务地址
+)
+
 func init() {
 	tmpRunMode, err := web.AppConfig.String("run_mode")
 	if err != nil {
@@ -73,10 +83,15 @@ func init() {
 	MYSQL_URL = config["mysql_url"]
 	MYSQL_URL_DATA = config["mysql_url_data"]
 	MYSQL_URL_RDDP = config["mysql_url_rddp"]
-	if RunMode == "release" {
-
-	} else {
 
+	REDIS_CACHE = config["beego_cache"]
+	if len(REDIS_CACHE) <= 0 {
+		panic(any("redis链接参数没有配置"))
+	}
+	Rc, Re = cache.NewCache(REDIS_CACHE) //初始化缓存
+	if Re != nil {
+		fmt.Println(Re)
+		panic(any(Re))
 	}
 
 	//商家编码
@@ -120,4 +135,9 @@ func init() {
 		ES_PASSWORD = config["es_password"]
 	}
 
+	// 内部配置
+	{
+		EdbChartLibUrl = config["edb_chart_lib_url"]
+	}
+
 }

+ 125 - 2
utils/constants.go

@@ -4,7 +4,7 @@ const (
 	Md5Key = "Ks@h64WJ#tcVgG8$&WlNfqvLAtMgpxWN"
 )
 
-//常量定义
+// 常量定义
 const (
 	FormatTime             = "15:04:05"                //时间格式
 	FormatDate             = "2006-01-02"              //日期格式
@@ -21,5 +21,128 @@ const (
 )
 
 const (
-	APPNAME          = "弘则-对外API"
+	APPNAME = "弘则-OpenApi"
+)
+
+// 数据来源渠道
+const (
+	DATA_SOURCE_THS                                  = iota + 1 //同花顺
+	DATA_SOURCE_WIND                                            //wind->2
+	DATA_SOURCE_PB                                              //彭博->3
+	DATA_SOURCE_CALCULATE                                       //指标运算->4
+	DATA_SOURCE_CALCULATE_LJZZY                                 //累计值转月->5
+	DATA_SOURCE_CALCULATE_TBZ                                   //同比值->6
+	DATA_SOURCE_CALCULATE_TCZ                                   //同差值->7
+	DATA_SOURCE_CALCULATE_NSZYDPJJS                             //N数值移动平均计算->8
+	DATA_SOURCE_MANUAL                                          //手工指标->9
+	DATA_SOURCE_LZ                                              //隆众->10
+	DATA_SOURCE_YS                                              //有色->11
+	DATA_SOURCE_CALCULATE_HBZ                                   //环比值->12
+	DATA_SOURCE_CALCULATE_HCZ                                   //环差值->13
+	DATA_SOURCE_CALCULATE_BP                                    //变频->14
+	DATA_SOURCE_GL                                              //钢联->15
+	DATA_SOURCE_ZZ                                              //郑商所->16
+	DATA_SOURCE_DL                                              //大商所->17
+	DATA_SOURCE_SH                                              //上期所->18
+	DATA_SOURCE_CFFEX                                           //中金所->19
+	DATA_SOURCE_SHFE                                            //上期能源->20
+	DATA_SOURCE_GIE                                             //欧洲天然气->21
+	DATA_SOURCE_CALCULATE_TIME_SHIFT                            //时间移位->22
+	DATA_SOURCE_CALCULATE_ZJPJ                                  //直接拼接->23
+	DATA_SOURCE_CALCULATE_LJZTBPJ                               //累计值同比拼接->24
+	DATA_SOURCE_LT                                              //路透->25
+	DATA_SOURCE_COAL                                            //中国煤炭网->26
+	DATA_SOURCE_PYTHON                                          //python代码->27
+	DATA_SOURCE_PB_FINANCE                                      //彭博财务数据->28
+	DATA_SOURCE_GOOGLE_TRAVEL                                   //谷歌出行->29
+	DATA_SOURCE_PREDICT                                         //普通预测指标->30
+	DATA_SOURCE_PREDICT_CALCULATE                               //预测指标运算->31
+	DATA_SOURCE_PREDICT_CALCULATE_TBZ                           //预测同比值->32
+	DATA_SOURCE_PREDICT_CALCULATE_TCZ                           //预测同差值->33
+	DATA_SOURCE_MYSTEEL_CHEMICAL                                //钢联化工->34
+	DATA_SOURCE_CALCULATE_CJJX                                  //超季节性->35
+	DATA_SOURCE_EIA_STEO                                        //eia steo报告->36
+	DATA_SOURCE_CALCULATE_NHCC                                  //计算指标(拟合残差)->37
+	DATA_SOURCE_COM_TRADE                                       //联合国商品贸易数据->38
+	DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS                     //预测指标 - N数值移动平均计算 -> 39
+	DATA_SOURCE_CALCULATE_ADJUST                                //数据调整->40
+	DATA_SOURCE_SCI                                             //卓创数据(红桃三)->41
+	DATA_SOURCE_PREDICT_CALCULATE_LJZZY                         //预测指标 - 累计值转月->42
+	DATA_SOURCE_PREDICT_CALCULATE_HBZ                           //预测指标 - 环比值->43
+	DATA_SOURCE_PREDICT_CALCULATE_HCZ                           //预测指标 - 环差值->44
+	DATA_SOURCE_PREDICT_CALCULATE_BP                            //预测指标 - 变频->45
+	DATA_SOURCE_PREDICT_CALCULATE_TIME_SHIFT                    //预测指标 - 时间移位->46
+	DATA_SOURCE_PREDICT_CALCULATE_ZJPJ                          //预测指标 - 直接拼接->47
+	DATA_SOURCE_PREDICT_CALCULATE_LJZTBPJ                       //预测指标 - 累计值同比拼接->48
+	DATA_SOURCE_PREDICT_CALCULATE_CJJX                          //预测指标 - 超季节性->49
+	DATA_SOURCE_PREDICT_CALCULATE_NHCC                          //预测指标 - 计算指标(拟合残差)->50
+	DATA_SOURCE_CALCULATE_JP                                    //变频->51
+	DATA_SOURCE_CALCULATE_NH                                    //年化->52
+	DATA_SOURCE_CALCULATE_KSZS                                  //扩散指数->53
+	DATA_SOURCE_PREDICT_CALCULATE_JP                            //预测指标 - 计算指标(降频)->54
+	DATA_SOURCE_PREDICT_CALCULATE_NH                            //预测指标 - 计算指标(年化)->55
+	DATA_SOURCE_PREDICT_CALCULATE_KSZS                          //预测指标 - 计算指标(扩散指数)->56
+	DATA_SOURCE_BAIINFO                                         //百川盈孚 ->57
+	DATA_SOURCE_STOCK_PLANT                                     //存量装置 ->58
+	DATA_SOURCE_CALCULATE_CORRELATION                           //滚动相关性->59
+	DATA_SOURCE_NATIONAL_STATISTICS                             //国家统计局->60
+	DATA_SOURCE_CALCULATE_LJZZJ                                 //累计值转季 -> 61
+	DATA_SOURCE_CALCULATE_LJZ                                   //累计值 -> 62
+	DATA_SOURCE_CALCULATE_LJZNCZJ                               //累计值(年初至今) -> 63
+	DATA_SOURCE_PREDICT_CALCULATE_LJZZJ                         //预测指标 - 累计值转季->64
+	DATA_SOURCE_PREDICT_CALCULATE_LJZ                           //预测指标 - 累计值 -> 65
+	DATA_SOURCE_PREDICT_CALCULATE_LJZNCZJ                       //预测指标 - 累计值(年初至今) -> 66
+	DATA_SOURCE_CALCULATE_STANDARD_DEVIATION                    //标准差->67
+	DATA_SOURCE_CALCULATE_PERCENTILE                            //百分位图表->68
+	DATA_SOURCE_PREDICT_CALCULATE_STANDARD_DEVIATION            //预测标准差->69
+	DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE                    //预测百分位->70
+	DATA_SOURCE_FUBAO                                           //富宝->71
+	DATA_SOURCE_CALCULATE_ZSXY                                  // 指数修匀->72
+	DATA_SOURCE_PREDICT_CALCULATE_ZSXY                          // 预测指数修匀->73
+	DATA_SOURCE_CALCULATE_ZDYFX                                 // 自定义分析->74
+	DATA_SOURCE_CALCULATE_RJZ                                   // 日均值计算->75
+)
+
+// 图表类型
+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 // 统计特征-频率分布图表
+)
+
+// 批量配置图表的位置来源
+const (
+	CHART_MULTIPLE_GRAPH_CURVE                           = 1  // 曲线图
+	CHART_MULTIPLE_GRAPH_CORRELATION                     = 2  // 相关性图
+	CHART_MULTIPLE_GRAPH_ROLLING_CORRELATION_ONE         = 3  // 滚动相关性图1
+	CHART_MULTIPLE_GRAPH_ROLLING_CORRELATION_TWO         = 4  // 滚动相关性图2
+	CHART_MULTIPLE_GRAPH_LINE_EQUATION_ONE               = 5  // 拟合方程-斜率图
+	CHART_MULTIPLE_GRAPH_LINE_EQUATION_TWO               = 6  // 拟合方程-截距图
+	CHART_MULTIPLE_GRAPH_LINE_EQUATION_THREE             = 7  // 拟合方程-相关性图
+	CHART_MULTIPLE_GRAPH_LINE_FEATURE_STANDARD_DEVIATION = 8  // 统计特征-标准差图表
+	CHART_MULTIPLE_GRAPH_LINE_FEATURE_PERCENTILE         = 9  // 统计特征-百分位图表
+	CHART_MULTIPLE_GRAPH_LINE_FEATURE_FREQUENCY          = 10 // 统计特征-频率分布图表
+)
+
+// 图表样式类型
+const (
+	CHART_TYPE_CURVE           = 1  //曲线图
+	CHART_TYPE_BAR             = 7  //柱形图
+	CHART_TYPE_SECTION_SCATTER = 10 //截面散点图样式
+)
+
+const (
+	CACHE_CHART_INFO_DATA = "chart:info:data:" // 图表数据
+	DateTypeNYears        = 20                 // 时间类型为最近N年
+)
+
+// 图库接口地址
+const (
+	ChartLibChartDetailFromUnicodeApi = "/v1/chart/detail" // 图表详情
 )