eia_steo.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package services
  2. import (
  3. "context"
  4. "encoding/json"
  5. "eta/eta_crawler/models"
  6. "fmt"
  7. "github.com/rdlucklib/rdluck_tools/http"
  8. "reflect"
  9. "strconv"
  10. "time"
  11. )
  12. func SyncEiaSteoData(cont context.Context) (err error) {
  13. err = syncEiaSteoData()
  14. return
  15. }
  16. func syncEiaSteoData() (err error) {
  17. // 获取数据
  18. //官网地址:https://www.eia.gov/outlooks/steo/data/browser/#/?v=6&f=M&s=0&start=201701&end=202312&linechart=~T3_STCHANGE_WORLD&maptype=0&ctype=linechart&map=
  19. // 这是获取数据的链接(月度的)
  20. eiaSteoUrl := "https://www.eia.gov/outlooks/steo/data/browser/data/index.php?v=6&f=M&s=0&id=&linechart=PAPR_OECD~PAPR_NONOPEC&maptype=0&ctype=linechart&map=&method=getData"
  21. eiaSteoData, err := queryData(eiaSteoUrl)
  22. if err != nil {
  23. fmt.Println("读取失败", err)
  24. return
  25. }
  26. // 获取分类列表
  27. classifyList, err := models.GetBaseFromEiaSteoClassifyAll()
  28. if err != nil {
  29. fmt.Println("获取分类失败:", err)
  30. return
  31. }
  32. classifyMap := make(map[string]*models.BaseFromEiaSteoClassify)
  33. for _, v := range classifyList {
  34. classifyMap[v.ClassifyNameOriginal] = v
  35. }
  36. // 获取指标列表
  37. indexList, err := models.GetBaseFromEiaSteoIndexAll()
  38. if err != nil {
  39. fmt.Println("获取分类失败:", err)
  40. return
  41. }
  42. indexMap := make(map[string]*models.BaseFromEiaSteoIndex)
  43. for _, v := range indexList {
  44. indexMap[v.IndexCode] = v
  45. }
  46. var nowClassify *models.BaseFromEiaSteoClassify
  47. for _, v := range eiaSteoData.VIEWSDATA.ROWS {
  48. // 如果没有数据,那么就返回
  49. if v.HASDATA != 1 {
  50. continue
  51. }
  52. if v.LEVEL == 1 {
  53. tmpNowClassify, ok := classifyMap[v.CHARTNAME]
  54. if !ok {
  55. nowClassify = &models.BaseFromEiaSteoClassify{
  56. BaseFromEiaSteoClassifyId: 0,
  57. ClassifyName: v.CHARTNAME,
  58. ClassifyNameOriginal: v.CHARTNAME,
  59. ModifyTime: time.Now(),
  60. CreateTime: time.Now(),
  61. }
  62. // 新增指标
  63. err = nowClassify.AddBaseFromEiaSteoClassify()
  64. if err != nil {
  65. return
  66. }
  67. classifyMap[v.CHARTNAME] = nowClassify
  68. } else {
  69. nowClassify = tmpNowClassify
  70. }
  71. //continue
  72. }
  73. // 如果系列名称为空的话,那么也返回
  74. if v.SERIESID == `` {
  75. continue
  76. }
  77. if v.LEVEL > 1 && v.SERIESID == `` {
  78. continue
  79. }
  80. var eiaSteoIndex *models.BaseFromEiaSteoIndex
  81. eiaSteoIndex, ok := indexMap[v.SERIESID]
  82. // 指标名称(中文)
  83. indexName := EiaSteoNameMap[v.SERIESID]
  84. if indexName == `` {
  85. indexName = v.CHARTNAME
  86. }
  87. if !ok {
  88. eiaSteoIndex = &models.BaseFromEiaSteoIndex{
  89. //BaseFromEiaSteoIndexId: 0,
  90. BaseFromEiaSteoClassifyId: nowClassify.BaseFromEiaSteoClassifyId,
  91. IndexCode: v.SERIESID,
  92. IndexName: indexName,
  93. IndexNameOriginal: v.CHARTNAME,
  94. Frequency: "月度",
  95. Level: v.LEVEL,
  96. Unit: v.UNITS,
  97. Super: v.SUPER,
  98. Precision: v.PRECISION,
  99. LastHistorical: strconv.Itoa(v.LASTHISTORICAL),
  100. Description: v.DESCRIPTION,
  101. IsMappable: v.ISMAPPABLE,
  102. StartDate: time.Now(),
  103. EndDate: time.Now(),
  104. ModifyTime: time.Now(),
  105. CreateTime: time.Now(),
  106. }
  107. // 新增指标
  108. err = eiaSteoIndex.Add()
  109. if err != nil {
  110. return
  111. }
  112. indexMap[v.SERIESID] = eiaSteoIndex
  113. } else {
  114. updateCol := make([]string, 0)
  115. if eiaSteoIndex.BaseFromEiaSteoClassifyId != nowClassify.BaseFromEiaSteoClassifyId {
  116. eiaSteoIndex.BaseFromEiaSteoClassifyId = nowClassify.BaseFromEiaSteoClassifyId
  117. updateCol = append(updateCol, "BaseFromEiaSteoClassifyId")
  118. }
  119. if eiaSteoIndex.IndexName != indexName {
  120. eiaSteoIndex.IndexName = indexName
  121. updateCol = append(updateCol, "IndexName")
  122. }
  123. if eiaSteoIndex.IndexNameOriginal != v.CHARTNAME {
  124. eiaSteoIndex.IndexNameOriginal = v.CHARTNAME
  125. updateCol = append(updateCol, "IndexNameOriginal")
  126. }
  127. // Frequency: "月度",
  128. // Level: v.LEVEL,
  129. // Unit: v.UNITS,
  130. // Super: v.SUPER,
  131. // Precision: v.PRECISION,
  132. // LastHistorical: strconv.Itoa(v.LASTHISTORICAL),
  133. // Description: v.DESCRIPTION,
  134. // IsMappable: v.ISMAPPABLE,
  135. if len(updateCol) > 0 {
  136. eiaSteoIndex.Update(updateCol)
  137. }
  138. }
  139. //校验数据类型对不对
  140. valType := reflect.TypeOf(v.DATA)
  141. //if valType.String() == "map[string]interface{}"{
  142. // fmt.Println("匹配上了")
  143. //}
  144. switch valType.String() {
  145. case "[]interface {}": // 没有数据
  146. case "map[string]interface {}": // 有数据
  147. data := v.DATA.(map[string]interface{})
  148. err = models.HandleEiaSteoData(data, eiaSteoIndex)
  149. if err != nil {
  150. return
  151. }
  152. //if eiaSteoIndex.IndexCode == "PATC_OECD_EUROPE" {
  153. // os.Exit(0)
  154. //}
  155. }
  156. fmt.Println(v.CHARTNAME, v.SERIESID, "==", v.PRECISION, "===========")
  157. }
  158. return
  159. }
  160. // queryData 接口请求网站数据
  161. func queryData(eiaSteoUrl string) (eiaSteoData EiaSteoData, err error) {
  162. body, err := http.Get(eiaSteoUrl)
  163. if err != nil {
  164. fmt.Println("err:", err)
  165. }
  166. //utils.FileLog.Info("eia steo 报告数据:" + string(body))
  167. err = json.Unmarshal(body, &eiaSteoData)
  168. return
  169. }
  170. type EiaSteoData struct {
  171. SERIESDATA struct {
  172. DATACOLUMNS []interface{} `json:"DATACOLUMNS"`
  173. ROWS []interface{} `json:"ROWS"`
  174. } `json:"SERIESDATA"`
  175. VIEWSDATA struct {
  176. DATACOLUMNS []int `json:"DATACOLUMNS"`
  177. ROWS []struct {
  178. CHARTNAME string `json:"CHART_NAME"`
  179. DESCRIPTION string `json:"DESCRIPTION"`
  180. HASDATA int `json:"HAS_DATA"`
  181. PRECISION int `json:"PRECISION"`
  182. SERIESID string `json:"SERIES_ID"`
  183. UNITS string `json:"UNITS"`
  184. SUPER string `json:"SUPER"`
  185. LEVEL int `json:"LEVEL"`
  186. //DATA map[int]float64 `json:"DATA"`
  187. DATA interface{} `json:"DATA"`
  188. LASTHISTORICAL int `json:"LAST_HISTORICAL,omitempty"`
  189. ISMAPPABLE int `json:"IS_MAPPABLE,omitempty"`
  190. } `json:"ROWS"`
  191. } `json:"VIEWSDATA"`
  192. }
  193. // EiaSteoNameMap 中英文互换
  194. var EiaSteoNameMap = map[string]string{
  195. "PAPR_OECD": "OECD石油产量",
  196. "PAPR_US": "美国五十州石油产量",
  197. "PAPR_CA": "加拿大石油产量",
  198. "PAPR_MX": "墨西哥石油产量",
  199. "PAPR_OTHEROECD": "其他OECD石油产量",
  200. "PAPR_NONOECD": "非OECD石油产量",
  201. "PAPR_OPEC": "OPEC13国石油产量",
  202. "COPR_OPEC": "OPEC13国原油产量",
  203. "OPEC_NC": "OPEC其他石油液体产量",
  204. "PAPR_FSU": "欧亚石油产量",
  205. "PAPR_CH": "中国石油产量",
  206. "PAPR_OTHER_NONOECD": "其他非OECD石油产量",
  207. "PAPR_WORLD": "全球石油产量",
  208. "PAPR_NONOPEC": "非OPEC石油产量",
  209. "PATC_OECD": "OECD石油需求",
  210. "PATC_US": "美国五十州石油需求",
  211. "PATC_UST": "美国领地石油需求",
  212. "PATC_CA": "加拿大石油需求",
  213. "PATC_OECD_EUROPE": "欧洲石油需求",
  214. "PATC_JA": "日本石油需求",
  215. "PATC_OTHER_OECD": "其他OECD石油需求",
  216. "PATC_NON_OECD": "非OECD石油需求",
  217. "PATC_FSU": "欧亚石油需求",
  218. "PATC_NONOECD_EUROPE": "非OECD欧洲石油需求",
  219. "PATC_CH": "中国石油需求",
  220. "PATC_OTHER_ASIA": "其他亚洲石油需求",
  221. "PATC_OTHER_NONOECD": "其他非OECD石油需求",
  222. "PATC_WORLD": "全球石油需求",
  223. "T3_STCHANGE_US": "美国50州石油库存去化(需求-供给)",
  224. "T3_STCHANGE_OOECD": "其他OECD石油库存去化(需求-供给)",
  225. "T3_STCHANGE_NOECD": "非OECD石油库存去化(需求-供给)",
  226. "T3_STCHANGE_WORLD": "全球石油库存去化(需求-供给)",
  227. "PASC_US": "美国商业库存",
  228. "PASC_OECD_T3": "OECD商业库存",
  229. }