package services import ( "eta/eta_forum_admin/models" "eta/eta_forum_admin/models/mgodb" "eta/eta_forum_admin/utils" "fmt" "github.com/shopspring/decimal" "time" ) // GetEdbDataList 获取指标的数据(日期正序返回) func GetEdbDataList(endInfoId, edbType int, startDate, endDate string) (list []*models.EdbDataList, err error) { dataList := make([]*mgodb.EdbDataBase, 0) var startDateT, endDateT time.Time if startDate != "" { startDateT, err = time.ParseInLocation(utils.FormatDate, startDate, time.Local) if err != nil { err = fmt.Errorf("日期格式错误 error, %v", err) return } } if endDate != "" { endDateT, err = time.ParseInLocation(utils.FormatDate, endDate, time.Local) if err != nil { err = fmt.Errorf("日期格式错误 error, %v", err) return } } if edbType == 1 { dataList, err = mgodb.GetEdbDataList(endInfoId, startDateT, endDateT) if err != nil { err = fmt.Errorf("查询指标数据出错 error, %v", err) return } } else { dataList, err = mgodb.GetEdbCalculateDataList(endInfoId, startDateT, endDateT) if err != nil { err = fmt.Errorf("查询指标数据出错 error, %v", err) return } } list = make([]*models.EdbDataList, 0) for _, v := range dataList { // 字符串转成浮点数 list = append(list, &models.EdbDataList{ EdbInfoId: v.EdbInfoId, DataTime: v.DataTime.Format(utils.FormatDate), DataTimestamp: v.DataTimestamp, Value: v.Value, }, ) } 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).RoundCeil(4).Float64() } else { valFloat = 0 } return valFloat } // GetEdbDataTbzForSeason 获取指标的同比值数据 func GetEdbDataTbzForSeason(frequency string, tmpDataList []*models.EdbDataList, startDateTime time.Time) (dataList []*models.EdbDataList, minValue, maxValue float64, err error) { dataList = make([]*models.EdbDataList, 0) // 数据处理 var dateArr []string dataMap := make(map[string]*models.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 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 frequency == "季度" || 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 }