浏览代码

获取指标同比值数据和季节性数据

xyxie 5 月之前
父节点
当前提交
f2585834dc
共有 8 个文件被更改,包括 739 次插入31 次删除
  1. 169 0
      controllers/edb.go
  2. 3 2
      go.mod
  3. 4 2
      go.sum
  4. 27 27
      models/data_manage/chart_info.go
  5. 32 0
      models/data_manage/edb_data.go
  6. 197 0
      models/data_manage/edb_data_quarter.go
  7. 18 0
      routers/commentsRouter.go
  8. 289 0
      services/data/edb_data.go

+ 169 - 0
controllers/edb.go

@@ -366,3 +366,172 @@ func (this *EdbInfoController) TraceEdbInfo() {
 	br.Data = resp
 	br.Msg = "刷新成功"
 }
+
+// EdbInfoDataTb
+// @Title 获取指标数据同比值
+// @Description 获取指标数据
+// @Param   EdbInfoId   query   int  true       "指标ID"
+// @Param   DateType   query   int  true       "日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间,6:自定义起始时间至今,7:18年至今,8:19年至今,9:20年至今,10:全部"
+// @Param   StartDate   query   string  true       "自定义开始日期"
+// @Param   EndDate   query   string  true       "自定义结束日期"
+// @Success 200 {object} data_manage.EdbInfoDataResp
+// @router /data/tb [get]
+func (this *EdbController) EdbInfoDataTb() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	edbInfoType, _ := this.GetInt("EdbInfoType")
+	if edbInfoType < 0 {
+		edbInfoType = 1
+	}
+
+	startDate := this.GetString("StartDate")
+	unicode := this.GetString("UniqueCode")
+	edbCode := this.GetString("EdbCode")
+	if unicode == "" && edbCode == "" {
+		br.Msg = "参数有误"
+		return
+	}
+	edbOb := new(data_manage.EdbInfo)
+	edbInfo := new(data_manage.EdbInfo)
+	var err error
+	if unicode != "" {
+		edbInfo, err = edbOb.GetItemByUniCode(unicode)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				br.Msg = "指标不存在"
+				return
+			}
+			br.Msg = "获取失败"
+			br.ErrMsg = "EdbDetail GetItemByUniCode err: " + err.Error()
+			return
+		}
+	} else if edbCode != "" {
+		edbInfo, err = edbOb.GetItemByEdbCode(edbCode)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				br.Msg = "指标不存在"
+				return
+			}
+			br.Msg = "获取失败"
+			br.ErrMsg = "EdbDetail GetItemByEdbCode err: " + err.Error()
+			return
+		}
+	}
+	if edbInfo.EdbInfoType != 0 {
+		br.Msg = "不支持预测指标"
+		return
+	}
+	var startDateTime time.Time
+	if startDate != `` {
+		startDateTime, err = time.ParseInLocation(utils.FormatDate, startDate, time.Local)
+		if err != nil {
+			br.Msg = "开始日期异常"
+			br.Msg = "开始日期异常,Err:" + err.Error()
+			return
+		}
+		//同比值的计算方式,是需要与去年同期对比,所以如果用户需要某个时间段的数据的话,获取基础数据时,需要往前面推(1年+兼容的日期频度(目前是35天))
+		startDate = startDateTime.AddDate(-1, 0, -35).Format(utils.FormatDate)
+	}
+	tmpDataList, err := data.GetEdbDataList(edbInfo, startDate)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.Msg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	// 计算同比值
+	dataList, minValue, maxValue, err := data.GetEdbDataTbz(edbInfo, tmpDataList, startDateTime)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.Msg = "计算同比值失败,Err:" + err.Error()
+		return
+	}
+
+	edbInfo.MaxValue = maxValue
+	edbInfo.MinValue = minValue
+
+	resp := new(data_manage.EdbInfoDataResp)
+	resp.EdbInfo = edbInfo
+	resp.DataList = dataList
+	br.Ret = 200
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// EdbInfoDataSeasonal
+// @Title 获取指标数据(季节性)
+// @Description 获取指标数据
+// @Param   EdbInfoId   query   int  true       "指标ID"
+// @Param   DateType   query   int  true       "日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间,6:自定义起始时间至今,7:18年至今,8:19年至今,9:20年至今,10:全部"
+// @Param   StartDate   query   string  true       "自定义开始日期"
+// @Param   EndDate   query   string  true       "自定义结束日期"
+// @Param   Calendar   query   string  true       "公历/农历"
+// @Success 200 {object} data_manage.EdbInfoDataResp
+// @router /data/seasonal [get]
+func (this *EdbController) EdbInfoDataSeasonal() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	startDate := this.GetString("StartDate")
+
+	calendar := this.GetString("Calendar")
+	if calendar == "" {
+		calendar = "公历"
+	}
+	unicode := this.GetString("UniqueCode")
+	edbCode := this.GetString("EdbCode")
+	if unicode == "" && edbCode == "" {
+		br.Msg = "参数有误"
+		return
+	}
+	edbOb := new(data_manage.EdbInfo)
+	edbInfo := new(data_manage.EdbInfo)
+	var err error
+	if unicode != "" {
+		edbInfo, err = edbOb.GetItemByUniCode(unicode)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				br.Msg = "指标不存在"
+				return
+			}
+			br.Msg = "获取失败"
+			br.ErrMsg = "EdbDetail GetItemByUniCode err: " + err.Error()
+			return
+		}
+	} else if edbCode != "" {
+		edbInfo, err = edbOb.GetItemByEdbCode(edbCode)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				br.Msg = "指标不存在"
+				return
+			}
+			br.Msg = "获取失败"
+			br.ErrMsg = "EdbDetail GetItemByEdbCode err: " + err.Error()
+			return
+		}
+	}
+	if edbInfo.EdbInfoType != 0 {
+		br.Msg = "不支持预测指标"
+		return
+	}
+
+	dataList, err := data.GetChartEdbSeasonalData(calendar, startDate, edbInfo)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
+		return
+	}
+	resp := new(data_manage.EdbInfoDataSeasonalResp)
+	resp.EdbInfo = edbInfo
+	resp.DataList = dataList
+	br.Ret = 200
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 3 - 2
go.mod

