Bladeren bron

Merge branch 'eta_2.2.5_rzd_1012@guomengyuan'

# Conflicts:
#	utils/common.go
gmy 3 maanden geleden
bovenliggende
commit
c9cce699da

+ 12 - 0
models/base_from_rzd_classify.go

@@ -0,0 +1,12 @@
+// Package models @Author gmy 2024/10/21 9:26:00
+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)"`
+}

+ 12 - 0
models/base_from_rzd_data.go

@@ -0,0 +1,12 @@
+// @Author gmy 2024/8/7 9:50:00
+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)"`
+}

+ 22 - 0
models/base_from_rzd_index.go

@@ -0,0 +1,22 @@
+// Package models
+// @Author gmy 2024/8/7 9:38:00
+package models
+
+type BaseFromRzdIndex struct {
+	BaseFromRzdIndexId   int    `orm:"column(base_from_rzd_index_id);pk"`
+	CreateTime           string `orm:"column(create_time)"`
+	ModifyTime           string `orm:"column(modify_time)"`
+	BaseFromLyClassifyId int    `orm:"column(base_from_ly_classify_id)"`
+	IndexCode            string `orm:"column(index_code)"`
+	IndexName            string `orm:"column(index_name)"`
+	Frequency            string `orm:"column(frequency)"`
+	Unit                 string `orm:"column(unit)"`
+}
+
+type IndexInfo struct {
+	IndexName   string
+	IndexCode   string
+	Value       float64
+	IndexInfoId int
+	DataTime    string
+}

+ 14 - 0
models/edb_data_rzd.go

@@ -0,0 +1,14 @@
+// Package models
+// @Author gmy 2024/9/14 16:13:00
+package models
+
+type EdbDataRzd struct {
+	edbDataId     int     `orm:"column(edb_data_id);pk"`
+	CreateTime    string  `orm:"column(create_time)"`
+	ModifyTime    string  `orm:"column(modify_time)"`
+	EdbInfoId     int     `orm:"column(edb_info_id)"`
+	EdbCode       string  `orm:"column(edb_code)"`
+	DataTime      string  `orm:"column(data_time)"`
+	Value         float64 `orm:"column(value)"`
+	DataTimestamp uint64  `orm:"column(data_timestamp)"`
+}

+ 437 - 0
services/ruizide/data_processor.go

