xyxie 1 рік тому
батько
коміт
24fe890396

+ 42 - 153
controllers/chart.go

@@ -7,7 +7,6 @@ import (
 	"eta/eta_chart_lib/services/data"
 	"eta/eta_chart_lib/utils"
 	"fmt"
-	"strconv"
 	"strings"
 	"time"
 )
@@ -74,88 +73,16 @@ func (this *ChartController) ChartInfoDetail() {
 	}
 	startDate := chartInfo.StartDate
 	endDate := chartInfo.EndDate
-	seasonStartDate := chartInfo.SeasonStartDate
-	seasonEndDate := chartInfo.SeasonEndDate
+	//seasonStartDate := chartInfo.SeasonStartDate
+	//seasonEndDate := chartInfo.SeasonEndDate
 	calendar := chartInfo.Calendar
 	chartType := chartInfo.ChartType
+	startYear := chartInfo.StartYear
 
 	if calendar == "" {
 		calendar = "公历"
 	}
 
-	switch dateType {
-	case 1:
-		startDate = "2000-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 2:
-		startDate = "2010-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 3:
-		startDate = "2015-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 4:
-		startDate = strconv.Itoa(time.Now().Year()) + "-01-01"
-		startDate = "2021-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 5:
-		startDate = startDate + "-01"
-		endDate = endDate + "-01"
-	case 6:
-		//startDate = startDate + "-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 7:
-		startDate = "2018-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 8:
-		startDate = "2019-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 9:
-		startDate = "2020-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 11:
-		startDate = "2022-01-01"
-		endDate = ""
-	}
-
-	// 兼容日期错误
-	{
-		if strings.Count(startDate, "-") == 1 {
-			startDate = startDate + "-01"
-		}
-		if strings.Count(endDate, "-") == 1 {
-			endDate = endDate + "-01"
-		}
-	}
-
-	if chartType == 2 {
-		if seasonStartDate != "" {
-			startDate = seasonStartDate + "-01"
-		} else {
-			fivePre := time.Now().AddDate(-4, 0, 0).Year()
-			startDate = strconv.Itoa(fivePre) + "-01-01"
-		}
-		if seasonEndDate != "" {
-			seasonEndDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, seasonEndDate+"-01", time.Local)
-			if tmpErr != nil {
-				br.Msg = "获取失败"
-				br.ErrMsg = "获取图表,指标信息失败,Err:" + tmpErr.Error()
-				return
-			}
-			endDate = seasonEndDateTime.AddDate(0, 1, -1).Format(utils.FormatDate)
-		} else {
-			//endDate = time.Now().Format(utils.FormatDate)
-			endDate = ""
-		}
-	}
-
 	mappingList, err := models.GetChartEdbMappingList(chartInfoId)
 	if err != nil {
 		br.Msg = "获取失败"
@@ -163,6 +90,25 @@ func (this *ChartController) ChartInfoDetail() {
 		return
 	}
 
+	yearMax := 0
+	if dateType == utils.DateTypeNYears {
+		for _, v := range mappingList {
+			if v.LatestDate != "" {
+				lastDateT, tErr := time.Parse(utils.FormatDate, v.LatestDate)
+				if tErr != nil {
+					br.Msg = "获取失败"
+					br.ErrMsg = "获取图表日期信息失败,Err:" + tErr.Error()
+					return
+				}
+				if lastDateT.Year() > yearMax {
+					yearMax = lastDateT.Year()
+				}
+			}
+		}
+	}
+	// 开始/结束日期
+	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax)
+
 	extraConfigStr := chartInfo.ExtraConfig
 	// 柱方图的一些配置
 	var barConfig data_manage.BarChartInfoReq
@@ -181,7 +127,7 @@ func (this *ChartController) ChartInfoDetail() {
 		extraConfigStr = chartInfo.BarConfig
 	}
 