@@ -12,11 +12,13 @@ require (
 	github.com/beego/beego/v2 v2.0.7
 	github.com/go-redis/redis/v8 v8.11.5
 	github.com/go-sql-driver/mysql v1.7.1
-	github.com/h2non/filetype v1.1.3
+	github.com/google/uuid v1.6.0
 	github.com/minio/minio-go/v7 v7.0.77
+	github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19
 	github.com/olivere/elastic/v7 v7.0.32
 	github.com/qiniu/qmgo v1.1.8
 	github.com/rdlucklib/rdluck_tools v1.0.3
+	github.com/shopspring/decimal v1.4.0
 	go.mongodb.org/mongo-driver v1.15.0
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
 )
@@ -33,7 +35,6 @@ require (
 	github.com/goccy/go-json v0.10.3 // indirect
 	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/golang/snappy v0.0.1 // indirect
-	github.com/google/uuid v1.6.0 // indirect
 	github.com/hashicorp/golang-lru v0.5.4 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect

+ 4 - 2
go.sum

@@ -115,8 +115,6 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
-github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
 github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@@ -178,6 +176,8 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6f
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 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/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
 github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=
@@ -230,6 +230,8 @@ github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
 github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
+github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
+github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
 github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
 github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
 github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=

+ 27 - 27
models/data_manage/chart_info.go

@@ -442,35 +442,35 @@ type ChartViewButton struct {
 //	Value string
 //}
 
-//type QuarterData struct {
-//	Year                 int
-//	DataList             []*EdbDataList
-//	CuttingDataTimestamp int64 `description:"切割的时间戳"`
-//	ChartLegend          string
-//	Years                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 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]
-//}
+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 {

+ 32 - 0
models/data_manage/edb_data.go

@@ -338,3 +338,35 @@ func (m *EdbData) getThsHfEdbDataListByMongo(source, subSource int, edbCode, sta
 
 	return
 }
+
+// EdbInfoDataSeasonalResp 指标季节性数据返回
+type EdbInfoDataSeasonalResp struct {
+	EdbInfo  *EdbInfo
+	DataList interface{}
+}
+
+type EdbInfoDataResp struct {
+	EdbInfo  *EdbInfo
+	DataList []*EdbDataList
+}
+
+type EdbDataList struct {
+	//EdbDataId     int     `description:" 指标数据ID"`
+	//	EdbInfoId     int     `description:"指标ID"`
+	DataTime      string  //`json:"-" description:"数据日期"`
+	DataTimestamp int64   `description:"数据日期"`
+	Value         float64 `description:"数据值"`
+}
+
+func FormatEdbData2List(origin *EdbData) (item *EdbDataList) {
+	if origin == nil {
+		return
+	}
+	item = new(EdbDataList)
+	//item.EdbDataId = origin.EdbDataId
+	//item.EdbInfoId = origin.EdbInfoId
+	item.DataTime = utils.TimeTransferString(utils.FormatDate, origin.DataTime)
+	item.Value = origin.Value
+	item.DataTimestamp = origin.DataTimestamp
+	return
+}

+ 197 - 0
models/data_manage/edb_data_quarter.go

@@ -0,0 +1,197 @@
+package data_manage
+
+import (
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/nosixtools/solarlunar"
+	"strconv"
+	"time"
+)
+
+type EdbDataItems struct {
+	Items                []*EdbDataList
+	Year                 int
+	BetweenDay           int   `json:"-" description:"公历与农历之间相差的天数"`
+	CuttingDataTimestamp int64 `description:"切割的时间戳"`
+}
+type EdbDataResult struct {
+	List []*EdbDataItems
+}
+
+// 指标季度数据计算(公历转农历)
+func AddCalculateQuarterV4(dataList []*EdbDataList) (result *EdbDataResult, err error) {
+	var errMsg string
+	defer func() {
+		if errMsg != "" {
+			fmt.Println("errMsg:", errMsg)
+		}
+	}()
+
+	endDate := dataList[len(dataList)-1].DataTime
+	endDateForm, err := time.Parse(utils.FormatDate, endDate)
+	if err != nil {
+		return result, err
+	}
+	thisMonth := int(endDateForm.Month())
+
+	result = new(EdbDataResult)
+	var yearArr []int
+	yearMap := make(map[int]int)
+	var cureentDate time.Time
+	if thisMonth < 11 {
+		for k, v := range dataList {
+			dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+			if err != nil {
+				errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+				return result, err
+			}
+			if k == len(dataList)-1 {
+				cureentDate = dateTime
+			}
+			year := dateTime.Year()
+			if _, ok := yearMap[year]; !ok {
+				yearArr = append(yearArr, year)
+			}
+			yearMap[year] = year
+		}
+	} else {
+		for k, v := range dataList {
+			dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+			if err != nil {
+				errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+				return result, err
+			}
+			if k == len(dataList)-1 {
+				cureentDate = dateTime
+			}
+			year := dateTime.Year() + 1
+			if _, ok := yearMap[year]; !ok {
+				yearArr = append(yearArr, year)
+			}
+			yearMap[year] = year
+		}
+	}
+	//排序
+	fmt.Println("yearArr:", yearArr)
+	thisYear := cureentDate.Year()
+	//thisMonth := int(cureentDate.Month())
+
+	fmt.Println("thisMonth:", thisMonth)
+	for ky, vy := range yearArr {
+		fmt.Println("line 432:", ky, vy, thisYear, thisMonth)
+		if thisMonth < 11 {
+			currentYearCjnl := strconv.Itoa(thisYear) + "-01-01"               //当前年份春节农历
+			currentYearCjgl := solarlunar.LunarToSolar(currentYearCjnl, false) //当前年份春节公历
+			currentYearCjglDate, err := time.Parse(utils.FormatDate, currentYearCjgl)
+			if err != nil {
+				errMsg = "生成当前春节失败,Err:" + err.Error()
+				return result, err
+			}
+
+			preYear := vy
+			preYearCjnl := strconv.Itoa(preYear) + "-01-01"            //之前年份春节农历
+			preYearCjgl := solarlunar.LunarToSolar(preYearCjnl, false) //之前年份春节公历
+			preYearCjglDate, err := time.Parse(utils.FormatDate, preYearCjgl)
+			if err != nil {
+				errMsg = "生成历史年份春节失败,Err:" + err.Error()
+				return result, err
+			}
+			day := currentYearCjglDate.Sub(preYearCjglDate).Hours() / float64(24)
+
+			fmt.Println("day:", day, currentYearCjglDate, preYearCjglDate)
+
+			items := new(EdbDataItems)
+			items.BetweenDay = int(day) //公历日期换算成农历,需要减除的天数
+			items.Year = preYear
+			for _, v := range dataList {
+				dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+				if err != nil {
+					errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+					return result, err
+				}
+				newDate := dateTime.AddDate(0, 0, int(day))
+				selectDateStr := strconv.Itoa(thisYear) + "-11" + "-30"
+				selectDate, _ := time.Parse(utils.FormatDate, selectDateStr)
+				if newDate.Before(selectDate) || newDate == selectDate {
+					timestamp := newDate.UnixNano() / 1e6
+					item := new(EdbDataList)
+					item.DataTime = newDate.Format(utils.FormatDate)
+					//item.EdbInfoId = v.EdbInfoId
+					item.Value = v.Value
+					//item.EdbDataId = v.EdbDataId
+					item.DataTimestamp = timestamp
+					items.Items = append(items.Items, item)
+				}
+			}
+			result.List = append(result.List, items)
+		} else {
+			nextYear := thisYear + 1
+			nextYearCjnl := strconv.Itoa(nextYear) + "-01-01"            //当前年份春节农历
+			nextYearCjgl := solarlunar.LunarToSolar(nextYearCjnl, false) //当前年份春节公历
+
+			nextYearCjglDate, err := time.Parse(utils.FormatDate, nextYearCjgl)
+			if err != nil {
+				errMsg = "生成当前春节失败,Err:" + err.Error()
+				return result, err
+			}
+			preYear := vy
+			preYearCjnl := strconv.Itoa(preYear) + "-01-01"            //之前年份春节农历
+			preYearCjgl := solarlunar.LunarToSolar(preYearCjnl, false) //之前年份春节公历
+			preYearCjglDate, err := time.Parse(utils.FormatDate, preYearCjgl)
+			if err != nil {
+				errMsg = "生成历史年份春节失败,Err:" + err.Error()
+				return result, err
+			}
+			day := nextYearCjglDate.Sub(preYearCjglDate).Hours() / float64(24)
+
+			fmt.Println("day:", day, nextYearCjglDate, preYearCjglDate)
+
+			items := new(EdbDataItems)
+			items.BetweenDay = int(day) //公历日期换算成农历,需要减除的天数
+			items.Year = preYear - 1
+			fmt.Println("preYear:", preYear, "ky:", ky, "yearArrLen:", len(yearArr))
+			if ky+1 < len(yearArr) {
+				for _, v := range dataList {
+					dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+					if err != nil {
+						errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+						return result, err
+					}
+					newDate := dateTime.AddDate(0, 0, int(day))
+					selectDateStr := strconv.Itoa(nextYear) + "-05" + "-31"
+					selectDate, _ := time.Parse(utils.FormatDate, selectDateStr)
+
+					if newDate.Before(selectDate) || newDate == selectDate {
+						timestamp := newDate.UnixNano() / 1e6
+						item := new(EdbDataList)
+						item.DataTime = newDate.Format(utils.FormatDate)
+						//item.EdbInfoId = v.EdbInfoId
+						item.Value = v.Value
+						//item.EdbDataId = v.EdbDataId
+						item.DataTimestamp = timestamp
+						items.Items = append(items.Items, item)
+					}
+				}
+				result.List = append(result.List, items)
+			} else {
+				for _, v := range dataList {
+					dateTime, err := time.Parse(utils.FormatDate, v.DataTime)
+					if err != nil {
+						errMsg = "time.Parse Err:" + err.Error() + ";DataTime:" + v.DataTime
+						return result, err
+					}
+					timestamp := dateTime.UnixNano() / 1e6
+					item := new(EdbDataList)
+					item.DataTime = dateTime.Format(utils.FormatDate)
+					//item.EdbInfoId = v.EdbInfoId
+					item.Value = v.Value
+					//item.EdbDataId = v.EdbDataId
+					item.DataTimestamp = timestamp
+					items.Items = append(items.Items, item)
+				}
+				result.List = append(result.List, items)
+			}
+		}
+	}
+	return
+}

+ 18 - 0
routers/commentsRouter.go

@@ -97,6 +97,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"] = append(beego.GlobalControllerRouter["eta/eta_hub/controllers:EdbController"],
+        beego.ControllerComments{
+            Method: "EdbInfoDataSeasonal",
+            Router: `/data/seasonal`,
+            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: "EdbInfoDataTb",
+            Router: `/data/tb`,
+            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",

+ 289 - 0
services/data/edb_data.go

@@ -0,0 +1,289 @@
+package data
+
+import (
+	"errors"
+	"eta/eta_hub/models/data_manage"
+	"eta/eta_hub/utils"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"time"
+)
+
+// GetEdbDataTbz 获取指标的同比值数据
+func GetEdbDataTbz(edbInfo *data_manage.EdbInfo, tmpDataList []*data_manage.EdbDataList, startDateTime time.Time) (dataList []*data_manage.EdbDataList, minValue, maxValue float64, err error) {
+	dataList = make([]*data_manage.EdbDataList, 0)
+
+	// 数据处理
+	var dateArr []string
+	dataMap := make(map[string]*data_manage.EdbDataList)
+	for _, v := range tmpDataList {
+		dateArr = append(dateArr, v.DataTime)
+		dataMap[v.DataTime] = v
+	}
+	for _, av := range dateArr {
+		currentItem, ok := dataMap[av]
+		// 如果找不到当前日期的数据,那么终止当前循环,进入下一循环
+		if !ok {
+			continue
+		}
+		tmpItem := *currentItem
+		var isOk bool //是否计算出来结果
+
+		//当前日期
+		currentDate, tmpErr := time.ParseInLocation(utils.FormatDate, av, time.Local)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		// 如果存在开始日期,同时,当前日期早于开始日期,那么终止当前循环,进入下一循环
+		if !startDateTime.IsZero() && currentDate.Before(startDateTime) {
+			continue
+		}
+		//上一年的日期
+		preDate := currentDate.AddDate(-1, 0, 0)
+		preDateStr := preDate.Format(utils.FormatDate)
+		if findItem, ok := dataMap[preDateStr]; ok { //上一年同期找到
+			tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
+			isOk = true
+		} else {
+			if edbInfo.Frequency == "月度" { //向上和向下,各找一个月
+				for i := 0; i <= 35; i++ {
+					nextDateDay := preDate.AddDate(0, 0, i)
+					nextDateDayStr := nextDateDay.Format(utils.FormatDate)
+					if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
+						tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
+						isOk = true
+						break
+					} else {
+						preDateDay := preDate.AddDate(0, 0, -i)
+						preDateDayStr := preDateDay.Format(utils.FormatDate)
+						if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
+							tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
+							isOk = true
+							break
+						}
+					}
+				}
+			} else if edbInfo.Frequency == "季度" || edbInfo.Frequency == "年度" {
+				if findItem, ok := dataMap[preDateStr]; ok { //上一年同期->下一个月找到
+					tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
+					isOk = true
+					break
+				}
+			} else {
+				nextDateDay := preDate.AddDate(0, 0, 1)
+				nextDateDayStr := nextDateDay.Format(utils.FormatDate)
+
+				preDateDay := preDate.AddDate(0, 0, -1)
+				preDateDayStr := preDateDay.Format(utils.FormatDate)
+
+				for i := 0; i < 35; i++ {
+					if i >= 1 {
+						nextDateDay = nextDateDay.AddDate(0, 0, i)
+						nextDateDayStr = nextDateDay.Format(utils.FormatDate)
+					}
+					if findItem, ok := dataMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
+						tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
+						isOk = true
+						break
+					} else {
+						if i >= 1 {
+							preDateDay = preDate.AddDate(0, 0, -i)
+							preDateDayStr = nextDateDay.Format(utils.FormatDate)
+						}
+						if findItem, ok := dataMap[preDateDayStr]; ok { //上一年同期->上一个月找到
+							tmpItem.Value = TbzDiv(currentItem.Value, findItem.Value)
+							isOk = true
+							break
+						}
+					}
+				}
+			}
+		}
+
+		if isOk {
+			if tmpItem.Value > maxValue {
+				maxValue = tmpItem.Value
+			}
+			if tmpItem.Value < minValue {
+				minValue = tmpItem.Value
+			}
+			dataList = append(dataList, &tmpItem)
+		}
+	}
+
+	return
+}
+
+// GetChartEdbSeasonalData 获取指标的季节性数据
+func GetChartEdbSeasonalData(calendar, startDate string, edbInfo *data_manage.EdbInfo) (resultData interface{}, err error) {
+	var startDateReal string
+	startDateReal = startDate
+	calendarPreYear := 0
+	if calendar == "农历" {
+		newStartDateReal, tmpErr := time.Parse(utils.FormatDate, startDateReal)
+		if tmpErr != nil {
+			err = tmpErr
+			fmt.Println("time.Parse:" + err.Error())
+			return
+		}
+		calendarPreYear = newStartDateReal.Year() - 1
+		newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
+		startDateReal = newStartDateReal.Format(utils.FormatDate)
+	}
+	dataList, err := GetEdbDataList(edbInfo, startDateReal)
+	if err != nil {
+		err = fmt.Errorf("获取指标数据出错 Err:%s", err.Error())
+		return
+	}
+
+	latestDateStr := edbInfo.LatestDate //实际数据的截止日期
+	latestDate, tmpErr := time.Parse(utils.FormatDate, edbInfo.LatestDate)
+	if tmpErr != nil {
+		err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + edbInfo.LatestDate))
+		return
+	}
+	latestDateYear := latestDate.Year() //实际数据截止年份
+
+	if calendar == "农历" {
+		if len(dataList) <= 0 {
+			resultData = new(data_manage.EdbDataResult)
+		} else {
+			result, tmpErr := data_manage.AddCalculateQuarterV4(dataList)
+			if tmpErr != nil {
+				err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
+				return
+			}
+
+			// 处理季节图的截止日期
+			for k, edbDataItems := range result.List {
+				var cuttingDataTimestamp int64
+
+				// 切割的日期时间字符串
+				cuttingDataTimeStr := latestDate.AddDate(0, 0, edbDataItems.BetweenDay).Format(utils.FormatDate)
+				//如果等于最后的实际日期,那么遍历找到该日期对应的时间戳,并将其赋值为 切割时间戳
+				if edbDataItems.Year >= latestDateYear {
+					for _, tmpData := range edbDataItems.Items {
+						if tmpData.DataTime == cuttingDataTimeStr {
+							cuttingDataTimestamp = tmpData.DataTimestamp
+							break
+						}
+					}
+				}
+				edbDataItems.CuttingDataTimestamp = cuttingDataTimestamp
+				result.List[k] = edbDataItems
+			}
+			//fmt.Println("result", result.List[0].Items[0].DataTime)
+			//fmt.Println("calendarPreYear:", calendarPreYear)
+			//fmt.Println("result.List[0].Year", result.List[0].Year)
+			if result.List[0].Year != calendarPreYear {
+				itemList := make([]*data_manage.EdbDataList, 0)
+				items := new(data_manage.EdbDataItems)
+				//items.Year = calendarPreYear
+				items.Items = itemList
+
+				newResult := new(data_manage.EdbDataResult)
+				newResult.List = append(newResult.List, items)
+				newResult.List = append(newResult.List, result.List...)
+				resultData = newResult
+			} else {
+				resultData = result
+			}
+		}
+
+	} else {
+		currentYear := time.Now().Year()
+
+		quarterDataList := make([]*data_manage.QuarterData, 0)
+		quarterMap := make(map[int][]*data_manage.EdbDataList)
+		var quarterArr []int
+
+		for _, v := range dataList {
+			itemDate, tmpErr := time.Parse(utils.FormatDate, v.DataTime)
+			if tmpErr != nil {
+				err = errors.New("季度指标日期转换,Err:" + tmpErr.Error() + ";DataTime:" + v.DataTime)
+				return
+			}
+			year := itemDate.Year()
+			newItemDate := itemDate.AddDate(currentYear-year, 0, 0)
+			timestamp := newItemDate.UnixNano() / 1e6
+			v.DataTimestamp = timestamp
+			if findVal, ok := quarterMap[year]; !ok {
+				quarterArr = append(quarterArr, year)
+				findVal = append(findVal, v)
+				quarterMap[year] = findVal
+			} else {
+				findVal = append(findVal, v)
+				quarterMap[year] = findVal
+			}
+		}
+		for _, v := range quarterArr {
+			itemList := quarterMap[v]
+			quarterItem := new(data_manage.QuarterData)
+			quarterItem.Year = v
+			quarterItem.DataList = itemList
+
+			//如果等于最后的实际日期,那么将切割时间戳记录
+			if v == latestDateYear {
+				var cuttingDataTimestamp int64
+				for _, tmpData := range itemList {
+					if tmpData.DataTime == latestDateStr {
+						cuttingDataTimestamp = tmpData.DataTimestamp
+						break
+					}
+				}
+				quarterItem.CuttingDataTimestamp = cuttingDataTimestamp
+			} else if v > latestDateYear {
+				//如果大于最后的实际日期,那么第一个点就是切割的时间戳
+				if len(itemList) > 0 {
+					quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
+				}
+			}
+			quarterDataList = append(quarterDataList, quarterItem)
+		}
+		resultData = quarterDataList
+	}
+	return
+}
+
+// TbzDiv 同比值计算
+func TbzDiv(a, b float64) float64 {
+	var valFloat float64
+	if b != 0 {
+		af := decimal.NewFromFloat(a)
+		bf := decimal.NewFromFloat(b)
+		val, _ := af.Div(bf).Float64()
+		val = val - 1
+		valFloat, _ = decimal.NewFromFloat(val).Round(4).Float64()
+	} else {
+		valFloat = 0
+	}
+	return valFloat
+}
+
+// GetEdbDataList 获取指标数据
+func GetEdbDataList(edbInfo *data_manage.EdbInfo, startDate string) (dataList []*data_manage.EdbDataList, err error) {
+	var list []*data_manage.EdbData
+	switch edbInfo.EdbInfoType {
+	case 0:
+		dataOb := new(data_manage.EdbData)
+		list, err = dataOb.GetItemsBySourceAndCode(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbCode, startDate, []string{}, "data_time ASC")
+	//case 1:
+	//_, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, startDate, endDate, false)
+	default:
+		err = errors.New(fmt.Sprint("获取失败,不支持预测指标", edbInfo.EdbInfoType))
+
+	}
+	if err != nil {
+		return
+	}
+
+	if len(list) <= 0 {
+		return
+	}
+
+	for _, v := range list {
+		dataList = append(dataList, data_manage.FormatEdbData2List(v))
+	}
+	return
+}