@@ -0,0 +1,437 @@
+package ruizide
+
+import (
+	"context"
+	"encoding/json"
+	"eta/eta_data_analysis/models"
+	"eta/eta_data_analysis/utils"
+	"fmt"
+	"github.com/chromedp/cdproto/cdp"
+	"github.com/xuri/excelize/v2"
+	"io"
+	"log"
+	"os"
+	"path/filepath"
+	"time"
+
+	"github.com/chromedp/chromedp"
+)
+
+// 定义选择器
+var (
+	downloadDir  = utils.RZD_EXCEL_PATH
+	defaultDir   = utils.RZD_DOWNLOAD_PATH
+	rzdLoginPath = "https://clients.rystadenergy.com/clients/"
+	rzdBatchSize = 500
+
+	clientSearchLink       = `div.d-none.d-lg-flex.flex-grow-1 a[href="/clients/search/"]`
+	downloadButtonSelector = `div.btn.btn-link.btn-sm.dashboard-action.dashboard-action--download-data`
+)
+
+// 处理数据下载的步骤
+func downloadData(ctx context.Context) error {
+	// Analytics Library
+	if err := chromedp.Run(ctx,
+		chromedp.Sleep(5*time.Second), // 考虑移除这一行,如果不必要的话
+		chromedp.Navigate(rzdLoginPath),
+		chromedp.WaitVisible(`div.d-none.d-lg-flex.flex-grow-1`, chromedp.ByQuery),
+		chromedp.Click(clientSearchLink, chromedp.ByQuery),
+		chromedp.WaitVisible(`input[class="ais-SearchBox-input rounded border py-2 px-3 shadow-sm font-size-14 w-100"]`, chromedp.ByQuery),
+		chromedp.SetValue(`input[class="ais-SearchBox-input rounded border py-2 px-3 shadow-sm font-size-14 w-100"]`, "oil demand signals weekly report", chromedp.ByQuery),
+		chromedp.Sleep(10*time.Second),
+		//chromedp.Click(`div.ais-InfiniteHits li a:has(img[src="/Static/img/icons/xls.png"])`, chromedp.ByQuery),
+	); err != nil {
+		return fmt.Errorf("下载 Analytics Library 数据错误: %v", err)
+	}
+
+	xpath := `//div[@id='search-page-hits']//li//a[.//div//span[@class='align-middle' and text()='Data']]`
+	var inputCount int
+	var nodes []*cdp.Node // 使用 *cdp.Node
+	if err := chromedp.Run(ctx,
+		chromedp.ActionFunc(func(ctx context.Context) error {
+
+			// 获取匹配的节点
+			if err := chromedp.Nodes(xpath, &nodes, chromedp.BySearch).Do(ctx); err != nil {
+				return fmt.Errorf("检查节点失败: %v", err)
+			}
+
+			// 获取节点数量
+			inputCount = len(nodes)
+			fmt.Printf("找到 %d 个匹配的元素\n", inputCount)
+
+			if inputCount > 0 {
+				// 点击第一个节点
+				return chromedp.MouseClickNode(nodes[0]).Do(ctx) // 使用 []cdp.NodeID
+			}
+			return nil
+		}),
+		chromedp.Sleep(10*time.Second),
+	); err != nil {
+		return fmt.Errorf("下载 Analytics Library 数据错误: %v", err)
+	}
+	// 解析文件移动到目标目录
+	if err := waitAndRenameDownloadedFile("Oil_Demand_Signals_Weekly_Report_"+utils.GetCurrentYearMonth()+".xlsx", downloadDir); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// 等待下载文件并重命名
+func waitAndRenameDownloadedFile(newFileName, targetDir string) error {
+	// 等待一段时间以确保文件下载完成
+	time.Sleep(100 * time.Second) // 可能需要根据实际情况调整
+
+	// 查找下载目录中的文件
+	files, err := filepath.Glob(filepath.Join(defaultDir, "*.xlsx"))
+	if err != nil {
+		return fmt.Errorf("查找文件时出错: %v", err)
+	}
+
+	// 如果没有找到文件,返回错误
+	if len(files) == 0 {
+		return fmt.Errorf("未找到任何下载的文件")
+	}
+
+	// 找到最新的文件
+	var latestFile string
+	var latestTime time.Time
+
+	for _, file := range files {
+		info, err := os.Stat(file)
+		if err != nil {
+			return fmt.Errorf("获取文件信息时出错: %v", err)
+		}
+		if info.ModTime().After(latestTime) {
+			latestTime = info.ModTime()
+			latestFile = file
+		}
+	}
+
+	// 目标文件的完整路径
+	targetFilePath := filepath.Join(targetDir, newFileName)
+
+	// 重命名并移动到目标目录
+	if latestFile != "" {
+		if err := moveFile(latestFile, targetFilePath); err != nil {
+			return fmt.Errorf("重命名文件时出错: %v", err)
+		}
+		// 打印重命名后的文件名
+		fmt.Printf("文件重命名并移动到: %s\n", targetFilePath)
+	}
+
+	return nil
+}
+
+func moveFile(source, destination string) error {
+	// 复制文件
+	srcFile, err := os.Open(source)
+	if err != nil {
+		return fmt.Errorf("打开源文件时出错: %v", err)
+	}
+	defer srcFile.Close()
+
+	dstFile, err := os.Create(destination)
+	if err != nil {
+		return fmt.Errorf("创建目标文件时出错: %v", err)
+	}
+	defer dstFile.Close()
+
+	if _, err := io.Copy(dstFile, srcFile); err != nil {
+		return fmt.Errorf("复制文件时出错: %v", err)
+	}
+	time.Sleep(60 * time.Second)
+
+	// 删除源文件
+	/*if err := os.Remove(source); err != nil {
+		return fmt.Errorf("删除源文件时出错: %v", err)
+	}*/
+
+	return nil
+}
+
+// 解析网页数据,下载文件
+// 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
+	}
+
+	// 创建 chromedp 执行上下文
+	options := []chromedp.ExecAllocatorOption{
+		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")),
+	}
+
+	allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), options...)
+	defer cancel()
+	ctx, cancel := chromedp.NewContext(allocCtx)
+	defer cancel()
+
+	// 启动 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)
+		return
+	}*/
+
+	// 登录操作
+	if err := login(ctx); err != nil {
+		fmt.Printf("登录错误: %v\n", err)
+		return nil
+	}
+
+	// 下载数据
+	if err := downloadData(ctx); err != nil {
+		fmt.Printf("数据下载错误: %v\n", err)
+		return nil
+	}
+
+	fmt.Println("数据下载完成")
+
+	// 解析表格 读取数据
+	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
+				}
+				baseFromLyDataList, err := processor.Process(tableName, sheetName, rowIndex, rowData)
+				if err != nil {
+					log.Printf("processor.Process err: %v", err)
+					return
+				}
+				indexData = append(indexData, baseFromLyDataList...)
+			}
+
+			// 新增数据源指标数据
+			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(time.Now().UnixNano() / int64(time.Millisecond)),
+					}
+					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
+				}
+			}
+
+		}
+	}
+}
+
+func login(ctx context.Context) error {
+
+	return chromedp.Run(ctx,
+		chromedp.Navigate(rzdLoginPath),
+		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.WaitVisible(`a[href="/clients/"]`, chromedp.ByQuery), // 等待 Analytics Library 链接可见
+		chromedp.Sleep(5*time.Second),                                 // 等待页面加载完成
+	)
+}
+
+func httpRequestFill(data interface{}, urlMethod string) (postEdbLib []byte, err error) {
+	// 转换成json
+	marshal, err := json.Marshal(data)
+	if err != nil {
+		return nil, err
+	}
+	// json 转 interface
+	var result map[string]interface{}
+	err = json.Unmarshal(marshal, &result)
+	if err != nil {
+		return nil, err
+	}
+
+	postEdbLib, err = utils.PostEdbLibRequest(result, urlMethod)
+	if err != nil {
+		// 有错误就不继续执行
+		log.Printf("postEdbLib err: %v", err)
+		return nil, err
+	}
+	return postEdbLib, nil
+}