-	edbList, xEdbIdValue, yDataList, dataResp, err, errMsg := data.GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr)
+	edbList, xEdbIdValue, yDataList, dataResp, err, errMsg := data.GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr, chartInfo.SeasonExtraConfig)
 	if err != nil {
 		br.Msg = "获取失败"
 		if errMsg != `` {
@@ -347,8 +293,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, key string) (
 	}
 	startDate := chartInfo.StartDate
 	endDate := chartInfo.EndDate
-	seasonStartDate := chartInfo.SeasonStartDate
-	seasonEndDate := chartInfo.SeasonEndDate
+	startYear := chartInfo.StartYear
 	calendar := chartInfo.Calendar
 	chartType := chartInfo.ChartType
 
@@ -356,85 +301,29 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, key string) (
 		calendar = "公历"
 	}
 
-	switch dateType {
-	case 1:
-		startDate = "2000-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 2:
-		startDate = "2010-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 3:
-		startDate = "2015-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 4:
-		startDate = strconv.Itoa(time.Now().Year()) + "-01-01"
-		startDate = "2021-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 5:
-		startDate = startDate + "-01"
-		endDate = endDate + "-01"
-	case 6:
-		//startDate = startDate + "-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 7:
-		startDate = "2018-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 8:
-		startDate = "2019-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 9:
-		startDate = "2020-01-01"
-		//endDate = time.Now().Format(utils.FormatDate)
-		endDate = ""
-	case 11:
-		startDate = "2022-01-01"
-		endDate = ""
-	}
-
-	// 兼容日期错误
-	{
-		if strings.Count(startDate, "-") == 1 {
-			startDate = startDate + "-01"
-		}
-		if strings.Count(endDate, "-") == 1 {
-			endDate = endDate + "-01"
-		}
-	}
-
-	if chartType == 2 {
-		if seasonStartDate != "" {
-			startDate = seasonStartDate + "-01"
-		} else {
-			fivePre := time.Now().AddDate(-4, 0, 0).Year()
-			startDate = strconv.Itoa(fivePre) + "-01-01"
-		}
-		if seasonEndDate != "" {
-			seasonEndDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, seasonEndDate+"-01", time.Local)
-			if tmpErr != nil {
-				msg = "获取失败"
-				errMsg = "获取图表,指标信息失败,Err:" + tmpErr.Error()
-				return
-			}
-			endDate = seasonEndDateTime.AddDate(0, 1, -1).Format(utils.FormatDate)
-		} else {
-			//endDate = time.Now().Format(utils.FormatDate)
-			endDate = ""
-		}
-	}
-
 	mappingList, err := models.GetChartEdbMappingList(chartInfoId)
 	if err != nil {
 		msg = "获取失败"
 		errMsg = "获取图表,指标信息失败,Err:" + err.Error()
 		return
 	}
+	yearMax := 0
+	if dateType == utils.DateTypeNYears {
+		for _, v := range mappingList {
+			if v.LatestDate != "" {
+				lastDateT, tErr := time.Parse(utils.FormatDate, v.LatestDate)
+				if tErr != nil {
+					msg = "获取失败"
+					errMsg = "获取图表日期信息失败,Err:" + tErr.Error()
+					return
+				}
+				if lastDateT.Year() > yearMax {
+					yearMax = lastDateT.Year()
+				}
+			}
+		}
+	}
+	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax)
 
 	extraConfigStr := chartInfo.ExtraConfig
 	// 柱方图的一些配置
@@ -454,7 +343,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfo, key string) (
 		extraConfigStr = chartInfo.BarConfig
 	}
 
