|
@@ -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
|
|
|
+}
|