+ 3482 - 0
services/ruizide/processor_business_logic.go

@@ -0,0 +1,3482 @@
+// 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 {
+			// 编辑
+			if requestResponse.Data.Value != math.Round(indexInfo.Value*10000)/10000 {
+				rzdData := requestResponse.Data
+				rzdData.Value = math.Round(indexInfo.Value*10000) / 10000
+
+				_, 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
+}

+ 243 - 0
services/ruizide/processor_factory.go

@@ -0,0 +1,243 @@
+package ruizide
+
+import (
+	"eta/eta_data_analysis/models"
+	"fmt"
+)
+
+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)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Production" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyTargetProductionProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Target_Cut" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyTargetCutProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Actual_Cut" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyActualCutProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Compliance" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyComplianceProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Upstream_Supply_OPEC_Policy_Production_Subject_To_Cut" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &UpstreamSupplyOPECPolicyProductionSubjectToCutProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Products_Demand_Products_Demand_Mean" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &ProductsDemandProductsDemandMeanProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Products_Demand_Products_Demand+Sigma" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &ProductsDemandProductsDemandAddSigmaProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Products_Demand_Products_Demand-Sigma" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &ProductsDemandProductsDemandSubSigmaProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Balances_Total_Liquids_Balances" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &BalancesTotalLiquidsBalancesProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Geography_Latitude" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &GeographyLatitudeProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	} else if tableName == "Oil_Market_Cube_Geography_Longitude" {
+		switch sheetName {
+		case "ExportCubeBrowser 1":
+			return &GeographyLongitudeProcessor{}, nil
+		default:
+			return nil, fmt.Errorf("unknown sheetName: %s", sheetName)
+		}
+	}
+
+	// 可以添加更多的逻辑来处理其他产品和类别
+	return nil, fmt.Errorf("no processor found for tableName %s and sheetName %s", tableName, sheetName)
+}

+ 7 - 0
services/task.go

@@ -5,6 +5,7 @@ import (
 	oilchemService "eta/eta_data_analysis/services/base_from_oilchem"
 	oilchemService "eta/eta_data_analysis/services/base_from_oilchem"
 	"eta/eta_data_analysis/services/fenwei"
 	"eta/eta_data_analysis/services/fenwei"
 	"eta/eta_data_analysis/services/liangyou"
 	"eta/eta_data_analysis/services/liangyou"
+	"eta/eta_data_analysis/services/ruizide"
 	"eta/eta_data_analysis/utils"
 	"eta/eta_data_analysis/utils"
 	"fmt"
 	"fmt"
 	"io/fs"
 	"io/fs"
@@ -61,6 +62,12 @@ func Task() {
 		task.AddTask("粮油商务网", lyData)
 		task.AddTask("粮油商务网", lyData)
 	}
 	}
 
 