-	edbList, xEdbIdValue, yDataList, dataResp, err, tmpErrMsg := data.GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr)
+	edbList, xEdbIdValue, yDataList, dataResp, err, tmpErrMsg := data.GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr, chartInfo.SeasonExtraConfig)
 	if err != nil {
 		msg = "获取失败"
 		if tmpErrMsg != `` {

+ 65 - 27
models/chart.go

@@ -12,33 +12,35 @@ import (
 )
 
 type ChartInfo struct {
-	ChartInfoId     int       `json:"-" orm:"column(chart_info_id);pk"`
-	ChartName       string    `description:"来源名称"`
-	ChartNameEn     string    `description:"英文图表名称"`
-	ChartClassifyId int       `json:"-" description:"图表分类id"`
-	SysUserId       int       `json:"-"`
-	SysUserRealName string    `json:"-"`
-	UniqueCode      string    `description:"图表唯一编码"`
-	CreateTime      time.Time `json:"-"`
-	ModifyTime      time.Time `json:"-"`
-	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:"图表图片"`
-	BarConfig       string    `description:"柱方图的配置,json数据" json:"-"`
-	LeftMin         string    `description:"图表左侧最小值"`
-	LeftMax         string    `description:"图表左侧最大值"`
-	Source          int       `description:"1:ETA图库;2:商品价格曲线"`
-	UnitEn          string    `description:"英文图表名称"`
-	ExtraConfig     string    `description:"图表额外配置,json数据" json:"-"`
-	ChartSource     string    `description:"图表来源str"`
-	ChartSourceEn   string    `description:"图表来源(英文)"`
+	ChartInfoId       int       `json:"-" orm:"column(chart_info_id);pk"`
+	ChartName         string    `description:"来源名称"`
+	ChartNameEn       string    `description:"英文图表名称"`
+	ChartClassifyId   int       `json:"-" description:"图表分类id"`
+	SysUserId         int       `json:"-"`
+	SysUserRealName   string    `json:"-"`
+	UniqueCode        string    `description:"图表唯一编码"`
+	CreateTime        time.Time `json:"-"`
+	ModifyTime        time.Time `json:"-"`
+	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:"图表图片"`
+	BarConfig         string    `description:"柱方图的配置,json数据" json:"-"`
+	LeftMin           string    `description:"图表左侧最小值"`
+	LeftMax           string    `description:"图表左侧最大值"`
+	Source            int       `description:"1:ETA图库;2:商品价格曲线"`
+	UnitEn            string    `description:"英文图表名称"`
+	ExtraConfig       string    `description:"图表额外配置,json数据" json:"-"`
+	ChartSource       string    `description:"图表来源str"`
+	ChartSourceEn     string    `description:"图表来源(英文)"`
+	SeasonExtraConfig string    `description:"季节性图表中的配置,json数据"`
+	StartYear         int       `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
 }
 
 func GetChartInfoByUniqueCode(uniqueCode string) (item *ChartInfo, err error) {
@@ -157,6 +159,16 @@ 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 ChartInfoDetailResp struct {
@@ -388,3 +400,29 @@ type CorrelationInfo struct {
 	PeriodData      string `description:"X轴-期数数据"`
 	CorrelationData string `description:"Y轴-相关性系数"`
 }
+
+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 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]
+}

+ 380 - 91
services/data/chart_info.go

@@ -11,6 +11,7 @@ import (
 	"github.com/shopspring/decimal"
 	"math"
 	"sort"
+	"strconv"
 	"time"
 )
 
@@ -61,7 +62,7 @@ func GetLeadUnitEn(unit string) (unitEn string) {
 }
 
 // GetChartEdbData 获取图表的指标数据
-func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, extraConfigStr string) (edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, yDataList []models.YData, dataResp interface{}, err error, errMsg string) {
+func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, extraConfigStr, seasonExtraConfig string) (edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, yDataList []models.YData, dataResp interface{}, err error, errMsg string) {
 	edbList = make([]*models.ChartEdbInfoMapping, 0)
 	// 指标对应的所有数据
 	xEdbIdValue = make([]int, 0)
@@ -102,7 +103,7 @@ func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate st
 	}
 
 	// 指标对应的所有数据
-	edbDataListMap, edbList, err := getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
+	edbDataListMap, edbList, err := getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig)
 	if err != nil {
 		return
 	}
@@ -137,13 +138,13 @@ func GetChartEdbData(chartInfoId, chartType int, calendar, startDate, endDate st
 }
 
 // GetEdbDataMapList 获取指标最后的基础数据
-func GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
-	edbDataListMap, edbList, err = getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
+func GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, seasonExtraConfig string) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
+	edbDataListMap, edbList, err = getEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig)
 	return
 }
 
 // getEdbDataMapList 获取指标最后的基础数据
-func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
+func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, seasonExtraConfig string) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
 	// 指标对应的所有数据
 	edbDataListMap = make(map[int][]*models.EdbDataList)
 
@@ -284,13 +285,6 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 
 		if chartType == 2 {
 			latestDateStr := v.LatestDate //实际数据的截止日期
-			latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
-			if tmpErr != nil {
-				err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
-				return
-			}
-			latestDateYear := latestDate.Year() //实际数据截止年份
-
 			if calendar == "农历" {
 				if len(dataList) <= 0 {
 					result := new(models.EdbDataResult)
@@ -302,89 +296,19 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 						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
-					}
-
-					if result.List[0].Year != calendarPreYear {
-						itemList := make([]*models.EdbDataList, 0)
-						items := new(models.EdbDataItems)
-						//items.Year = calendarPreYear
-						items.Items = itemList
-
-						newResult := new(models.EdbDataResult)
-						newResult.List = append(newResult.List, items)
-						newResult.List = append(newResult.List, result.List...)
-						item.DataList = newResult
-					} else {
-						item.DataList = result
+					quarterDataList, tErr := GetSeasonEdbInfoDataListByXDateNong(result, latestDateStr, seasonExtraConfig, calendarPreYear)
+					if tErr != nil {
+						err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
+						return
 					}
+					item.DataList = quarterDataList
 				}
 
 			} else {
-				currentYear := time.Now().Year()
-
-				quarterDataList := make([]*models.QuarterData, 0)
-				quarterMap := make(map[int][]*models.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(models.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)
+				quarterDataList, tErr := GetSeasonEdbInfoDataListByXDate(dataList, latestDateStr, seasonExtraConfig)
+				if tErr != nil {
+					err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
+					return
 				}
 				item.DataList = quarterDataList
 			}
@@ -399,6 +323,371 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 	return
 }
 
+// GetSeasonEdbInfoDataListByXDate 季节性图的指标数据根据横轴展示
+func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDateStr string, seasonExtraConfig string) (quarterDataListSort models.QuarterDataList, err error) {
+	xStartDate := "01-01"
+	xEndDate := "12-31"
+	jumpYear := 0
+	legends := make([]models.SeasonChartLegend, 0)
+	var seasonExtra models.SeasonExtraItem
+	if seasonExtraConfig != "" {
+		err = json.Unmarshal([]byte(seasonExtraConfig), &seasonExtra)
+		if err != nil {
+			return
+		}
+	}
+
+	if seasonExtra.XStartDate != "" {
+		xStartDate = seasonExtra.XStartDate
+		xEndDate = seasonExtra.XEndDate
+		jumpYear = seasonExtra.JumpYear
+		legends = seasonExtra.ChartLegend
+	}
+
+	length := len(dataList)
+	if length == 0 {
+		return
+	}
+	legendMap := make(map[string]string)
+	if len(legends) > 0 {
+		for _, v := range legends {
+			legendMap[v.Name] = v.Value
+		}
+	}
+	//判断横轴的两个时间之间是不是跨年了,如果跨年了,则横轴截止年份比起始年份+1,如果不跨年,截止年份等于起始年份
+	//根据数据确定最早的年份,和最近年份
+	//根据横轴的日期,汇总所有的年份
+	startDate := dataList[0].DataTime
+	startDateT, tmpErr := time.Parse(utils.FormatDate, startDate)
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+	startYear := startDateT.Year()
+	//获取数据的最新日期
+	lastDate := dataList[length-1].DataTime
+	lastDateT, tmpErr := time.Parse(utils.FormatDate, lastDate)
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+	endYear := lastDateT.Year()
+	dataMap := make(map[string]models.QuarterXDateItem)
+
+	quarterDataList := make([]*models.QuarterData, 0)
+	quarterMap := make(map[string][]*models.EdbDataList)
+
+	//整理出日期
+	leftNameFlag := true
+	for currentStartYear := startYear; currentStartYear <= endYear; currentStartYear++ {
+		startStr := fmt.Sprintf("%d-%s", currentStartYear, xStartDate)
+		currentEndYear := currentStartYear
+		if jumpYear == 1 {
+			currentEndYear = currentStartYear + 1
+		}
+		endStr := fmt.Sprintf("%d-%s", currentEndYear, xEndDate)
+		name := fmt.Sprintf("%s_%s", startStr, endStr)
+		showName := fmt.Sprintf("%d_%d", currentStartYear, currentEndYear)
+
+		startT, tEr := time.Parse(utils.FormatDate, startStr)
+		if tEr != nil {
+			err = tEr
+			return
+		}
+
+		endT, tEr := time.Parse(utils.FormatDate, endStr)
+		if tEr != nil {
+			err = tEr
+			return
+		}
+
+		if lastDateT.Before(startT) {
+			//如果最新的日期在起始日之前,则跳出循环
+			break
+		}
+
+		if startT.Before(lastDateT) && endT.After(lastDateT) {
+			if endYear > currentStartYear {
+				leftNameFlag = false
+			}
+		}
+		item := models.QuarterXDateItem{
+			StartDate: startT,
+			EndDate:   endT,
+			ShowName:  showName,
+		}
+		dataMap[name] = item
+	}
+
+	for k, v := range dataMap {
+		if leftNameFlag {
+			v.ChartLegend = strconv.Itoa(v.StartDate.Year())
+		} else {
+			v.ChartLegend = strconv.Itoa(v.EndDate.Year())
+		}
+		dataMap[k] = v
+	}
+
+	nowYear := time.Now().Year()
+	for _, v := range dataList {
+		dataTimeT, _ := time.Parse(utils.FormatDate, v.DataTime)
+		year := dataTimeT.Year()
+		newItemDate := dataTimeT.AddDate(nowYear-year, 0, 0)
+		for k, dateItem := range dataMap {
+			if (dateItem.StartDate.Before(dataTimeT) && dateItem.EndDate.After(dataTimeT)) || dateItem.StartDate == dataTimeT || dateItem.EndDate == dataTimeT {
+				if jumpYear == 1 {
+					//计算前一年最大的日期, 只补齐数据到去年
+					beforeYearMaxDate := fmt.Sprintf("%d-12-31", dateItem.StartDate.Year())
+					beforeYearMaxDateT, _ := time.Parse(utils.FormatDate, beforeYearMaxDate)
+					if dataTimeT.Before(beforeYearMaxDateT) || dataTimeT == beforeYearMaxDateT {
+						newItemDate = dataTimeT.AddDate(nowYear-year-1, 0, 0)
+					}
+				}
+				timestamp := newItemDate.UnixNano() / 1e6
+				v.DataTimestamp = timestamp
+				if findVal, ok := quarterMap[k]; !ok {
+					findVal = append(findVal, v)
+					quarterMap[k] = findVal
+				} else {
+					findVal = append(findVal, v)
+					quarterMap[k] = findVal
+				}
+
+				if v.DataTime == latestDateStr {
+					dateItem.CuttingDataTimestamp = v.DataTimestamp
+					dataMap[k] = dateItem
+				}
+				break
+			}
+		}
+	}
+	latestDate, _ := time.Parse(utils.FormatDate, latestDateStr)
+	for k, v := range dataMap {
+		itemList := quarterMap[k]
+		quarterItem := new(models.QuarterData)
+		quarterItem.Years = v.ShowName
+		quarterItem.ChartLegend = v.ChartLegend
+		if le, ok := legendMap[v.ShowName]; ok {
+			quarterItem.ChartLegend = le
+		}
+		quarterItem.DataList = itemList
+		quarterItem.CuttingDataTimestamp = v.CuttingDataTimestamp
+
+		//如果等于最后的实际日期,那么将切割时间戳记录
+		if quarterItem.CuttingDataTimestamp == 0 {
+			//如果大于最后的实际日期,那么第一个点就是切割的时间戳
+			if latestDate.Before(v.StartDate) && len(itemList) > 0 {
+				quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
+			}
+		}
+		quarterDataList = append(quarterDataList, quarterItem)
+	}
+
+	// todo 处理图例名称
+	if len(quarterDataList) > 0 {
+		quarterDataListSort = quarterDataList
+		sort.Sort(quarterDataListSort)
+	}
+	return
+}
+
+// GetSeasonEdbInfoDataListByXDateNong 季节性图的指标数据根据横轴选择农历时展示
+func GetSeasonEdbInfoDataListByXDateNong(result *models.EdbDataResult, latestDateStr string, seasonExtraConfig string, calendarPreYear int) (quarterDataListSort models.QuarterDataList, err error) {
+	xStartDate := "01-01"
+	xEndDate := "12-31"
+	jumpYear := 0
+	legends := make([]models.SeasonChartLegend, 0)
+	var seasonExtra models.SeasonExtraItem
+	if seasonExtraConfig != "" {
+		err = json.Unmarshal([]byte(seasonExtraConfig), &seasonExtra)
+		if err != nil {
+			return
+		}
+	}
+
+	if seasonExtra.XStartDate != "" {
+		xStartDate = seasonExtra.XStartDate
+		xEndDate = seasonExtra.XEndDate
+		jumpYear = seasonExtra.JumpYear
+		legends = seasonExtra.ChartLegend
+	}
+
+	length := len(result.List)
+	if length == 0 {
+		return
+	}
+	legendMap := make(map[string]string)
+	if len(legends) > 0 {
+		for _, v := range legends {
+			legendMap[v.Name] = v.Value
+		}
+	}
+	//判断横轴的两个时间之间是不是跨年了,如果跨年了,则横轴截止年份比起始年份+1,如果不跨年,截止年份等于起始年份
+	//根据数据确定最早的年份,和最近年份
+	//根据横轴的日期,汇总所有的年份
+	startYear := calendarPreYear
+	itemLength := len(result.List[length-1].Items)
+	//获取数据的最新日期
+	lastDate := result.List[length-1].Items[itemLength-1].DataTime
+	lastDateT, tmpErr := time.Parse(utils.FormatDate, lastDate)
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+	endYear := lastDateT.Year()
+	dataMap := make(map[string]models.QuarterXDateItem)
+
+	quarterDataList := make([]*models.QuarterData, 0)
+	resultData := make([]*models.QuarterData, 0)
+	quarterMap := make(map[string][]*models.EdbDataList)
+	//整理出日期
+	leftNameFlag := true
+	for currentStartYear := startYear; currentStartYear <= endYear; currentStartYear++ {
+		startStr := fmt.Sprintf("%d-%s", currentStartYear, xStartDate)
+		currentEndYear := currentStartYear
+		if jumpYear == 1 {
+			currentEndYear = currentStartYear + 1
+		}
+		endStr := fmt.Sprintf("%d-%s", currentEndYear, xEndDate)
+		showName := fmt.Sprintf("%d_%d", currentStartYear, currentEndYear)
+
+		startT, tEr := time.Parse(utils.FormatDate, startStr)
+		if tEr != nil {
+			err = tEr
+			return
+		}
+
+		endT, tEr := time.Parse(utils.FormatDate, endStr)
+		if tEr != nil {
+			err = tEr
+			return
+		}
+
+		if lastDateT.Before(startT) {
+			//如果最新的日期在起始日之前,则跳出循环
+			break
+		}
+
+		if (startT.Before(lastDateT) && endT.After(lastDateT)) || startT == lastDateT || endT == lastDateT {
+			if endYear > currentStartYear {
+				leftNameFlag = false
+			}
+		}
+		item := models.QuarterXDateItem{
+			StartDate: startT,
+			EndDate:   endT,
+			ShowName:  showName,
+		}
+		dataMap[showName] = item
+	}
+	for k, v := range dataMap {
+		if leftNameFlag {
+			v.ChartLegend = strconv.Itoa(v.StartDate.Year())
+		} else {
+			v.ChartLegend = strconv.Itoa(v.EndDate.Year())
+		}
+		dataMap[k] = v
+	}
+
+	yearDataListMap := make(map[int]*models.EdbDataItems)
+
+	for _, lv := range result.List {
+		yearDataListMap[lv.Year] = lv
+	}
+
+	//判断哪些点应该落在同一条时间线上
+	maxY := 0
+	for _, lv := range result.List {
+		for _, item := range lv.Items {
+			dataTimeT, _ := time.Parse(utils.FormatDate, item.DataTime)
+			if dataTimeT.Year() > maxY {
+				maxY = dataTimeT.Year()
+			}
+		}
+	}
+	endTmp := fmt.Sprintf("%d-%s", maxY, xEndDate)
+	endTmpT, _ := time.Parse(utils.FormatDate, endTmp)
+	minY := maxY
+	if jumpYear == 1 {
+		minY = maxY - 1
+	}
+	startTmp := fmt.Sprintf("%d-%s", minY, xStartDate)
+	startTmpT, _ := time.Parse(utils.FormatDate, startTmp)
+
+	for name, dateItem := range dataMap {
+		lv, ok1 := yearDataListMap[dateItem.EndDate.Year()]
+		if result.List[0].Year == calendarPreYear {
+			lv, ok1 = yearDataListMap[dateItem.StartDate.Year()]
+		}
+		if !ok1 {
+			break
+		}
+
+		for _, item := range lv.Items {
+			dataTimeT, _ := time.Parse(utils.FormatDate, item.DataTime)
+			//查出当前年份里最大的数据的年份,和第二大的年份
+			if (startTmpT.Before(dataTimeT) && endTmpT.After(dataTimeT)) || startTmpT == dataTimeT || endTmpT == dataTimeT {
+				if findVal, ok := quarterMap[name]; !ok {
+					findVal = append(findVal, item)
+					quarterMap[name] = findVal
+				} else {
+					findVal = append(findVal, item)
+					quarterMap[name] = findVal
+				}
+				// todo 统计截止日
+				if lv.Year == endYear && item.DataTime == latestDateStr {
+					if dv, ok1 := dataMap[name]; ok1 {
+						dv.CuttingDataTimestamp = item.DataTimestamp
+						dataMap[name] = dv
+					}
+				}
+			}
+		}
+	}
+
+	latestDate, _ := time.Parse(utils.FormatDate, latestDateStr)
+	for k, v := range dataMap {
+		itemList := quarterMap[k]
+		quarterItem := new(models.QuarterData)
+		quarterItem.Years = v.ShowName
+		quarterItem.ChartLegend = v.ChartLegend
+		if le, ok := legendMap[v.ShowName]; ok {
+			quarterItem.ChartLegend = le
+		}
+		quarterItem.DataList = itemList
+		quarterItem.CuttingDataTimestamp = v.CuttingDataTimestamp
+
+		//如果等于最后的实际日期,那么将切割时间戳记录
+		if quarterItem.CuttingDataTimestamp == 0 {
+			//如果大于最后的实际日期,那么第一个点就是切割的时间戳
+			if latestDate.Before(v.StartDate) && len(itemList) > 0 {
+				quarterItem.CuttingDataTimestamp = itemList[0].DataTimestamp - 100
+			}
+		}
+		quarterDataList = append(quarterDataList, quarterItem)
+	}
+
+	if result.List[0].Year != calendarPreYear {
+		itemList := make([]*models.EdbDataList, 0)
+		items := new(models.QuarterData)
+		//items.Year = calendarPreYear
+		items.DataList = itemList
+
+		newResult := make([]*models.QuarterData, 0)
+		newResult = append(newResult, items)
+		newResult = append(newResult, quarterDataList...)
+		resultData = newResult
+	} else {
+		resultData = quarterDataList
+	}
+
+	if len(quarterDataList) > 0 {
+		quarterDataListSort = resultData
+		sort.Sort(quarterDataListSort)
+	}
+	return
+}
+
 // BarChartData 柱方图的数据处理
 func BarChartData(mappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (edbIdList []int, yDataList []models.YData, err error) {
 	// 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})

+ 1 - 1
services/data/line_equation/chart_info.go

@@ -134,7 +134,7 @@ func GetChartEdbData(chartInfoId int, lineChartInfoConfig request.LineChartInfoR
 	// 指标对应的所有数据
 	chartType := 1 //1:普通图,2:季节性图
 	calendar := "公历"
-	edbDataListMap, edbList, err := data.GetEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList)
+	edbDataListMap, edbList, err := data.GetEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, "")
 	if err != nil {
 		return
 	}

+ 3 - 3
services/data/line_feature/chart_info.go

@@ -15,7 +15,7 @@ func GetStandardDeviationData(chartInfoId int, startDate, endDate string, mappin
 	edbList = make([]*models.ChartEdbInfoMapping, 0)
 
 	// 指标对应的所有数据
-	_, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, startDate, endDate, []*models.ChartEdbInfoMapping{mappingInfo})
+	_, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, startDate, endDate, []*models.ChartEdbInfoMapping{mappingInfo}, "")
 	if err != nil {
 		return
 	}
@@ -88,7 +88,7 @@ func GetPercentileData(chartInfoId int, startDate, endDate string, mappingInfo *
 	}
 	calculateDay := calculateValue * moveUnitDays
 	// 指标对应的所有数据
-	_, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, startDate, endDate, []*models.ChartEdbInfoMapping{mappingInfo})
+	_, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, startDate, endDate, []*models.ChartEdbInfoMapping{mappingInfo}, "")
 	if err != nil {
 		return
 	}
@@ -180,7 +180,7 @@ func GetFrequencyDistributionData(chartInfoId int, mappingInfo *models.ChartEdbI
 	edbList = make([]*models.ChartEdbInfoMapping, 0)
 
 	// 指标对应的所有数据
-	_, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, startDate, endDate, []*models.ChartEdbInfoMapping{mappingInfo})
+	_, edbList, err = data.GetEdbDataMapList(chartInfoId, 1, `公历`, startDate, endDate, []*models.ChartEdbInfoMapping{mappingInfo}, "")
 	if err != nil {
 		return
 	}

+ 61 - 0
utils/common.go

@@ -1003,3 +1003,64 @@ func GetLocalIP() (ip string, err error) {
 	}
 	return
 }
+
+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
+}

+ 1 - 1
utils/constants.go

@@ -14,7 +14,7 @@ const (
 	PageSize20            = 20
 	PageSize30            = 30
 )
-
+const DateTypeNYears = 20 //时间类型为最近N年
 // 手机号,电子邮箱正则
 const (
 	RegularMobile = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0-9])|(17[0-9])|(16[0-9])|(19[0-9]))\\d{8}$" //手机号码