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 }