+	if utils.RZD_OPEN == "1" {
+		rzdData := task.NewTask("refreshRzdData", "0 0 12 * * *", ruizide.ResolverNet) // 睿姿得数据
+
+		task.AddTask("睿咨得数据", rzdData)
+	}
+
 	if utils.MtjhOpen == "1" {
 	if utils.MtjhOpen == "1" {
 		c := cron.New(cron.WithSeconds())
 		c := cron.New(cron.WithSeconds())
 		//每2分钟检测一次指标文件是否更新
 		//每2分钟检测一次指标文件是否更新

+ 339 - 0
static/ruizide.json

@@ -0,0 +1,339 @@
+{
+  "Analytics Library": {
+    "Road Index": [
+      "Road Index/Brazil/Index:日度:%",
+      "Road Index/Canada/Index:日度:%",
+      "Road Index/China/Index:日度:%",
+      "Road Index/Europe/Index:日度:%",
+      "Road Index/India/Index:日度:%",
+      "Road Index/Indonesia/Index:日度:%",
+      "Road Index/United States/Index:日度:%",
+      "Road Index/Brazil/Index 7DMA:日度:%",
+      "Road Index/Canada/Index 7DMA:日度:%",
+      "Road Index/China/Index 7DMA:日度:%",
+      "Road Index/Europe/Index 7DMA:日度:%",
+      "Road Index/India/Index 7DMA:日度:%",
+      "Road Index/Indonesia/Index 7DMA:日度:%",
+      "Road Index/United States/Index 7DMA:日度:%"
+    ],
+    "Road Active Fleet": [
+      "Road Active Fleet/Brazil/Active Fleet:日度:辆",
+      "Road Active Fleet/Canada/Active Fleet:日度:辆",
+      "Road Active Fleet/China/Active Fleet:日度:辆",
+      "Road Active Fleet/Europe/Active Fleet:日度:辆",
+      "Road Active Fleet/India/Active Fleet:日度:辆",
+      "Road Active Fleet/Indonesia/Active Fleet:日度:辆",
+      "Road Active Fleet/United States/Active Fleet:日度:辆",
+      "Road Active Fleet/Brazil/Active Fleet 7DMA:日度:辆",
+      "Road Active Fleet/Canada/Active Fleet 7DMA:日度:辆",
+      "Road Active Fleet/China/Active Fleet 7DMA:日度:辆",
+      "Road Active Fleet/Europe/Active Fleet 7DMA:日度:辆",
+      "Road Active Fleet/India/Active Fleet 7DMA:日度:辆",
+      "Road Active Fleet/Indonesia/Active Fleet 7DMA:日度:辆",
+      "Road Active Fleet/United States/Active Fleet 7DMA:日度:辆"
+    ],
+    "Aviation Index": [
+      "Aviation Index/Brazil/Index:日度:%",
+      "Aviation Index/Canada/Index:日度:%",
+      "Aviation Index/China/Index:日度:%",
+      "Aviation Index/Europe/Index:日度:%",
+      "Aviation Index/India/Index:日度:%",
+      "Aviation Index/Indonesia/Index:日度:%",
+      "Aviation Index/United States/Index:日度:%",
+      "Aviation Index/Brazil/Index 7DMA:日度:%",
+      "Aviation Index/Canada/Index 7DMA:日度:%",
+      "Aviation Index/China/Index 7DMA:日度:%",
+      "Aviation Index/Europe/Index 7DMA:日度:%",
+      "Aviation Index/India/Index 7DMA:日度:%",
+      "Aviation Index/Indonesia/Index 7DMA:日度:%",
+      "Aviation Index/United States/Index 7DMA:日度:%"
+    ],
+    "Aviation Active Fleet": [
+      "Aviation Active Fleet/Brazil/Active Fleet:日度:辆",
+      "Aviation Active Fleet/Canada/Active Fleet:日度:辆",
+      "Aviation Active Fleet/China/Active Fleet:日度:辆",
+      "Aviation Active Fleet/Europe/Active Fleet:日度:辆",
+      "Aviation Active Fleet/India/Active Fleet:日度:辆",
+      "Aviation Active Fleet/Indonesia/Active Fleet:日度:辆",
+      "Aviation Active Fleet/United States/Active Fleet:日度:辆",
+      "Aviation Active Fleet/Brazil/Active Fleet 7DMA:日度:辆",
+      "Aviation Active Fleet/Canada/Active Fleet 7DMA:日度:辆",
+      "Aviation Active Fleet/China/Active Fleet 7DMA:日度:辆",
+      "Aviation Active Fleet/Europe/Active Fleet 7DMA:日度:辆",
+      "Aviation Active Fleet/India/Active Fleet 7DMA:日度:辆",
+      "Aviation Active Fleet/Indonesia/Active Fleet 7DMA:日度:辆",
+      "Aviation Active Fleet/United States/Active Fleet 7DMA:日度:辆"
+    ],
+    "Gasoline Demand": [
+      "Gasoline Demand/Europe/Demand:日度:千桶每天",
+      "Gasoline Demand/Germany/Demand:日度:千桶每天",
+      "Gasoline Demand/Indonesia/Demand:日度:千桶每天",
+      "Gasoline Demand/United Kingdom/Demand:日度:千桶每天",
+      "Gasoline Demand/United States/Demand:日度:千桶每天",
+      "Gasoline Demand/Europe/Demand 7DMA:日度:千桶每天",
+      "Gasoline Demand/Germany/Demand 7DMA:日度:千桶每天",
+      "Gasoline Demand/Indonesia/Demand 7DMA:日度:千桶每天",
+      "Gasoline Demand/United Kingdom/Demand 7DMA:日度:千桶每天",
+      "Gasoline Demand/United States/Demand 7DMA:日度:千桶每天"
+    ],
+    "Diesel Demand": [
+      "Diesel Demand/Brazil/Demand:日度:千桶每天",
+      "Diesel Demand/Europe/Demand:日度:千桶每天",
+      "Diesel Demand/France/Demand:日度:千桶每天",
+      "Diesel Demand/Germany/Demand:日度:千桶每天",
+      "Diesel Demand/United States/Demand:日度:千桶每天",
+      "Diesel Demand/Brazil/Demand 7DMA:日度:千桶每天",
+      "Diesel Demand/Europe/Demand 7DMA:日度:千桶每天",
+      "Diesel Demand/France/Demand 7DMA:日度:千桶每天",
+      "Diesel Demand/Germany/Demand 7DMA:日度:千桶每天",
+      "Diesel Demand/United States/Demand 7DMA:日度:千桶每天"
+    ],
+    "Jet Fuel Demand": [
+      "Jet Fuel Demand/China/Demand:日度:千桶每天",
+      "Jet Fuel Demand/Europe/Demand:日度:千桶每天",
+      "Jet Fuel Demand/UAE/Demand:日度:千桶每天",
+      "Jet Fuel Demand/United Kingdom/Demand:日度:千桶每天",
+      "Jet Fuel Demand/United States/Demand:日度:千桶每天",
+      "Jet Fuel Demand/China/Demand 7DMA:日度:千桶每天",
+      "Jet Fuel Demand/Europe/Demand 7DMA:日度:千桶每天",
+      "Jet Fuel Demand/UAE/Demand 7DMA:日度:千桶每天",
+      "Jet Fuel Demand/United Kingdom/Demand 7DMA:日度:千桶每天",
+      "Jet Fuel Demand/United States/Demand 7DMA:日度:千桶每天"
+    ],
+    "Maritime Bunker Demand": [
+      "Maritime Bunker Demand/China/Demand:日度:千桶每天",
+      "Maritime Bunker Demand/Europe/Demand:日度:千桶每天",
+      "Maritime Bunker Demand/Saudi Arabia/Demand:日度:千桶每天",
+      "Maritime Bunker Demand/Singapore/Demand:日度:千桶每天",
+      "Maritime Bunker Demand/UAE/Demand:日度:千桶每天",
+      "Maritime Bunker Demand/United States/Demand:日度:千桶每天",
+      "Maritime Bunker Demand/China/Demand 7DMA:日度:千桶每天",
+      "Maritime Bunker Demand/Europe/Demand 7DMA:日度:千桶每天",
+      "Maritime Bunker Demand/Saudi Arabia/Demand 7DMA:日度:千桶每天",
+      "Maritime Bunker Demand/Singapore/Demand 7DMA:日度:千桶每天",
+      "Maritime Bunker Demand/UAE/Demand 7DMA:日度:千桶每天",
+      "Maritime Bunker Demand/United States/Demand 7DMA:日度:千桶每天"
+    ]
+  },
+  "Cube Dashboards": {
+    "Oil Supply Analysis": [
+      "Oil Supply Analysis/Oil And Gas Category/Crude Oil:月度:千桶每天",
+      "Oil Supply Analysis/Oil And Gas Category/Condensate:月度:千桶每天",
+      "Oil Supply Analysis/Region/Australasia:月度:千桶每天",
+      "Oil Supply Analysis/Region/Caribbean:月度:千桶每天",
+      "Oil Supply Analysis/Region/Central America :月度:千桶每天",
+      "Oil Supply Analysis/Region/Central Asia :月度:千桶每天",
+      "Oil Supply Analysis/Region/East Africa:月度:千桶每天",
+      "Oil Supply Analysis/Region/East Asia :月度:千桶每天",
+      "Oil Supply Analysis/Region/Eastern Europe:月度:千桶每天",
+      "Oil Supply Analysis/Region/Melanesia, Micronesia&Polynesia:月度:千桶每天",
+      "Oil Supply Analysis/Region/Middle East:月度:千桶每天",
+      "Oil Supply Analysis/Region/North Africa:月度:千桶每天",
+      "Oil Supply Analysis/Region/North America:月度:千桶每天",
+      "Oil Supply Analysis/Region/Russia :月度:千桶每天",
+      "Oil Supply Analysis/Region/South Africa:月度:千桶每天",
+      "Oil Supply Analysis/Region/South America:月度:千桶每天",
+      "Oil Supply Analysis/Region/South Asia:月度:千桶每天",
+      "Oil Supply Analysis/Region/South East Asia:月度:千桶每天",
+      "Oil Supply Analysis/Region/Southern Europe:月度:千桶每天",
+      "Oil Supply Analysis/Region/West Africa:月度:千桶每天",
+      "Oil Supply Analysis/Region/Western Europe:月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Accidental Damage:月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Civil Unrest or Attacks :月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Maintenance:月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Natural Events:月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Other Planned:月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Other Unplanned:月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Production:月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Reguatory Order :月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Strike:月度:千桶每天",
+      "Oil Supply Analysis/CapacityDetail/Unutilized Capacity:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Heavy Reguar:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Heavy Sour:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Heavy Sweet:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Heavy Unspecified:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Light Reguar:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Light Sour:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Light Sweet:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Light Unspecified :月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Medium Regular :月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Medium Sour:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Medium Sweet:月度:千桶每天",
+      "Oil Supply Analysis/Oil Classification Group/Medium lnspecified:月度:千桶每天"
+    ],
+    "Oil Demand Analysis": [
+      "Oil Demand Analysis/Continent/Africa:月度:千桶每天",
+      "Oil Demand Analysis/Continent/Asia:月度:千桶每天",
+      "Oil Demand Analysis/Continent/Europe:月度:千桶每天",
+      "Oil Demand Analysis/Continent/Middle East:月度:千桶每天",
+      "Oil Demand Analysis/Continent/North America:月度:千桶每天",
+      "Oil Demand Analysis/Continent/Oceania:月度:千桶每天",
+      "Oil Demand Analysis/Continent/Russia:月度:千桶每天",
+      "Oil Demand Analysis/Continent/South America:月度:千桶每天",
+      "Oil Demand Analysis/Region/Australasia:月度:千桶每天",
+      "Oil Demand Analysis/Region/Caribbean:月度:千桶每天",
+      "Oil Demand Analysis/Region/Central America:月度:千桶每天",
+      "Oil Demand Analysis/Region/Central Asia:月度:千桶每天",
+      "Oil Demand Analysis/Region/East Africa:月度:千桶每天",
+      "Oil Demand Analysis/Region/East Asia:月度:千桶每天",
+      "Oil Demand Analysis/Region/Eastern Europe:月度:千桶每天",
+      "Oil Demand Analysis/Region/MiddleEast:月度:千桶每天",
+      "Oil Demand Analysis/Region/North Africa:月度:千桶每天",
+      "Oil Demand Analysis/Region/North America:月度:千桶每天",
+      "Oil Demand Analysis/Region/Russia:月度:千桶每天",
+      "Oil Demand Analysis/Region/South Africa:月度:千桶每天",
+      "Oil Demand Analysis/Region/South Ameries :月度:千桶每天",
+      "Oil Demand Analysis/Region/South Asia :月度:千桶每天",
+      "Oil Demand Analysis/Region/South East Asia:月度:千桶每天",
+      "Oil Demand Analysis/Region/Southern Europe:月度:千桶每天",
+      "Oil Demand Analysis/Region/West Africa:月度:千桶每天",
+      "Oil Demand Analysis/Region/Western Europe:月度:千桶每天",
+      "Oil Demand Analysis/Country/Others:月度:千桶每天",
+      "Oil Demand Analysis/Country/Algeria:月度:千桶每天",
+      "Oil Demand Analysis/Country/Argentina:月度:千桶每天",
+      "Oil Demand Analysis/Country/Australia:月度:千桶每天",
+      "Oil Demand Analysis/Country/Belgium:月度:千桶每天",
+      "Oil Demand Analysis/Country/Brazil:月度:千桶每天",
+      "Oil Demand Analysis/Country/Canada:月度:千桶每天",
+      "Oil Demand Analysis/Country/Chile:月度:千桶每天",
+      "Oil Demand Analysis/Country/China:月度:千桶每天",
+      "Oil Demand Analysis/Country/Colombia:月度:千桶每天",
+      "Oil Demand Analysis/Country/Egypt:月度:千桶每天",
+      "Oil Demand Analysis/Country/France:月度:千桶每天",
+      "Oil Demand Analysis/Country/Germany:月度:千桶每天",
+      "Oil Demand Analysis/Country/Hong Kong(China):月度:千桶每天",
+      "Oil Demand Analysis/Country/India:月度:千桶每天",
+      "Oil Demand Analysis/Country/Indonesia:月度:千桶每天",
+      "Oil Demand Analysis/Country/Iran:月度:千桶每天",
+      "Oil Demand Analysis/Country/Iraq:月度:千桶每天",
+      "Oil Demand Analysis/Country/Italy:月度:千桶每天",
+      "Oil Demand Analysis/Country/Japan:月度:千桶每天",
+      "Oil Demand Analysis/Country/Kazakhstan:月度:千桶每天",
+      "Oil Demand Analysis/Country/Kuwait :月度:千桶每天",
+      "Oil Demand Analysis/Country/Malaysia:月度:千桶每天",
+      "Oil Demand Analysis/Country/Mexico:月度:千桶每天",
+      "Oil Demand Analysis/Country/Netherlands:月度:千桶每天",
+      "Oil Demand Analysis/Country/Nigeria:月度:千桶每天",
+      "Oil Demand Analysis/Country/Other Caribbean:月度:千桶每天",
+      "Oil Demand Analysis/Country/Other South Asia:月度:千桶每天",
+      "Oil Demand Analysis/Country/Other West Africa:月度:千桶每天",
+      "Oil Demand Analysis/Country/Pakistan:月度:千桶每天",
+      "Oil Demand Analysis/Country/Philippines:月度:千桶每天",
+      "Oil Demand Analysis/Country/Poland:月度:千桶每天",
+      "Oil Demand Analysis/Country/RuSsia:月度:千桶每天",
+      "Oil Demand Analysis/Country/Saudi Arabia:月度:千桶每天",
+      "Oil Demand Analysis/Country/Singapore:月度:千桶每天",
+      "Oil Demand Analysis/Country/South Africa:月度:千桶每天",
+      "Oil Demand Analysis/Country/South Korea:月度:千桶每天",
+      "Oil Demand Analysis/Country/Spain:月度:千桶每天",
+      "Oil Demand Analysis/Country/Taiwan (China):月度:千桶每天",
+      "Oil Demand Analysis/Country/Thailand:月度:千桶每天",
+      "Oil Demand Analysis/Country/Turkey:月度:千桶每天",
+      "Oil Demand Analysis/Country/UAE:月度:千桶每天",
+      "Oil Demand Analysis/Country/United Kingdom :月度:千桶每天",
+      "Oil Demand Analysis/Country/United States:月度:千桶每天",
+      "Oil Demand Analysis/Country/Venezuela:月度:千桶每天",
+      "Oil Demand Analysis/Country/Vietnam:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Biodiesel:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Biojet:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Direct crude burn:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Distillates:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Ethanol:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Fuel oil :月度:千桶每天",
+      "Oil Demand Analysis/Product category/Gasoline:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Jet fuel and kerosene:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Naphtha:月度:千桶每天",
+      "Oil Demand Analysis/Product category/NGL:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Other:月度:千桶每天",
+      "Oil Demand Analysis/Product category/Other products:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Biodiesel:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Biojet:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Bitumen:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Butane:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Diesel:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Direct crude burn:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Ethane:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Ethanol:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Fuel oil :月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Fuel oil+scrubber:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Gasoil:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/GasoLine:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Jet fuel:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Kerosene:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Low sulfur fuel oil:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Lubricants:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Naphtha:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Other:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Paraffine :月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Petroleum Coke:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/Propane:月度:千桶每天",
+      "Oil Demand Analysis/Product detail/White spirits :月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Agriculture:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Aviation:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Buildings:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Energy generation:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Industry:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Maritime:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Non energy use:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Petrochemicals:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Rail:月度:千桶每天",
+      "Oil Demand Analysis/Sector category/Road transport:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Agriculture:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Aviation:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Buildings:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Buses:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Energy own use:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Industry:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Maritime:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Non energy use:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Petrochemicals:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Power:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Rail:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Trucks:月度:千桶每天",
+      "Oil Demand Analysis/Sector detail/Vehieles:月度:千桶每天",
+      "Oil Demand Analysis/Scenario/Products Demand Base Case:月度:千桶每天"
+    ],
+    "Supply Revision Analysis": [
+      "Supply Revision Analysis/Country Revision Group/Azerbaijan/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Iraq/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Kazakhstan/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Kuwait/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Oman/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Other/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Qatar/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Russia/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Saudi Arabia/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/UAE/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/United States/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Current/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Previous/YearQuarter:季度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Azerbaijan/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Iraq/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Kazakhstan/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Kuwait/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Oman/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Other/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Qatar/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Russia/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Saudi Arabia/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/UAE/Year:年度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/United States/Year:年度:千桶每天",
+      "Supply Revision Analysis/Current/Year:年度:千桶每天",
+      "Supply Revision Analysis/Previous/Year:年度:千桶每天",
+      "Supply Revision Analysis/Current/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Previous/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Azerbaijan/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Iraq/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Kazakhstan/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Kuwait/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Oman/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Other/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Qatar/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Russia/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/Saudi Arabia/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/UAE/YearMonth:月度:千桶每天",
+      "Supply Revision Analysis/Country Revision Group/United States/YearMonth:月度:千桶每天"
+    ]
+  }
+
+}

+ 6 - 0
utils/common.go

@@ -1341,3 +1341,9 @@ func ParseExcelDateToTime(text string) (dateT time.Time, e error) {
 	}
 	}
 	return
 	return
 }
 }
