ソースを参照

睿姿得数据爬取

gmy 6 ヶ月 前
コミット
bd2f33884f

+ 26 - 3
services/ruizide/data_processor.go

@@ -272,8 +272,25 @@ func resolverNet() {
 // func fileResolver() {
 func main() {
 	var tableNameList = []string{
-		"Oil_Demand_Signals_Weekly_Report",
-		"Supply_Revision_Analysis",
+		//"Oil_Demand_Signals_Weekly_Report",
+		//"Supply_Revision_Analysis",
+		//"Oil_Market_Cube_Upstream_Supply_Oil_Quality_Api",
+		"Oil_Market_Cube_Upstream_Supply_Oil_Quality_Sulphur",
+		"Oil_Market_Cube_Upstream_Supply_Capacity_Capacity",
+		"Oil_Market_Cube_Upstream_Supply_Production",
+		"Oil_Market_Cube_Upstream_Supply_Production_Wo_Seasonality",
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Reference_Production",
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Production",
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Cut",
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Actual_Cut",
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Compliance",
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Production_Subject_To_Cut",
+		"Oil_Market_Cube_Products_Demand_Products_Demand_Mean",
+		"Oil_Market_Cube_Products_Demand_Products_Demand+Sigma",
+		"Oil_Market_Cube_Products_Demand_Products_Demand-Sigma",
+		"Oil_Market_Cube_Balances_Total_Liquids_Balances",
+		"Oil_Market_Cube_Geography_Latitude",
+		"Oil_Market_Cube_Geography_Longitude",
 	}
 	for _, tableName := range tableNameList {
 		var fileName string
@@ -291,7 +308,7 @@ func main() {
 		sheetNames := f.GetSheetList()
 		for _, sheetName := range sheetNames {
 			fmt.Printf("读取工作表: %s\n", sheetName)
-			if strings.Contains(sheetName, "Content") {
+			/*if strings.Contains(sheetName, "Content") {
 				continue
 			}
 			if strings.Contains(sheetName, "Road Index") {
@@ -309,6 +326,12 @@ func main() {
 			if strings.Contains(sheetName, "Demand - Gasoline") {
 				continue
 			}
+			if strings.Contains(sheetName, "Demand - Diesel") {
+				continue
+			}
+			if strings.Contains(sheetName, "Demand - Jet Fuel") {
+				continue
+			}*/
 
 			// 获取工作表的最大行数
 			maxRow, err := f.GetRows(sheetName) // 直接获取所有行数据

+ 1380 - 36
services/ruizide/processor_business_logic.go

@@ -25,6 +25,7 @@ var classifyMap = map[string]string{
 	"Demand - Maritime Bunker":         "analytics library",
 	"Oil_Demand_Signals_Weekly_Report": "analytics library",
 	"cube dashboards":                  "cube dashboards",
+	"Oil Market Cube":                  "Oil Market Cube",
 }
 
 // RoadIndexProcessor
@@ -464,12 +465,12 @@ func (p *DemandDieselProcessor) Process(tableName string, sheetName string, rowI
 
 	// step_2: 指标
 	// 指标名称
-	indexNameOne := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColTwo
+	indexNameOne := "Demand Diesel" + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
+	indexNameTwo := "Demand Diesel" + "/" + rowData[len(rowData)-3] + "/" + indexNameColTwo
 
 	// 生成指标编码
-	indexCodeOne, err := getIndexId(sheetName, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColOne)
-	indexCodeTwo, err := getIndexId(sheetName, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColTwo)
+	indexCodeOne, err := getIndexId("Demand Diesel", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColOne)
+	indexCodeTwo, err := getIndexId("Demand Diesel", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColTwo)
 
 	var indexInfoList []*models.IndexInfo
 	valueOne, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
@@ -543,12 +544,12 @@ func (p *DemandJetFuelProcessor) Process(tableName string, sheetName string, row
 
 	// step_2: 指标
 	// 指标名称
-	indexNameOne := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColTwo
+	indexNameOne := "Demand Jet Fuel" + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
+	indexNameTwo := "Demand Jet Fuel" + "/" + rowData[len(rowData)-3] + "/" + indexNameColTwo
 
 	// 生成指标编码
-	indexCodeOne, err := getIndexId(sheetName, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColOne)
-	indexCodeTwo, err := getIndexId(sheetName, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColTwo)
+	indexCodeOne, err := getIndexId("Demand Jet Fuel", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColOne)
+	indexCodeTwo, err := getIndexId("Demand Jet Fuel", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColTwo)
 
 	var indexInfoList []*models.IndexInfo
 	valueOne, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
@@ -622,12 +623,12 @@ func (p *DemandMaritimeBunkerProcessor) Process(tableName string, sheetName stri
 
 	// step_2: 指标
 	// 指标名称
-	indexNameOne := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColTwo
+	indexNameOne := "Demand Maritime Bunker" + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
+	indexNameTwo := "Demand Maritime Bunker" + "/" + rowData[len(rowData)-3] + "/" + indexNameColTwo
 
 	// 生成指标编码
-	indexCodeOne, err := getIndexId(sheetName, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColOne)
-	indexCodeTwo, err := getIndexId(sheetName, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColTwo)
+	indexCodeOne, err := getIndexId("Demand Maritime Bunker", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColOne)
+	indexCodeTwo, err := getIndexId("Demand Maritime Bunker", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColTwo)
 
 	var indexInfoList []*models.IndexInfo
 	valueOne, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
@@ -1432,7 +1433,7 @@ func (p *OilDemandAnalysisContinentProcessor) Process(tableName string, sheetNam
 	//indexNameColPrefix := "CountryRevisionGroup"
 
 	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
+	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
 	if err != nil {
 		return nil, err
 	}
@@ -1440,10 +1441,10 @@ func (p *OilDemandAnalysisContinentProcessor) Process(tableName string, sheetNam
 
 	// step_2: 指标
 	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
+	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
 
 	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
+	indexCode, err := getIndexId("Oil Demand Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
 
 	indexInfoMap := make(map[string]string)
 	indexInfoMap[indexCode] = indexName
@@ -1499,7 +1500,7 @@ func (p *OilDemandAnalysisRegionProcessor) Process(tableName string, sheetName s
 	//indexNameColPrefix := "CountryRevisionGroup"
 
 	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
+	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
 	if err != nil {
 		return nil, err
 	}
@@ -1507,10 +1508,10 @@ func (p *OilDemandAnalysisRegionProcessor) Process(tableName string, sheetName s
 
 	// step_2: 指标
 	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
+	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
 
 	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
+	indexCode, err := getIndexId("Oil Demand Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
 
 	indexInfoMap := make(map[string]string)
 	indexInfoMap[indexCode] = indexName
@@ -1566,7 +1567,7 @@ func (p *OilDemandAnalysisCountryProcessor) Process(tableName string, sheetName
 	//indexNameColPrefix := "CountryRevisionGroup"
 
 	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
+	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
 	if err != nil {
 		return nil, err
 	}
@@ -1574,10 +1575,10 @@ func (p *OilDemandAnalysisCountryProcessor) Process(tableName string, sheetName
 
 	// step_2: 指标
 	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
+	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
 
 	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
+	indexCode, err := getIndexId("Oil Demand Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
 
 	indexInfoMap := make(map[string]string)
 	indexInfoMap[indexCode] = indexName
@@ -1633,7 +1634,7 @@ func (p *OilDemandAnalysisProductCategoryProcessor) Process(tableName string, sh
 	//indexNameColPrefix := "CountryRevisionGroup"
 
 	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
+	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
 	if err != nil {
 		return nil, err
 	}
@@ -1641,10 +1642,10 @@ func (p *OilDemandAnalysisProductCategoryProcessor) Process(tableName string, sh
 
 	// step_2: 指标
 	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
+	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
 
 	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
+	indexCode, err := getIndexId("Oil Demand Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
 
 	indexInfoMap := make(map[string]string)
 	indexInfoMap[indexCode] = indexName
@@ -1700,7 +1701,7 @@ func (p *OilDemandAnalysisProductDetailProcessor) Process(tableName string, shee
 	//indexNameColPrefix := "CountryRevisionGroup"
 
 	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
+	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
 	if err != nil {
 		return nil, err
 	}
@@ -1708,10 +1709,10 @@ func (p *OilDemandAnalysisProductDetailProcessor) Process(tableName string, shee
 
 	// step_2: 指标
 	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
+	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
 
 	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
+	indexCode, err := getIndexId("Oil Demand Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
 
 	indexInfoMap := make(map[string]string)
 	indexInfoMap[indexCode] = indexName
@@ -1767,7 +1768,7 @@ func (p *OilDemandAnalysisSectorCategoryProcessor) Process(tableName string, she
 	//indexNameColPrefix := "CountryRevisionGroup"
 
 	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
+	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
 	if err != nil {
 		return nil, err
 	}
@@ -1775,10 +1776,10 @@ func (p *OilDemandAnalysisSectorCategoryProcessor) Process(tableName string, she
 
 	// step_2: 指标
 	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
+	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
 
 	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
+	indexCode, err := getIndexId("Oil Demand Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
 
 	indexInfoMap := make(map[string]string)
 	indexInfoMap[indexCode] = indexName
@@ -1834,7 +1835,7 @@ func (p *OilDemandAnalysisSectorDetailProcessor) Process(tableName string, sheet
 	//indexNameColPrefix := "CountryRevisionGroup"
 
 	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
+	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
 	if err != nil {
 		return nil, err
 	}
@@ -1842,10 +1843,10 @@ func (p *OilDemandAnalysisSectorDetailProcessor) Process(tableName string, sheet
 
 	// step_2: 指标
 	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
+	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
 
 	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
+	indexCode, err := getIndexId("Oil Demand Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
 
 	indexInfoMap := make(map[string]string)
 	indexInfoMap[indexCode] = indexName
@@ -1901,7 +1902,7 @@ func (p *OilDemandAnalysisScenarioProcessor) Process(tableName string, sheetName
 	//indexNameColPrefix := "CountryRevisionGroup"
 
 	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
+	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
 	if err != nil {
 		return nil, err
 	}
@@ -1909,10 +1910,10 @@ func (p *OilDemandAnalysisScenarioProcessor) Process(tableName string, sheetName
 
 	// step_2: 指标
 	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
+	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
 
 	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
+	indexCode, err := getIndexId("Oil Demand Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
 
 	indexInfoMap := make(map[string]string)
 	indexInfoMap[indexCode] = indexName
@@ -1952,6 +1953,1349 @@ func (p *OilDemandAnalysisScenarioProcessor) Process(tableName string, sheetName
 	return dataList, err
 }
 
+// UpstreamSupplyOilQualityApiProcessor
+// @Description: UpstreamSupplyOilQualityApiProcessor处理器
+type UpstreamSupplyOilQualityApiProcessor struct{}
+
+var rzdApiFlag string
+
+func (p *UpstreamSupplyOilQualityApiProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing UpstreamSupplyOilQualityApiProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdApiFlag = rowData[0]
+	} else {
+		rowData[0] = rzdApiFlag
+	}
+
+	frequency := "月度"
+	unit := "°"
+	indexNameColSuffix := "Oil Quality"
+	//indexNameColPrefix := "CountryRevisionGroup"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColSuffix + "/" + "API"
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply "+indexNameColSuffix, strings.ToLower("API"), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOilQualityApiProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOilQualityApiProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// OilMarketCubeUpstreamSupplyOilQualitySulphurProcessor
+// @Description: OilMarketCubeUpstreamSupplyOilQualitySulphurProcessor处理器
+type OilMarketCubeUpstreamSupplyOilQualitySulphurProcessor struct{}
+
+var rzdSulphurFlag string
+
+func (p *OilMarketCubeUpstreamSupplyOilQualitySulphurProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing OilMarketCubeUpstreamSupplyOilQualitySulphurProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdSulphurFlag = rowData[0]
+	} else {
+		rowData[0] = rzdSulphurFlag
+	}
+
+	frequency := "月度"
+	unit := "%wt"
+	indexNameColSuffix := "Oil Quality"
+	//indexNameColPrefix := "CountryRevisionGroup"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColSuffix + "/" + "Sulphur"
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply "+indexNameColSuffix, strings.ToLower("Sulphur"), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("OilMarketCubeUpstreamSupplyOilQualitySulphurProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("OilMarketCubeUpstreamSupplyOilQualitySulphurProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// OilMarketCubeUpstreamSupplyCapacityCapacityProcessor
+// @Description: OilMarketCubeUpstreamSupplyCapacityCapacityProcessor处理器
+type OilMarketCubeUpstreamSupplyCapacityCapacityProcessor struct{}
+
+var rzdCapacityFlag string
+
+func (p *OilMarketCubeUpstreamSupplyCapacityCapacityProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing OilMarketCubeUpstreamSupplyCapacityCapacityProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdCapacityFlag = rowData[0]
+	} else {
+		rowData[0] = rzdCapacityFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColSuffix := "Capacity"
+	//indexNameColPrefix := "CountryRevisionGroup"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply ", strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("OilMarketCubeUpstreamSupplyCapacityCapacityProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("OilMarketCubeUpstreamSupplyCapacityCapacityProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// OilMarketCubeUpstreamSupplyProductionProcessor
+// @Description: OilMarketCubeUpstreamSupplyProductionProcessor处理器
+type OilMarketCubeUpstreamSupplyProductionProcessor struct{}
+
+var rzdProductionFlag string
+
+func (p *OilMarketCubeUpstreamSupplyProductionProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing OilMarketCubeUpstreamSupplyProductionProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdProductionFlag = rowData[0]
+	} else {
+		rowData[0] = rzdProductionFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColSuffix := "Production"
+	//indexNameColPrefix := "CountryRevisionGroup"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply", strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("OilMarketCubeUpstreamSupplyProductionProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("OilMarketCubeUpstreamSupplyProductionProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// UpstreamSupplyProductionWoSeasonalityProcessor
+// @Description: UpstreamSupplyProductionWoSeasonalityProcessor处理器
+type UpstreamSupplyProductionWoSeasonalityProcessor struct{}
+
+var rzdProductionWoSeasonalityFlag string
+
+func (p *UpstreamSupplyProductionWoSeasonalityProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing UpstreamSupplyProductionWoSeasonalityProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdProductionWoSeasonalityFlag = rowData[0]
+	} else {
+		rowData[0] = rzdProductionWoSeasonalityFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColSuffix := "Production Wo Seasonality"
+	//indexNameColPrefix := "CountryRevisionGroup"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply", strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyProductionWoSeasonalityProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyProductionWoSeasonalityProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// UpstreamSupplyOPECPolicyReferenceProductionProcessor
+// @Description: UpstreamSupplyOPECPolicyReferenceProductionProcessor处理器
+type UpstreamSupplyOPECPolicyReferenceProductionProcessor struct{}
+
+var rzdReferenceProductionFlag string
+
+func (p *UpstreamSupplyOPECPolicyReferenceProductionProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing UpstreamSupplyOPECPolicyReferenceProductionProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdReferenceProductionFlag = rowData[0]
+	} else {
+		rowData[0] = rzdReferenceProductionFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Reference Production"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColPrefix + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply "+indexNameColPrefix, strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyReferenceProductionProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyReferenceProductionProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// UpstreamSupplyOPECPolicyTargetProductionProcessor
+// @Description: UpstreamSupplyOPECPolicyTargetProductionProcessor处理器
+type UpstreamSupplyOPECPolicyTargetProductionProcessor struct{}
+
+var rzdTargetProductionFlag string
+
+func (p *UpstreamSupplyOPECPolicyTargetProductionProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing UpstreamSupplyOPECPolicyTargetProductionProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdTargetProductionFlag = rowData[0]
+	} else {
+		rowData[0] = rzdTargetProductionFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Target Production"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColPrefix + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply "+indexNameColPrefix, strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyTargetProductionProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyTargetProductionProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// UpstreamSupplyOPECPolicyTargetCutProcessor
+// @Description: UpstreamSupplyOPECPolicyTargetCutProcessor处理器
+type UpstreamSupplyOPECPolicyTargetCutProcessor struct{}
+
+var rzdTargetCutFlag string
+
+func (p *UpstreamSupplyOPECPolicyTargetCutProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing UpstreamSupplyOPECPolicyTargetCutProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdTargetCutFlag = rowData[0]
+	} else {
+		rowData[0] = rzdTargetCutFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Target Cut"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColPrefix + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply "+indexNameColPrefix, strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyTargetCutProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyTargetCutProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// UpstreamSupplyOPECPolicyActualCutProcessor
+// @Description: UpstreamSupplyOPECPolicyActualCutProcessor处理器
+type UpstreamSupplyOPECPolicyActualCutProcessor struct{}
+
+var rzdActualCutFlag string
+
+func (p *UpstreamSupplyOPECPolicyActualCutProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing UpstreamSupplyOPECPolicyActualCutProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdActualCutFlag = rowData[0]
+	} else {
+		rowData[0] = rzdActualCutFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Actual Cut"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColPrefix + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply "+indexNameColPrefix, strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyActualCutProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyActualCutProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// UpstreamSupplyOPECPolicyComplianceProcessor
+// @Description: UpstreamSupplyOPECPolicyComplianceProcessor处理器
+type UpstreamSupplyOPECPolicyComplianceProcessor struct{}
+
+var rzdComplianceFlag string
+
+func (p *UpstreamSupplyOPECPolicyComplianceProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing UpstreamSupplyOPECPolicyComplianceProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdComplianceFlag = rowData[0]
+	} else {
+		rowData[0] = rzdComplianceFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Compliance"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColPrefix + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply "+indexNameColPrefix, strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyComplianceProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyComplianceProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor
+// @Description: UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor处理器
+type UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor struct{}
+
+var rzdProductionSubjectToCutFlag string
+
+func (p *UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdProductionSubjectToCutFlag = rowData[0]
+	} else {
+		rowData[0] = rzdProductionSubjectToCutFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Production Subject To Cut"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Upstream Supply")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Upstream Supply" + "/" + indexNameColPrefix + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Upstream Supply "+indexNameColPrefix, strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// ProductsDemandProductsDemandMeanProcessor
+// @Description: ProductsDemandProductsDemandMeanProcessor处理器
+type ProductsDemandProductsDemandMeanProcessor struct{}
+
+var rzdProductsDemandMeanFlag string
+
+func (p *ProductsDemandProductsDemandMeanProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing ProductsDemandProductsDemandMeanProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdProductsDemandMeanFlag = rowData[0]
+	} else {
+		rowData[0] = rzdProductsDemandMeanFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	//indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Products Demand Mean (1.0 DG) "
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Products Demand")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Products Demand" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Products Demand "+"Products Demand Mean", strings.ReplaceAll(strings.ToLower("1.0dg"), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("ProductsDemandProductsDemandMeanProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("ProductsDemandProductsDemandMeanProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// ProductsDemandProductsDemandAddSigmaProcessor
+// @Description: ProductsDemandProductsDemandAddSigmaProcessor处理器
+type ProductsDemandProductsDemandAddSigmaProcessor struct{}
+
+var rzdAddSigmaFlag string
+
+func (p *ProductsDemandProductsDemandAddSigmaProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing ProductsDemandProductsDemandAddSigmaProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdAddSigmaFlag = rowData[0]
+	} else {
+		rowData[0] = rzdAddSigmaFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	//indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Products Demand +Sigma (2.2 DG) "
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Products Demand")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Products Demand" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Products Demand "+"Products Demand Sigma", strings.ReplaceAll(strings.ToLower("2.2dg"), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("ProductsDemandProductsDemandAddSigmaProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("ProductsDemandProductsDemandAddSigmaProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// ProductsDemandProductsDemandSubSigmaProcessor
+// @Description: ProductsDemandProductsDemandSubSigmaProcessor处理器
+type ProductsDemandProductsDemandSubSigmaProcessor struct{}
+
+var rzdSubSigmaFlag string
+
+func (p *ProductsDemandProductsDemandSubSigmaProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing ProductsDemandProductsDemandSubSigmaProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdSubSigmaFlag = rowData[0]
+	} else {
+		rowData[0] = rzdSubSigmaFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	//indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Products Demand -Sigma (1.8 DG) "
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Products Demand")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Products Demand" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Products Demand "+"Products Demand Sigma", strings.ReplaceAll(strings.ToLower("1.8dg"), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("ProductsDemandProductsDemandSubSigmaProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("ProductsDemandProductsDemandSubSigmaProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// BalancesTotalLiquidsBalancesProcessor
+// @Description: BalancesTotalLiquidsBalancesProcessor处理器
+type BalancesTotalLiquidsBalancesProcessor struct{}
+
+var rzdTotalLiquidsBalancesFlag string
+
+func (p *BalancesTotalLiquidsBalancesProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing BalancesTotalLiquidsBalancesProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdTotalLiquidsBalancesFlag = rowData[0]
+	} else {
+		rowData[0] = rzdTotalLiquidsBalancesFlag
+	}
+
+	frequency := "月度"
+	unit := "kbbl/d"
+	//indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Total Liquids Balances"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Balances")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Balances" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Balances", strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("BalancesTotalLiquidsBalancesProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("BalancesTotalLiquidsBalancesProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// GeographyLatitudeProcessor
+// @Description: GeographyLatitudeProcessor处理器
+type GeographyLatitudeProcessor struct{}
+
+var rzdLatitudeFlag string
+
+func (p *GeographyLatitudeProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing GeographyLatitudeProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdLatitudeFlag = rowData[0]
+	} else {
+		rowData[0] = rzdLatitudeFlag
+	}
+
+	frequency := "月度"
+	unit := ""
+	//indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Latitude"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Geography")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Geography" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Geography", strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("GeographyLatitudeProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("GeographyLatitudeProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
+// GeographyLongitudeProcessor
+// @Description: GeographyLongitudeProcessor处理器
+type GeographyLongitudeProcessor struct{}
+
+var rzdLongitudeFlag string
+
+func (p *GeographyLongitudeProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
+	logs.Info("Processing GeographyLongitudeProcessor...")
+	if rowIndex <= 1 {
+		return nil, nil
+	}
+
+	if rowData[0] != "" {
+		rzdLongitudeFlag = rowData[0]
+	} else {
+		rowData[0] = rzdLongitudeFlag
+	}
+
+	frequency := "月度"
+	unit := ""
+	//indexNameColPrefix := "OPEC_Policy"
+	indexNameColSuffix := "Longitude"
+
+	if !utils.IsNumeric(rowData[0]) {
+		return nil, nil
+	}
+	if rowData[1] == "Sum" {
+		return nil, nil
+	}
+
+	// step_1: 分类
+	classifyId, err := dealClassify("Oil Market Cube", "Geography")
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("classifyId: %v", classifyId)
+
+	// step_2: 指标
+	// 指标名称
+	indexName := "Geography" + "/" + indexNameColSuffix
+
+	// 生成指标编码
+	indexCode, err := getIndexId("Geography", strings.ReplaceAll(strings.ToLower(indexNameColSuffix), " ", ""), "")
+
+	var indexInfoList []*models.IndexInfo
+	value, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
+	if err != nil {
+		return nil, err
+	}
+
+	dataTime := rowData[0]
+	format, err := utils.ConvertDateFormat6(dataTime + "-" + rowData[1])
+	if err != nil {
+		return nil, err
+	}
+
+	indexInfoList = append(indexInfoList, &models.IndexInfo{
+		IndexName: indexName,
+		IndexCode: indexCode,
+		Value:     value,
+		DataTime:  format,
+	})
+
+	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("GeographyLongitudeProcessor indexInfoList: %v", indexInfoList)
+
+	// step_3: 指标数据
+	dataList, err := dealData(indexInfoList)
+	if err != nil {
+		return nil, err
+	}
+	logs.Info("GeographyLongitudeProcessor dataList: %v", dataList)
+
+	return dataList, err
+}
+
 func dealData(indexInfoList []*models.IndexInfo) ([]models.BaseFromRzdData, error) {
 	var dataList []models.BaseFromRzdData
 	for _, indexInfo := range indexInfoList {

+ 120 - 0
services/ruizide/processor_factory.go

@@ -117,7 +117,127 @@ func GetProcessor(tableName string, sheetName string) (ReportProcessor, error) {
 		default:
 			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
 		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_Oil_Quality_Api" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOilQualityApiProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_Oil_Quality_Sulphur" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &OilMarketCubeUpstreamSupplyOilQualitySulphurProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_Capacity_Capacity" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &OilMarketCubeUpstreamSupplyCapacityCapacityProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_Production" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &OilMarketCubeUpstreamSupplyProductionProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_Production_Wo_Seasonality" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyProductionWoSeasonalityProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Reference_Production" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyReferenceProductionProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Production" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyTargetProductionProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Cut" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyTargetCutProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Actual_Cut" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyActualCutProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Compliance" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyComplianceProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Production_Subject_To_Cut" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Products_Demand_Products_Demand_Mean" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &ProductsDemandProductsDemandMeanProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Products_Demand_Products_Demand+Sigma" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &ProductsDemandProductsDemandAddSigmaProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Products_Demand_Products_Demand-Sigma" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &ProductsDemandProductsDemandSubSigmaProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Balances_Total_Liquids_Balances" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &BalancesTotalLiquidsBalancesProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Geography_Latitude" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &GeographyLatitudeProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Geography_Longitude" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &GeographyLongitudeProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
 	}
+
 	// 可以添加更多的逻辑来处理其他产品和类别
 	return nil, fmt.Errorf("no processor found for tableName %s and sheetName %s", tableName, sheetName)
 }

+ 6 - 0
utils/common.go

@@ -1330,3 +1330,9 @@ func RangeRand(min, max int64) int64 {
 		return min + result.Int64()
 	}
 }
+
+// IsNumeric 判断字符串是否为数字
+func IsNumeric(s string) bool {
+	_, err := strconv.ParseFloat(s, 64) // 或者使用 ParseInt(s, 10, 64) 判断整数
+	return err == nil
+}

+ 31 - 3
utils/date_util.go

@@ -576,9 +576,7 @@ func ConvertDateFormat3(dataText string) (string, error) {
 	}
 
 	// 计算最后一天
-	lastDay := time.Date(year+2000, month.Month(), 0, 0, 0, 0, 0, time.UTC) // year+2000 将年份转为四位数
-	lastDay = lastDay.AddDate(0, 1, 0)                                      // 加一个月
-	lastDay = lastDay.AddDate(0, 0, -1)                                     // 减去一天,得到当前月份的最后一天
+	lastDay := time.Date(year+2000, month.Month()+1, 0, 0, 0, 0, 0, time.UTC) // 直接设置为下个月的第一天,再设为0日得到上个月最后一天
 
 	return lastDay.Format("2006-01-02"), nil
 }
@@ -609,3 +607,33 @@ func ConvertDateFormat5(dataText string) (string, error) {
 	// 格式化为输出格式
 	return dateTime.Format("2006-01-02"), nil
 }
+
+// ConvertDateFormat6 转换时间格式 2023-March --> 2023-03-31
+func ConvertDateFormat6(dataText string) (string, error) {
+	// 拆分年份和月份
+	parts := strings.Split(dataText, "-")
+	if len(parts) != 2 {
+		return "", fmt.Errorf("日期格式不正确")
+	}
+
+	// 提取年份和月份
+	yearStr := parts[0]
+	monthStr := parts[1]
+
+	// 转换年份
+	year, err := strconv.Atoi(yearStr)
+	if err != nil {
+		return "", fmt.Errorf("无效的年份: %v", err)
+	}
+
+	// 获取月份数字
+	month, err := time.Parse("January", monthStr)
+	if err != nil {
+		return "", fmt.Errorf("无效的月份: %v", err)
+	}
+
+	// 获取最后一天
+	lastDay := time.Date(year, month.Month()+1, 0, 0, 0, 0, 0, time.UTC) // 使用月份数字加1,再设为0日得到上个月最后一天
+
+	return lastDay.Format("2006-01-02"), nil
+}