eia_steo.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package services
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/rdlucklib/rdluck_tools/http"
  7. "hongze/hongze_data_crawler/models"
  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. if v.LEVEL == 1 {
  49. tmpNowClassify, ok := classifyMap[v.CHARTNAME]
  50. if !ok {
  51. nowClassify = &models.BaseFromEiaSteoClassify{
  52. BaseFromEiaSteoClassifyId: 0,
  53. ClassifyName: v.CHARTNAME,
  54. ClassifyNameOriginal: v.CHARTNAME,
  55. ModifyTime: time.Now(),
  56. CreateTime: time.Now(),
  57. }
  58. // 新增指标
  59. err = nowClassify.AddBaseFromEiaSteoClassify()
  60. if err != nil {
  61. return
  62. }
  63. classifyMap[v.CHARTNAME] = nowClassify
  64. } else {
  65. nowClassify = tmpNowClassify
  66. }
  67. continue
  68. }
  69. if v.LEVEL > 1 && v.SERIESID == `` {
  70. continue
  71. }
  72. var eiaSteoIndex *models.BaseFromEiaSteoIndex
  73. eiaSteoIndex, ok := indexMap[v.SERIESID]
  74. // 指标名称(中文)
  75. indexName := EiaSteoNameMap[v.SERIESID]
  76. if indexName == `` {
  77. indexName = v.CHARTNAME
  78. }
  79. if !ok {
  80. eiaSteoIndex = &models.BaseFromEiaSteoIndex{
  81. //BaseFromEiaSteoIndexId: 0,
  82. BaseFromEiaSteoClassifyId: nowClassify.BaseFromEiaSteoClassifyId,
  83. IndexCode: v.SERIESID,
  84. IndexName: indexName,
  85. IndexNameOriginal: v.CHARTNAME,
  86. Frequency: "月度",
  87. Level: v.LEVEL,
  88. Unit: v.UNITS,
  89. Super: v.SUPER,
  90. Precision: v.PRECISION,
  91. LastHistorical: strconv.Itoa(v.LASTHISTORICAL),
  92. Description: v.DESCRIPTION,
  93. IsMappable: v.ISMAPPABLE,
  94. StartDate: time.Now(),
  95. EndDate: time.Now(),
  96. ModifyTime: time.Now(),
  97. CreateTime: time.Now(),
  98. }
  99. // 新增指标
  100. err = eiaSteoIndex.Add()
  101. if err != nil {
  102. return
  103. }
  104. indexMap[v.SERIESID] = eiaSteoIndex
  105. } else {
  106. updateCol := make([]string, 0)
  107. if eiaSteoIndex.BaseFromEiaSteoClassifyId != nowClassify.BaseFromEiaSteoClassifyId {
  108. eiaSteoIndex.BaseFromEiaSteoClassifyId = nowClassify.BaseFromEiaSteoClassifyId
  109. updateCol = append(updateCol, "BaseFromEiaSteoClassifyId")
  110. }
  111. if eiaSteoIndex.IndexName != indexName {
  112. eiaSteoIndex.IndexName = indexName
  113. updateCol = append(updateCol, "IndexName")
  114. }
  115. if eiaSteoIndex.IndexNameOriginal != v.CHARTNAME {
  116. eiaSteoIndex.IndexNameOriginal = v.CHARTNAME
  117. updateCol = append(updateCol, "IndexNameOriginal")
  118. }
  119. // Frequency: "月度",
  120. // Level: v.LEVEL,
  121. // Unit: v.UNITS,
  122. // Super: v.SUPER,
  123. // Precision: v.PRECISION,
  124. // LastHistorical: strconv.Itoa(v.LASTHISTORICAL),
  125. // Description: v.DESCRIPTION,
  126. // IsMappable: v.ISMAPPABLE,
  127. if len(updateCol) > 0 {
  128. eiaSteoIndex.Update(updateCol)
  129. }
  130. }
  131. //校验数据类型对不对
  132. valType := reflect.TypeOf(v.DATA)
  133. //if valType.String() == "map[string]interface{}"{
  134. // fmt.Println("匹配上了")
  135. //}
  136. switch valType.String() {
  137. case "[]interface {}": // 没有数据
  138. case "map[string]interface {}": // 有数据
  139. data := v.DATA.(map[string]interface{})
  140. err = models.HandleEiaSteoData(data, eiaSteoIndex)
  141. if err != nil {
  142. return
  143. }
  144. //if eiaSteoIndex.IndexCode == "PATC_OECD_EUROPE" {
  145. // os.Exit(0)
  146. //}
  147. }
  148. fmt.Println(v.CHARTNAME, v.SERIESID, "==", v.PRECISION, "===========")
  149. }
  150. return
  151. }
  152. // queryData 接口请求网站数据
  153. func queryData(eiaSteoUrl string) (eiaSteoData EiaSteoData, err error) {
  154. body, err := http.Get(eiaSteoUrl)
  155. if err != nil {
  156. fmt.Println("err:", err)
  157. }
  158. //utils.FileLog.Info("eia steo 报告数据:" + string(body))
  159. err = json.Unmarshal(body, &eiaSteoData)
  160. return
  161. }
  162. type EiaSteoData struct {
  163. SERIESDATA struct {
  164. DATACOLUMNS []interface{} `json:"DATACOLUMNS"`
  165. ROWS []interface{} `json:"ROWS"`
  166. } `json:"SERIESDATA"`
  167. VIEWSDATA struct {
  168. DATACOLUMNS []int `json:"DATACOLUMNS"`
  169. ROWS []struct {
  170. CHARTNAME string `json:"CHART_NAME"`
  171. DESCRIPTION string `json:"DESCRIPTION"`
  172. HASDATA int `json:"HAS_DATA"`
  173. PRECISION int `json:"PRECISION"`
  174. SERIESID string `json:"SERIES_ID"`
  175. UNITS string `json:"UNITS"`
  176. SUPER string `json:"SUPER"`
  177. LEVEL int `json:"LEVEL"`
  178. //DATA map[int]float64 `json:"DATA"`
  179. DATA interface{} `json:"DATA"`
  180. LASTHISTORICAL int `json:"LAST_HISTORICAL,omitempty"`
  181. ISMAPPABLE int `json:"IS_MAPPABLE,omitempty"`
  182. } `json:"ROWS"`
  183. } `json:"VIEWSDATA"`
  184. }
  185. // EiaSteoNameMap 中英文互换
  186. var EiaSteoNameMap = map[string]string{
  187. "PAPR_OECD": "OECD石油产量",
  188. "PAPR_US": "美国五十州石油产量",
  189. "PAPR_CA": "加拿大石油产量",
  190. "PAPR_MX": "墨西哥石油产量",
  191. "PAPR_OTHEROECD": "其他OECD石油产量",
  192. "PAPR_NONOECD": "非OECD石油产量",
  193. "PAPR_OPEC": "OPEC13国石油产量",
  194. "COPR_OPEC": "OPEC13国原油产量",
  195. "OPEC_NC": "OPEC其他石油液体产量",
  196. "PAPR_FSU": "欧亚石油产量",
  197. "PAPR_CH": "中国石油产量",
  198. "PAPR_OTHER_NONOECD": "其他非OECD石油产量",
  199. "PAPR_WORLD": "全球石油产量",
  200. "PAPR_NONOPEC": "非OPEC石油产量",
  201. "PATC_OECD": "OECD石油需求",
  202. "PATC_US": "美国五十州石油需求",
  203. "PATC_UST": "美国领地石油需求",
  204. "PATC_CA": "加拿大石油需求",
  205. "PATC_OECD_EUROPE": "欧洲石油需求",
  206. "PATC_JA": "日本石油需求",
  207. "PATC_OTHER_OECD": "其他OECD石油需求",
  208. "PATC_NON_OECD": "非OECD石油需求",
  209. "PATC_FSU": "欧亚石油需求",
  210. "PATC_NONOECD_EUROPE": "非OECD欧洲石油需求",
  211. "PATC_CH": "中国石油需求",
  212. "PATC_OTHER_ASIA": "其他亚洲石油需求",
  213. "PATC_OTHER_NONOECD": "其他非OECD石油需求",
  214. "PATC_WORLD": "全球石油需求",
  215. "T3_STCHANGE_US": "美国50州石油库存去化(需求-供给)",
  216. "T3_STCHANGE_OOECD": "其他OECD石油库存去化(需求-供给)",
  217. "T3_STCHANGE_NOECD": "非OECD石油库存去化(需求-供给)",
  218. "T3_STCHANGE_WORLD": "全球石油库存去化(需求-供给)",
  219. "PASC_US": "美国商业库存",
  220. "PASC_OECD_T3": "OECD商业库存",
  221. }