+
+// IsNumeric 判断字符串是否为数字
+func IsNumeric(s string) bool {
+	_, err := strconv.ParseFloat(s, 64) // 或者使用 ParseInt(s, 10, 64) 判断整数
+	return err == nil
+}

+ 17 - 0
utils/config.go

@@ -80,6 +80,15 @@ var (
 	LY_OPEN      string
 	LY_OPEN      string
 )
 )
 
 
+// 睿姿得数据
+var (
+	RZD_USERNAME      string
+	RZD_PASSWORD      string
+	RZD_EXCEL_PATH    string
+	RZD_OPEN          string
+	RZD_DOWNLOAD_PATH string
+)
+
 // CCF化纤信息
 // CCF化纤信息
 var (
 var (
 	CCFOpen           string // 是否配置CCF
 	CCFOpen           string // 是否配置CCF
@@ -221,6 +230,14 @@ func init() {
 		LY_OPEN = config["ly_open"]
 		LY_OPEN = config["ly_open"]
 	}
 	}
 
 
+	{
+		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"]
+	}
+
 	// 隆众数据
 	// 隆众数据
 	{
 	{
 		OilchemAccount = config["oilchem_account"]
 		OilchemAccount = config["oilchem_account"]

+ 13 - 0
utils/constants.go

@@ -98,6 +98,7 @@ const (
 	DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE                    //预测百分位->70
 	DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE                    //预测百分位->70
 	DATA_SOURCE_FUBAO                                           //富宝数据->71
 	DATA_SOURCE_FUBAO                                           //富宝数据->71
 	DATA_SOURCE_LY                                   = 91       // 粮油商务网
 	DATA_SOURCE_LY                                   = 91       // 粮油商务网
+	DATA_SOURCE_RZD                                  = 97       // 睿姿得数据
 )
 )
 
 
 // 指标来源的中文展示
 // 指标来源的中文展示
@@ -264,6 +265,18 @@ const (
 	GET_LY_INDEX_BY_CODE                              = "/ly/get/ly/index/by/code"                              // 根据指标编码获取指标
 	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获取指标信息
 	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_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_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"                 // 修改指标库指标数据
+
 )
 )
 
 
 const (
 const (

+ 151 - 0
utils/date_util.go

@@ -486,3 +486,154 @@ func GetCurrentMonth(dateText string) (string, error) {
 
 
 	return fmt.Sprintf("%d月", month), nil
 	return fmt.Sprintf("%d月", month), nil
 }
 }
+
+// GetCurrentYearMonth 获取当前年月 yyyyMM
+func GetCurrentYearMonth() string {
+	// 获取当前时间
+	now := time.Now()
+
+	// 格式化为 "YYYYMM" 形式
+	yearMonth := now.Format("200601")
+
+	return yearMonth
+}
+
+// ConvertDateFormat 转换时间格式 MM-dd-yy --> yyyy-MM-dd
+func ConvertDateFormat(dataText string) (string, error) {
+	// 定义输入和输出的时间格式
+	inputFormat := "01-02-06"    // MM-dd-yy
+	outputFormat := "2006-01-02" // yyyy-MM-dd
+
+	// 解析输入的日期
+	date, err := time.Parse(inputFormat, dataText)
+	if err != nil {
+		return "", err
+	}
+
+	// 格式化为输出格式
+	return date.Format(outputFormat), nil
+}
+
+// ConvertDateFormat2 转换时间格式 yyyy-MMQ --> 取每一季度最后一天,例如 2024-01Q --> 2024-03-31
+func ConvertDateFormat2(dataText string) (string, error) {
+
+	// 提取年份和季度信息
+	yearStr := dataText[:4]
+	quarterStr := dataText[6:7]
+
+	// 转换年份
+	year, err := strconv.Atoi(yearStr)
+	if err != nil {
+		return "", fmt.Errorf("无效的年份: %v", err)
+	}
+
+	// 根据季度选择最后一天
+	var endOfQuarter string
+	switch quarterStr {
+	case "1":
+		endOfQuarter = fmt.Sprintf("%d-03-31", year)
+	case "2":
+		endOfQuarter = fmt.Sprintf("%d-06-30", year)
+	case "3":
+		endOfQuarter = fmt.Sprintf("%d-09-30", year)
+	case "4":
+		endOfQuarter = fmt.Sprintf("%d-12-31", year)
+	default:
+		return "", fmt.Errorf("无效的季度: %s", quarterStr)
+	}
+
+	// 确保日期格式正确
+	_, err = time.Parse("2006-01-02", endOfQuarter)
+	if err != nil {
+		return "", fmt.Errorf("日期解析失败: %v", err)
+	}
+
+	return endOfQuarter, nil
+}
+
+// ConvertDateFormat3 转换时间格式 Jan-23 --> 2023-01-31
+func ConvertDateFormat3(dataText string) (string, error) {
+	// 拆分月份和年份
+	parts := strings.Split(dataText, "-")
+	if len(parts) != 2 {
+		return "", fmt.Errorf("日期格式不正确")
+	}
+
+	// 提取月份和年份
+	monthStr := parts[0]
+	yearStr := parts[1]
+
+	// 转换年份
+	year, err := strconv.Atoi(yearStr)
+	if err != nil {
+		return "", fmt.Errorf("无效的年份: %v", err)
+	}
+
+	// 获取月份数字
+	month, err := time.Parse("Jan", monthStr)
+	if err != nil {
+		return "", fmt.Errorf("无效的月份: %v", err)
+	}
+
+	// 计算最后一天
+	lastDay := time.Date(year+2000, month.Month()+1, 0, 0, 0, 0, 0, time.UTC) // 直接设置为下个月的第一天,再设为0日得到上个月最后一天
+
+	return lastDay.Format("2006-01-02"), nil
+}
+
+// ConvertDateFormat4 转换时间格式 2022 --> 2022-12-31
+func ConvertDateFormat4(dataText string) (string, error) {
+	// 解析输入年份
+	year, err := strconv.Atoi(dataText)
+	if err != nil {
+		return "", fmt.Errorf("无法解析年份: %v", err)
+	}
+
+	// 创建该年最后一天的日期
+	lastDay := time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC)
+
+	// 返回格式化后的日期字符串
+	return lastDay.Format("2006-01-02"), nil
+}
+
+// ConvertDateFormat5 转换时间格式 yyyy-MM-dd HH:mm:ss --> yyyy-MM-dd
+func ConvertDateFormat5(dataText string) (string, error) {
+	// 解析输入的日期和时间
+	dateTime, err := time.Parse("2006-01-02 15:04:05", dataText)
+	if err != nil {
+		return "", err
+	}
+
+	// 格式化为输出格式
+	return dateTime.Format("2006-01-02"), nil
+}
+
+// ConvertDateFormat6 转换时间格式 2023-March --> 2023-03-31
+func ConvertDateFormat6(dataText string) (string, error) {
+	// 拆分年份和月份
+	parts := strings.Split(dataText, "-")
+	if len(parts) != 2 {
+		return "", fmt.Errorf("日期格式不正确")
+	}
+
+	// 提取年份和月份
+	yearStr := parts[0]
+	monthStr := parts[1]
+
+	// 转换年份
+	year, err := strconv.Atoi(yearStr)
+	if err != nil {
+		return "", fmt.Errorf("无效的年份: %v", err)
+	}
+
+	// 获取月份数字
+	month, err := time.Parse("January", monthStr)
+	if err != nil {
+		return "", fmt.Errorf("无效的月份: %v", err)
+	}
+
+	// 获取最后一天
+	lastDay := time.Date(year, month.Month()+1, 0, 0, 0, 0, 0, time.UTC) // 使用月份数字加1,再设为0日得到上个月最后一天
+
+	return lastDay.Format("2006-01-02"), nil
+}