Browse Source

Merge branch 'pool_378_rzd_data_deal' of eta_server/eta_data_analysis into master

chenhan 3 weeks ago
parent
commit
84ef5e0f47

+ 40 - 0
controllers/rzd_controller.go

@@ -0,0 +1,40 @@
+package controllers
+
+import (
+	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/services/ruizide"
+	"eta/eta_data_analysis/utils"
+	"github.com/beego/beego/v2/server/web"
+)
+
+type RzdController struct {
+	web.Controller
+}
+
+// DealData
+// @Title 解析睿咨得数据
+// @Description 合同套餐列表
+// @Param   DayFlag  query  int  false
+// @Param   WeekFlag  query  int  false
+// @Success 200 {object} company.GetUnusualRenewListGroupMonthResp
+// @router /rz_deal_data [post]
+func (this *RzdController) DealData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var err error
+	// 解析文件移动到目标目录
+	err = ruizide.FileResolver()
+	if err != nil {
+		utils.FileLog.Error("睿咨得数据处理失败 err:%v", err)
+		br.Msg = "操作异常"
+		br.ErrMsg = "操作异常,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 2 - 0
models/base.go

@@ -28,7 +28,9 @@ type BaseResponseResult struct {
 
 type RequestResponse[T any] struct {
 	Ret     int    `json:"Ret"`
+	ErrMsg  string `json:"ErrMsg"`
 	Success bool   `json:"Success"`
+	ErrCode string `json:"ErrCode"`
 	Data    T      `json:"Data"` // 这里是你要获取的关键字段
 	Msg     string `json:"Msg"`
 }

+ 19 - 7
models/base_from_rzd_classify.go

@@ -2,11 +2,23 @@
 package models
 
 type BaseFromRzdClassify struct {
-	BaseFromRzdClassifyId int    `orm:"column(base_from_rzd_classify_id);pk"`
-	CreateTime            string `orm:"column(create_time)"`
-	ModifyTime            string `orm:"column(modify_time)"`
-	ClassifyName          string `orm:"column(classify_name)"`
-	ParentId              int    `orm:"column(parent_id)"`
-	Sort                  int    `orm:"column(sort)"`
-	ClassifyNameEn        string `orm:"column(classify_name_en)"`
+	BaseFromRzdClassifyId int
+	CreateTime            string
+	ModifyTime            string
+	ClassifyName          string
+	ParentId              int
+	Sort                  int
+	ClassifyNameEn        string
+}
+type AddRzdClassify struct {
+	ClassifyName   string
+	ParentId       int
+	Sort           int
+	ClassifyNameEn string
+	Children       []AddRzdClassify
+}
+
+type RzdClassifyMapStruct struct {
+	ClassifyName string
+	Sort         int
 }

+ 13 - 7
models/base_from_rzd_data.go

@@ -2,11 +2,17 @@
 package models
 
 type BaseFromRzdData struct {
-	BaseFromRzdDataId  int     `orm:"column(base_from_rzd_data_id);pk"`
-	BaseFromRzdIndexId int     `orm:"column(base_from_rzd_index_id)"`
-	CreateTime         string  `orm:"column(create_time)"`
-	DataTime           string  `orm:"column(data_time)"`
-	IndexCode          string  `orm:"column(index_code)"`
-	ModifyTime         string  `orm:"column(modify_time)"`
-	Value              float64 `orm:"column(value)"`
+	BaseFromRzdDataId  int
+	BaseFromRzdIndexId int
+	DataTime           string
+	IndexCode          string
+	Value              float64
+}
+
+type RzdIndexData struct {
+	BaseFromRzdDataId  int
+	BaseFromRzdIndexId int
+	DataTime           string
+	IndexCode          string
+	Value              float64
 }

+ 17 - 3
models/base_from_rzd_index.go

@@ -2,6 +2,11 @@
 // @Author gmy 2024/8/7 9:38:00
 package models
 
+import (
+	"github.com/shopspring/decimal"
+	"time"
+)
+
 type BaseFromRzdIndex struct {
 	BaseFromRzdIndexId   int    `orm:"column(base_from_rzd_index_id);pk"`
 	CreateTime           string `orm:"column(create_time)"`
@@ -14,9 +19,18 @@ type BaseFromRzdIndex struct {
 }
 
 type IndexInfo struct {
+	StartDate   time.Time
+	EndDate     time.Time
+	LatestValue decimal.Decimal
 	IndexName   string
 	IndexCode   string
-	Value       float64
-	IndexInfoId int
-	DataTime    string
+	Frequency   string
+	Unit        string
+	ClassifyId  int
+	DataList    []IndexData
+}
+
+type IndexData struct {
+	DataTime time.Time
+	Value    decimal.Decimal
 }

+ 9 - 0
routers/commentsRouter.go

@@ -7,6 +7,15 @@ import (
 
 func init() {
 
+    beego.GlobalControllerRouter["eta/eta_data_analysis/controllers:RzdController"] = append(beego.GlobalControllerRouter["eta/eta_data_analysis/controllers:RzdController"],
+        beego.ControllerComments{
+            Method: "DealData",
+            Router: `/rz_deal_data`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_data_analysis/controllers:YongyiController"] = append(beego.GlobalControllerRouter["eta/eta_data_analysis/controllers:YongyiController"],
         beego.ControllerComments{
             Method: "Analysis",

+ 5 - 0
routers/router.go

@@ -19,6 +19,11 @@ func init() {
 				&controllers.YongyiController{},
 			),
 		),
+		web.NSNamespace("/rzd",
+			web.NSInclude(
+				&controllers.RzdController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 8 - 8
services/liangyou/commodity_liangyou.go

@@ -126,7 +126,7 @@ func fetchReportData(ctx context.Context, product, category, report string, keyw
 	if err != nil {
 		return err
 	}
-	logs.Info("categoryPageURL: %s: %s: %s", product, category, categoryPageURL)
+	utils.FileLog.Info("categoryPageURL: %s: %s: %s", product, category, categoryPageURL)
 
 	//var allReportURLs []string
 	var allReportURLMap = make(map[string]string)
@@ -177,7 +177,7 @@ func fetchReportData(ctx context.Context, product, category, report string, keyw
 
 	}
 
-	logs.Info("所有报告 URLs: %s: %s: %v", product, category, allReportURLMap)
+	utils.FileLog.Info("所有报告 URLs: %s: %s: %v", product, category, allReportURLMap)
 
 	if len(allReportURLMap) == 0 {
 		return fmt.Errorf("未找到报告 URL")
@@ -205,7 +205,7 @@ func fetchReportData(ctx context.Context, product, category, report string, keyw
 			}
 
 			if time.Now().Sub(toTime) > 7*24*time.Hour {
-				logs.Info("报告已处理: %s: %s: %s: %s", product, category, report, key)
+				utils.FileLog.Info("报告已处理: %s: %s: %s: %s", product, category, report, key)
 				continue
 			}
 		}
@@ -258,7 +258,7 @@ func fetchReportData(ctx context.Context, product, category, report string, keyw
 			logs.Error("维护指标数据读取进度错误: %s, %s, %v: %v", product, category, key, err)
 			continue
 		}
-		logs.Info("维护指标数据读取进度成功: %s, %s, %v", product, category, key)
+		utils.FileLog.Info("维护指标数据读取进度成功: %s, %s, %v", product, category, key)
 	}
 
 	return nil
@@ -267,7 +267,7 @@ func fetchReportData(ctx context.Context, product, category, report string, keyw
 func fillProductPageURL(ctx context.Context, product string, category string) (string, error) {
 	// 选择 dl 标签下所有 a 标签的 XPath
 	selector := `//dl[contains(@class, 'dl_hot')]//a`
-	logs.Info("选择器表达式: %s", selector)
+	utils.FileLog.Info("选择器表达式: %s", selector)
 
 	var nodes []*cdp.Node
 	var productPageURL string
@@ -295,14 +295,14 @@ func fillProductPageURL(ctx context.Context, product string, category string) (s
 		}
 
 		// 打印获取的 OuterHTML 内容
-		logs.Info("Link OuterHTML: %s", outerHTML)
+		utils.FileLog.Info("Link OuterHTML: %s", outerHTML)
 
 		// 从 OuterHTML 中提取 href 和文本内容
 		// 使用正则或字符串处理提取 href 和文本内容
 		href, linkText := extractHrefAndText(outerHTML)
 
 		// 打印提取的 href 和文本内容
-		logs.Info("Link Text: %s, Href: %s", linkText, href)
+		utils.FileLog.Info("Link Text: %s, Href: %s", linkText, href)
 
 		// 如果文本内容匹配目标产品
 		if linkText == product {
@@ -340,7 +340,7 @@ func fillProductPageURL(ctx context.Context, product string, category string) (s
 	}
 
 	// 返回点击后的页面URL
-	logs.Info("productPageURL: %s", productPageURL)
+	utils.FileLog.Info("productPageURL: %s", productPageURL)
 	return productPageURL, nil
 }
 

+ 33 - 33
services/liangyou/processor_business_logic.go

@@ -32,7 +32,7 @@ type TableData struct {
 type ImportCostProcessor struct{}
 
 func (p *ImportCostProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
-	logs.Info("Processing import cost...")
+	utils.FileLog.Info("Processing import cost...")
 
 	// 解析关键字
 	if len(keywords) < 5 {
@@ -136,7 +136,7 @@ func (p *ImportCostProcessor) Process(ctx context.Context, product string, repor
 
 						indexData := requestResponse.Data
 						if len(indexData) > 0 {
-							logs.Info("ProcessingImportCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+							utils.FileLog.Info("ProcessingImportCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							continue
 						}
 
@@ -262,7 +262,7 @@ func (p *ProcessingProfitProcessor) Process(ctx context.Context, product string,
 
 						indexData := requestResponse.Data
 						if len(indexData) > 0 {
-							logs.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+							utils.FileLog.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							continue
 						}
 
@@ -382,7 +382,7 @@ func (p *ShippingCostProcessor) Process(ctx context.Context, product string, rep
 
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
-						logs.Info("ShippingCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+						utils.FileLog.Info("ShippingCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						continue
 					}
 
@@ -416,7 +416,7 @@ type SupplyDemandBalanceProcessor struct{}
 
 func (p *SupplyDemandBalanceProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
 	// https://www.fao.com.cn/art/gG7gKTCNDHLJNsq9QRYjoQ==.htm
-	logs.Info("Processing processing report...")
+	utils.FileLog.Info("Processing processing report...")
 	// 解析关键字
 	if len(keywords) < 4 {
 		return []models.BaseFromLyData{}, fmt.Errorf("SupplyDemandBalanceProcessor Process() : keywords must contain at least 4 elements")
@@ -428,7 +428,7 @@ func (p *SupplyDemandBalanceProcessor) Process(ctx context.Context, product stri
 
 	// 提取所有表格数据
 	tableData := getTableData(reportContent, true)
-	logs.Info("SupplyDemandBalanceProcessor Process() : Table data: %v", tableData)
+	utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : Table data: %v", tableData)
 
 	// 提取日期信息
 	dateText, err := getDateInfo(ctx)
@@ -452,7 +452,7 @@ func (p *SupplyDemandBalanceProcessor) Process(ctx context.Context, product stri
 		return nil, err
 	}
 	monthSuffix := "预估"
-	logs.Info("SupplyDemandBalanceProcessor Process() : Target Year: %s:%s\n", currentYearAndNextYear, month+monthSuffix)
+	utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : Target Year: %s:%s\n", currentYearAndNextYear, month+monthSuffix)
 
 	// 处理提取的表格数据
 	var result []models.BaseFromLyData
@@ -525,7 +525,7 @@ func (p *SupplyDemandBalanceProcessor) Process(ctx context.Context, product stri
 
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
-						logs.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+						utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 存在走更新逻辑 主要更新今年在去年的预估值
 						indexData := indexData[0]
 						if indexData.Value != value {
@@ -601,7 +601,7 @@ func (p *SupplyDemandBalanceProcessor) Process(ctx context.Context, product stri
 type PurchaseShippingProcessor struct{}
 
 func (p *PurchaseShippingProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
-	logs.Info("Processing purchase shipping...")
+	utils.FileLog.Info("Processing purchase shipping...")
 	// 解析关键字
 	if len(keywords) < 3 {
 		return []models.BaseFromLyData{}, fmt.Errorf("SupplyDemandBalanceProcessor Process() : keywords must contain at least 3 elements")
@@ -612,7 +612,7 @@ func (p *PurchaseShippingProcessor) Process(ctx context.Context, product string,
 
 	// 提取所有表格数据
 	tableData := getPurchaseShippingTableData(reportContent)
-	logs.Info("SupplyDemandBalanceProcessor Process() : Table data: %v", tableData)
+	utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : Table data: %v", tableData)
 
 	// 提取日期信息
 	dateText, err := getDateInfo(ctx)
@@ -705,7 +705,7 @@ func (p *PurchaseShippingProcessor) Process(ctx context.Context, product string,
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
 						if indexData[0].Value != value {
-							logs.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+							utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 
 							lyData := indexData[0]
 							time, err := utils.StringToTime(lyData.ModifyTime)
@@ -784,7 +784,7 @@ type ProcessingReportProcessor struct {
 }
 
 func (p *ProcessingReportProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
-	logs.Info("Processing processing report...")
+	utils.FileLog.Info("Processing processing report...")
 	// 解析关键字
 	if len(keywords) < 3 {
 		return []models.BaseFromLyData{}, fmt.Errorf("ProcessingReportProcessor Process() : keywords must contain at least 3 elements")
@@ -829,7 +829,7 @@ func (p *ProcessingReportProcessor) Process(ctx context.Context, product string,
 
 	indexData := requestResponse.Data
 	if len(indexData) > 0 {
-		logs.Info("ProcessingReportProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+		utils.FileLog.Info("ProcessingReportProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 		// 不必做更新处理,报告每周刷新,即使本周和上周数据一致,也需要每周记录
 		return []models.BaseFromLyData{}, nil
 	}
@@ -909,7 +909,7 @@ func (p *ProcessingReportProcessor) Process(ctx context.Context, product string,
 
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
-						logs.Info("ProcessingReportProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+						utils.FileLog.Info("ProcessingReportProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需走更新逻辑,报告每日更新,即使今天和昨天数据一致,也需要每天记录,如果到这里也只是说,今天这个报告被读取了两次
 						continue
 					}
@@ -936,7 +936,7 @@ func (p *ProcessingReportProcessor) Process(ctx context.Context, product string,
 
 			/*if len(row) > 0 && strings.Contains(row[0], rowName) {
 				if weekIdx < len(row) {
-					logs.Info("Value in column '%s' - '%s': %s", columnName, rowName, row[columnIdx])
+					utils.FileLog.Info("Value in column '%s' - '%s': %s", columnName, rowName, row[columnIdx])
 					numFlag := isNumeric(row[columnIdx])
 					if numFlag {
 						value, err := strconv.ParseFloat(row[columnIdx], 64)
@@ -967,7 +967,7 @@ type InventoryAnalysisProcessor struct{}
 
 func (p *InventoryAnalysisProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
 	// https://www.fao.com.cn/art/yg1IKj9FpPEIDv2LefnPhQ==.htm
-	logs.Info("Processing inventory analysis...")
+	utils.FileLog.Info("Processing inventory analysis...")
 
 	// 解析关键字
 	if len(keywords) < 4 {
@@ -983,7 +983,7 @@ func (p *InventoryAnalysisProcessor) Process(ctx context.Context, product string
 
 	// 提取所有表格数据
 	tableData := getTableData(reportContent, true)
-	logs.Info("SupplyDemandBalanceProcessor Process() : Table data: %v", tableData)
+	utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : Table data: %v", tableData)
 
 	// 提取日期信息
 	dateText, err := getDateInfo(ctx)
@@ -1044,7 +1044,7 @@ func (p *InventoryAnalysisProcessor) Process(ctx context.Context, product string
 
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
-						logs.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+						utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需走更新逻辑,报告每周更新,即使本周和上周数据一致,也需要每周记录,如果到这里也只是说,今天这个报告被读取了两次
 						continue
 					}
@@ -1157,7 +1157,7 @@ func (p *PriceSpreadArbitrageProcessor) Process(ctx context.Context, product str
 
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
-						logs.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+						utils.FileLog.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需走更新逻辑,报告每天更新,即使今天和每天数据一致,也需要每天记录,如果到这里也只是说,今天这个报告被读取了两次
 						continue
 					}
@@ -1210,7 +1210,7 @@ func (p *DailyTransactionProcessor) Process(ctx context.Context, product string,
 		return []models.BaseFromLyData{}, fmt.Errorf("DailyTransactionProcessor Process() : No table data found")
 
 	}
-	logs.Info("SupplyDemandBalanceProcessor Process() : areaTableData data: %v, blocTableData data: %v", areaTableData, blocTableData)
+	utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : areaTableData data: %v, blocTableData data: %v", areaTableData, blocTableData)
 	// 提取日期信息
 	dateText, err := getDateInfo(ctx)
 	if err != nil {
@@ -1279,7 +1279,7 @@ func (p *DailyTransactionProcessor) Process(ctx context.Context, product string,
 
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
-						logs.Info("DailyTransactionProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+						utils.FileLog.Info("DailyTransactionProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需走更新逻辑,报告每周更新,一周出来一周中每天得数据,即使本周和上周数据一致,也需要每天记录,如果到这里也只是说,今天这个报告被读取了两次
 						continue
 					}
@@ -1344,7 +1344,7 @@ func (p *DailyTransactionProcessor) Process(ctx context.Context, product string,
 
 							indexData := requestResponse.Data
 							if len(indexData) > 0 {
-								logs.Info("DailyTransactionProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+								utils.FileLog.Info("DailyTransactionProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 								// 无需走更新逻辑,报告每周更新,即使本周和上周数据一致,也需要每周记录,如果到这里也只是说,今天这个报告被读取了两次
 								continue
 							}
@@ -1436,7 +1436,7 @@ func (p *DailyTransactionProcessor) Process(ctx context.Context, product string,
 
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
-						logs.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+						utils.FileLog.Info("SupplyDemandBalanceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						continue
 					}
 
@@ -1468,7 +1468,7 @@ func (p *DailyTransactionProcessor) Process(ctx context.Context, product string,
 type PalmOilImportCostProcessor struct{}
 
 func (p *PalmOilImportCostProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
-	logs.Info("Processing palm oil import cost...")
+	utils.FileLog.Info("Processing palm oil import cost...")
 	// 解析关键字
 	if len(keywords) < 5 {
 		return []models.BaseFromLyData{}, fmt.Errorf("PalmOilImportCostProcessor Process() : keywords must contain at least 5 elements")
@@ -1575,7 +1575,7 @@ func (p *PalmOilImportCostProcessor) Process(ctx context.Context, product string
 
 						indexData := requestResponse.Data
 						if len(indexData) > 0 {
-							logs.Info("PalmOilImportCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+							utils.FileLog.Info("PalmOilImportCostProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							continue
 						}
 
@@ -1611,7 +1611,7 @@ func (p *PalmOilImportCostProcessor) Process(ctx context.Context, product string
 type ImportEstimateProcessor struct{}
 
 func (p *ImportEstimateProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
-	logs.Info("Processing import estimate...")
+	utils.FileLog.Info("Processing import estimate...")
 	// 解析关键字
 	if len(keywords) < 4 {
 		return []models.BaseFromLyData{}, fmt.Errorf("ImportEstimateProcessor Process() : keywords must contain at least 4 elements")
@@ -1713,7 +1713,7 @@ func (p *ImportEstimateProcessor) Process(ctx context.Context, product string, r
 
 							if len(indexData) > 0 {
 								if indexData[0].Value != value {
-									logs.Info("ImportEstimateProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+									utils.FileLog.Info("ImportEstimateProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 
 									lyData := indexData[0]
 									time, err := utils.StringToTime(lyData.ModifyTime)
@@ -1793,7 +1793,7 @@ func (p *ImportEstimateProcessor) Process(ctx context.Context, product string, r
 type InternationalPriceProcessor struct{}
 
 func (p *InternationalPriceProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
-	logs.Info("Processing international price...")
+	utils.FileLog.Info("Processing international price...")
 	// 解析关键字
 	if len(keywords) < 4 {
 		return []models.BaseFromLyData{}, fmt.Errorf("InternationalPriceProcessor Process() : keywords must contain at least 4 elements")
@@ -1885,7 +1885,7 @@ func (p *InternationalPriceProcessor) Process(ctx context.Context, product strin
 
 						indexData := requestResponse.Data
 						if len(indexData) > 0 {
-							logs.Info("InternationalPriceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+							utils.FileLog.Info("InternationalPriceProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							// 无需更新 指标展示本月和后两月的数据,报告每天更新,每天的值可能会改变,即使今天和每天数据一致,也需要每天记录,如果到这里也只是说,今天这个报告被读取了两次
 							continue
 						}
@@ -1920,7 +1920,7 @@ func (p *InternationalPriceProcessor) Process(ctx context.Context, product strin
 type CanadaStatisticsBureauProcessor struct{}
 
 func (p *CanadaStatisticsBureauProcessor) Process(ctx context.Context, product string, reportContent string, keywords []string, classifyId int) ([]models.BaseFromLyData, error) {
-	logs.Info("Processing Canada statistics bureau...")
+	utils.FileLog.Info("Processing Canada statistics bureau...")
 	// 解析关键字
 	if len(keywords) < 4 {
 		return []models.BaseFromLyData{}, fmt.Errorf("CanadaStatisticsBureauProcessor Process() : keywords must contain at least 4 elements")
@@ -1995,7 +1995,7 @@ func (p *CanadaStatisticsBureauProcessor) Process(ctx context.Context, product s
 
 					indexData := requestResponse.Data
 					if len(indexData) > 0 {
-						logs.Info("CanadaStatisticsBureauProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+						utils.FileLog.Info("CanadaStatisticsBureauProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 						// 无需更新 指标展示本周的数据,报告每周更新,即使本周和上周数据一致,也需要每周记录,如果到这里也只是说,今天这个报告被读取了两次
 						continue
 					}
@@ -2117,7 +2117,7 @@ func (p *ImportExportAnalysisProcessor) Process(ctx context.Context, product str
 
 						indexData := requestResponse.Data
 						if len(indexData) > 0 {
-							logs.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
+							utils.FileLog.Info("ProcessingProfitProcessor Process() : Data already exists for index %d and date %s", indexId, dateText)
 							continue
 						}
 
@@ -2202,7 +2202,7 @@ func getDateInfo(ctx context.Context) (string, error) {
 		return "", fmt.Errorf("processing Process() : Failed to extract report date: %v", err)
 	}
 
-	logs.Info("Processing Process() : Report Extracted Date: %s", dateText)
+	utils.FileLog.Info("Processing Process() : Report Extracted Date: %s", dateText)
 	return dateText, nil
 }
 

+ 100 - 244
services/ruizide/data_processor.go

@@ -3,10 +3,10 @@ package ruizide
 import (
 	"context"
 	"encoding/json"
+	"errors"
 	"eta/eta_data_analysis/models"
 	"eta/eta_data_analysis/utils"
 	"fmt"
-	"github.com/xuri/excelize/v2"
 	"io"
 	"log"
 	"os"
@@ -16,11 +16,10 @@ import (
 	"github.com/chromedp/chromedp"
 )
 
-// 定义选择器
 var (
-	downloadDir  = utils.RZD_EXCEL_PATH
-	defaultDir   = utils.RZD_DOWNLOAD_PATH
-	rzdLoginPath = "https://portal.rystadenergy.com/home"
+	excelDir     = utils.RZD_EXCEL_PATH
+	downloadDir  = utils.RZD_DOWNLOAD_PATH
+	rzdLoginPath = utils.RZD_LOGIN_PATH
 	rzdBatchSize = 500
 )
 
@@ -57,20 +56,20 @@ func downloadData(ctx context.Context) error {
 	}
 
 	// 解析文件移动到目标目录
-	if err := waitAndRenameDownloadedFile("Oil_Demand_Signals_Weekly_Report_"+utils.GetCurrentYearMonth()+".xlsx", downloadDir); err != nil {
+	if err := WaitAndRenameDownloadedFile("Oil_Demand_Signals_Weekly_Report_"+utils.GetCurrentYearMonth()+".xlsx", excelDir); err != nil {
 		return err
 	}
 
 	return nil
 }
 
-// 等待下载文件并重命名
-func waitAndRenameDownloadedFile(newFileName, targetDir string) error {
+// WaitAndRenameDownloadedFile 等待下载文件并重命名
+func WaitAndRenameDownloadedFile(newFileName, targetDir string) error {
 	// 等待一段时间以确保文件下载完成
 	time.Sleep(100 * time.Second) // 可能需要根据实际情况调整
 
 	// 查找下载目录中的文件
-	files, err := filepath.Glob(filepath.Join(defaultDir, "*.xlsx"))
+	files, err := filepath.Glob(filepath.Join(downloadDir, "*.xlsx"))
 	if err != nil {
 		return fmt.Errorf("查找文件时出错: %v", err)
 	}
@@ -104,27 +103,32 @@ func waitAndRenameDownloadedFile(newFileName, targetDir string) error {
 			return fmt.Errorf("重命名文件时出错: %v", err)
 		}
 		// 打印重命名后的文件名
+		utils.FileLog.Info("文件重命名并移动到: ", targetFilePath)
 		fmt.Printf("文件重命名并移动到: %s\n", targetFilePath)
 	}
 
 	return nil
 }
 
-func moveFile(source, destination string) error {
+func moveFile(source, destination string) (err error) {
 	// 复制文件
 	srcFile, err := os.Open(source)
 	if err != nil {
 		return fmt.Errorf("打开源文件时出错: %v", err)
 	}
-	defer srcFile.Close()
+	defer func() {
+		_ = srcFile.Close()
+	}()
 
 	dstFile, err := os.Create(destination)
 	if err != nil {
 		return fmt.Errorf("创建目标文件时出错: %v", err)
 	}
-	defer dstFile.Close()
+	defer func() {
+		_ = dstFile.Close()
+	}()
 
-	if _, err := io.Copy(dstFile, srcFile); err != nil {
+	if _, err = io.Copy(dstFile, srcFile); err != nil {
 		return fmt.Errorf("复制文件时出错: %v", err)
 	}
 	time.Sleep(60 * time.Second)
@@ -136,264 +140,87 @@ func moveFile(source, destination string) error {
 
 	return nil
 }
+func createPath(paths []string) (err error) {
+	for _, path := range paths {
+		if path == "" {
+			continue
+		}
+		_, err = os.Stat(path)
+		if err != nil {
+			if os.IsNotExist(err) {
+				if err = os.MkdirAll(path, os.ModePerm); err != nil {
+					fmt.Printf("睿咨得创建目录时出错: %v\n", err)
+					utils.FileLog.Error("睿咨得创建目录时出错: %v", err)
+					return
+				}
+			} else {
+				return
+			}
+		}
 
-// 解析网页数据,下载文件
-// func main() {
-func ResolverNet(cont context.Context) (err error) {
-	// 创建下载目录
-	if err := os.MkdirAll(downloadDir, os.ModePerm); err != nil {
-		fmt.Printf("创建下载目录时出错: %v\n", err)
-		return nil
 	}
+	return
+}
 
+// ResolverNet 解析网页数据,下载文件
+func ResolverNet(_ context.Context) (err error) {
+	if err = createPath([]string{excelDir}); err != nil {
+		return
+	}
 	// 创建 chromedp 执行上下文
-	options := []chromedp.ExecAllocatorOption{
+	options := append(chromedp.DefaultExecAllocatorOptions[:3],
+		//关闭无头模式
 		chromedp.Flag("headless", false),
 		chromedp.Flag("disable-blink-features", "AutomationControlled"),
 		chromedp.UserAgent(`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36`),
-		// 设置了但并不生效,直接从默认下载路径读取过来
-		//chromedp.Flag("download.default_directory", downloadDir),
-		//chromedp.Flag("download.prompt_for_download", false), // 不弹出下载对话框
 		chromedp.Flag("safebrowsing.enabled", true), // 启用安全浏览
-		//chromedp.UserDataDir(filepath.Join(downloadDir, "user-data")),
-	}
+	)
+	parentCtx, cancel := chromedp.NewExecAllocator(context.Background(), options...)
 
-	allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), options...)
-	defer cancel()
-	ctx, cancel := chromedp.NewContext(allocCtx)
-	defer cancel()
+	ctx, ctxCancel := chromedp.NewContext(parentCtx)
+	defer func() {
+		cancel()
+		ctxCancel()
+	}()
 
 	// 启动 Chrome 实例
-	if err := chromedp.Run(ctx); err != nil {
-		fmt.Printf("启动 Chrome 实例时出错: %v\n", err)
-		return nil
-	}
-
-	// 设置下载行为
-	/*if err := setDownloadBehavior(ctx); err != nil {
-		fmt.Printf("设置下载路径时出错: %v\n", err)
+	if err = chromedp.Run(ctx); err != nil {
+		utils.FileLog.Error("睿咨得启动 Chrome 实例时出错:", err.Error())
+		fmt.Printf("睿咨得启动 Chrome 实例时出错: %v\n", err)
 		return
-	}*/
+	}
 
 	// 登录操作
-	if err := login(ctx); err != nil {
-		fmt.Printf("登录错误: %v\n", err)
-		return nil
+	if err = login(ctx); err != nil {
+		utils.FileLog.Error("睿咨得登录错误:", err.Error())
+		fmt.Printf("睿咨得登录错误: %v\n", err)
+		return
 	}
-
+	fmt.Printf("登录成功")
 	// 下载数据
-	if err := downloadData(ctx); err != nil {
-		fmt.Printf("数据下载错误: %v\n", err)
-		return nil
+	if err = downloadData(ctx); err != nil {
+		utils.FileLog.Error("睿咨得数据下载错误:", err.Error())
+		fmt.Printf("睿咨得数据下载错误: %v\n", err)
+		return
 	}
-
-	fmt.Println("数据下载完成")
-
+	utils.FileLog.Info("睿咨得数据下载完成")
 	// 解析表格 读取数据
-	fileResolver()
-
-	return nil
-}
-
-// 解析本地文件
-func fileResolver() {
-	//func main() {
-	var tableNameList = []string{
-		"Oil_Demand_Signals_Weekly_Report",
-		"Oil_Supply_Analysis",
-		"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",
-		"Oil_Demand_Analysis_Product_Detail",
-		"Oil_Demand_Analysis_Region",
-		"Oil_Demand_Analysis_Scenario",
-		"Oil_Demand_Analysis_Continent",
-		"Oil_Demand_Analysis_Country",
-		"Oil_Demand_Analysis_Product_Category",
-		"Oil_Demand_Analysis_Sector_Category",
-		"Oil_Demand_Analysis_Sector_Detail",
-	}
-	for _, tableName := range tableNameList {
-		var fileName string
-		// 解析表格
-		fileName = tableName + "_" + utils.GetCurrentYearMonth() + ".xlsx"
-		filePath := filepath.Join(downloadDir, fileName)
-
-		// 打开 Excel 文件
-		f, err := excelize.OpenFile(filePath)
-		if err != nil {
-			log.Fatalf("无法打开 Excel 文件: %v", err)
-		}
-
-		// 获取所有工作表
-		sheetNames := f.GetSheetList()
-
-		for _, sheetName := range sheetNames {
-			fmt.Printf("读取工作表: %s\n", sheetName)
-
-			// 获取工作表的最大行数
-			maxRow, err := f.GetRows(sheetName) // 直接获取所有行数据
-			if err != nil {
-				log.Fatalf("获取工作表数据时出错: %v", err)
-				continue
-			}
-
-			// 遍历行并打印内容
-			indexData := []models.BaseFromRzdData{}
-			for rowIndex, rowData := range maxRow {
-
-				// 因为excel文件中的sheet表格不固定 对于 Supply_Revision_Analysis, Oil_Supply_Analysis 文件 手动调整sheet表格顺序
-				if tableName == "Supply_Revision_Analysis" && rowIndex == 0 {
-					if rowData[0] == "YearQuarter" && rowData[1] == "Revision" && rowData[2] == "CountryRevisionGroup" {
-						sheetName = "Chart1"
-					}
-					if rowData[0] == "YearQuarter" && rowData[1] == "Current" && rowData[2] == "Previous" {
-						sheetName = "Chart2"
-					}
-					if rowData[0] == "Year" && rowData[1] == "Revision" && rowData[2] == "CountryRevisionGroup" {
-						sheetName = "Chart3"
-					}
-					if rowData[0] == "Year" && rowData[1] == "Current" && rowData[2] == "Previous" {
-						sheetName = "Chart4"
-					}
-					if rowData[0] == "Previous" && rowData[1] == "Current" && rowData[2] == "YearMonth" {
-						sheetName = "Chart5"
-					}
-					if rowData[0] == "YearMonth" && rowData[1] == "CountryRevisionGroup" && rowData[2] == "Revision" {
-						sheetName = "Chart6"
-					}
-				} else if tableName == "Oil_Supply_Analysis" && rowIndex == 0 {
-					if rowData[0] == "Viz Date" && rowData[1] == "OilAndGasCategory" && rowData[2] == "supply_kbbld" {
-						sheetName = "Chart1"
-					}
-					if rowData[0] == "Viz Date" && rowData[1] == "supply_kbbld" && rowData[2] == "Region" {
-						sheetName = "Chart2"
-					}
-					if rowData[0] == "Viz Date" && rowData[1] == "CapacityDetail" && rowData[2] == "Capacity_kbbld" {
-						sheetName = "Chart3"
-					}
-					if rowData[0] == "Viz Date" && rowData[1] == "Oil Classification Group" && rowData[2] == "supply_kbbld" {
-						sheetName = "Chart4"
-					}
-				}
-
-				processor, err := GetProcessor(tableName, sheetName)
-				if err != nil {
-					continue
-				}
-				baseFromRzdDataList, err := processor.Process(tableName, sheetName, rowIndex, rowData)
-				if err != nil {
-					log.Printf("processor.Process err: %v", err)
-					return
-				}
-				indexData = append(indexData, baseFromRzdDataList...)
-			}
-
-			// 新增数据源指标数据
-			if len(indexData) > 0 {
-				for i := 0; i < len(indexData); i += rzdBatchSize {
-					// 计算当前批次的结束索引
-					end := i + rzdBatchSize
-					if end > len(indexData) {
-						end = len(indexData)
-					}
-
-					// 获取当前批次的数据
-					batchData := indexData[i:end]
-
-					// 转换成json
-					marshal, err := json.Marshal(batchData)
-					if err != nil {
-						log.Printf("json.Marshal err: %v", err)
-						return
-					}
-
-					// 发送 HTTP POST 请求
-					_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_RZD_DATA, string(marshal), "application/json")
-					if err != nil {
-						log.Printf("postEdbLib err: %v", err)
-						return
-					}
-				}
-			}
-
-			// 新增指标库数据
-			edbDataList := []models.EdbDataRzd{}
-			for _, index := range indexData {
-				// 补充 判断是否存在于指标库
-				paramsLib := make(map[string]interface{})
-				paramsLib["IndexCode"] = index.IndexCode
-				paramsLib["Source"] = utils.DATA_SOURCE_RZD
-				postEdbLib, err := httpRequestFill(paramsLib, utils.GET_RZD_EDB_INFO_BY_INDEX_CODE)
-				if err != nil {
-					// 有错误就不继续执行
-					log.Printf("postEdbLib err: %v", err)
-					continue
-				}
-				var requestResponse models.RequestResponse[models.EdbInfo]
-				err = json.Unmarshal(postEdbLib, &requestResponse)
-				if err != nil {
-					log.Printf("postEdbLib err: %v", err)
-					continue
-				}
-
-				if requestResponse.Data.EdbInfoId != 0 {
-					edbDataRzd := models.EdbDataRzd{
-						CreateTime:    utils.GetCurrentTime(),
-						ModifyTime:    utils.GetCurrentTime(),
-						EdbInfoId:     index.BaseFromRzdIndexId,
-						EdbCode:       index.IndexCode,
-						DataTime:      index.DataTime,
-						Value:         index.Value,
-						DataTimestamp: uint64(utils.StringToTimeFormat(index.DataTime, utils.FormatDate).UnixMilli()),
-					}
-					edbDataList = append(edbDataList, edbDataRzd)
-				}
-			}
-
-			if len(edbDataList) > 0 {
-				// 转换成json
-				marshal, err := json.Marshal(edbDataList)
-				if err != nil {
-					log.Printf("postEdbLib err: %v", err)
-					return
-				}
-				_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_RZD_EDB_DATA, string(marshal), "application/json")
-				if err != nil {
-					// 有错误就不继续执行
-					log.Printf("postEdbLib err: %v", err)
-					return
-				}
-			}
-
-		}
-	}
+	err = FileResolver()
+	return
 }
 
 func login(ctx context.Context) error {
-
+	if rzdLoginPath == "" {
+		return errors.New("睿咨得登录页面地址未配置")
+	}
 	return chromedp.Run(ctx,
 		chromedp.Navigate(rzdLoginPath),
+		chromedp.WaitVisible(`body`, chromedp.ByQuery),
 		chromedp.SetValue(`input[id="Username"]`, utils.RZD_USERNAME, chromedp.ByQuery),
 		chromedp.SetValue(`input[id="Password"]`, utils.RZD_PASSWORD, chromedp.ByQuery),
 		chromedp.WaitEnabled(`//button[text()='Login']`, chromedp.BySearch),
-		chromedp.Click(`//button[text()='Login']`, chromedp.BySearch),
 		chromedp.Sleep(5*time.Second),
+		chromedp.Click(`//button[text()='Login']`, chromedp.BySearch),
 
 		// 等待并点击登录后页面的链接
 		/*chromedp.WaitVisible(`a[href="/home"]`, chromedp.ByQuery), // 等待 Analytics Library 链接可见
@@ -422,3 +249,32 @@ func httpRequestFill(data interface{}, urlMethod string) (postEdbLib []byte, err
 	}
 	return postEdbLib, nil
 }
+
+// FileResolver 解析本地文件
+func FileResolver() error {
+	//获取rzd数据库分类数据
+	rzdClassifyList, err := getRzdClassifyList()
+	if err != nil {
+		fmt.Printf("获取睿咨得分类数据失败: %v", err)
+		utils.FileLog.Error("获取睿咨得分类数据失败:", err.Error())
+		return err
+	}
+	RzdClassifyMap = make(map[string]*models.BaseFromRzdClassify)
+	//更新睿咨得分类Map
+	for _, classify := range rzdClassifyList {
+		RzdClassifyMap[classify.ClassifyName] = classify
+	}
+	for _, tableName := range tableNameList {
+		rzdProcessor, processorErr := GetRZDProcessor(tableName)
+		if processorErr != nil {
+			utils.FileLog.Error("获取睿咨得数据处理器:", processorErr.Error())
+			continue
+		}
+		err = rzdProcessor.Process(tableName)
+		if err != nil {
+			utils.FileLog.Error(fmt.Sprintf("%s处理数据失败:", tableName), err.Error())
+			continue
+		}
+	}
+	return nil
+}

+ 144 - 0
services/ruizide/oil_demand_analysis_processor.go

@@ -0,0 +1,144 @@
+package ruizide
+
+import (
+	"encoding/json"
+	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/utils"
+	"github.com/xuri/excelize/v2"
+	"os"
+	"path/filepath"
+)
+
+const (
+	OilDemandAnalysis = "Oil Demand Analysis"
+	SheetName         = "Chart 1"
+)
+
+var (
+	OilDemandAnalysisConfigMap = map[string]OSAPConfig{
+		"Oil_Demand_Analysis_Product_Detail": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Product detail",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+		"Oil_Demand_Analysis_Region": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Region",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+		"Oil_Demand_Analysis_Scenario": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Scenario",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+		"Oil_Demand_Analysis_Continent": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Continent",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+		"Oil_Demand_Analysis_Country": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Country",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+		"Oil_Demand_Analysis_Product_Category": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Product category",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+		"Oil_Demand_Analysis_Sector_Detail": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Sector detail",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+		"Oil_Demand_Analysis_Sector_Category": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Sector category",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+	}
+)
+
+type OilDemandAnalysisProcessor struct {
+}
+
+func (p *OilDemandAnalysisProcessor) Process(tableName string) (err error) {
+	var fileName string
+	// 解析表格
+	fileName = tableName + "_" + utils.GetCurrentYearMonth() + ".xlsx"
+	filePath := filepath.Join(excelDir, fileName)
+	if _, err = os.Stat(filePath); os.IsNotExist(err) {
+		utils.FileLog.Error("文件不存在: %v", err)
+		return
+	}
+	// 打开 Excel 文件
+	file, err := excelize.OpenFile(filePath)
+	if err != nil {
+		utils.FileLog.Error("无法打开 Excel 文件: %v", err)
+		return
+	}
+	classifyIds, err := dealClassify(CubeDashboards, []string{OilDemandAnalysis})
+	// 获取所有工作表
+	if err != nil {
+		utils.FileLog.Error("获取分类Id失败: %v", err)
+		return
+	}
+	//按照sheet页来处理数据,一个sheet发送一次服务器
+	var indexMap = make(map[string]*models.IndexInfo)
+	// 获取工作表的最大行数
+	dataRows, excelErr := file.GetRows(SheetName) // 直接获取所有行数据
+	if excelErr != nil {
+		utils.FileLog.Error("获取工作表数据时出错: %v", excelErr)
+		return
+	}
+	if sheetConfig, ok := OilDemandAnalysisConfigMap[tableName]; ok {
+		// 匹配非数字字符
+		classifyId := classifyIds[OilDemandAnalysis]
+		indexMap, err = DataHandler(dataRows, sheetConfig, classifyId, OilDemandAnalysis)
+		// 新增数据源指标数据
+		if len(indexMap) > 0 {
+			for _, index := range indexMap {
+				pars := chunkIndexData(index, rzdBatchSize)
+				for _, par := range pars {
+					// 转换成json
+					marshal, parseErr := json.Marshal(par)
+					if parseErr != nil {
+						utils.FileLog.Error("json.Marshal err: %v", parseErr)
+						return parseErr
+					}
+					// 发送 HTTP POST 请求
+					_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_RZD_DATA, string(marshal), "application/json")
+					if err != nil {
+						utils.FileLog.Error("postEdbLib err: %v", err)
+						return err
+					}
+				}
+			}
+		}
+	}
+	return
+}

+ 337 - 0
services/ruizide/oil_demand_signals_weekly_report_processor.go

@@ -0,0 +1,337 @@
+package ruizide
+
+import (
+	"encoding/json"
+	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/utils"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"github.com/xuri/excelize/v2"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+)
+
+var (
+	OilDemandSignalsWeeklyReportConfigMap = map[string]config{
+		"Road Index": {
+			Frequency:       "日度",
+			Unit:            "%",
+			IndexNameColOne: "Index",
+			IndexNameColTwo: "Index 7DMA",
+			IndexPrefix:     "Road Index",
+			BeginRow:        4,
+			Rows:            5,
+			IndexRow:        2,
+			DataOneRow:      3,
+			DataTwoRow:      4,
+			DateRow:         1,
+		},
+		"Road Active Fleet": {
+			Frequency:       "日度",
+			Unit:            "辆",
+			IndexNameColOne: "Active Fleet",
+			IndexNameColTwo: "Active Fleet 7DMA",
+			IndexPrefix:     "Road Active Fleet",
+			BeginRow:        4,
+			Rows:            5,
+			IndexRow:        2,
+			DataOneRow:      3,
+			DataTwoRow:      4,
+			DateRow:         1,
+		},
+		"Aviation Index": {
+			Frequency:       "日度",
+			Unit:            "%",
+			IndexNameColOne: "Index",
+			IndexNameColTwo: "Index 7DMA",
+			IndexPrefix:     "Aviation Index",
+			BeginRow:        4,
+			Rows:            5,
+			IndexRow:        2,
+			DataOneRow:      3,
+			DataTwoRow:      4,
+			DateRow:         1,
+		},
+		"Aviation Active Fleet": {
+			Frequency:       "日度",
+			Unit:            "辆",
+			IndexNameColOne: "Active Fleet",
+			IndexNameColTwo: "Active Fleet 7DMA",
+			IndexPrefix:     "Aviation Active Fleet",
+			BeginRow:        4,
+			Rows:            5,
+			IndexRow:        2,
+			DataOneRow:      3,
+			DataTwoRow:      4,
+			DateRow:         1,
+		},
+		"Demand - Gasoline": {
+			Frequency:       "日度",
+			Unit:            "千桶每天",
+			IndexNameColOne: "Demand",
+			IndexNameColTwo: "Demand 7DMA",
+			IndexPrefix:     "Gasoline Demand",
+			BeginRow:        4,
+			Rows:            6,
+			IndexRow:        3,
+			DataOneRow:      4,
+			DataTwoRow:      5,
+			DateRow:         1,
+		},
+		"Demand - Diesel": {
+			Frequency:       "日度",
+			Unit:            "千桶每天",
+			IndexNameColOne: "Demand",
+			IndexNameColTwo: "Demand 7DMA",
+			IndexPrefix:     "Demand Diesel",
+			BeginRow:        4,
+			Rows:            6,
+			IndexRow:        3,
+			DataOneRow:      4,
+			DataTwoRow:      5,
+			DateRow:         1,
+		},
+		"Demand - Jet Fuel": {
+			Frequency:       "日度",
+			Unit:            "千桶每天",
+			IndexNameColOne: "Demand",
+			IndexNameColTwo: "Demand 7DMA",
+			IndexPrefix:     "Demand Jet Fuel",
+			BeginRow:        4,
+			Rows:            6,
+			IndexRow:        3,
+			DataOneRow:      4,
+			DataTwoRow:      5,
+			DateRow:         1,
+		},
+		"Demand - Maritime Bunker": {
+			Frequency:       "日度",
+			Unit:            "千桶每天",
+			IndexNameColOne: "Demand",
+			IndexNameColTwo: "Demand 7DMA",
+			IndexPrefix:     "Demand Maritime Bunker",
+			BeginRow:        4,
+			Rows:            6,
+			IndexRow:        3,
+			DataOneRow:      4,
+			DataTwoRow:      5,
+			DateRow:         1,
+		},
+	}
+)
+
+type config struct {
+	Frequency       string
+	Unit            string
+	IndexNameColOne string
+	IndexNameColTwo string
+	IndexPrefix     string
+	BeginRow        int
+	Rows            int
+	IndexRow        int
+	DataOneRow      int
+	DataTwoRow      int
+	DateRow         int
+}
+type OilDemandSignalsWeeklyReportProcessor struct {
+}
+
+func (p *OilDemandSignalsWeeklyReportProcessor) Process(tableName string) (err error) {
+	var fileName string
+	// 解析表格
+	fileName = tableName + "_" + utils.GetCurrentYearMonth() + ".xlsx"
+	filePath := filepath.Join(excelDir, fileName)
+	if _, err = os.Stat(filePath); os.IsNotExist(err) {
+		utils.FileLog.Error("文件不存在: %v", err)
+		return
+	}
+	// 打开 Excel 文件
+	file, err := excelize.OpenFile(filePath)
+	if err != nil {
+		utils.FileLog.Error("无法打开 Excel 文件: %v", err)
+		return
+	}
+	sheetNames := file.GetSheetList()
+	classifyIds, err := dealClassify(tableName, sheetNames)
+	// 获取所有工作表
+	if err != nil {
+		utils.FileLog.Error("获取分类Id失败: %v", err)
+		return
+	}
+	//按照sheet页来处理数据,一个sheet发送一次服务器
+	for _, sheetName := range sheetNames {
+		var indexMap = make(map[string]*models.IndexInfo)
+		if sheetName == "Content" {
+			utils.FileLog.Info("跳过工作表:", sheetName)
+			continue
+		}
+		utils.FileLog.Info("读取工作表: %s\n", sheetName)
+		// 获取工作表的最大行数
+		dataRows, excelErr := file.GetRows(sheetName) // 直接获取所有行数据
+		if excelErr != nil {
+			utils.FileLog.Error("获取工作表数据时出错: %v", excelErr)
+			continue
+		}
+		sheetConfig := OilDemandSignalsWeeklyReportConfigMap[sheetName]
+		for _, rowData := range dataRows[sheetConfig.BeginRow:] {
+			//处理数据不全的情况
+			less := sheetConfig.Rows - len(rowData)
+			if less > 0 {
+				for i := 0; i < less; i++ {
+					rowData = append(rowData, "")
+				}
+			}
+			// 匹配非数字字符
+			//re := regexp.MustCompile(`^[-+]?\d*\.?\d+$`)
+
+			classifyId := classifyIds[sheetName]
+			// step_2: 指标
+			// 指标名称
+			indexNameOne := sheetName + "/" + rowData[sheetConfig.IndexRow] + "/" + sheetConfig.IndexNameColOne
+			indexNameTwo := sheetName + "/" + rowData[sheetConfig.IndexRow] + "/" + sheetConfig.IndexNameColTwo
+			// 生成指标编码
+			indexCodeOne := getIndexId(sheetName, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), sheetConfig.IndexNameColOne)
+			indexCodeTwo := getIndexId(sheetName, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), sheetConfig.IndexNameColTwo)
+			dataTime := rowData[sheetConfig.DateRow]
+			date, _, convertErr := utils.ConvertDateFormat(dataTime)
+			if convertErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("转换时间数据失败,index_code:%s,time_value:%s err:%v", indexCodeOne, dataTime, convertErr))
+				continue
+			}
+			if rowData[sheetConfig.DataOneRow] != "" {
+				valueOne, parseErr := decimal.NewFromString(strings.ReplaceAll(rowData[sheetConfig.DataOneRow], ",", ""))
+				if parseErr != nil {
+					utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCodeOne, rowData[sheetConfig.DataOneRow], err))
+					continue
+				} else {
+					if index, ok := indexMap[indexCodeOne]; ok {
+						if index.StartDate.After(date) {
+							index.StartDate = date
+						}
+						if index.EndDate.Before(date) {
+							index.EndDate = date
+							index.LatestValue = valueOne
+						}
+						index.DataList = append(index.DataList, models.IndexData{
+							DataTime: date,
+							Value:    valueOne,
+						})
+					} else {
+						indexMap[indexCodeOne] = &models.IndexInfo{
+							IndexName:   indexNameOne,
+							IndexCode:   indexCodeOne,
+							Frequency:   sheetConfig.Frequency,
+							Unit:        sheetConfig.Unit,
+							StartDate:   date,
+							EndDate:     date,
+							LatestValue: valueOne,
+							ClassifyId:  classifyId,
+							DataList: []models.IndexData{
+								{
+									DataTime: date,
+									Value:    valueOne,
+								},
+							},
+						}
+					}
+				}
+			}
+			if rowData[sheetConfig.DataTwoRow] != "" {
+				valueTwo, parseErr := decimal.NewFromString(strings.ReplaceAll(rowData[sheetConfig.DataTwoRow], ",", ""))
+				if parseErr != nil {
+					utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCodeTwo, rowData[sheetConfig.DataTwoRow], err))
+					continue
+				} else {
+					if index, ok := indexMap[indexCodeTwo]; ok {
+						if index.StartDate.After(date) {
+							index.StartDate = date
+						}
+						if index.EndDate.Before(date) {
+							index.EndDate = date
+							index.LatestValue = valueTwo
+						}
+						index.DataList = append(index.DataList, models.IndexData{
+							DataTime: date,
+							Value:    valueTwo,
+						})
+					} else {
+						indexMap[indexCodeTwo] = &models.IndexInfo{
+							IndexName:   indexNameTwo,
+							IndexCode:   indexCodeTwo,
+							Frequency:   sheetConfig.Frequency,
+							Unit:        sheetConfig.Unit,
+							StartDate:   date,
+							EndDate:     date,
+							LatestValue: valueTwo,
+							ClassifyId:  classifyId,
+							DataList: []models.IndexData{
+								{
+									DataTime: date,
+									Value:    valueTwo,
+								},
+							},
+						}
+					}
+				}
+			}
+		}
+		utils.FileLog.Info("读取工作表完成:", sheetName)
+		// 新增数据源指标数据
+		if len(indexMap) > 0 {
+			for _, index := range indexMap {
+				pars := chunkIndexData(index, rzdBatchSize)
+				for _, par := range pars {
+					// 转换成json
+					marshal, parseErr := json.Marshal(par)
+					if parseErr != nil {
+						utils.FileLog.Error("json.Marshal err: %v", parseErr)
+						return parseErr
+					}
+					// 发送 HTTP POST 请求
+					_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_RZD_DATA, string(marshal), "application/json")
+					if err != nil {
+						utils.FileLog.Error("postEdbLib err: %v", err)
+						return err
+					}
+				}
+			}
+		}
+	}
+	return
+}
+func isValidNumber(s string) bool {
+	// 匹配整数或浮点数(支持正负号)
+	re := regexp.MustCompile(`^[-+]?\d*\.?\d+$`)
+	return re.MatchString(s)
+}
+func chunkIndexData(index *models.IndexInfo, rzdBatchSize int) (pars []models.IndexInfo) {
+	var chunks int
+	total := len(index.DataList)
+	count := total % rzdBatchSize
+	if count > 0 {
+		chunks = (total + rzdBatchSize - count) / rzdBatchSize
+	} else {
+		chunks = total / rzdBatchSize
+	}
+	for i := 0; i < chunks; i++ {
+		start := i * rzdBatchSize
+		end := start + rzdBatchSize
+		if end > total {
+			end = total
+		}
+		pars = append(pars, models.IndexInfo{
+			IndexName:   index.IndexName,
+			IndexCode:   index.IndexCode,
+			LatestValue: index.LatestValue,
+			StartDate:   index.StartDate,
+			EndDate:     index.EndDate,
+			Frequency:   index.Frequency,
+			Unit:        index.Unit,
+			ClassifyId:  index.ClassifyId,
+			DataList:    index.DataList[start:end],
+		})
+	}
+	return
+}

+ 364 - 0
services/ruizide/oil_market_cube_processor.go

@@ -0,0 +1,364 @@
+package ruizide
+
+import (
+	"encoding/json"
+	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/utils"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"github.com/xuri/excelize/v2"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+const (
+	MCSheetName    = "ExportCubeBrowser 1"
+	OilMarketCube  = "Oil Market Cube"
+	UpstreamSupply = "Upstream Supply"
+	Balances       = "Balances"
+	ProductsDemand = "Products Demand"
+	Geography      = "Geography"
+	MCBeginRow     = 2
+	MCRows         = 3
+)
+
+type MCPConfig struct {
+	Frequency          string
+	Unit               string
+	IndexNameColSuffix string
+	IndexNameColPrefix string
+	YearRow            int
+	DataRow            int
+	MonthRow           int
+	SuffixName         string
+	CodeArea           string
+	PrefixStr          string
+	ClassifyName       string
+}
+
+var (
+	OilMarketCubeConfigMap = map[string]MCPConfig{
+		"Oil_Market_Cube_Upstream_Supply_Oil_Quality_API": {
+			Frequency:          "月度",
+			Unit:               "°",
+			IndexNameColSuffix: "Oil Quality",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			SuffixName:         "API",
+			ClassifyName:       UpstreamSupply,
+			CodeArea:           "API",
+		},
+		"Oil_Market_Cube_Upstream_Supply_Oil_Quality_Sulphur": {
+			Frequency:          "月度",
+			Unit:               "%wt",
+			IndexNameColSuffix: "Oil Quality",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			SuffixName:         "Sulphur",
+			ClassifyName:       UpstreamSupply,
+			CodeArea:           "Sulphur",
+		},
+		"Oil_Market_Cube_Upstream_Supply_Capacity_Capacity": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Capacity",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Upstream_Supply_Production": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Production",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Upstream_Supply_Production_Wo_Seasonality": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Production Wo Seasonality",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Reference_Production": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Reference Production",
+			IndexNameColPrefix: "OPEC_Policy",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Production": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Target Production",
+			IndexNameColPrefix: "OPEC_Policy",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Cut": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Target Cut",
+			IndexNameColPrefix: "OPEC_Policy",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Actual_Cut": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Actual Cut",
+			IndexNameColPrefix: "OPEC_Policy",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Compliance": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Compliance",
+			IndexNameColPrefix: "OPEC_Policy",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Production_Subject_To_Cut": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Production Subject To Cut",
+			IndexNameColPrefix: "OPEC_Policy",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       UpstreamSupply,
+		},
+		"Oil_Market_Cube_Products_Demand_Products_Demand_Mean": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Products Demand Mean (1.0 DG) ",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       ProductsDemand,
+			CodeArea:           "1.0dg",
+			PrefixStr:          "Products Demand Mean",
+		},
+		"Oil_Market_Cube_Products_Demand_Products_Demand+Sigma": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Products Demand +Sigma (2.2 DG) ",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       ProductsDemand,
+			CodeArea:           "2.2dg",
+			PrefixStr:          "Products Demand Sigma",
+		},
+		"Oil_Market_Cube_Products_Demand_Products_Demand-Sigma": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Products Demand -Sigma (1.8 DG) ",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       ProductsDemand,
+			CodeArea:           "1.8dg",
+			PrefixStr:          "Products Demand Sigma",
+		},
+		"Oil_Market_Cube_Balances_Total_Liquids_Balances": {
+			Frequency:          "月度",
+			Unit:               "kbbl/d",
+			IndexNameColSuffix: "Total Liquids Balances",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       Balances,
+		},
+		"Oil_Market_Cube_Geography_Latitude": {
+			Frequency:          "月度",
+			Unit:               "",
+			IndexNameColSuffix: "Latitude",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       Geography,
+		},
+		"Oil_Market_Cube_Geography_Longitude": {
+			Frequency:          "月度",
+			Unit:               "",
+			IndexNameColSuffix: "Longitude",
+			MonthRow:           1,
+			DataRow:            2,
+			YearRow:            0,
+			ClassifyName:       Geography,
+		},
+	}
+)
+
+type OilMarketCubeProcessor struct {
+}
+
+func (p *OilMarketCubeProcessor) Process(tableName string) (err error) {
+	var fileName string
+	// 解析表格
+	fileName = tableName + "_" + utils.GetCurrentYearMonth() + ".xlsx"
+	filePath := filepath.Join(excelDir, fileName)
+	if _, err = os.Stat(filePath); os.IsNotExist(err) {
+		utils.FileLog.Error("文件不存在: %v", err)
+		return
+	}
+	// 打开 Excel 文件
+	file, err := excelize.OpenFile(filePath)
+	if err != nil {
+		utils.FileLog.Error("无法打开 Excel 文件: %v", err)
+		return
+	}
+
+	//按照sheet页来处理数据,一个sheet发送一次服务器
+	var indexMap = make(map[string]*models.IndexInfo)
+	// 获取工作表的最大行数
+	dataRows, excelErr := file.GetRows(MCSheetName) // 直接获取所有行数据
+	if excelErr != nil {
+		utils.FileLog.Error("获取工作表数据时出错: %v", excelErr)
+		return
+	}
+	if sheetConfig, ok := OilMarketCubeConfigMap[tableName]; ok {
+		classifyIds, classifyErr := dealClassify(OilMarketCube, []string{sheetConfig.ClassifyName})
+		// 获取所有工作表
+		if classifyErr != nil {
+			utils.FileLog.Error("获取分类Id失败: %v", classifyErr)
+			return
+		}
+		// 匹配非数字字符
+		classifyId := classifyIds[sheetConfig.ClassifyName]
+		indexMap, err = MarketCubeDataHandler(dataRows, sheetConfig, classifyId)
+		// 新增数据源指标数据
+		if len(indexMap) > 0 {
+			for _, index := range indexMap {
+				pars := chunkIndexData(index, rzdBatchSize)
+				for _, par := range pars {
+					// 转换成json
+					marshal, parseErr := json.Marshal(par)
+					if parseErr != nil {
+						utils.FileLog.Error("json.Marshal err: %v", parseErr)
+						return parseErr
+					}
+					// 发送 HTTP POST 请求
+					_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_RZD_DATA, string(marshal), "application/json")
+					if err != nil {
+						utils.FileLog.Error("postEdbLib err: %v", err)
+						return err
+					}
+				}
+			}
+		}
+	}
+	return
+}
+func MarketCubeDataHandler(dataRows [][]string, sheetConfig MCPConfig, classifyId int) (indexMap map[string]*models.IndexInfo, err error) {
+	indexMap = make(map[string]*models.IndexInfo)
+	var yearStr string
+	for _, rowData := range dataRows[MCBeginRow : len(dataRows)-1] {
+		less := MCRows - len(rowData)
+		if less > 0 {
+			for i := 0; i < less; i++ {
+				rowData = append(rowData, "")
+			}
+		}
+		if rowData[sheetConfig.YearRow] != "" {
+			yearStr = rowData[sheetConfig.YearRow]
+		}
+		// step_2: 指标
+		// 指标名称
+		var indexName, indexCode string
+		if sheetConfig.IndexNameColPrefix == "" {
+			indexName = sheetConfig.ClassifyName + "/" + sheetConfig.IndexNameColSuffix
+			if sheetConfig.SuffixName != "" {
+				indexName = indexName + "/" + sheetConfig.SuffixName
+			}
+		} else {
+			indexName = sheetConfig.ClassifyName + "/" + sheetConfig.IndexNameColPrefix + "/" + sheetConfig.IndexNameColSuffix
+		}
+		// 生成指标编码
+		var area, prefix string
+		if sheetConfig.PrefixStr == "" {
+			prefix = sheetConfig.IndexNameColPrefix
+		} else {
+			prefix = sheetConfig.PrefixStr
+		}
+		if sheetConfig.CodeArea != "" {
+			area = sheetConfig.CodeArea
+		} else {
+			area = sheetConfig.IndexNameColSuffix
+		}
+		if sheetConfig.IndexNameColPrefix != "" {
+			indexCode = getIndexId(fmt.Sprintf("%s %s", sheetConfig.ClassifyName, prefix), strings.ReplaceAll(strings.ToLower(area), " ", ""), "")
+		} else {
+			indexCode = getIndexId(sheetConfig.ClassifyName, strings.ReplaceAll(strings.ToLower(area), " ", ""), "")
+		}
+		dataTime := fmt.Sprintf("%s-%s", yearStr, rowData[sheetConfig.MonthRow])
+		if dataTime == "0" {
+			continue
+		}
+		date, _, convertErr := utils.ConvertDateFormatForMC(dataTime)
+		if convertErr != nil {
+			utils.FileLog.Error(fmt.Sprintf("转换时间数据失败,index_code:%s,time_value:%s err:%v", indexCode, dataTime, convertErr))
+			continue
+		}
+		if rowData[sheetConfig.DataRow] != "" {
+			value, parseErr := decimal.NewFromString(rowData[sheetConfig.DataRow])
+			if parseErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCode, rowData[sheetConfig.DataRow], err))
+				continue
+			} else {
+				if index, ok := indexMap[indexCode]; ok {
+					if index.StartDate.After(date) {
+						index.StartDate = date
+					}
+					if index.EndDate.Before(date) {
+						index.EndDate = date
+						index.LatestValue = value
+					}
+					index.DataList = append(index.DataList, models.IndexData{
+						DataTime: date,
+						Value:    value,
+					})
+				} else {
+					indexMap[indexCode] = &models.IndexInfo{
+						IndexName:   indexName,
+						IndexCode:   indexCode,
+						Frequency:   sheetConfig.Frequency,
+						Unit:        sheetConfig.Unit,
+						StartDate:   date,
+						EndDate:     date,
+						LatestValue: value,
+						ClassifyId:  classifyId,
+						DataList: []models.IndexData{
+							{
+								DataTime: date,
+								Value:    value,
+							},
+						},
+					}
+				}
+			}
+		}
+	}
+	return
+}

+ 193 - 0
services/ruizide/oil_supply_analysis_processor.go

@@ -0,0 +1,193 @@
+package ruizide
+
+import (
+	"encoding/json"
+	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/utils"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"github.com/xuri/excelize/v2"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+const (
+	OilSupplyAnalysis = "Oil Supply Analysis"
+	OsaBeginRow       = 1
+	OsaRows           = 3
+)
+
+var (
+	OilSupplyAnalysisConfigMap = map[string]OSAPConfig{
+		"Chart 1": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Oil Classification Group",
+			IndexRow:           1,
+			DataRow:            2,
+			DateRow:            0,
+		},
+		"Chart 3": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "CapacityDetail",
+			IndexRow:           1,
+			DataRow:            2,
+			DateRow:            0,
+		},
+		"Chart 4": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Region",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+		},
+		"Chart 5": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "OilAndGasCategory",
+			IndexRow:           1,
+			DataRow:            2,
+			DateRow:            0,
+		},
+	}
+)
+
+type OSAPConfig struct {
+	Frequency          string
+	Unit               string
+	IndexNameColSuffix string
+	IndexRow           int
+	DataRow            int
+	DateRow            int
+}
+
+type OilSupplyAnalysisProcessor struct {
+}
+
+func (p *OilSupplyAnalysisProcessor) Process(tableName string) (err error) {
+	var fileName string
+	// 解析表格
+	fileName = tableName + "_" + utils.GetCurrentYearMonth() + ".xlsx"
+	filePath := filepath.Join(excelDir, fileName)
+	if _, err = os.Stat(filePath); os.IsNotExist(err) {
+		utils.FileLog.Error("文件不存在: %v", err)
+		return
+	}
+	// 打开 Excel 文件
+	file, err := excelize.OpenFile(filePath)
+	if err != nil {
+		utils.FileLog.Error("无法打开 Excel 文件: %v", err)
+		return
+	}
+	sheetNames := file.GetSheetList()
+	classifyIds, err := dealClassify(CubeDashboards, []string{OilSupplyAnalysis})
+	// 获取所有工作表
+	if err != nil {
+		utils.FileLog.Error("获取分类Id失败: %v", err)
+		return
+	}
+	//按照sheet页来处理数据,一个sheet发送一次服务器
+	for _, sheetName := range sheetNames {
+		var indexMap = make(map[string]*models.IndexInfo)
+		// 获取工作表的最大行数
+		dataRows, excelErr := file.GetRows(sheetName) // 直接获取所有行数据
+		if excelErr != nil {
+			utils.FileLog.Error("获取工作表数据时出错: %v", excelErr)
+			continue
+		}
+		if sheetConfig, ok := OilSupplyAnalysisConfigMap[sheetName]; ok {
+			// 匹配非数字字符
+			classifyId := classifyIds[OilSupplyAnalysis]
+			indexMap, err = DataHandler(dataRows, sheetConfig, classifyId, OilSupplyAnalysis)
+			// 新增数据源指标数据
+			if len(indexMap) > 0 {
+				for _, index := range indexMap {
+					pars := chunkIndexData(index, rzdBatchSize)
+					for _, par := range pars {
+						// 转换成json
+						marshal, parseErr := json.Marshal(par)
+						if parseErr != nil {
+							utils.FileLog.Error("json.Marshal err: %v", parseErr)
+							return parseErr
+						}
+						// 发送 HTTP POST 请求
+						_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_RZD_DATA, string(marshal), "application/json")
+						if err != nil {
+							utils.FileLog.Error("postEdbLib err: %v", err)
+							return err
+						}
+					}
+				}
+			}
+		}
+	}
+	return
+}
+func DataHandler(dataRows [][]string, sheetConfig OSAPConfig, classifyId int, topName string) (indexMap map[string]*models.IndexInfo, err error) {
+	indexMap = make(map[string]*models.IndexInfo)
+	for _, rowData := range dataRows[OsaBeginRow : len(dataRows)-1] {
+		less := OsaRows - len(rowData)
+		if less > 0 {
+			for i := 0; i < less; i++ {
+				rowData = append(rowData, "")
+			}
+		}
+		// step_2: 指标
+		// 指标名称
+		indexName := topName + "/" + sheetConfig.IndexNameColSuffix + "/" + rowData[sheetConfig.IndexRow]
+		// 生成指标编码
+		indexCode := getIndexId(fmt.Sprintf("%s %s", topName, sheetConfig.IndexNameColSuffix), strings.ReplaceAll(strings.ToLower(rowData[sheetConfig.IndexRow]), " ", ""), "")
+		dataTime := rowData[sheetConfig.DateRow]
+		if dataTime == "0" {
+			continue
+		}
+
+		date, _, convertErr := utils.ConvertDateFormatForOSA(dataTime)
+		if convertErr != nil {
+			utils.FileLog.Error(fmt.Sprintf("转换时间数据失败,index_code:%s,time_value:%s err:%v", indexCode, dataTime, convertErr))
+			continue
+		}
+		if rowData[sheetConfig.DataRow] != "" {
+			value, parseErr := decimal.NewFromString(rowData[sheetConfig.DataRow])
+			if parseErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCode, rowData[sheetConfig.DataRow], err))
+				continue
+			} else {
+				if index, ok := indexMap[indexCode]; ok {
+					if index.StartDate.After(date) {
+						index.StartDate = date
+					}
+					if index.EndDate.Before(date) {
+						index.EndDate = date
+						index.LatestValue = value
+					}
+					index.DataList = append(index.DataList, models.IndexData{
+						DataTime: date,
+						Value:    value,
+					})
+				} else {
+					indexMap[indexCode] = &models.IndexInfo{
+						IndexName:   indexName,
+						IndexCode:   indexCode,
+						Frequency:   sheetConfig.Frequency,
+						Unit:        sheetConfig.Unit,
+						StartDate:   date,
+						EndDate:     date,
+						LatestValue: value,
+						ClassifyId:  classifyId,
+						DataList: []models.IndexData{
+							{
+								DataTime: date,
+								Value:    value,
+							},
+						},
+					}
+				}
+			}
+		}
+	}
+	return
+}

+ 0 - 3483
services/ruizide/processor_business_logic.go

@@ -1,3483 +0,0 @@
-// Package ruizide
-// @Author gmy 2024/10/21 10:50:00
-package ruizide
-
-import (
-	"encoding/json"
-	"eta/eta_data_analysis/models"
-	"eta/eta_data_analysis/utils"
-	"fmt"
-	"github.com/beego/beego/v2/core/logs"
-	"math"
-	"strconv"
-	"strings"
-	"unicode"
-)
-
-var classifyMap = map[string]string{
-	"Road Index":                       "analytics library",
-	"Road Active Fleet":                "analytics library",
-	"Aviation Index":                   "analytics library",
-	"Aviation Active Fleet":            "analytics library",
-	"Demand-Gasoline":                  "analytics library",
-	"Demand - Diesel":                  "analytics library",
-	"Demand - Jet Fuel":                "analytics library",
-	"Demand - Maritime Bunker":         "analytics library",
-	"Oil_Demand_Signals_Weekly_Report": "analytics library",
-	"cube dashboards":                  "cube dashboards",
-	"Oil Market Cube":                  "Oil Market Cube",
-}
-
-// RoadIndexProcessor
-// @Description: AnalyticsLibrary处理器
-type RoadIndexProcessor struct{}
-
-func (p *RoadIndexProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing AnalyticsLibrary...")
-	if tableName == "Content" {
-		return nil, nil
-	}
-	if rowIndex < 4 {
-		return nil, nil
-	}
-
-	frequency := "日度"
-	unit := "%"
-	indexNameColOne := "Index"
-	indexNameColTwo := "Index 7DMA"
-
-	// step_1: 分类
-	classifyId, err := dealClassify(tableName, sheetName)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := sheetName + "/" + 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)
-
-	indexInfoMap := make(map[string]string)
-	indexInfoMap[indexCodeOne] = indexNameOne
-	indexInfoMap[indexCodeTwo] = indexNameTwo
-
-	var indexInfoList []*models.IndexInfo
-	valueOne, err := strconv.ParseFloat(rowData[len(rowData)-2], 64)
-	if err != nil {
-		return nil, err
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	valueTwo, err := strconv.ParseFloat(rowData[len(rowData)-1], 64)
-	if err != nil {
-		return nil, err
-	}
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// RoadActiveFleetProcessor
-// @Description: RoadActiveFleetProcessor处理器
-type RoadActiveFleetProcessor struct{}
-
-func (p *RoadActiveFleetProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing RoadActiveFleet...")
-	if tableName == "Content" {
-		return nil, nil
-	}
-	if rowIndex < 4 {
-		return nil, nil
-	}
-
-	frequency := "日度"
-	unit := "辆"
-	indexNameColOne := "Active Fleet"
-	indexNameColTwo := "Active Fleet 7DMA"
-
-	// step_1: 分类
-	classifyId, err := dealClassify(tableName, sheetName)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := sheetName + "/" + 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)
-
-	var indexInfoList []*models.IndexInfo
-	valueOne, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	valueTwo, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("RoadActiveFleetProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("RoadActiveFleetProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// AviationIndexProcessor
-// @Description: AviationIndexProcessor处理器
-type AviationIndexProcessor struct{}
-
-func (p *AviationIndexProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing AviationIndexProcessor...")
-	if tableName == "Content" {
-		return nil, nil
-	}
-	if rowIndex < 4 {
-		return nil, nil
-	}
-
-	frequency := "日度"
-	unit := "%"
-	indexNameColOne := "Index"
-	indexNameColTwo := "Index 7DMA"
-
-	// step_1: 分类
-	classifyId, err := dealClassify(tableName, sheetName)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := sheetName + "/" + 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)
-
-	var indexInfoList []*models.IndexInfo
-	valueOne, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	valueTwo, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("AviationIndexProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("AviationIndexProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// AviationActiveFleetProcessor
-// @Description: AviationActiveFleetProcessor处理器
-type AviationActiveFleetProcessor struct{}
-
-func (p *AviationActiveFleetProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing AviationActiveFleetProcessor...")
-	if tableName == "Content" {
-		return nil, nil
-	}
-	if rowIndex < 4 {
-		return nil, nil
-	}
-
-	frequency := "日度"
-	unit := "辆"
-	indexNameColOne := "Active Fleet"
-	indexNameColTwo := "Active Fleet 7DMA"
-
-	// step_1: 分类
-	classifyId, err := dealClassify(tableName, sheetName)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := sheetName + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := sheetName + "/" + 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)
-
-	var indexInfoList []*models.IndexInfo
-	valueOne, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	valueTwo, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("AviationActiveFleetProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("AviationActiveFleetProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// DemandGasolineProcessor
-// @Description: DemandGasolineProcessor处理器
-type DemandGasolineProcessor struct{}
-
-func (p *DemandGasolineProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing DemandGasolineProcessor...")
-	if tableName == "Content" {
-		return nil, nil
-	}
-	if rowIndex < 4 {
-		return nil, nil
-	}
-
-	frequency := "日度"
-	unit := "千桶每天"
-	indexNameColOne := "Demand"
-	indexNameColTwo := "Demand 7DMA"
-
-	// step_1: 分类
-	classifyId, err := dealClassify(tableName, sheetName)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := "Gasoline Demand" + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := "Gasoline Demand" + "/" + rowData[len(rowData)-3] + "/" + indexNameColTwo
-
-	// 生成指标编码
-	indexCodeOne, err := getIndexId("Gasoline Demand", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColOne)
-	indexCodeTwo, err := getIndexId("Gasoline Demand", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-3]), " ", ""), indexNameColTwo)
-
-	var indexInfoList []*models.IndexInfo
-	var valueOne float64
-	if rowData[len(rowData)-2] == "" {
-		valueOne = 0
-	} else {
-		valueOne, err = strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	var valueTwo float64
-	if rowData[len(rowData)-1] == "" {
-		valueTwo = 0
-	} else {
-		valueTwo, err = strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("DemandGasolineProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("DemandGasolineProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// DemandDieselProcessor
-// @Description: DemandDieselProcessor处理器
-type DemandDieselProcessor struct{}
-
-func (p *DemandDieselProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing DemandDieselProcessor...")
-	if tableName == "Content" {
-		return nil, nil
-	}
-	if rowIndex < 4 {
-		return nil, nil
-	}
-
-	frequency := "日度"
-	unit := "千桶每天"
-	indexNameColOne := "Demand"
-	indexNameColTwo := "Demand 7DMA"
-
-	// step_1: 分类
-	classifyId, err := dealClassify(tableName, sheetName)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := "Demand Diesel" + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := "Demand Diesel" + "/" + 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)
-	if err != nil {
-		return nil, err
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	valueTwo, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("DemandDieselProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("DemandDieselProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// DemandJetFuelProcessor
-// @Description: DemandJetFuelProcessor处理器
-type DemandJetFuelProcessor struct{}
-
-func (p *DemandJetFuelProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing DemandJetFuelProcessor...")
-	if tableName == "Content" {
-		return nil, nil
-	}
-	if rowIndex < 4 {
-		return nil, nil
-	}
-
-	frequency := "日度"
-	unit := "千桶每天"
-	indexNameColOne := "Demand"
-	indexNameColTwo := "Demand 7DMA"
-
-	// step_1: 分类
-	classifyId, err := dealClassify(tableName, sheetName)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := "Demand Jet Fuel" + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := "Demand Jet Fuel" + "/" + 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)
-	if err != nil {
-		return nil, err
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	valueTwo, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("DemandJetFuelProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("DemandJetFuelProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// DemandMaritimeBunkerProcessor
-// @Description: DemandMaritimeBunkerProcessor处理器
-type DemandMaritimeBunkerProcessor struct{}
-
-func (p *DemandMaritimeBunkerProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing DemandMaritimeBunkerProcessor...")
-	if tableName == "Content" {
-		return nil, nil
-	}
-	if rowIndex < 4 {
-		return nil, nil
-	}
-
-	frequency := "日度"
-	unit := "千桶每天"
-	indexNameColOne := "Demand"
-	indexNameColTwo := "Demand 7DMA"
-
-	// step_1: 分类
-	classifyId, err := dealClassify(tableName, sheetName)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := "Demand Maritime Bunker" + "/" + rowData[len(rowData)-3] + "/" + indexNameColOne
-	indexNameTwo := "Demand Maritime Bunker" + "/" + 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)
-	if err != nil {
-		return nil, err
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	valueTwo, err := strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-	if err != nil {
-		return nil, err
-	}
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("DemandMaritimeBunkerProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("DemandMaritimeBunkerProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// SupplyRevisionAnalysisChartOneProcessor
-// @Description: SupplyRevisionAnalysisChartOneProcessor处理器
-type SupplyRevisionAnalysisChartOneProcessor struct{}
-
-func (p *SupplyRevisionAnalysisChartOneProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing SupplyRevisionAnalysisChartOne...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "季度"
-	unit := "千桶每天"
-	indexNameColSuffix := "YearQuarter"
-	indexNameColPrefix := "Country Revision Group"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Supply Revision Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-1]
-
-	// 生成指标编码
-	indexCode, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix+" Year Quarter", strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-1]), " ", ""), "")
-
-	indexInfoMap := make(map[string]string)
-	indexInfoMap[indexCode] = indexName
-
-	var indexInfoList []*models.IndexInfo
-	var value float64
-	if rowData[len(rowData)-2] == "" {
-		value = 0
-	} else {
-		value, err = strconv.ParseFloat(rowData[len(rowData)-2], 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	dataTime := rowData[0]
-	format, err := utils.ConvertDateFormat2(dataTime)
-	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("SupplyRevisionAnalysisChartOneProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartOneProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// SupplyRevisionAnalysisChartTwoProcessor
-// @Description: SupplyRevisionAnalysisChartTwoProcessor处理器
-type SupplyRevisionAnalysisChartTwoProcessor struct{}
-
-func (p *SupplyRevisionAnalysisChartTwoProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing SupplyRevisionAnalysisChartTwoProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "季度"
-	unit := "千桶每天"
-	indexNameColPrefix := "YearQuarter"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Supply Revision Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + "Current"
-	indexNameTwo := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + "Previous"
-
-	// 生成指标编码
-	indexCodeOne, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix, "Current", "")
-	indexCodeTwo, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix, "Previous", "")
-
-	var indexInfoList []*models.IndexInfo
-	var valueOne float64
-	if rowData[len(rowData)-2] == "" {
-		valueOne = 0
-	} else {
-		valueOne, err = strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	dataTimeOne := rowData[1]
-	formatOne, err := utils.ConvertDateFormat2(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	var valueTwo float64
-	if rowData[len(rowData)-1] == "" {
-		valueTwo = 0
-	} else {
-		valueTwo, err = strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartTwoProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartTwoProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// SupplyRevisionAnalysisChartThreeProcessor
-// @Description: SupplyRevisionAnalysisChartThreeProcessor
-type SupplyRevisionAnalysisChartThreeProcessor struct{}
-
-func (p *SupplyRevisionAnalysisChartThreeProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing SupplyRevisionAnalysisChartThreeProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "年度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Year"
-	indexNameColPrefix := "Country Revision Group"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Supply Revision Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-1]
-
-	// 生成指标编码
-	indexCode, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix+" "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-1]), " ", ""), "")
-
-	indexInfoMap := make(map[string]string)
-	indexInfoMap[indexCode] = indexName
-
-	var indexInfoList []*models.IndexInfo
-	var value float64
-	if rowData[len(rowData)-2] == "" {
-		value = 0
-	} else {
-		value, err = strconv.ParseFloat(rowData[len(rowData)-2], 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	dataTime := rowData[0]
-	format, err := utils.ConvertDateFormat4(dataTime)
-	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("SupplyRevisionAnalysisChartThreeProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartThreeProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// SupplyRevisionAnalysisChartFourProcessor
-// @Description: SupplyRevisionAnalysisChartFourProcessor处理器
-type SupplyRevisionAnalysisChartFourProcessor struct{}
-
-func (p *SupplyRevisionAnalysisChartFourProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing SupplyRevisionAnalysisChartFourProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "年度"
-	unit := "千桶每天"
-	indexNameColPrefix := "Year"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Supply Revision Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + "Current"
-	indexNameTwo := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + "Previous"
-
-	// 生成指标编码
-	indexCodeOne, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix, "current", "")
-	indexCodeTwo, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix, "previous", "")
-
-	var indexInfoList []*models.IndexInfo
-	var valueOne float64
-	if rowData[len(rowData)-2] == "" {
-		valueOne = 0
-	} else {
-		valueOne, err = strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	dataTimeOne := rowData[0]
-	formatOne, err := utils.ConvertDateFormat4(dataTimeOne)
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	var valueTwo float64
-	if rowData[len(rowData)-1] == "" {
-		valueTwo = 0
-	} else {
-		valueTwo, err = strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-1], ",", ""), 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartFourProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartFourProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// SupplyRevisionAnalysisChartFiveProcessor
-// @Description: SupplyRevisionAnalysisChartFiveProcessor处理器
-type SupplyRevisionAnalysisChartFiveProcessor struct{}
-
-func (p *SupplyRevisionAnalysisChartFiveProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing SupplyRevisionAnalysisChartFiveProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColPrefix := "YearMonth"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Supply Revision Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexNameOne := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + "Current/Chat5"
-	indexNameTwo := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + "Previous/Chat5"
-
-	// 生成指标编码
-	indexCodeOne, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix, "currentchat5", "")
-	indexCodeTwo, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix, "previouschat5", "")
-
-	var indexInfoList []*models.IndexInfo
-	var valueOne float64
-	if rowData[len(rowData)-2] == "" {
-		valueOne = 0
-	} else {
-		valueOne, err = strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-2], ",", ""), 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	dataTimeOne := rowData[len(rowData)-1]
-	timeSplit := strings.Split(dataTimeOne, "-")
-	formatOne, err := utils.GetLastDayOfMonth(timeSplit[0] + "-" + timeSplit[1])
-	if err != nil {
-		return nil, err
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameOne,
-		IndexCode: indexCodeOne,
-		Value:     valueOne,
-		DataTime:  formatOne,
-	})
-	var valueTwo float64
-	if rowData[len(rowData)-3] == "" {
-		valueTwo = 0
-	} else {
-		valueTwo, err = strconv.ParseFloat(strings.ReplaceAll(rowData[len(rowData)-3], ",", ""), 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	indexInfoList = append(indexInfoList, &models.IndexInfo{
-		IndexName: indexNameTwo,
-		IndexCode: indexCodeTwo,
-		Value:     valueTwo,
-		DataTime:  formatOne,
-	})
-
-	indexInfoList, err = dealIndex(indexInfoList, frequency, unit, classifyId)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartFiveProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartFiveProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// SupplyRevisionAnalysisChartSixProcessor
-// @Description: SupplyRevisionAnalysisChartSixProcessor
-type SupplyRevisionAnalysisChartSixProcessor struct{}
-
-func (p *SupplyRevisionAnalysisChartSixProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing SupplyRevisionAnalysisChartSixProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "YearMonth"
-	indexNameColPrefix := "Country Revision Group"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Supply Revision Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Supply Revision Analysis" + "/" + indexNameColPrefix + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
-
-	// 生成指标编码
-	indexCode, err := getIndexId("Supply Revision Analysis "+indexNameColPrefix+" "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
-
-	indexInfoMap := make(map[string]string)
-	indexInfoMap[indexCode] = indexName
-
-	var indexInfoList []*models.IndexInfo
-	var value float64
-	if rowData[len(rowData)-1] == "" {
-		value = 0
-	} else {
-		value, err = strconv.ParseFloat(rowData[len(rowData)-1], 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	dataTime := rowData[0]
-	timeSplit := strings.Split(dataTime, "-")
-	format, err := utils.GetLastDayOfMonth(timeSplit[0] + "-" + timeSplit[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("SupplyRevisionAnalysisChartSixProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("SupplyRevisionAnalysisChartSixProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilSupplyAnalysisChartOneProcessor
-// @Description: OilSupplyAnalysisChartOneProcessor处理器
-type OilSupplyAnalysisChartOneProcessor struct{}
-
-func (p *OilSupplyAnalysisChartOneProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilSupplyAnalysisChartOne...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Oil And Gas Category"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
-
-	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
-
-	indexInfoMap := make(map[string]string)
-	indexInfoMap[indexCode] = indexName
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilSupplyAnalysisChartOneProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilSupplyAnalysisChartOneProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilSupplyAnalysisChartTwoProcessor
-// @Description: OilSupplyAnalysisChartTwoProcessor处理器
-type OilSupplyAnalysisChartTwoProcessor struct{}
-
-func (p *OilSupplyAnalysisChartTwoProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilSupplyAnalysisChartTwoProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Region"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-1]
-
-	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-1]), " ", ""), "")
-
-	indexInfoMap := make(map[string]string)
-	indexInfoMap[indexCode] = indexName
-
-	var indexInfoList []*models.IndexInfo
-	value, err := strconv.ParseFloat(rowData[len(rowData)-2], 64)
-	if err != nil {
-		return nil, err
-	}
-
-	dataTime := rowData[0]
-	format, err := utils.ConvertDateFormat3(dataTime)
-	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("OilSupplyAnalysisChartTwoProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilSupplyAnalysisChartTwoProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilSupplyAnalysisChartThreeProcessor
-// @Description: OilSupplyAnalysisChartThreeProcessor处理器
-type OilSupplyAnalysisChartThreeProcessor struct{}
-
-func (p *OilSupplyAnalysisChartThreeProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilSupplyAnalysisChartThreeProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "CapacityDetail"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
-
-	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
-
-	indexInfoMap := make(map[string]string)
-	indexInfoMap[indexCode] = indexName
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilSupplyAnalysisChartThreeProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilSupplyAnalysisChartThreeProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilSupplyAnalysisChartFourProcessor
-// @Description: OilSupplyAnalysisChartFourProcessor处理器
-type OilSupplyAnalysisChartFourProcessor struct{}
-
-func (p *OilSupplyAnalysisChartFourProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilSupplyAnalysisChartFourProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Oil Classification Group"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Supply Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Supply Analysis" + "/" + indexNameColSuffix + "/" + rowData[len(rowData)-2]
-
-	// 生成指标编码
-	indexCode, err := getIndexId("Oil Supply Analysis "+indexNameColSuffix, strings.ReplaceAll(strings.ToLower(rowData[len(rowData)-2]), " ", ""), "")
-
-	indexInfoMap := make(map[string]string)
-	indexInfoMap[indexCode] = indexName
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilSupplyAnalysisChartFourProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilSupplyAnalysisChartFourProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilDemandAnalysisContinentProcessor
-// @Description: OilDemandAnalysisContinentProcessor处理器
-type OilDemandAnalysisContinentProcessor struct{}
-
-func (p *OilDemandAnalysisContinentProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilDemandAnalysisContinentProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Continent"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + 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
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilDemandAnalysisContinentProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilDemandAnalysisContinentProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilDemandAnalysisRegionProcessor
-// @Description: OilDemandAnalysisRegionProcessor处理器
-type OilDemandAnalysisRegionProcessor struct{}
-
-func (p *OilDemandAnalysisRegionProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilDemandAnalysisRegionProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Region"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + 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
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilDemandAnalysisRegionProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilDemandAnalysisRegionProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilDemandAnalysisCountryProcessor
-// @Description: OilDemandAnalysisCountryProcessor
-type OilDemandAnalysisCountryProcessor struct{}
-
-func (p *OilDemandAnalysisCountryProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilDemandAnalysisCountryProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Country"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + 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
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilDemandAnalysisCountryProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilDemandAnalysisCountryProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilDemandAnalysisProductCategoryProcessor
-// @Description: OilDemandAnalysisProductCategoryProcessor处理器
-type OilDemandAnalysisProductCategoryProcessor struct{}
-
-func (p *OilDemandAnalysisProductCategoryProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilDemandAnalysisProductCategoryProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Product category"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + 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
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilDemandAnalysisProductCategoryProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilDemandAnalysisProductCategoryProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilDemandAnalysisProductDetailProcessor
-// @Description: OilDemandAnalysisProductDetailProcessor处理器
-type OilDemandAnalysisProductDetailProcessor struct{}
-
-func (p *OilDemandAnalysisProductDetailProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilDemandAnalysisProductDetailProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Product detail"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + 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
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilDemandAnalysisProductDetailProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilDemandAnalysisProductDetailProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilDemandAnalysisSectorCategoryProcessor
-// @Description: OilDemandAnalysisSectorCategoryProcessor处理器
-type OilDemandAnalysisSectorCategoryProcessor struct{}
-
-func (p *OilDemandAnalysisSectorCategoryProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilDemandAnalysisSectorCategoryProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Sector category"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + 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
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilDemandAnalysisSectorCategoryProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilDemandAnalysisSectorCategoryProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilDemandAnalysisSectorDetailProcessor
-// @Description: OilDemandAnalysisSectorDetailProcessor处理器
-type OilDemandAnalysisSectorDetailProcessor struct{}
-
-func (p *OilDemandAnalysisSectorDetailProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilDemandAnalysisSectorDetailProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Sector detail"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + 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
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilDemandAnalysisSectorDetailProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilDemandAnalysisSectorDetailProcessor dataList: %v", dataList)
-
-	return dataList, err
-}
-
-// OilDemandAnalysisScenarioProcessor
-// @Description: OilDemandAnalysisScenarioProcessor处理器
-type OilDemandAnalysisScenarioProcessor struct{}
-
-func (p *OilDemandAnalysisScenarioProcessor) Process(tableName string, sheetName string, rowIndex int, rowData []string) ([]models.BaseFromRzdData, error) {
-	logs.Info("Processing OilDemandAnalysisScenarioProcessor...")
-	if rowIndex < 1 {
-		return nil, nil
-	}
-
-	frequency := "月度"
-	unit := "千桶每天"
-	indexNameColSuffix := "Scenario"
-	//indexNameColPrefix := "CountryRevisionGroup"
-
-	// step_1: 分类
-	classifyId, err := dealClassify("cube dashboards", "Oil Demand Analysis")
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("classifyId: %v", classifyId)
-
-	// step_2: 指标
-	// 指标名称
-	indexName := "Oil Demand Analysis" + "/" + indexNameColSuffix + "/" + 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
-
-	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.ConvertDateFormat3(dataTime)
-	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("OilDemandAnalysisScenarioProcessor indexInfoList: %v", indexInfoList)
-
-	// step_3: 指标数据
-	dataList, err := dealData(indexInfoList)
-	if err != nil {
-		return nil, err
-	}
-	logs.Info("OilDemandAnalysisScenarioProcessor dataList: %v", dataList)
-
-	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 {
-		paramsLib := make(map[string]interface{})
-		paramsLib["IndexCode"] = indexInfo.IndexCode
-		paramsLib["DataTime"] = indexInfo.DataTime
-		postEdbLib, err := httpRequestFill(paramsLib, utils.GET_RZD_INDEX_DATA_BY_CODE_AND_TIME)
-		if err != nil {
-			return nil, err
-		}
-		var requestResponse models.RequestResponse[models.BaseFromRzdData]
-		err = json.Unmarshal(postEdbLib, &requestResponse)
-		if err != nil {
-			return nil, err
-		}
-		if requestResponse.Data.BaseFromRzdIndexId == 0 {
-			dataOne := models.BaseFromRzdData{
-				BaseFromRzdIndexId: indexInfo.IndexInfoId,
-				CreateTime:         utils.GetCurrentTime(),
-				DataTime:           indexInfo.DataTime,
-				IndexCode:          indexInfo.IndexCode,
-				ModifyTime:         utils.GetCurrentTime(),
-				Value:              math.Round(indexInfo.Value*10000) / 10000,
-			}
-			dataList = append(dataList, dataOne)
-		} else {
-			// 编辑
-			value := math.Round(indexInfo.Value*10000) / 10000
-			if requestResponse.Data.Value != value {
-				rzdData := requestResponse.Data
-				rzdData.Value = value
-
-				_, err = httpRequestFill(rzdData, utils.UPDATE_RZD_EDB_DATA)
-				if err != nil {
-					return nil, err
-				}
-			}
-		}
-	}
-
-	return dataList, nil
-}
-
-func dealIndex(indexInfoList []*models.IndexInfo, frequency string, unit string, classifyId int) ([]*models.IndexInfo, error) {
-	for _, index := range indexInfoList {
-		// 处理第一个指标
-		paramsLib := make(map[string]interface{})
-		paramsLib["indexCode"] = index.IndexCode
-		postEdbLib, err := httpRequestFill(paramsLib, utils.GET_RZD_INDEX_BY_CODE)
-		if err != nil {
-			return nil, fmt.Errorf("getIndexId() : Failed to get rzd index by code: %v", err)
-		}
-		var requestResponse models.RequestResponse[models.BaseFromRzdIndex]
-		err = json.Unmarshal(postEdbLib, &requestResponse)
-		if err != nil {
-			return nil, err
-		}
-		if requestResponse.Data.BaseFromRzdIndexId == 0 {
-			indexOne := models.BaseFromRzdIndex{
-				CreateTime:           utils.GetCurrentTime(),
-				ModifyTime:           utils.GetCurrentTime(),
-				BaseFromLyClassifyId: classifyId,
-				IndexCode:            index.IndexCode,
-				IndexName:            index.IndexName,
-				Frequency:            frequency,
-				Unit:                 unit,
-			}
-			// 这里避免服务器宕机 出现唯一索引异常,进行分开保存
-			postEdbLib, err = httpRequestFill(indexOne, utils.ADD_RZD_INDEX)
-			if err != nil {
-				return nil, fmt.Errorf("getIndexId() : Failed to get rzd index by code: %v", err)
-			}
-			var requestResponse models.RequestResponse[int]
-			err = json.Unmarshal(postEdbLib, &requestResponse)
-			if err != nil {
-				return nil, err
-			}
-			logs.Info("indexOneId: %v", requestResponse.Data)
-
-			index.IndexInfoId = requestResponse.Data
-		} else {
-			logs.Info("indexOneId: %v", requestResponse.Data.BaseFromRzdIndexId)
-			index.IndexInfoId = requestResponse.Data.BaseFromRzdIndexId
-		}
-	}
-	return indexInfoList, nil
-}
-
-func getIndexId(prefix string, area string, suffix string) (string, error) {
-	prefixWords := strings.Fields(prefix) // 分割字符串为单词
-	firstLetters := ""
-
-	for _, word := range prefixWords {
-		if len(word) > 0 {
-			firstLetters += string(unicode.ToLower(rune(word[0]))) // 获取小写的第一个字母
-		}
-	}
-
-	suffixWords := strings.Fields(suffix) // 分割字符串为单词
-	SecondLetters := ""
-
-	for _, word := range suffixWords {
-		if len(word) > 0 {
-			SecondLetters += string(unicode.ToLower(rune(word[0]))) // 获取小写的第一个字母
-		}
-	}
-	indexCode := "rzd" + firstLetters + area + SecondLetters
-
-	return indexCode, nil
-}
-
-// 处理分类
-func dealClassify(tableName, sheetName string) (int, error) {
-	// 查询一级分类是否存在
-	paramsLib := make(map[string]interface{})
-	paramsLib["classifyName"] = classifyMap[tableName]
-	postEdbLib, err := httpRequestFill(paramsLib, utils.GET_RZD_CLASSIFY_BY_NAME)
-	if err != nil {
-		return 0, fmt.Errorf("AnalyticsLibraryProcessor Process() : failed to get classify: %v", err)
-	}
-	var requestResponse models.RequestResponse[models.BaseFromRzdClassify]
-	err = json.Unmarshal(postEdbLib, &requestResponse)
-	if err != nil {
-		return 0, err
-	}
-
-	// 处理一级分类
-	var parentId int
-	if requestResponse.Data.BaseFromRzdClassifyId == 0 {
-		// 一级分类不存在,新增一级分类
-		paramsLib = make(map[string]interface{})
-		paramsLib["parentId"] = 0
-		paramsLib["classifyName"] = classifyMap[tableName]
-		postEdbLib, err = httpRequestFill(paramsLib, utils.ADD_RZD_CLASSIFY)
-		if err != nil {
-			return 0, fmt.Errorf("AnalyticsLibraryProcessor Process() : failed to add classify: %v", err)
-		}
-		var requestResponse models.RequestResponse[int]
-		err = json.Unmarshal(postEdbLib, &requestResponse)
-		if err != nil {
-			return 0, err
-		}
-		parentId = requestResponse.Data
-	} else {
-		// 一级分类已存在,使用其 ID
-		parentId = requestResponse.Data.BaseFromRzdClassifyId
-	}
-	// 查询二级分类是否存在
-	paramsSubLib := make(map[string]interface{})
-	paramsSubLib["classifyName"] = sheetName // 这里替换成实际的二级分类名称
-	postSubEdbLib, err := httpRequestFill(paramsSubLib, utils.GET_RZD_CLASSIFY_BY_NAME)
-	if err != nil {
-		return 0, fmt.Errorf("AnalyticsLibraryProcessor Process() : failed to get sub classify: %v", err)
-	}
-
-	var subRequestResponse models.RequestResponse[models.BaseFromRzdClassify]
-	err = json.Unmarshal(postSubEdbLib, &subRequestResponse)
-	if err != nil {
-		return 0, err
-	}
-
-	// 新增二级分类
-	var classifyId int
-	if subRequestResponse.Data.BaseFromRzdClassifyId == 0 {
-		paramsLib = make(map[string]interface{})
-		paramsLib["parentId"] = parentId
-		paramsLib["classifyName"] = sheetName
-		postEdbLib, err = httpRequestFill(paramsLib, utils.ADD_RZD_CLASSIFY)
-		if err != nil {
-			return 0, fmt.Errorf("AnalyticsLibraryProcessor Process() : failed to add classify: %v", err)
-		}
-		var requestResponse models.RequestResponse[int]
-		err = json.Unmarshal(postEdbLib, &requestResponse)
-		if err != nil {
-			return 0, err
-		}
-		classifyId = requestResponse.Data
-	} else {
-		classifyId = subRequestResponse.Data.BaseFromRzdClassifyId
-	}
-
-	return classifyId, nil
-}

+ 264 - 217
services/ruizide/processor_factory.go

@@ -1,243 +1,290 @@
 package ruizide
 
 import (
+	"encoding/json"
 	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/utils"
 	"fmt"
+	"strings"
+	"unicode"
+)
+
+// 定义选择器
+var (
+	tableNameList = []string{
+		"Oil_Demand_Signals_Weekly_Report",
+		"Oil_Supply_Analysis",
+		"Supply_Revision_Analysis",
+		"Oil_Demand_Analysis_Product_Detail",
+		"Oil_Demand_Analysis_Region",
+		"Oil_Demand_Analysis_Scenario",
+		"Oil_Demand_Analysis_Continent",
+		"Oil_Demand_Analysis_Country",
+		"Oil_Demand_Analysis_Product_Category",
+		"Oil_Demand_Analysis_Sector_Category",
+		"Oil_Demand_Analysis_Sector_Detail",
+		"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",
+	}
+
+	RzdClassifyMap = make(map[string]*models.BaseFromRzdClassify)
+	classifyMap    = map[string]models.RzdClassifyMapStruct{
+		"Road Index": {
+			ClassifyName: "Road Index",
+			Sort:         1,
+		},
+		"Road Active Fleet": {
+			ClassifyName: "Road Active Fleet",
+			Sort:         2,
+		},
+		"Aviation Index": {
+			ClassifyName: "Aviation Index",
+			Sort:         3,
+		},
+		"Aviation Active Fleet": {
+			ClassifyName: "Aviation Active Fleet",
+			Sort:         4,
+		},
+		"Demand - Gasoline": {
+			ClassifyName: "Demand - Gasoline",
+			Sort:         5,
+		},
+		"Demand - Diesel": {
+			ClassifyName: "Demand - Diesel",
+			Sort:         6,
+		},
+		"Demand - Jet Fuel": {
+			ClassifyName: "Demand - Jet Fuel",
+			Sort:         7,
+		},
+		"Demand - Maritime Bunker": {
+			ClassifyName: "Demand - Maritime Bunker",
+			Sort:         8,
+		},
+		"Oil_Demand_Signals_Weekly_Report": {
+			ClassifyName: "analytics library",
+			Sort:         1,
+		},
+		"cube dashboards": {
+			ClassifyName: "cube dashboards",
+			Sort:         2,
+		},
+		"Oil Market Cube": {
+			ClassifyName: "Oil Market Cube",
+			Sort:         3,
+		},
+		"Supply Revision Analysis": {
+			ClassifyName: "Supply Revision Analysis",
+			Sort:         1,
+		},
+		"Oil Supply Analysis": {
+			ClassifyName: "Oil Supply Analysis",
+			Sort:         2,
+		},
+		"Oil Demand Analysis": {
+			ClassifyName: "Oil Demand Analysis",
+			Sort:         3,
+		},
+		"Upstream Supply": {
+			ClassifyName: "Upstream Supply",
+			Sort:         1,
+		},
+		"Products Demand": {
+			ClassifyName: "Products Demand",
+			Sort:         2,
+		},
+		"Balances": {
+			ClassifyName: "Balances",
+			Sort:         3,
+		},
+		"Geography": {
+			ClassifyName: "Geography",
+			Sort:         4,
+		},
+	}
 )
 
 type ReportProcessor interface {
 	Process(string, string, int, []string) ([]models.BaseFromRzdData, error)
 }
 
-func GetProcessor(tableName string, sheetName string) (ReportProcessor, error) {
-	if tableName == "Oil_Demand_Signals_Weekly_Report" {
-		switch sheetName {
-		case "Road Index":
-			return &RoadIndexProcessor{}, nil
-		case "Road Active Fleet":
-			return &RoadActiveFleetProcessor{}, nil
-		case "Aviation Index":
-			return &AviationIndexProcessor{}, nil
-		case "Aviation Active Fleet":
-			return &AviationActiveFleetProcessor{}, nil
-		case "Demand - Gasoline":
-			return &DemandGasolineProcessor{}, nil
-		case "Demand - Diesel":
-			return &DemandDieselProcessor{}, nil
-		case "Demand - Jet Fuel":
-			return &DemandJetFuelProcessor{}, nil
-		case "Demand - Maritime Bunker":
-			return &DemandMaritimeBunkerProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Supply_Revision_Analysis" {
-		switch sheetName {
-		case "Chart1":
-			return &SupplyRevisionAnalysisChartOneProcessor{}, nil
-		case "Chart2":
-			return &SupplyRevisionAnalysisChartTwoProcessor{}, nil
-		case "Chart3":
-			return &SupplyRevisionAnalysisChartThreeProcessor{}, nil
-		case "Chart4":
-			return &SupplyRevisionAnalysisChartFourProcessor{}, nil
-		case "Chart5":
-			return &SupplyRevisionAnalysisChartFiveProcessor{}, nil
-		case "Chart6":
-			return &SupplyRevisionAnalysisChartSixProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Supply_Analysis" {
-		switch sheetName {
-		case "Chart1":
-			return &OilSupplyAnalysisChartOneProcessor{}, nil
-		case "Chart2":
-			return &OilSupplyAnalysisChartTwoProcessor{}, nil
-		case "Chart3":
-			return &OilSupplyAnalysisChartThreeProcessor{}, nil
-		case "Chart4":
-			return &OilSupplyAnalysisChartFourProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Demand_Analysis_Continent" {
-		switch sheetName {
-		case "Chart1":
-			return &OilDemandAnalysisContinentProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Demand_Analysis_Region" {
-		switch sheetName {
-		case "Chart1":
-			return &OilDemandAnalysisRegionProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Demand_Analysis_Country" {
-		switch sheetName {
-		case "Chart1":
-			return &OilDemandAnalysisCountryProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Demand_Analysis_Product_Category" {
-		switch sheetName {
-		case "Chart1":
-			return &OilDemandAnalysisProductCategoryProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Demand_Analysis_Product_Detail" {
-		switch sheetName {
-		case "Chart1":
-			return &OilDemandAnalysisProductDetailProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Demand_Analysis_Sector_Category" {
-		switch sheetName {
-		case "Chart1":
-			return &OilDemandAnalysisSectorCategoryProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Demand_Analysis_Sector_Detail" {
-		switch sheetName {
-		case "Chart1":
-			return &OilDemandAnalysisSectorDetailProcessor{}, nil
-		default:
-			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
-		}
-	} else if tableName == "Oil_Demand_Analysis_Scenario" {
-		switch sheetName {
-		case "Chart1":
-			return &OilDemandAnalysisScenarioProcessor{}, nil
-		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)
+type RzdDataProcessor interface {
+	Process(tableName string) error
+}
+
+var RzdProcessorMap = map[string]RzdDataProcessor{
+	"Oil_Demand_Signals_Weekly_Report":                                      &OilDemandSignalsWeeklyReportProcessor{},
+	"Supply_Revision_Analysis":                                              &SupplyRevisionAnalysisProcessor{},
+	"Oil_Supply_Analysis":                                                   &OilSupplyAnalysisProcessor{},
+	"Oil_Demand_Analysis_Product_Detail":                                    &OilDemandAnalysisProcessor{},
+	"Oil_Demand_Analysis_Region":                                            &OilDemandAnalysisProcessor{},
+	"Oil_Demand_Analysis_Scenario":                                          &OilDemandAnalysisProcessor{},
+	"Oil_Demand_Analysis_Continent":                                         &OilDemandAnalysisProcessor{},
+	"Oil_Demand_Analysis_Country":                                           &OilDemandAnalysisProcessor{},
+	"Oil_Demand_Analysis_Product_Category":                                  &OilDemandAnalysisProcessor{},
+	"Oil_Demand_Analysis_Sector_Category":                                   &OilDemandAnalysisProcessor{},
+	"Oil_Demand_Analysis_Sector_Detail":                                     &OilDemandAnalysisProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_Oil_Quality_API":                       &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_Oil_Quality_Sulphur":                   &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_Capacity_Capacity":                     &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_Production":                            &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_Production_Wo_Seasonality":             &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Reference_Production":      &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Production":         &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Cut":                &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Actual_Cut":                &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Compliance":                &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Production_Subject_To_Cut": &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Products_Demand_Products_Demand_Mean":                  &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Products_Demand_Products_Demand+Sigma":                 &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Products_Demand_Products_Demand-Sigma":                 &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Balances_Total_Liquids_Balances":                       &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Geography_Latitude":                                    &OilMarketCubeProcessor{},
+	"Oil_Market_Cube_Geography_Longitude":                                   &OilMarketCubeProcessor{},
+}
+
+func GetRZDProcessor(tableName string) (RzdDataProcessor, error) {
+	if processor, ok := RzdProcessorMap[tableName]; !ok {
+		return nil, fmt.Errorf("no processor found for tableName %s", tableName)
+	} else {
+		return processor, nil
+	}
+}
+
+func getIndexId(prefix string, area string, suffix string) (indexCode string) {
+	prefixWords := strings.Fields(prefix) // 分割字符串为单词
+	firstLetters := ""
+	for _, word := range prefixWords {
+		if len(word) > 0 {
+			firstLetters += string(unicode.ToLower(rune(word[0]))) // 获取小写的第一个字母
 		}
-	} 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)
+	}
+	suffixWords := strings.Fields(suffix) // 分割字符串为单词
+	SecondLetters := ""
+
+	for _, word := range suffixWords {
+		if len(word) > 0 {
+			SecondLetters += string(unicode.ToLower(rune(word[0]))) // 获取小写的第一个字母
 		}
-	} 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)
+	}
+	indexCode = "rzd" + firstLetters + area + SecondLetters
+	return
+}
+
+// 处理分类
+type BatchAddClassifyType struct {
+	List []models.AddRzdClassify
+}
+
+func dealClassify(tableName string, sheetNames []string) (classifyList map[string]int, err error) {
+	var rzdClassifyList []models.AddRzdClassify
+	var parentId int
+	classifyList = make(map[string]int)
+	rzdMapStruct := classifyMap[tableName]
+	// 查询一级分类是否存在
+	if classify, ok := RzdClassifyMap[rzdMapStruct.ClassifyName]; !ok {
+		parentClassify := models.AddRzdClassify{
+			ClassifyName: rzdMapStruct.ClassifyName,
+			Sort:         rzdMapStruct.Sort,
+			ParentId:     0,
 		}
-	} 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)
+		rzdClassifyList = append(rzdClassifyList, parentClassify)
+		resp, httpErr := httpRequestFill(BatchAddClassifyType{
+			List: rzdClassifyList,
+		}, utils.BATCH_ADD_RZD_CLASSYFY)
+		if httpErr != nil {
+			err = fmt.Errorf("添加睿咨得分类失败: %v", err)
+			return
 		}
-	} 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)
+		var rzdResp models.RequestResponse[[]models.BaseFromRzdClassify]
+		jsonErr := json.Unmarshal(resp, &rzdResp)
+		if jsonErr != nil {
+			err = fmt.Errorf("解析添加睿咨得分类失败: %v", err)
+			return
 		}
-	} 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)
+		if rzdResp.Ret != 200 {
+			err = fmt.Errorf("添加睿咨得分类失败: %v", err)
+			return
 		}
-	} 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)
+		parentId = rzdResp.Data[0].BaseFromRzdClassifyId
+		classifyList[tableName] = rzdResp.Data[0].BaseFromRzdClassifyId
+	} else {
+		parentId = classify.BaseFromRzdClassifyId
+		classifyList[tableName] = classify.BaseFromRzdClassifyId
+	}
+	rzdClassifyList = []models.AddRzdClassify{}
+	//处理二级分类
+	for _, sheetName := range sheetNames {
+		if sheetName == "Content" {
+			continue
 		}
-	} 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)
+		rzdMapStruct = classifyMap[sheetName]
+		if classify, ok := RzdClassifyMap[rzdMapStruct.ClassifyName]; !ok {
+			rzdClassifyList = append(rzdClassifyList, models.AddRzdClassify{
+				ClassifyName: rzdMapStruct.ClassifyName,
+				Sort:         rzdMapStruct.Sort,
+				ParentId:     parentId,
+			})
+		} else {
+			classifyList[sheetName] = classify.BaseFromRzdClassifyId
 		}
-	} 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)
+	}
+	if len(rzdClassifyList) > 0 {
+		resp, httpErr := httpRequestFill(BatchAddClassifyType{
+			List: rzdClassifyList}, utils.BATCH_ADD_RZD_CLASSYFY)
+		if httpErr != nil {
+			err = fmt.Errorf("添加睿咨得分类失败: %v", err)
+			return
 		}
-	} 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)
+		var rzdResp models.RequestResponse[[]models.BaseFromRzdClassify]
+		jsonErr := json.Unmarshal(resp, &rzdResp)
+		if jsonErr != nil {
+			err = fmt.Errorf("解析添加睿咨得分类失败: %v", err)
+			return
 		}
-	} 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)
+		if rzdResp.Ret != 200 {
+			err = fmt.Errorf("添加睿咨得分类失败: %v", err)
+			return
 		}
-	} 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)
+		for _, classify := range rzdResp.Data {
+			classifyList[classify.ClassifyName] = classify.BaseFromRzdClassifyId
 		}
 	}
+	return
+}
 
-	// 可以添加更多的逻辑来处理其他产品和类别
-	return nil, fmt.Errorf("no processor found for tableName %s and sheetName %s", tableName, sheetName)
+// 处理分类
+func getRzdClassifyList() (list []*models.BaseFromRzdClassify, err error) {
+	//查询睿咨得分类
+	postEdbLib, httpErr := httpRequestFill(nil, utils.GET_RZD_CLASSIFY)
+	if httpErr != nil {
+		err = fmt.Errorf("获取睿咨得分类数据失败: %v", httpErr)
+		return
+	}
+	var requestResponse models.RequestResponse[[]*models.BaseFromRzdClassify]
+	jsonErr := json.Unmarshal(postEdbLib, &requestResponse)
+	if jsonErr != nil {
+		err = fmt.Errorf("获取睿咨得分类数据失败,解析JSON数据失败: %v", jsonErr)
+		return
+	}
+	if requestResponse.Ret != 200 {
+		err = fmt.Errorf("获取睿咨得分类数据失败,请求应答异常: %v", requestResponse.ErrMsg)
+		return
+	}
+	return requestResponse.Data, nil
 }

+ 383 - 0
services/ruizide/supply_revision_analysis_processor.go

@@ -0,0 +1,383 @@
+package ruizide
+
+import (
+	"encoding/json"
+	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/utils"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"github.com/xuri/excelize/v2"
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
+)
+
+const (
+	CubeDashboards         = "cube dashboards"
+	SupplyRevisionAnalysis = "Supply Revision Analysis"
+	BeginRow               = 1
+	Rows                   = 3
+)
+
+var (
+	SupplyRevisionAnalysisConfigMap = map[string]SRAPConfig{
+		"Chart 1": {
+			Frequency:          "季度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Year Quarter",
+			IndexNameColPrefix: "Country Revision Group",
+			chartType:          "one",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+			DateType:           "quarter",
+		},
+		"Chart 2": {
+			Frequency:          "季度",
+			Unit:               "千桶每天",
+			IndexNameColPrefix: "Year Quarter",
+			chartType:          "two",
+			NamePrevious:       "Previous",
+			NameCurrent:        "Current",
+			CodePrevious:       "Previous",
+			CodeCurrent:        "Current",
+			DataPreviousRow:    2,
+			DataCurrentRow:     1,
+			DateRow:            0,
+			DateType:           "quarter",
+		},
+		"Chart 3": {
+			Frequency:          "年度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Year",
+			IndexNameColPrefix: "Country Revision Group",
+			chartType:          "one",
+			IndexRow:           2,
+			DataRow:            1,
+			DateRow:            0,
+			DateType:           "year",
+		},
+		"Chart 4": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColPrefix: "Year",
+			chartType:          "two",
+			NamePrevious:       "Previous",
+			NameCurrent:        "Current",
+			CodePrevious:       "Previous",
+			CodeCurrent:        "Current",
+			DataPreviousRow:    2,
+			DataCurrentRow:     1,
+			DateRow:            0,
+			DateType:           "year",
+		},
+		"Chart 5": {
+			Frequency:          "月度",
+			Unit:               "千桶每天",
+			IndexNameColPrefix: "Year Month",
+			chartType:          "two",
+			NamePrevious:       "Previous/Chat5",
+			NameCurrent:        "Current/Chat5",
+			CodePrevious:       "previouschat5",
+			CodeCurrent:        "currentchat5",
+			DataPreviousRow:    0,
+			DataCurrentRow:     1,
+			DateRow:            2,
+			DateType:           "month",
+		},
+		"Chart 6": {
+			Frequency:          "日度",
+			Unit:               "千桶每天",
+			IndexNameColSuffix: "Year Month",
+			IndexNameColPrefix: "Country Revision Group",
+			chartType:          "one",
+			IndexRow:           1,
+			DataRow:            2,
+			DateRow:            0,
+			DateType:           "month",
+		},
+	}
+)
+
+type SRAPConfig struct {
+	Frequency          string
+	Unit               string
+	IndexNameColSuffix string
+	IndexNameColPrefix string
+	IndexRow           int
+	DataRow            int
+	DataPreviousRow    int
+	DataCurrentRow     int
+	DateRow            int
+	DateType           string
+	chartType          string
+	NamePrevious       string
+	NameCurrent        string
+	CodePrevious       string
+	CodeCurrent        string
+}
+
+type SupplyRevisionAnalysisProcessor struct {
+}
+
+func (p *SupplyRevisionAnalysisProcessor) Process(tableName string) (err error) {
+	var fileName string
+	// 解析表格
+	fileName = tableName + "_" + utils.GetCurrentYearMonth() + ".xlsx"
+	filePath := filepath.Join(excelDir, fileName)
+	if _, err = os.Stat(filePath); os.IsNotExist(err) {
+		utils.FileLog.Error("文件不存在: %v", err)
+		return
+	}
+	// 打开 Excel 文件
+	file, err := excelize.OpenFile(filePath)
+	if err != nil {
+		utils.FileLog.Error("无法打开 Excel 文件: %v", err)
+		return
+	}
+	sheetNames := file.GetSheetList()
+	classifyIds, err := dealClassify(CubeDashboards, []string{SupplyRevisionAnalysis})
+	// 获取所有工作表
+	if err != nil {
+		utils.FileLog.Error("获取分类Id失败: %v", err)
+		return
+	}
+	//按照sheet页来处理数据,一个sheet发送一次服务器
+	for _, sheetName := range sheetNames {
+		var indexMap = make(map[string]*models.IndexInfo)
+		utils.FileLog.Info("读取工作表: %s\n", sheetName)
+		// 获取工作表的最大行数
+		dataRows, excelErr := file.GetRows(sheetName) // 直接获取所有行数据
+		if excelErr != nil {
+			utils.FileLog.Error("获取工作表数据时出错: %v", excelErr)
+			continue
+		}
+		sheetConfig := SupplyRevisionAnalysisConfigMap[sheetName]
+		// 匹配非数字字符
+		classifyId := classifyIds[SupplyRevisionAnalysis]
+		switch sheetConfig.chartType {
+		case "one":
+			indexMap, err = OneDataHandler(dataRows, sheetConfig, classifyId)
+		case "two":
+			indexMap, err = TwoDataHandler(dataRows, sheetConfig, classifyId)
+		}
+		// 新增数据源指标数据
+		if len(indexMap) > 0 {
+			for _, index := range indexMap {
+				pars := chunkIndexData(index, rzdBatchSize)
+				for _, par := range pars {
+					// 转换成json
+					marshal, parseErr := json.Marshal(par)
+					if parseErr != nil {
+						utils.FileLog.Error("json.Marshal err: %v", parseErr)
+						return parseErr
+					}
+					// 发送 HTTP POST 请求
+					_, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_RZD_DATA, string(marshal), "application/json")
+					if err != nil {
+						utils.FileLog.Error("postEdbLib err: %v", err)
+						return err
+					}
+				}
+			}
+		}
+	}
+	return
+}
+func OneDataHandler(dataRows [][]string, sheetConfig SRAPConfig, classifyId int) (indexMap map[string]*models.IndexInfo, err error) {
+	indexMap = make(map[string]*models.IndexInfo)
+	//re := regexp.MustCompile(`^\d*\.?\d*\s*$`)
+	for _, rowData := range dataRows[BeginRow : len(dataRows)-1] {
+		//处理数据不全的情况
+		less := Rows - len(rowData)
+		if less > 0 {
+			for i := 0; i < less; i++ {
+				rowData = append(rowData, "")
+			}
+		}
+		// step_2: 指标
+		// 指标名称
+		indexName := SupplyRevisionAnalysis + "/" + sheetConfig.IndexNameColPrefix + "/" + sheetConfig.IndexNameColSuffix + "/" + rowData[sheetConfig.IndexRow]
+		// 生成指标编码
+		indexCode := getIndexId(fmt.Sprintf("%s %s %s", SupplyRevisionAnalysis, sheetConfig.IndexNameColPrefix, sheetConfig.IndexNameColSuffix), strings.ReplaceAll(strings.ToLower(rowData[sheetConfig.IndexRow]), " ", ""), "")
+		dataTime := rowData[sheetConfig.DateRow]
+		if dataTime == "0" {
+			continue
+		}
+		var date time.Time
+		var convertErr error
+		switch sheetConfig.DateType {
+		case "quarter":
+			date, _, convertErr = utils.ConvertDateFormatQuarter(dataTime)
+		case "year":
+			date, _, convertErr = utils.ConvertDateFormatYear(dataTime)
+		case "month":
+			timeSplit := strings.Split(dataTime, "-")
+			date, _, convertErr = utils.ConvertLastDayOfMonth(fmt.Sprintf("%s-%s", timeSplit[0], timeSplit[1]))
+		}
+		if convertErr != nil {
+			utils.FileLog.Error(fmt.Sprintf("转换时间数据失败,index_code:%s,time_value:%s err:%v", indexCode, dataTime, convertErr))
+			continue
+		}
+		if rowData[sheetConfig.DataRow] != "" {
+			value, parseErr := decimal.NewFromString(rowData[sheetConfig.DataRow])
+			if parseErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCode, rowData[sheetConfig.DataRow], err))
+				continue
+			} else {
+				if index, ok := indexMap[indexCode]; ok {
+					if index.StartDate.After(date) {
+						index.StartDate = date
+					}
+					if index.EndDate.Before(date) {
+						index.EndDate = date
+						index.LatestValue = value
+					}
+					index.DataList = append(index.DataList, models.IndexData{
+						DataTime: date,
+						Value:    value,
+					})
+				} else {
+					indexMap[indexCode] = &models.IndexInfo{
+						IndexName:   indexName,
+						IndexCode:   indexCode,
+						Frequency:   sheetConfig.Frequency,
+						Unit:        sheetConfig.Unit,
+						StartDate:   date,
+						EndDate:     date,
+						LatestValue: value,
+						ClassifyId:  classifyId,
+						DataList: []models.IndexData{
+							{
+								DataTime: date,
+								Value:    value,
+							},
+						},
+					}
+				}
+			}
+		}
+	}
+	return
+}
+func TwoDataHandler(dataRows [][]string, sheetConfig SRAPConfig, classifyId int) (indexMap map[string]*models.IndexInfo, err error) {
+	indexMap = make(map[string]*models.IndexInfo)
+	// 匹配非数字字符
+	//re := regexp.MustCompile(`^\d*\.?\d*\s*$`)
+	for _, rowData := range dataRows[BeginRow : len(dataRows)-1] {
+		//处理数据不全的情况
+		less := Rows - len(rowData)
+		if less > 0 {
+			for i := 0; i < less; i++ {
+				rowData = append(rowData, "")
+			}
+		}
+		// step_2: 指标
+		// 指标名称
+		indexNameCurrent := SupplyRevisionAnalysis + "/" + sheetConfig.IndexNameColPrefix + "/" + sheetConfig.NameCurrent
+		indexNamePrevious := SupplyRevisionAnalysis + "/" + sheetConfig.IndexNameColPrefix + "/" + sheetConfig.NamePrevious
+
+		// 生成指标编码
+		indexCodeCurrent := getIndexId(fmt.Sprintf("%s %s", SupplyRevisionAnalysis, sheetConfig.IndexNameColPrefix), sheetConfig.CodeCurrent, "")
+		indexCodePrevious := getIndexId(fmt.Sprintf("%s %s", SupplyRevisionAnalysis, sheetConfig.IndexNameColPrefix), sheetConfig.CodePrevious, "")
+
+		dataTime := rowData[sheetConfig.DateRow]
+		if dataTime == "0" {
+			continue
+		}
+		var date time.Time
+		var convertErr error
+		switch sheetConfig.DateType {
+		case "quarter":
+			date, _, convertErr = utils.ConvertDateFormatQuarter(dataTime)
+		case "year":
+			date, _, convertErr = utils.ConvertDateFormatYear(dataTime)
+		case "month":
+			timeSplit := strings.Split(dataTime, "-")
+			date, _, convertErr = utils.ConvertLastDayOfMonth(fmt.Sprintf("%s-%s", timeSplit[0], timeSplit[1]))
+		}
+		if convertErr != nil {
+			utils.FileLog.Error(fmt.Sprintf("转换时间数据失败,index_code:%s,time_value:%s err:%v", indexNameCurrent, dataTime, convertErr))
+			continue
+		}
+
+		if rowData[sheetConfig.DataCurrentRow] != "" {
+			valueCurrent, parseErr := decimal.NewFromString(rowData[sheetConfig.DataCurrentRow])
+			if parseErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCodeCurrent, rowData[sheetConfig.DataCurrentRow], err))
+				continue
+			} else {
+				if index, ok := indexMap[indexCodeCurrent]; ok {
+					if index.StartDate.After(date) {
+						index.StartDate = date
+					}
+					if index.EndDate.Before(date) {
+						index.EndDate = date
+						index.LatestValue = valueCurrent
+					}
+					index.DataList = append(index.DataList, models.IndexData{
+						DataTime: date,
+						Value:    valueCurrent,
+					})
+				} else {
+					indexMap[indexCodeCurrent] = &models.IndexInfo{
+						IndexName:   indexNameCurrent,
+						IndexCode:   indexCodeCurrent,
+						Frequency:   sheetConfig.Frequency,
+						Unit:        sheetConfig.Unit,
+						StartDate:   date,
+						EndDate:     date,
+						LatestValue: valueCurrent,
+						ClassifyId:  classifyId,
+						DataList: []models.IndexData{
+							{
+								DataTime: date,
+								Value:    valueCurrent,
+							},
+						},
+					}
+				}
+			}
+		}
+		if rowData[sheetConfig.DataPreviousRow] != "" {
+			valuePrevious, parseErr := decimal.NewFromString(rowData[sheetConfig.DataPreviousRow])
+			if parseErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCodePrevious, rowData[sheetConfig.DataPreviousRow], err))
+				continue
+			} else {
+				if index, ok := indexMap[indexCodePrevious]; ok {
+					if index.StartDate.After(date) {
+						index.StartDate = date
+					}
+					if index.EndDate.Before(date) {
+						index.EndDate = date
+						index.LatestValue = valuePrevious
+					}
+					index.DataList = append(index.DataList, models.IndexData{
+						DataTime: date,
+						Value:    valuePrevious,
+					})
+				} else {
+					indexMap[indexCodePrevious] = &models.IndexInfo{
+						IndexName:   indexNamePrevious,
+						IndexCode:   indexCodePrevious,
+						Frequency:   sheetConfig.Frequency,
+						Unit:        sheetConfig.Unit,
+						StartDate:   date,
+						EndDate:     date,
+						LatestValue: valuePrevious,
+						ClassifyId:  classifyId,
+						DataList: []models.IndexData{
+							{
+								DataTime: date,
+								Value:    valuePrevious,
+							},
+						},
+					}
+				}
+			}
+		}
+	}
+	return
+}

+ 6 - 2
services/task.go

@@ -67,8 +67,12 @@ func Task() {
 	}
 
 	if utils.RZD_OPEN == "1" {
-		rzdData := task.NewTask("refreshRzdData", "0 0 1 * * 4", ruizide.ResolverNet) // 睿姿得数据
-
+		// 各品种周报-默认每周五17-19点每隔半小时
+		rzdTaskTime := utils.RZD_TASK_TIME
+		if rzdTaskTime == "" {
+			rzdTaskTime = "0 0 1 * * 4"
+		}
+		rzdData := task.NewTask("refreshRzdData", rzdTaskTime, ruizide.ResolverNet) // 睿姿得数据
 		task.AddTask("睿咨得数据", rzdData)
 	}
 

+ 4 - 0
utils/config.go

@@ -83,11 +83,13 @@ var (
 
 // 睿姿得数据
 var (
+	RZD_TASK_TIME     string
 	RZD_USERNAME      string
 	RZD_PASSWORD      string
 	RZD_EXCEL_PATH    string
 	RZD_OPEN          string
 	RZD_DOWNLOAD_PATH string
+	RZD_LOGIN_PATH    string
 )
 
 // CCF化纤信息
@@ -248,11 +250,13 @@ func init() {
 	}
 
 	{
+		RZD_TASK_TIME = config["rzd_task_time"]
 		RZD_USERNAME = config["rzd_username"]
 		RZD_PASSWORD = config["rzd_password"]
 		RZD_EXCEL_PATH = config["rzd_excel_path"]
 		RZD_OPEN = config["rzd_open"]
 		RZD_DOWNLOAD_PATH = config["rzd_download_path"]
+		RZD_LOGIN_PATH = config["rzd_login_path"]
 	}
 
 	// 隆众数据

+ 3 - 7
utils/constants.go

@@ -267,13 +267,9 @@ const (
 	GET_LY_INDEX_BY_CODE                              = "/ly/get/ly/index/by/code"                              // 根据指标编码获取指标
 	GET_EDB_INFO_BY_INDEX_CODE                        = "/ly/get/edb/info/by/index/code"                        // 根据指标code获取指标信息
 	ADD_BATCH_LY_EDB_DATA                             = "/ly/add/batch/ly/edb/data"                             // 批量增加粮油指标库数据
-	ADD_RZD_INDEX                                     = "/rzd/add/rzd/index"                                    // 新增睿咨得指标
-	ADD_BATCH_RZD_DATA                                = "/rzd/add/batch/rzd/data"                               // 新增数据源指标数据列表
-	GET_RZD_INDEX_DATA_BY_CODE_AND_TIME               = "/rzd/get/rzd/index/data/by/code/and/time"              // 根据指标编码和日期获取指标数据
-	GET_EDB_RZD_DATA_BY_CODE_AND_TIME                 = "/rzd/get/edb/rzd/data/by/code/and/time"                // 根据指标编码和日期获取指标数据
-	GET_RZD_INDEX_BY_CODE                             = "/rzd/get/rzd/index/by/code"                            // 根据指标编码获取指标
-	GET_RZD_CLASSIFY_BY_NAME                          = "/rzd/get/rzd/classify/by/name"                         // 根据分类名称查询分类
-	ADD_RZD_CLASSIFY                                  = "/rzd/add/rzd/classify"                                 // 新增睿咨得分类
+	ADD_BATCH_RZD_DATA                                = "rzd/add/batch/rzd/data"                                // 新增数据源指标数据列表
+	GET_RZD_CLASSIFY                                  = "rzd/get/rzd/classify"                                  // 睿咨得查询分类
+	BATCH_ADD_RZD_CLASSYFY                            = "rzd/add/rzd/batch_add_classify"                        //批量增加睿咨得分类
 	ADD_BATCH_RZD_EDB_DATA                            = "/rzd/add/batch/rzd/edb/data"                           // 批量增加指标库指标数据
 	GET_RZD_EDB_INFO_BY_INDEX_CODE                    = "/rzd/get/rzd/edb/info/by/code"                         // 根据指标code获取指标信息
 	UPDATE_RZD_EDB_DATA                               = "/rzd/update/rzd/edb/data"                              // 修改指标库指标数据

+ 60 - 47
utils/date_util.go

@@ -362,7 +362,22 @@ func IsSameMonth(dateText1, dateText2 string) (bool, error) {
 }
 
 // GetLastDayOfMonth 获取传入年月的最后一天 dateText 格式为 2024-08 --> 2024-08-31
-func GetLastDayOfMonth(dateText string) (string, error) {
+func ConvertLastDayOfMonth(dateText string) (date time.Time, dateStr string, err error) {
+	// 解析日期
+	date, err = time.Parse("2006-01", strings.TrimSpace(dateText))
+	if err != nil {
+		err = fmt.Errorf("failed to parse date: %v", err)
+		return
+	}
+	// 获取下个月的第一天
+	nextMonth := date.AddDate(0, 1, 0)
+
+	// 获取本月的最后一天
+	date = nextMonth.AddDate(0, 0, -1)
+	dateStr = date.Format("2006-01-02")
+	return
+}
+func GetLastDayOfMonth(dateText string) (dateStr string, err error) {
 	// 解析日期
 	date, err := time.Parse("2006-01", strings.TrimSpace(dateText))
 	if err != nil {
@@ -510,23 +525,22 @@ func GetCurrentYearMonth() string {
 }
 
 // ConvertDateFormat 转换时间格式 MM-dd-yy --> yyyy-MM-dd
-func ConvertDateFormat(dataText string) (string, error) {
+func ConvertDateFormat(dataText string) (date time.Time, dateStr string, err error) {
 	// 定义输入和输出的时间格式
 	inputFormat := "01-02-06"    // MM-dd-yy
 	outputFormat := "2006-01-02" // yyyy-MM-dd
-
 	// 解析输入的日期
-	date, err := time.Parse(inputFormat, dataText)
+	date, err = time.ParseInLocation(inputFormat, dataText, time.Local)
 	if err != nil {
-		return "", err
+		return
 	}
-
 	// 格式化为输出格式
-	return date.Format(outputFormat), nil
+	dateStr = date.Format(outputFormat)
+	return
 }
 
 // ConvertDateFormat2 转换时间格式 yyyy-MMQ --> 取每一季度最后一天,例如 2024-01Q --> 2024-03-31
-func ConvertDateFormat2(dataText string) (string, error) {
+func ConvertDateFormatQuarter(dataText string) (date time.Time, dateStr string, err error) {
 
 	// 提取年份和季度信息
 	yearStr := dataText[:4]
@@ -535,76 +549,75 @@ func ConvertDateFormat2(dataText string) (string, error) {
 	// 转换年份
 	year, err := strconv.Atoi(yearStr)
 	if err != nil {
-		return "", fmt.Errorf("无效的年份: %v", err)
+		err = fmt.Errorf("无效的年份: %v", err)
+		return
 	}
-
 	// 根据季度选择最后一天
-	var endOfQuarter string
 	switch quarterStr {
 	case "1":
-		endOfQuarter = fmt.Sprintf("%d-03-31", year)
+		dateStr = fmt.Sprintf("%d-03-31", year)
 	case "2":
-		endOfQuarter = fmt.Sprintf("%d-06-30", year)
+		dateStr = fmt.Sprintf("%d-06-30", year)
 	case "3":
-		endOfQuarter = fmt.Sprintf("%d-09-30", year)
+		dateStr = fmt.Sprintf("%d-09-30", year)
 	case "4":
-		endOfQuarter = fmt.Sprintf("%d-12-31", year)
+		dateStr = fmt.Sprintf("%d-12-31", year)
 	default:
-		return "", fmt.Errorf("无效的季度: %s", quarterStr)
+		err = fmt.Errorf("无效的季度: %s", quarterStr)
+		return
 	}
-
 	// 确保日期格式正确
-	_, err = time.Parse("2006-01-02", endOfQuarter)
+	date, err = time.Parse("2006-01-02", dateStr)
 	if err != nil {
-		return "", fmt.Errorf("日期解析失败: %v", err)
+		err = fmt.Errorf("日期解析失败: %v", err)
+		return
 	}
-
-	return endOfQuarter, nil
+	return
 }
 
 // ConvertDateFormat3 转换时间格式 Jan-23 --> 2023-01-31
-func ConvertDateFormat3(dataText string) (string, error) {
+func ConvertDateFormatForOSA(dataText string) (date time.Time, dateStr string, err error) {
 	// 拆分月份和年份
 	parts := strings.Split(dataText, "-")
 	if len(parts) != 2 {
-		return "", fmt.Errorf("日期格式不正确")
+		err = fmt.Errorf("日期格式不正确")
+		return
 	}
-
 	// 提取月份和年份
 	monthStr := parts[0]
 	yearStr := parts[1]
-
 	// 转换年份
 	year, err := strconv.Atoi(yearStr)
 	if err != nil {
-		return "", fmt.Errorf("无效的年份: %v", err)
+		err = fmt.Errorf("无效的年份: %v", err)
+		return
 	}
-
 	// 获取月份数字
 	month, err := time.Parse("Jan", monthStr)
 	if err != nil {
-		return "", fmt.Errorf("无效的月份: %v", err)
+		err = fmt.Errorf("无效的月份: %v", err)
+		return
 	}
-
 	// 计算最后一天
-	lastDay := time.Date(year+2000, month.Month()+1, 0, 0, 0, 0, 0, time.UTC) // 直接设置为下个月的第一天,再设为0日得到上个月最后一天
-
-	return lastDay.Format("2006-01-02"), nil
+	date = time.Date(year+2000, month.Month()+1, 0, 0, 0, 0, 0, time.UTC) // 直接设置为下个月的第一天,再设为0日得到上个月最后一天
+	dateStr = date.Format("2006-01-02")
+	return
 }
 
 // ConvertDateFormat4 转换时间格式 2022 --> 2022-12-31
-func ConvertDateFormat4(dataText string) (string, error) {
+func ConvertDateFormatYear(dataText string) (date time.Time, dateStr string, err error) {
 	// 解析输入年份
 	year, err := strconv.Atoi(dataText)
 	if err != nil {
-		return "", fmt.Errorf("无法解析年份: %v", err)
+		err = fmt.Errorf("无法解析年份: %v", err)
+		return
 	}
 
 	// 创建该年最后一天的日期
-	lastDay := time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC)
-
+	date = time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC)
 	// 返回格式化后的日期字符串
-	return lastDay.Format("2006-01-02"), nil
+	dateStr = date.Format("2006-01-02")
+	return
 }
 
 // ConvertDateFormat5 转换时间格式 yyyy-MM-dd HH:mm:ss --> yyyy-MM-dd
@@ -620,31 +633,31 @@ func ConvertDateFormat5(dataText string) (string, error) {
 }
 
 // ConvertDateFormat6 转换时间格式 2023-March --> 2023-03-31
-func ConvertDateFormat6(dataText string) (string, error) {
+func ConvertDateFormatForMC(dataText string) (date time.Time, dateStr string, err error) {
 	// 拆分年份和月份
 	parts := strings.Split(dataText, "-")
 	if len(parts) != 2 {
-		return "", fmt.Errorf("日期格式不正确")
+		err = fmt.Errorf("日期格式不正确")
+		return
 	}
-
 	// 提取年份和月份
 	yearStr := parts[0]
 	monthStr := parts[1]
-
 	// 转换年份
 	year, err := strconv.Atoi(yearStr)
 	if err != nil {
-		return "", fmt.Errorf("无效的年份: %v", err)
+		err = fmt.Errorf("无效的年份: %v", err)
+		return
 	}
 
 	// 获取月份数字
 	month, err := time.Parse("January", monthStr)
 	if err != nil {
-		return "", fmt.Errorf("无效的月份: %v", err)
+		err = fmt.Errorf("无效的月份: %v", err)
+		return
 	}
-
 	// 获取最后一天
-	lastDay := time.Date(year, month.Month()+1, 0, 0, 0, 0, 0, time.UTC) // 使用月份数字加1,再设为0日得到上个月最后一天
-
-	return lastDay.Format("2006-01-02"), nil
+	date = time.Date(year, month.Month()+1, 0, 0, 0, 0, 0, time.UTC) // 使用月份数字加1,再设为0日得到上个月最后一天
+	dateStr = date.Format("2006-01-02")
+	return
 }

+ 2 - 4
utils/http_request.go

@@ -3,7 +3,6 @@ package utils
 import (
 	"encoding/json"
 
-	"fmt"
 	"io/ioutil"
 	"net/http"
 	"strings"
@@ -24,7 +23,6 @@ func PostEdbLibRequest(param map[string]interface{}, method string) (result []by
 }
 
 func HttpPostRequest(url, postData string, params ...string) ([]byte, error) {
-	fmt.Println("HttpPost Url:" + url)
 	body := ioutil.NopCloser(strings.NewReader(postData))
 	client := &http.Client{}
 	req, err := http.NewRequest("POST", url, body)
@@ -39,13 +37,13 @@ func HttpPostRequest(url, postData string, params ...string) ([]byte, error) {
 	req.Header.Set("authorization", MD5(APP_EDB_LIB_NAME_EN+EDB_LIB_Md5_KEY))
 	resp, err := client.Do(req)
 	if err != nil {
-		fmt.Println("client.Do err:" + err.Error())
+		FileLog.Error("client.Do err:" + err.Error())
 		return nil, err
 	}
 	defer resp.Body.Close()
 	b, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
-		fmt.Println("HttpPost:" + string(b))
+		FileLog.Error("HttpPost:" + string(b))
 	}
 	return b, err
 }