supply_revision_analysis_processor.go 13 KB

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