supply_revision_analysis_processor.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. package ruizide
  2. import (
  3. "encoding/json"
  4. "eta/eta_data_analysis/models"
  5. "eta/eta_data_analysis/utils"
  6. "fmt"
  7. "github.com/shopspring/decimal"
  8. "github.com/xuri/excelize/v2"
  9. "os"
  10. "path/filepath"
  11. "strings"
  12. "time"
  13. )
  14. const (
  15. CubeDashboards = "cube dashboards"
  16. SupplyRevisionAnalysis = "Supply Revision Analysis"
  17. BeginRow = 1
  18. Rows = 3
  19. )
  20. var (
  21. SupplyRevisionAnalysisConfigMap = map[string]SRAPConfig{
  22. "Chart 1": {
  23. Frequency: "季度",
  24. Unit: "千桶每天",
  25. IndexNameColSuffix: "Year Quarter",
  26. IndexNameColPrefix: "Country Revision Group",
  27. chartType: "one",
  28. IndexRow: 2,
  29. DataRow: 1,
  30. DateRow: 0,
  31. DateType: "quarter",
  32. },
  33. "Chart 2": {
  34. Frequency: "季度",
  35. Unit: "千桶每天",
  36. IndexNameColPrefix: "Year Quarter",
  37. chartType: "two",
  38. NamePrevious: "Previous",
  39. NameCurrent: "Current",
  40. CodePrevious: "Previous",
  41. CodeCurrent: "Current",
  42. DataPreviousRow: 2,
  43. DataCurrentRow: 1,
  44. DateRow: 0,
  45. DateType: "quarter",
  46. },
  47. "Chart 3": {
  48. Frequency: "年度",
  49. Unit: "千桶每天",
  50. IndexNameColSuffix: "Year",
  51. IndexNameColPrefix: "Country Revision Group",
  52. chartType: "one",
  53. IndexRow: 2,
  54. DataRow: 1,
  55. DateRow: 0,
  56. DateType: "year",
  57. },
  58. "Chart 4": {
  59. Frequency: "月度",
  60. Unit: "千桶每天",
  61. IndexNameColPrefix: "Year",
  62. chartType: "two",
  63. NamePrevious: "Previous",
  64. NameCurrent: "Current",
  65. CodePrevious: "Previous",
  66. CodeCurrent: "Current",
  67. DataPreviousRow: 2,
  68. DataCurrentRow: 1,
  69. DateRow: 0,
  70. DateType: "year",
  71. },
  72. "Chart 5": {
  73. Frequency: "月度",
  74. Unit: "千桶每天",
  75. IndexNameColPrefix: "Year Month",
  76. chartType: "two",
  77. NamePrevious: "Previous/Chat5",
  78. NameCurrent: "Current/Chat5",
  79. CodePrevious: "previouschat5",
  80. CodeCurrent: "currentchat5",
  81. DataPreviousRow: 0,
  82. DataCurrentRow: 1,
  83. DateRow: 2,
  84. DateType: "month",
  85. },
  86. "Chart 6": {
  87. Frequency: "日度",
  88. Unit: "千桶每天",
  89. IndexNameColSuffix: "Year Month",
  90. IndexNameColPrefix: "Country Revision Group",
  91. chartType: "one",
  92. IndexRow: 1,
  93. DataRow: 2,
  94. DateRow: 0,
  95. DateType: "month",
  96. },
  97. }
  98. )
  99. type SRAPConfig struct {
  100. Frequency string
  101. Unit string
  102. IndexNameColSuffix string
  103. IndexNameColPrefix string
  104. IndexRow int
  105. DataRow int
  106. DataPreviousRow int
  107. DataCurrentRow int
  108. DateRow int
  109. DateType string
  110. chartType string
  111. NamePrevious string
  112. NameCurrent string
  113. CodePrevious string
  114. CodeCurrent string
  115. }
  116. type SupplyRevisionAnalysisProcessor struct {
  117. }
  118. func (p *SupplyRevisionAnalysisProcessor) Process(tableName string) (err error) {
  119. var fileName string
  120. // 解析表格
  121. fileName = tableName + "_" + utils.GetCurrentYearMonth() + ".xlsx"
  122. filePath := filepath.Join(excelDir, fileName)
  123. if _, err = os.Stat(filePath); os.IsNotExist(err) {
  124. utils.FileLog.Error("文件不存在: %v", err)
  125. return
  126. }
  127. // 打开 Excel 文件
  128. file, err := excelize.OpenFile(filePath)
  129. if err != nil {
  130. utils.FileLog.Error("无法打开 Excel 文件: %v", err)
  131. return
  132. }
  133. sheetNames := file.GetSheetList()
  134. classifyIds, err := dealClassify(CubeDashboards, []string{SupplyRevisionAnalysis})
  135. // 获取所有工作表
  136. if err != nil {
  137. utils.FileLog.Error("获取分类Id失败: %v", err)
  138. return
  139. }
  140. //按照sheet页来处理数据,一个sheet发送一次服务器
  141. for _, sheetName := range sheetNames {
  142. var indexMap = make(map[string]*models.IndexInfo)
  143. utils.FileLog.Info("读取工作表: %s\n", sheetName)
  144. // 获取工作表的最大行数
  145. dataRows, excelErr := file.GetRows(sheetName) // 直接获取所有行数据
  146. if excelErr != nil {
  147. utils.FileLog.Error("获取工作表数据时出错: %v", excelErr)
  148. continue
  149. }
  150. sheetConfig := SupplyRevisionAnalysisConfigMap[sheetName]
  151. // 匹配非数字字符
  152. classifyId := classifyIds[SupplyRevisionAnalysis]
  153. switch sheetConfig.chartType {
  154. case "one":
  155. indexMap, err = OneDataHandler(dataRows, sheetConfig, classifyId)
  156. case "two":
  157. indexMap, err = TwoDataHandler(dataRows, sheetConfig, classifyId)
  158. }
  159. // 新增数据源指标数据
  160. if len(indexMap) > 0 {
  161. for _, index := range indexMap {
  162. pars := chunkIndexData(index, rzdBatchSize)
  163. for _, par := range pars {
  164. // 转换成json
  165. marshal, parseErr := json.Marshal(par)
  166. if parseErr != nil {
  167. utils.FileLog.Error("json.Marshal err: %v", parseErr)
  168. return parseErr
  169. }
  170. // 发送 HTTP POST 请求
  171. _, err = utils.HttpPostRequest(utils.EDB_LIB_URL+utils.ADD_BATCH_RZD_DATA, string(marshal), "application/json")
  172. if err != nil {
  173. utils.FileLog.Error("postEdbLib err: %v", err)
  174. return err
  175. }
  176. }
  177. }
  178. }
  179. }
  180. return
  181. }
  182. func OneDataHandler(dataRows [][]string, sheetConfig SRAPConfig, classifyId int) (indexMap map[string]*models.IndexInfo, err error) {
  183. indexMap = make(map[string]*models.IndexInfo)
  184. //re := regexp.MustCompile(`^\d*\.?\d*\s*$`)
  185. for _, rowData := range dataRows[BeginRow : len(dataRows)-1] {
  186. //处理数据不全的情况
  187. less := Rows - len(rowData)
  188. if less > 0 {
  189. for i := 0; i < less; i++ {
  190. rowData = append(rowData, "")
  191. }
  192. }
  193. // step_2: 指标
  194. // 指标名称
  195. indexName := SupplyRevisionAnalysis + "/" + sheetConfig.IndexNameColPrefix + "/" + sheetConfig.IndexNameColSuffix + "/" + rowData[sheetConfig.IndexRow]
  196. // 生成指标编码
  197. indexCode := getIndexId(fmt.Sprintf("%s %s %s", SupplyRevisionAnalysis, sheetConfig.IndexNameColPrefix, sheetConfig.IndexNameColSuffix), strings.ReplaceAll(strings.ToLower(rowData[sheetConfig.IndexRow]), " ", ""), "")
  198. dataTime := rowData[sheetConfig.DateRow]
  199. if dataTime == "0" {
  200. continue
  201. }
  202. var date time.Time
  203. var convertErr error
  204. switch sheetConfig.DateType {
  205. case "quarter":
  206. date, _, convertErr = utils.ConvertDateFormatQuarter(dataTime)
  207. case "year":
  208. date, _, convertErr = utils.ConvertDateFormatYear(dataTime)
  209. case "month":
  210. timeSplit := strings.Split(dataTime, "-")
  211. date, _, convertErr = utils.ConvertLastDayOfMonth(fmt.Sprintf("%s-%s", timeSplit[0], timeSplit[1]))
  212. }
  213. if convertErr != nil {
  214. utils.FileLog.Error(fmt.Sprintf("转换时间数据失败,index_code:%s,time_value:%s err:%v", indexCode, dataTime, convertErr))
  215. continue
  216. }
  217. if rowData[sheetConfig.DataRow] != "" {
  218. value, parseErr := decimal.NewFromString(rowData[sheetConfig.DataRow])
  219. if parseErr != nil {
  220. utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCode, rowData[sheetConfig.DataRow], err))
  221. continue
  222. } else {
  223. if index, ok := indexMap[indexCode]; ok {
  224. if index.StartDate.After(date) {
  225. index.StartDate = date
  226. }
  227. if index.EndDate.Before(date) {
  228. index.EndDate = date
  229. index.LatestValue = value
  230. }
  231. index.DataList = append(index.DataList, models.IndexData{
  232. DataTime: date,
  233. Value: value,
  234. })
  235. } else {
  236. indexMap[indexCode] = &models.IndexInfo{
  237. IndexName: indexName,
  238. IndexCode: indexCode,
  239. Frequency: sheetConfig.Frequency,
  240. Unit: sheetConfig.Unit,
  241. StartDate: date,
  242. EndDate: date,
  243. LatestValue: value,
  244. ClassifyId: classifyId,
  245. DataList: []models.IndexData{
  246. {
  247. DataTime: date,
  248. Value: value,
  249. },
  250. },
  251. }
  252. }
  253. }
  254. }
  255. }
  256. return
  257. }
  258. func TwoDataHandler(dataRows [][]string, sheetConfig SRAPConfig, classifyId int) (indexMap map[string]*models.IndexInfo, err error) {
  259. indexMap = make(map[string]*models.IndexInfo)
  260. // 匹配非数字字符
  261. //re := regexp.MustCompile(`^\d*\.?\d*\s*$`)
  262. for _, rowData := range dataRows[BeginRow : len(dataRows)-1] {
  263. //处理数据不全的情况
  264. less := Rows - len(rowData)
  265. if less > 0 {
  266. for i := 0; i < less; i++ {
  267. rowData = append(rowData, "")
  268. }
  269. }
  270. // step_2: 指标
  271. // 指标名称
  272. indexNameCurrent := SupplyRevisionAnalysis + "/" + sheetConfig.IndexNameColPrefix + "/" + sheetConfig.NameCurrent
  273. indexNamePrevious := SupplyRevisionAnalysis + "/" + sheetConfig.IndexNameColPrefix + "/" + sheetConfig.NamePrevious
  274. // 生成指标编码
  275. indexCodeCurrent := getIndexId(fmt.Sprintf("%s %s", SupplyRevisionAnalysis, sheetConfig.IndexNameColPrefix), sheetConfig.CodeCurrent, "")
  276. indexCodePrevious := getIndexId(fmt.Sprintf("%s %s", SupplyRevisionAnalysis, sheetConfig.IndexNameColPrefix), sheetConfig.CodePrevious, "")
  277. dataTime := rowData[sheetConfig.DateRow]
  278. if dataTime == "0" {
  279. continue
  280. }
  281. var date time.Time
  282. var convertErr error
  283. switch sheetConfig.DateType {
  284. case "quarter":
  285. date, _, convertErr = utils.ConvertDateFormatQuarter(dataTime)
  286. case "year":
  287. date, _, convertErr = utils.ConvertDateFormatYear(dataTime)
  288. case "month":
  289. timeSplit := strings.Split(dataTime, "-")
  290. date, _, convertErr = utils.ConvertLastDayOfMonth(fmt.Sprintf("%s-%s", timeSplit[0], timeSplit[1]))
  291. }
  292. if convertErr != nil {
  293. utils.FileLog.Error(fmt.Sprintf("转换时间数据失败,index_code:%s,time_value:%s err:%v", indexNameCurrent, dataTime, convertErr))
  294. continue
  295. }
  296. if rowData[sheetConfig.DataCurrentRow] != "" {
  297. valueCurrent, parseErr := decimal.NewFromString(rowData[sheetConfig.DataCurrentRow])
  298. if parseErr != nil {
  299. utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCodeCurrent, rowData[sheetConfig.DataCurrentRow], err))
  300. continue
  301. } else {
  302. if index, ok := indexMap[indexCodeCurrent]; ok {
  303. if index.StartDate.After(date) {
  304. index.StartDate = date
  305. }
  306. if index.EndDate.Before(date) {
  307. index.EndDate = date
  308. index.LatestValue = valueCurrent
  309. }
  310. index.DataList = append(index.DataList, models.IndexData{
  311. DataTime: date,
  312. Value: valueCurrent,
  313. })
  314. } else {
  315. indexMap[indexCodeCurrent] = &models.IndexInfo{
  316. IndexName: indexNameCurrent,
  317. IndexCode: indexCodeCurrent,
  318. Frequency: sheetConfig.Frequency,
  319. Unit: sheetConfig.Unit,
  320. StartDate: date,
  321. EndDate: date,
  322. LatestValue: valueCurrent,
  323. ClassifyId: classifyId,
  324. DataList: []models.IndexData{
  325. {
  326. DataTime: date,
  327. Value: valueCurrent,
  328. },
  329. },
  330. }
  331. }
  332. }
  333. }
  334. if rowData[sheetConfig.DataPreviousRow] != "" {
  335. valuePrevious, parseErr := decimal.NewFromString(rowData[sheetConfig.DataPreviousRow])
  336. if parseErr != nil {
  337. utils.FileLog.Error(fmt.Sprintf("转换data数据失败,index_code:%s,data_value:%s err:%v", indexCodePrevious, rowData[sheetConfig.DataPreviousRow], err))
  338. continue
  339. } else {
  340. if index, ok := indexMap[indexCodePrevious]; ok {
  341. if index.StartDate.After(date) {
  342. index.StartDate = date
  343. }
  344. if index.EndDate.Before(date) {
  345. index.EndDate = date
  346. index.LatestValue = valuePrevious
  347. }
  348. index.DataList = append(index.DataList, models.IndexData{
  349. DataTime: date,
  350. Value: valuePrevious,
  351. })
  352. } else {
  353. indexMap[indexCodePrevious] = &models.IndexInfo{
  354. IndexName: indexNamePrevious,
  355. IndexCode: indexCodePrevious,
  356. Frequency: sheetConfig.Frequency,
  357. Unit: sheetConfig.Unit,
  358. StartDate: date,
  359. EndDate: date,
  360. LatestValue: valuePrevious,
  361. ClassifyId: classifyId,
  362. DataList: []models.IndexData{
  363. {
  364. DataTime: date,
  365. Value: valuePrevious,
  366. },
  367. },
  368. }
  369. }
  370. }
  371. }
  372. }
  373. return
  374. }