supply_revision_analysis_processor.go 12 KB

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