smm_shanghai.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. package services
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "eta/eta_crawler/models"
  7. "eta/eta_crawler/services/sci99"
  8. "eta/eta_crawler/utils"
  9. "fmt"
  10. "io"
  11. "net/http"
  12. "strconv"
  13. "strings"
  14. "time"
  15. "github.com/beego/beego/v2/task"
  16. "github.com/xuri/excelize/v2"
  17. )
  18. type SmmRequest struct {
  19. Name string
  20. IndexCode string
  21. Url string
  22. Frequency string
  23. Unit string
  24. Value string
  25. }
  26. var nickelReqs = []SmmRequest{
  27. // {
  28. // Name: "SMM 1#电解镍",
  29. // IndexCode: "",
  30. // Url: "https://hq.smm.cn/ajax/spot/history/201102250239",
  31. // Frequency: "日度",
  32. // Unit: "元/吨",
  33. // },
  34. {
  35. Name: "1#金川镍",
  36. Url: "https://hq.smm.cn/ajax/spot/history/201102250174",
  37. Frequency: "日度",
  38. Unit: "元/吨",
  39. },
  40. {
  41. Name: "1#进口镍",
  42. Url: "https://hq.smm.cn/ajax/spot/history/201102250423",
  43. Frequency: "日度",
  44. Unit: "元/吨",
  45. },
  46. {
  47. Name: "镍豆",
  48. Url: "https://hq.smm.cn/ajax/spot/history/202008270001",
  49. Frequency: "日度",
  50. Unit: "元/吨",
  51. },
  52. // {
  53. // Name: `印尼内贸红土镍矿1.2%(到厂价)`,
  54. // Url: "https://hq.smm.cn/ajax/spot/history/202311230010",
  55. // Frequency: "周度",
  56. // Unit: "美元/湿吨",
  57. // },
  58. // {
  59. // Name: `印尼内贸红土镍矿1.6%(到厂价)`,
  60. // Url: "https://hq.smm.cn/ajax/spot/history/202311230011",
  61. // Frequency: "周度",
  62. // Unit: "美元/湿吨",
  63. // },
  64. {
  65. Name: `菲律宾红土镍矿0.9%,Al≥7%(CIF)`,
  66. Url: "https://hq.smm.cn/ajax/spot/history/201608170001",
  67. Frequency: "日度",
  68. Unit: "美元/湿吨",
  69. },
  70. // {
  71. // Name: `菲律宾红土镍矿0.9%,Al<7%(CIF) `, // 重名
  72. // Url: "https://hq.smm.cn/ajax/spot/history/202109140006",
  73. // Frequency: "日度",
  74. // Unit: "美元/湿吨",
  75. // },
  76. // {
  77. // Name: `菲律宾红土镍矿1.3%(CIF)`,
  78. // Url: "https://hq.smm.cn/ajax/spot/history/202109140001",
  79. // Frequency: "日度",
  80. // Unit: "美元/湿吨",
  81. // },
  82. // {
  83. // Name: `菲律宾红土镍矿1.4%(CIF)`,
  84. // Url: "https://hq.smm.cn/ajax/spot/history/202109140003",
  85. // Frequency: "日度",
  86. // Unit: "美元/湿吨",
  87. // },
  88. {
  89. Name: `菲律宾红土镍矿1.5%(CIF)`,
  90. Url: "https://hq.smm.cn/ajax/spot/history/201608170002",
  91. Frequency: "日度",
  92. Unit: "美元/湿吨",
  93. },
  94. {
  95. Name: `红土镍矿1.8%(CIF)`,
  96. Url: "https://hq.smm.cn/ajax/spot/history/201608170003",
  97. Frequency: "日度",
  98. Unit: "美元/湿吨",
  99. },
  100. {
  101. Name: `菲律宾红土镍矿0.9%,Al≥7%(FOB)`,
  102. Url: "https://hq.smm.cn/ajax/spot/history/201509220001",
  103. Frequency: "日度",
  104. Unit: "美元/湿吨",
  105. },
  106. // {
  107. // Name: `菲律宾红土镍矿0.9%,Al<7%(FOB)`, //重名
  108. // Url: "https://hq.smm.cn/ajax/spot/history/202109140005",
  109. // Frequency: "日度",
  110. // Unit: "美元/湿吨",
  111. // },
  112. // {
  113. // Name: `菲律宾红土镍矿1.3%(FOB)`,
  114. // Url: "https://hq.smm.cn/ajax/spot/history/202109140002",
  115. // Frequency: "日度",
  116. // Unit: "美元/湿吨",
  117. // },
  118. // {
  119. // Name: `菲律宾红土镍矿1.4%(FOB)`,
  120. // Url: "https://hq.smm.cn/ajax/spot/history/202109140004",
  121. // Frequency: "日度",
  122. // Unit: "美元/湿吨",
  123. // },
  124. {
  125. Name: `菲律宾红土镍矿1.5%(FOB)`,
  126. Url: "https://hq.smm.cn/ajax/spot/history/201509220002",
  127. Frequency: "日度",
  128. Unit: "美元/湿吨",
  129. },
  130. {
  131. Name: `红土镍矿1.8%(FOB)`,
  132. Url: "https://hq.smm.cn/ajax/spot/history/201509220003",
  133. Frequency: "日度",
  134. Unit: "美元/湿吨",
  135. },
  136. {
  137. Name: `8-12%高镍生铁(出厂价)`,
  138. Url: "https://hq.smm.cn/ajax/spot/history/201106150005",
  139. Frequency: "日度",
  140. Unit: "元/镍点",
  141. },
  142. {
  143. Name: `1.5-1.7%镍生铁(出厂价)`,
  144. Url: "https://hq.smm.cn/ajax/spot/history/201106150007",
  145. Frequency: "日度",
  146. Unit: "元/吨",
  147. },
  148. }
  149. var copperReqs = []SmmRequest{
  150. {
  151. Name: "SMM 1#电解铜",
  152. Url: "https://hq.smm.cn/ajax/spot/history/201102250376",
  153. Unit: "元/吨",
  154. Frequency: "日度",
  155. },
  156. {
  157. Name: "SMM 1#电解铜升贴水最大值",
  158. Url: "https://hq.smm.cn/ajax/premium/history/201102250185",
  159. Value: "highs",
  160. Frequency: "日度",
  161. },
  162. {
  163. Name: "SMM 1#电解铜升贴水最小值",
  164. Url: "https://hq.smm.cn/ajax/premium/history/201102250185",
  165. Value: "low",
  166. Frequency: "日度",
  167. },
  168. // {
  169. // Name: "SMM 广东1#电解铜",
  170. // Url: "https://hq.smm.cn/ajax/spot/history/201912300001",
  171. // Unit: "元/吨",
  172. // Frequency: "日度",
  173. // },
  174. {
  175. Name: "SMM 广东1#电解铜升贴水最大值",
  176. Url: "https://hq.smm.cn/ajax/premium/history/201912300002",
  177. Value: "highs",
  178. Frequency: "日度",
  179. },
  180. {
  181. Name: "SMM 广东1#电解铜升贴水最小值",
  182. Url: "https://hq.smm.cn/ajax/premium/history/201912300002",
  183. Value: "low",
  184. Frequency: "日度",
  185. },
  186. {
  187. Name: "进口铜精矿指数(周)",
  188. Url: "https://hq.smm.cn/ajax/spot/history/201910240001",
  189. Unit: "美元/吨",
  190. Frequency: "周度",
  191. },
  192. {
  193. Name: "废铜:广东:1#光亮铜线",
  194. Url: "https://hq.smm.cn/ajax/spot/history/201108090036",
  195. Unit: "元/吨",
  196. Frequency: "日度",
  197. },
  198. }
  199. var zincReqs = []SmmRequest{
  200. {
  201. Name: "SMM 0#锌锭",
  202. Url: "https://hq.smm.cn/ajax/spot/history/201102250173",
  203. Unit: "元/吨",
  204. Frequency: "日度",
  205. },
  206. {
  207. Name: "SMM 1#锌锭",
  208. Url: "https://hq.smm.cn/ajax/spot/history/201102250418",
  209. Unit: "元/吨",
  210. Frequency: "日度",
  211. },
  212. // {
  213. // Name: "SMM 0#锌锭溢价(广东)",
  214. // Url: "https://hq.smm.cn/ajax/spot/history/202010210003",
  215. // Unit: "元/吨",
  216. // Frequency: "日度",
  217. // },
  218. {
  219. Name: "SMM 0#锌锭(广东)",
  220. Url: "https://hq.smm.cn/ajax/spot/history/201102250231",
  221. Unit: "元/吨",
  222. Frequency: "日度",
  223. },
  224. // {
  225. // Name: "SMM 1#锌锭溢价(广东)",
  226. // Url: "https://hq.smm.cn/ajax/spot/history/202010210004",
  227. // Unit: "元/吨",
  228. // Frequency: "日度",
  229. // },
  230. {
  231. Name: "SMM 1#锌锭(广东)",
  232. Url: "https://hq.smm.cn/ajax/spot/history/201102250069",
  233. Unit: "元/吨",
  234. Frequency: "日度",
  235. },
  236. // {
  237. // Name: "SMM 0#锌锭溢价(天津)",
  238. // Url: "https://hq.smm.cn/ajax/spot/history/202010210001",
  239. // Unit: "元/吨",
  240. // Frequency: "日度",
  241. // },
  242. {
  243. Name: "SMM 1#锌锭(天津)",
  244. Url: "https://hq.smm.cn/ajax/spot/history/201102250556",
  245. Unit: "元/吨",
  246. Frequency: "日度",
  247. },
  248. {
  249. Name: "SMM 0#锌锭(天津)",
  250. Url: "https://hq.smm.cn/ajax/spot/history/201102250399",
  251. Unit: "元/吨",
  252. Frequency: "日度",
  253. },
  254. // {
  255. // Name: "SMM 1#锌锭溢价(天津)",
  256. // Url: "https://hq.smm.cn/ajax/spot/history/202010210002",
  257. // Unit: "元/吨",
  258. // Frequency: "日度",
  259. // },
  260. // {
  261. // Name: "SMM 0#锌锭溢价(宁波)",
  262. // Url: "https://hq.smm.cn/ajax/spot/history/202010210005",
  263. // Unit: "元/吨",
  264. // Frequency: "日度",
  265. // },
  266. // {
  267. // Name: "SMM 0#锌锭(宁波)",
  268. // Url: "https://hq.smm.cn/ajax/spot/history/202004070006",
  269. // Unit: "元/吨",
  270. // Frequency: "日度",
  271. // },
  272. // {
  273. // Name: "Zn50国产TC(月)",
  274. // Url: "https://hq.smm.cn/ajax/spot/history/201312030008",
  275. // Unit: "元/金属吨",
  276. // Frequency: "月度",
  277. // },
  278. // {
  279. // Name: "Zn50进口TC(月)",
  280. // Url: "https://hq.smm.cn/ajax/spot/history/201312030009",
  281. // Unit: "美元/千吨",
  282. // Frequency: "月度",
  283. // },
  284. {
  285. Name: "Zn50国产TC(周)",
  286. Url: "https://hq.smm.cn/ajax/spot/history/202004070002",
  287. Unit: "元/金属吨",
  288. Frequency: "周度",
  289. },
  290. {
  291. Name: "Zn50进口TC(周)",
  292. Url: "https://hq.smm.cn/ajax/spot/history/202004070001",
  293. Unit: "美元/千吨",
  294. Frequency: "周度",
  295. },
  296. {
  297. Name: "Zn50内蒙古国产TC(周)",
  298. Url: "https://hq.smm.cn/ajax/spot/history/201504080006",
  299. Unit: "元/金属吨",
  300. Frequency: "周度",
  301. },
  302. {
  303. Name: "Zn50陕西国产TC(周)",
  304. Url: "https://hq.smm.cn/ajax/spot/history/201504080007",
  305. Unit: "元/金属吨",
  306. Frequency: "周度",
  307. },
  308. {
  309. Name: "Zn50甘肃国产TC(周)",
  310. Url: "https://hq.smm.cn/ajax/spot/history/202108050001",
  311. Unit: "元/金属吨",
  312. Frequency: "周度",
  313. },
  314. {
  315. Name: "Zn50四川国产TC(周)",
  316. Url: "https://hq.smm.cn/ajax/spot/history/201504080008",
  317. Unit: "元/金属吨",
  318. Frequency: "周度",
  319. },
  320. {
  321. Name: "Zn50广西国产TC(周)",
  322. Url: "https://hq.smm.cn/ajax/spot/history/201504080009",
  323. Unit: "元/金属吨",
  324. Frequency: "周度",
  325. },
  326. {
  327. Name: "Zn50云南国产TC(周)",
  328. Url: "https://hq.smm.cn/ajax/spot/history/201504080010",
  329. Unit: "元/金属吨",
  330. Frequency: "周度",
  331. },
  332. {
  333. Name: "Zn50湖南国产TC(周)",
  334. Url: "https://hq.smm.cn/ajax/spot/history/201504080011",
  335. Unit: "元/金属吨",
  336. Frequency: "周度",
  337. },
  338. }
  339. type SmmResponse struct {
  340. Code int
  341. Data []*SmmData
  342. Msg string
  343. }
  344. type SmmData struct {
  345. Highs float64 `json:"highs"`
  346. Low float64 `json:"low"`
  347. Average float64 `json:"average"`
  348. VchangeRate float64 `json:"vchange_rate"`
  349. LowShow string `json:"low_show"`
  350. HighShow string `json:"high_show"`
  351. AverageShow string `json:"average_show"`
  352. ProductId string `json:"product_id"`
  353. Vchange float64 `json:"vchange"`
  354. RenewDate string `json:"renew_date"`
  355. ChangeValueShow string `json:"change_value_show"`
  356. ChangeRateShow string `json:"change_rate_show"`
  357. }
  358. type EdbInfoData struct {
  359. ClassifyName string
  360. IndexName string
  361. IndexCode string
  362. Frequency string
  363. Unit string
  364. Value string
  365. LastDate time.Time
  366. OldDate time.Time
  367. Data map[string]float64
  368. SmmData
  369. }
  370. func SyncShangHaiSmm(cont context.Context) (err error) {
  371. upMonth := time.Now().AddDate(0, -1, 0).Format(utils.FormatDate)
  372. curDate := time.Now().Format(utils.FormatDate)
  373. reqList := make([]SmmRequest, 0)
  374. reqList = append(reqList, zincReqs...)
  375. reqList = append(reqList, copperReqs...)
  376. reqList = append(reqList, nickelReqs...)
  377. edbInfoList := make([]*EdbInfoData, 0)
  378. for _, v := range reqList {
  379. url := fmt.Sprintf("%s/%s/%s", v.Url, upMonth, curDate)
  380. req, e := http.NewRequest("GET", url, nil)
  381. if e != nil {
  382. fmt.Println(e)
  383. return
  384. }
  385. // 发送请求
  386. client := &http.Client{}
  387. resp, e := client.Do(req)
  388. if e != nil {
  389. fmt.Println(e)
  390. return
  391. }
  392. var respData SmmResponse
  393. body, er := io.ReadAll(resp.Body)
  394. if er != nil {
  395. fmt.Println(er)
  396. return er
  397. }
  398. if err = json.Unmarshal(body, &respData); err != nil {
  399. fmt.Println(err)
  400. return
  401. }
  402. if respData.Code != 0 {
  403. fmt.Printf("上海有色爬虫请求失败, 指标名称:%s, 指标地址:%s", v.Name, v.Url)
  404. continue
  405. }
  406. data := respData.Data
  407. edbInfoList = append(edbInfoList, &EdbInfoData{
  408. IndexName: v.Name,
  409. Frequency: v.Frequency,
  410. Unit: v.Unit,
  411. Value: v.Value,
  412. SmmData: *data[len(data)-1],
  413. })
  414. }
  415. urlStr := `shanghai_smm/refresh/list`
  416. postUrl := utils.EDB_LIB_URL + urlStr
  417. postData, err := json.Marshal(edbInfoList)
  418. if err != nil {
  419. utils.FileLog.Info("Marshal Err:" + err.Error())
  420. return
  421. }
  422. result, err := sci99.HttpPost(postUrl, string(postData), "application/json")
  423. if err != nil {
  424. utils.FileLog.Info("HttpPost Err:" + err.Error())
  425. return
  426. }
  427. resp := new(models.BaseResponse)
  428. err = json.Unmarshal(result, &resp)
  429. if err != nil {
  430. fmt.Println(err)
  431. utils.FileLog.Info("Unmarshal resp Err:" + err.Error())
  432. return
  433. }
  434. if resp.Ret != 200 {
  435. fmt.Println("上海有色爬虫更新失败")
  436. return
  437. }
  438. return
  439. }
  440. // 解析读取历史excel数据,将历史数据转化为Smm结构体
  441. func ExcelToSmm(f *excelize.File, s string) (edbInfoList []*EdbInfoData) {
  442. cols, err := f.GetCols(s)
  443. if err != nil {
  444. fmt.Println(err)
  445. return
  446. }
  447. date := cols[0][4:]
  448. dateFormat := make([]string, 0)
  449. for _, v := range date {
  450. if v == "" {
  451. continue
  452. }
  453. var parseDate time.Time
  454. var err error
  455. // 表格的日期存在两种格式
  456. if strings.Contains(s, "锌") {
  457. parseDate, err = time.Parse(utils.FormatDate, v)
  458. if err != nil {
  459. parseDate, err = time.Parse("01-02-06", v)
  460. }
  461. } else {
  462. parseDate, err = time.Parse("01-02-06", v)
  463. if err != nil {
  464. parseDate, err = time.Parse(utils.FormatDate, v)
  465. }
  466. }
  467. if err != nil {
  468. fmt.Println(err)
  469. return
  470. }
  471. dateFormat = append(dateFormat, parseDate.Format(utils.FormatDate))
  472. }
  473. for i := 1; i < len(cols); i++ {
  474. tmpEdbInfo := new(EdbInfoData)
  475. tmpEdbInfo.IndexName = cols[i][0]
  476. tmpEdbInfo.IndexCode = cols[i][1]
  477. tmpEdbInfo.Frequency = cols[i][2]
  478. tmpEdbInfo.Unit = cols[i][3]
  479. tmpEdbInfo.Data = make(map[string]float64)
  480. tmpEdbInfo.OldDate = time.Now()
  481. for j := 4; j < len(cols[i]); j++ {
  482. floatVal, err := strconv.ParseFloat(cols[i][j], 64)
  483. if err != nil {
  484. fmt.Println("无效字符", cols[i][j])
  485. continue
  486. }
  487. tmpEdbInfo.Data[dateFormat[j-4]] = floatVal
  488. curTime, _ := time.Parse(utils.FormatDate, dateFormat[j-4])
  489. if curTime.After(tmpEdbInfo.LastDate) {
  490. tmpEdbInfo.LastDate = curTime
  491. }
  492. if curTime.Before(tmpEdbInfo.OldDate) {
  493. tmpEdbInfo.OldDate = curTime
  494. }
  495. }
  496. edbInfoList = append(edbInfoList, tmpEdbInfo)
  497. }
  498. return
  499. }
  500. func SyncOldExcel(ctx context.Context) error {
  501. fmt.Println("excel数据录入中")
  502. err := OldExcel()
  503. if err != nil {
  504. fmt.Println(err)
  505. utils.FileLog.Info(err.Error())
  506. return err
  507. }
  508. fmt.Println("excel数据录入成功")
  509. task.DeleteTask("shanghaiOldExcel")
  510. return nil
  511. }
  512. func OldExcel() (err error) {
  513. excelPath := utils.OLD_EXCEL_PATH_JR
  514. if excelPath == "" {
  515. fmt.Println("excel文件路径为空")
  516. return
  517. }
  518. f, err := excelize.OpenFile(excelPath)
  519. if err != nil {
  520. fmt.Print(err)
  521. return
  522. }
  523. var edbClassify = []string{`镍`, `铜`, `锌`, `锌(日度)`}
  524. for _, v := range edbClassify {
  525. edbInfoList := ExcelToSmm(f, v)
  526. _, err = json.Marshal(edbInfoList)
  527. if err != nil {
  528. fmt.Println(err)
  529. return
  530. }
  531. fmt.Println("成功:", v)
  532. urlStr := `shanghai_smm/refresh/excel`
  533. postUrl := utils.EDB_LIB_URL + urlStr
  534. postData, er := json.Marshal(edbInfoList)
  535. if er != nil {
  536. err = er
  537. utils.FileLog.Info("Marshal Err:" + er.Error())
  538. return
  539. }
  540. result, er := sci99.HttpPost(postUrl, string(postData), "application/json")
  541. if er != nil {
  542. err = er
  543. utils.FileLog.Info("HttpPost Err:" + er.Error())
  544. return
  545. }
  546. resp := new(models.BaseResponse)
  547. err = json.Unmarshal(result, &resp)
  548. if err != nil {
  549. utils.FileLog.Info("Unmarshal resp Err:" + err.Error())
  550. return
  551. }
  552. if resp.Ret != 200 {
  553. err = errors.New(resp.ErrMsg)
  554. utils.FileLog.Info("上海有色网excel历史有色数据更新失败")
  555. return
  556. }
  557. time.Sleep(time.Second)
  558. }
  559. return
  560. }