usda_psd.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. package services
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "eta/eta_crawler/services/alarm_msg"
  6. "eta/eta_crawler/utils"
  7. "fmt"
  8. "github.com/PuerkitoBio/goquery"
  9. "github.com/tealeg/xlsx"
  10. "io"
  11. "mime/multipart"
  12. "net/http"
  13. "os"
  14. "strconv"
  15. "strings"
  16. "time"
  17. )
  18. // UsdaPsdDataQueryParams 定义了JSON到Go结构体的映射
  19. type UsdaPsdDataQueryParams struct {
  20. QueryID int `json:"queryId"`
  21. CommodityGroupCode string `json:"commodityGroupCode"`
  22. Commodities []string `json:"commodities"`
  23. Attributes []int `json:"attributes"`
  24. Countries []string `json:"countries"`
  25. MarketYears []int `json:"marketYears"`
  26. ChkCommoditySummary bool `json:"chkCommoditySummary"`
  27. ChkAttribSummary bool `json:"chkAttribSummary"`
  28. ChkCountrySummary bool `json:"chkCountrySummary"`
  29. CommoditySummaryText string `json:"commoditySummaryText"`
  30. AttribSummaryText string `json:"attribSummaryText"`
  31. CountrySummaryText string `json:"countrySummaryText"`
  32. OptionColumn string `json:"optionColumn"`
  33. ChkTopCountry bool `json:"chkTopCountry"`
  34. TopCountryCount string `json:"topCountryCount"`
  35. ChkFileFormat bool `json:"chkfileFormat"`
  36. ChkPrevMonth bool `json:"chkPrevMonth"`
  37. ChkMonthChange bool `json:"chkMonthChange"`
  38. ChkCodes bool `json:"chkCodes"`
  39. ChkYearChange bool `json:"chkYearChange"`
  40. QueryName string `json:"queryName"`
  41. SortOrder string `json:"sortOrder"`
  42. TopCountryState bool `json:"topCountryState"`
  43. }
  44. type UsdaPsdData struct {
  45. TableHeaders []string `json:"tableHeaders"`
  46. QueryResult []map[string]interface{} `json:"queryResult"`
  47. }
  48. type UsdaPsdDataAttribute struct {
  49. AttributeId int `json:"attributeId"`
  50. }
  51. // UsdaFasIndex 美国农业部指标数据
  52. type UsdaFasIndex struct {
  53. ClassifyName string `description:"指标目录"`
  54. ParentClassifyName string `description:"父级指标目录"`
  55. ClassifySort int `description:"指标目录排序号"`
  56. IndexName string `description:"指标名称"`
  57. IndexCode string `description:"指标编码"`
  58. Unit string `description:"单位"`
  59. Sort int `description:"排序号"`
  60. Frequency string `description:"频度"`
  61. TerminalCode string `description:"编码"`
  62. ExcelDataMap map[string]string
  63. }
  64. // Meal, Palm Kernel:0813800
  65. // Meal, Peanut:0813200
  66. // Meal, Rapeseed:0813600
  67. // Meal, Soybean:0813100
  68. // Meal, Sunflowerseed:0813500
  69. // Oil, Coconut:4242000
  70. // Oil, Cottonseed:4233000
  71. // Oil, Olive:4235000
  72. // Oil, Palm:4243000
  73. // Oil, Palm Kernel:4244000
  74. // Oil, Peanut:4234000
  75. // Oil, Rapeseed:4239100
  76. // Oil, Soybean:4232000
  77. // Oil, Sunflowerseed:4236000
  78. // Oilseed, Cottonseed:2223000
  79. // Oilseed, Palm Kernel:2232000
  80. // Oilseed, Peanut:2221000
  81. // Oilseed, Rapeseed:2226000
  82. // Oilseed, Soybean:2222000
  83. // Oilseed, Sunflowerseed:2224000
  84. // 美国农业部月度供需平衡表数据
  85. func DownloadUsdaPsdData() (indexList []*UsdaFasIndex, err error) {
  86. // 从test.json文件中读取json串
  87. /*body, err := ioutil.ReadFile("test.json")
  88. if err != nil {
  89. return
  90. }
  91. // 解析json串
  92. item := new(UsdaPsdData)
  93. err = json.Unmarshal(body, &item)
  94. if err != nil {
  95. fmt.Println("json.Unmarshal err:" + err.Error())
  96. return
  97. }
  98. indexList, err = handleUsdaFasPsd(item)
  99. return*/
  100. defer func() {
  101. if err != nil {
  102. msg := "失败提醒" + "downloadUsdaPsdData ErrMsg:" + err.Error()
  103. fmt.Println("msg:", msg)
  104. utils.FileLog.Info(msg)
  105. go alarm_msg.SendAlarmMsg(msg, 3)
  106. }
  107. }()
  108. // 定义请求地址
  109. attributeUrl := "https://apps.fas.usda.gov/PSDOnlineApi/api/query/GetMultiCommodityAttributes?"
  110. dataUrl := "https://apps.fas.usda.gov/PSDOnlineApi/api/query/RunQuery"
  111. var commodities []string
  112. commodities = append(commodities, "0813800", "0813200", "0813600", "0813100", "0813500", "4242000", "4233000", "4235000", "4243000", "4244000", "4234000", "4239100", "4232000", "4236000", "2223000", "2232000", "2221000", "2226000", "2222000", "2224000")
  113. //commodities = append(commodities, "0430000")
  114. commodityCodes := strings.Join(commodities, ",")
  115. attributeUrl = attributeUrl + "commodityCodes=" + commodityCodes
  116. // 定义请求参数
  117. // 获取属性入参
  118. attributeBody, e := utils.HttpGetNoCookie(attributeUrl)
  119. if e != nil {
  120. err = e
  121. return
  122. }
  123. attrList := make([]UsdaPsdDataAttribute, 0)
  124. err = json.Unmarshal(attributeBody, &attrList)
  125. if err != nil {
  126. fmt.Println("json.Unmarshal err:" + err.Error())
  127. return
  128. }
  129. // 解析
  130. var attributes []int
  131. for _, v := range attrList {
  132. // 键值对的值
  133. attributes = append(attributes, v.AttributeId)
  134. }
  135. // 定义请求方法
  136. //attributes = append(attributes, 4, 20, 28, 57, 81, 84, 86, 88, 113, 130, 192, 125, 176, 178, 184)
  137. var countries []string
  138. countries = append(countries, "R00", "ALL")
  139. var marketYears []int
  140. marketYears = append(marketYears, 2024, 2023, 2022, 2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014)
  141. // {"queryId":0,"commodityGroupCode":null,"commodities":["0430000"],"attributes":[4,20,28,57,81,84,86,88,113,130,192,125,176,178,184],"countries":["R00","ALL"],"marketYears":[2024,2023,2022,2021,2020,2019,2018,2017,2016,2015,2014],"chkCommoditySummary":false,"chkAttribSummary":false,"chkCountrySummary":false,"commoditySummaryText":"","attribSummaryText":"","countrySummaryText":"","optionColumn":"year","chkTopCountry":false,"topCountryCount":"","chkfileFormat":false,"chkPrevMonth":true,"chkMonthChange":false,"chkCodes":false,"chkYearChange":false,"queryName":"","sortOrder":"Commodity/Attribute/Country","topCountryState":false}
  142. var req UsdaPsdDataQueryParams
  143. req.Commodities = commodities
  144. req.Attributes = attributes
  145. req.Countries = countries
  146. req.MarketYears = marketYears
  147. req.OptionColumn = "year"
  148. //req.ChkPrevMonth = true
  149. req.SortOrder = "Commodity/Country/Attribute"
  150. // 构造httppost请求
  151. reqBody, _ := json.Marshal(req)
  152. // 解析返回值
  153. headerParams := make(map[string]string)
  154. //headerParams["Cookie"] = "CT6T=312900; SF_cookie_3=68941398"
  155. //headerParams["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
  156. headerParams["Content-Type"] = "application/json"
  157. body, e := utils.HttpPostNoCookie(dataUrl, string(reqBody), headerParams)
  158. if e != nil {
  159. err = e
  160. return
  161. }
  162. item := new(UsdaPsdData)
  163. err = json.Unmarshal(body, &item)
  164. if err != nil {
  165. fmt.Println("json.Unmarshal err:" + err.Error())
  166. return
  167. }
  168. indexList, err = handleUsdaFasPsd(item)
  169. return
  170. }
  171. // 美国农业出库销售数据
  172. func DownloadUsdaFmsData() (indexList []*UsdaFasIndex, err error) {
  173. // todo 设置下载频率, 如果有正在处理中的,则暂停下载
  174. defer func() {
  175. if err != nil {
  176. msg := "失败提醒" + "DownloadUsdaFmsData ErrMsg:" + err.Error()
  177. fmt.Println("msg:", msg)
  178. utils.FileLog.Info(msg)
  179. go alarm_msg.SendAlarmMsg(msg, 3)
  180. }
  181. }()
  182. downloadFile := "downloaded_excel.xlsx"
  183. //请求首页,获取入参
  184. dataUrl := "https://apps.fas.usda.gov/esrquery/esrq.aspx"
  185. body1, err := utils.HttpGetNoCookie(dataUrl)
  186. if err != nil {
  187. return
  188. }
  189. htmlString := string(body1)
  190. // 解析返回值,截取htmlinput标签,input标签里,id=“__EVENTVALIDATION”的input标签里的值
  191. // 使用goquery读取HTML字符串
  192. doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlString))
  193. if err != nil {
  194. return
  195. }
  196. stateValue := doc.Find("input#__VIEWSTATE").AttrOr("value", "")
  197. stateEneratorValue := doc.Find("input#__VIEWSTATEGENERATOR").AttrOr("value", "")
  198. // 查询并获取input标签的值
  199. validValue := doc.Find("input#__EVENTVALIDATION").AttrOr("value", "")
  200. var body bytes.Buffer
  201. multipartWriter := multipart.NewWriter(&body)
  202. // 添加表单字段(如果需要的话)
  203. if err = multipartWriter.WriteField("__EVENTTARGET", ""); err != nil {
  204. err = fmt.Errorf("set __EVENTTARGET, Err:%s", err)
  205. return
  206. }
  207. if err = multipartWriter.WriteField("__EVENTARGUMENT", ""); err != nil {
  208. err = fmt.Errorf("set __EVENTARGUMENT, Err:%s", err)
  209. return
  210. }
  211. if err = multipartWriter.WriteField("__LASTFOCUS", ""); err != nil {
  212. err = fmt.Errorf("set __LASTFOCUS, Err:%s", err)
  213. return
  214. }
  215. if err = multipartWriter.WriteField("__VIEWSTATE", stateValue); err != nil {
  216. err = fmt.Errorf("set __VIEWSTATE, Err:%s", err)
  217. return
  218. }
  219. if err = multipartWriter.WriteField("__VIEWSTATEGENERATOR", stateEneratorValue); err != nil {
  220. err = fmt.Errorf("set __VIEWSTATEGENERATOR, Err:%s", err)
  221. return
  222. }
  223. if err = multipartWriter.WriteField("__EVENTVALIDATION", validValue); err != nil {
  224. err = fmt.Errorf("set __EVENTVALIDATION, Err:%s", err)
  225. return
  226. }
  227. //整理需要下载的品种ID
  228. //Soybeans:801,Soybean cake & meal:901,Soybean Oil:902
  229. CommodityIds := []string{"801", "901", "902"}
  230. for _, v := range CommodityIds {
  231. if err = multipartWriter.WriteField("ctl00$MainContent$lbCommodity", v); err != nil {
  232. err = fmt.Errorf("set ctl00$MainContent$lbCommodity, Err:%s", err)
  233. return
  234. }
  235. }
  236. // todo 下载的日期
  237. startDate := "08/22/2019"
  238. endDate := "08/22/2024"
  239. if err = multipartWriter.WriteField("ctl00$MainContent$lbCountry", "0:0"); err != nil {
  240. err = fmt.Errorf("set ctl00$MainContent$lbCountry, Err:%s", err)
  241. return
  242. }
  243. if err = multipartWriter.WriteField("ctl00$MainContent$ddlReportFormat", "10"); err != nil {
  244. return
  245. }
  246. if err = multipartWriter.WriteField("ctl00$MainContent$rblOutputType", "2"); err != nil {
  247. return
  248. }
  249. if err = multipartWriter.WriteField("ctl00$MainContent$tbStartDate", startDate); err != nil {
  250. return
  251. }
  252. if err = multipartWriter.WriteField("ctl00$MainContent$tbEndDate", endDate); err != nil {
  253. return
  254. }
  255. if err = multipartWriter.WriteField("ctl00$MainContent$rblColumnSelection", "regular"); err != nil {
  256. return
  257. }
  258. if err = multipartWriter.WriteField("ctl00$MainContent$btnSubmit", "Submit"); err != nil {
  259. return
  260. }
  261. // 注意:如果接口需要文件上传,这里应该使用multipartWriter.CreateFormFile来添加文件
  262. // 关闭multipart writer以添加最后的边界
  263. if err = multipartWriter.Close(); err != nil {
  264. err = fmt.Errorf("close multipart writer, Err:%s", err)
  265. return
  266. }
  267. // 构造请求
  268. req, err := http.NewRequest("POST", dataUrl, &body)
  269. if err != nil {
  270. err = fmt.Errorf("create request, Err:%s", err)
  271. return
  272. }
  273. // 设置请求头
  274. req.Header.Set("Content-Type", multipartWriter.FormDataContentType())
  275. // 发送请求
  276. client := &http.Client{}
  277. resp, err := client.Do(req)
  278. if err != nil {
  279. err = fmt.Errorf("send request, Err:%s", err)
  280. return
  281. }
  282. defer resp.Body.Close()
  283. // 检查响应状态码
  284. if resp.StatusCode != http.StatusOK {
  285. err = fmt.Errorf("unexpected status code: %d", resp.StatusCode)
  286. return
  287. }
  288. // 读取响应体
  289. out, err := os.Create(downloadFile)
  290. if err != nil {
  291. return
  292. }
  293. defer out.Close()
  294. // 将响应体写入到文件
  295. _, err = io.Copy(out, resp.Body)
  296. if err != nil {
  297. return
  298. }
  299. go func() {
  300. err = ParseUsdaFmsExcel(downloadFile)
  301. fmt.Println("Excel file downloaded successfully")
  302. }()
  303. return
  304. }
  305. func ParseUsdaFmsExcel(path string) (err error) {
  306. var xlFile *xlsx.File
  307. exist, err := PathExists(path)
  308. if err != nil {
  309. fmt.Println(err)
  310. err = fmt.Errorf("文件地址不存在 err:%s", err.Error())
  311. return
  312. }
  313. if !exist {
  314. err = fmt.Errorf("文件地址不存在")
  315. return
  316. }
  317. xlFile, err = xlsx.OpenFile(path)
  318. if err != nil {
  319. fmt.Println("OpenFile err:", err)
  320. err = fmt.Errorf("打开文件失败 err:%s", err.Error())
  321. return
  322. }
  323. //解析出表头第7行
  324. //拼接指标名称
  325. // 指标名称
  326. indexMap := make(map[string]*UsdaFasIndex)
  327. indexList := make([]*UsdaFasIndex, 0)
  328. sort := 0
  329. for _, sheet := range xlFile.Sheets {
  330. //遍历行读取
  331. maxCol := sheet.MaxCol
  332. for i := 0; i < maxCol; i++ {
  333. if i > 6 {
  334. row := sheet.Row(i)
  335. cells := row.Cells
  336. commodity := ""
  337. dateStr := ""
  338. country := ""
  339. dataVal := ""
  340. unit := "Metric Tons"
  341. for k, cell := range cells {
  342. text := cell.String()
  343. kind := ""
  344. indexName := ""
  345. if k == 1 { // 品种名称Commodity
  346. commodity = text
  347. } else if k == 2 {
  348. dateStr = text
  349. } else if k == 4 {
  350. country = text
  351. } else if k == 5 {
  352. kind = "Weekly Exports"
  353. } else if k == 6 {
  354. kind = "Accum Exports"
  355. } else if k == 7 {
  356. kind = "Outstanding Sale:CMY"
  357. } else if k == 8 {
  358. kind = "Gross Sale:CMY"
  359. } else if k == 9 {
  360. kind = "Net Sale :CMY"
  361. } else if k == 10 {
  362. kind = "Total Commitment:CMY"
  363. } else if k == 11 {
  364. kind = "Outstanding Sale:NMY"
  365. } else if k == 12 {
  366. kind = "Net Sale :NMY"
  367. }
  368. if k > 4 && k < 13 {
  369. // 处理日期
  370. fmt.Println(dateStr)
  371. fmt.Println(unit)
  372. timeT, e := time.ParseInLocation("01\\/02\\/2006", dateStr, time.Local)
  373. if e != nil {
  374. utils.FileLog.Info("日期格式转换失败 err:%s", e.Error())
  375. continue
  376. }
  377. date := timeT.Format(utils.FormatDate)
  378. dataVal = text
  379. indexName = fmt.Sprintf("%s: %s: %s", commodity, country, kind)
  380. inCode := "usda" + utils.GetFirstLetter(indexName)
  381. indexItem, okIndex := indexMap[indexName]
  382. // 首字母大写
  383. classifyName := commodity
  384. if !okIndex {
  385. // 新增指标
  386. indexItem = new(UsdaFasIndex)
  387. indexItem.IndexName = indexName
  388. indexItem.ClassifyName = classifyName
  389. indexItem.ParentClassifyName = "出口销售"
  390. indexItem.ClassifySort = 0
  391. indexItem.IndexCode = inCode
  392. indexItem.Frequency = "周度"
  393. indexItem.Sort = sort
  394. indexItem.Unit = unit
  395. indexItem.ExcelDataMap = make(map[string]string)
  396. sort++
  397. }
  398. val, e := strconv.ParseFloat(dataVal, 64)
  399. if e != nil {
  400. utils.FileLog.Info("数据转换失败 err:%s", e.Error())
  401. continue
  402. }
  403. indexItem.ExcelDataMap[date] = fmt.Sprintf("%.4f", val)
  404. indexMap[indexName] = indexItem
  405. }
  406. }
  407. }
  408. }
  409. }
  410. for _, v := range indexMap {
  411. fmt.Printf("IndexName: %s \n", v.IndexName)
  412. fmt.Printf("IndexCode: %s \n", v.IndexCode)
  413. indexList = append(indexList, v)
  414. if len(indexList) > 500 {
  415. err = addUsdaFasPsdData(indexList)
  416. if err != nil {
  417. return
  418. }
  419. indexList = []*UsdaFasIndex{}
  420. }
  421. }
  422. err = addUsdaFasPsdData(indexList)
  423. if err != nil {
  424. return
  425. }
  426. return
  427. }
  428. func handleUsdaFasPsd(item *UsdaPsdData) (indexList []*UsdaFasIndex, err error) {
  429. // 解析
  430. headerSlice := make([]string, 0)
  431. for index, v := range item.TableHeaders {
  432. // 键值对的值
  433. fmt.Println("key:", index, "value:", v)
  434. if !strings.Contains(v, "/") && !strings.Contains(v, " ") {
  435. v = strings.ToLower(v)
  436. }
  437. if v == "Unit Description" {
  438. v = "unit Description"
  439. }
  440. headerSlice = append(headerSlice, v)
  441. }
  442. // 解析
  443. // 遍历行读取
  444. indexList = make([]*UsdaFasIndex, 0)
  445. sort := 0
  446. // 指标名称
  447. indexMap := make(map[string]*UsdaFasIndex)
  448. // 键值对的值
  449. commodityRow := ""
  450. countriesRow := ""
  451. attributesRow := ""
  452. errMsg := ""
  453. for _, row := range item.QueryResult {
  454. unitK := headerSlice[len(headerSlice)-1]
  455. unit := row[unitK].(string)
  456. // unit 去掉左右两边的括号,去掉中间的空格
  457. unit = strings.Replace(unit, " ", "", -1)
  458. unit = strings.Trim(unit, "()")
  459. for _, k := range headerSlice {
  460. col, ok := row[k]
  461. if !ok || col == nil {
  462. continue
  463. }
  464. if k == "commodity" {
  465. commodityRow = col.(string)
  466. } else if k == "country" {
  467. countriesRow = col.(string)
  468. } else if k == "attribute" {
  469. attributesRow = col.(string)
  470. } else if k == "unit Description" {
  471. // unit = col.(string)
  472. } else {
  473. //数据列
  474. year, _ := strconv.Atoi(strings.Split(k, "/")[0])
  475. month := 0
  476. indexName := ""
  477. classifyName := ""
  478. classifySort := 0
  479. inCode := ""
  480. fre := "年度"
  481. lastStr := "Yearly"
  482. // year年度的最后一天日期
  483. dateT := time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC)
  484. if strings.Contains(k, "(") {
  485. fre = "月度"
  486. lastStr = "Monthly"
  487. // 截取括号中间的月度数据
  488. monthStr := strings.Split(k, "(")[1]
  489. monthStr = strings.Split(monthStr, ")")[0]
  490. // 将Jul英文月份前缀转成数字月份
  491. monthT, e := time.ParseInLocation("Jan", monthStr, time.Local)
  492. if e != nil {
  493. errMsg += fmt.Sprintf("月份转换错误:%s%s\n", monthStr, e.Error())
  494. continue
  495. }
  496. month = int(monthT.Month())
  497. // 将year和month拼接成日期,该月的最后一天日期
  498. dateT = time.Date(year, time.Month(month), 31, 0, 0, 0, 0, time.UTC)
  499. }
  500. date := dateT.Format("2006-01-02")
  501. // 封装成指标数据
  502. if commodityRow != "" && countriesRow != "" && attributesRow != "" {
  503. indexName = commodityRow + ": " + countriesRow + ": " + attributesRow + ": " + lastStr
  504. } else {
  505. fmt.Println("commodityRow:", commodityRow, "countriesRow:", countriesRow, "attributesRow:", attributesRow)
  506. errMsg += fmt.Sprintf("指标名称为空 commodityRow:%s,countriesRow:%s,attributesRow:%s\n", commodityRow, countriesRow, attributesRow)
  507. continue
  508. }
  509. inCode = "usda" + utils.GetFirstLetter(indexName)
  510. indexItem, okIndex := indexMap[indexName]
  511. // 首字母大写
  512. classifyName = commodityRow
  513. if !okIndex {
  514. // 新增指标
  515. indexItem = new(UsdaFasIndex)
  516. indexItem.IndexName = indexName
  517. indexItem.ClassifyName = classifyName
  518. indexItem.ParentClassifyName = "月度供需"
  519. indexItem.ClassifySort = classifySort
  520. indexItem.IndexCode = inCode
  521. indexItem.Frequency = fre
  522. indexItem.Sort = sort
  523. indexItem.Unit = unit
  524. indexItem.ExcelDataMap = make(map[string]string)
  525. sort++
  526. }
  527. val := col.(float64)
  528. indexItem.ExcelDataMap[date] = fmt.Sprintf("%.4f", val)
  529. indexMap[indexName] = indexItem
  530. continue
  531. }
  532. }
  533. }
  534. for _, v := range indexMap {
  535. fmt.Printf("IndexName: %s \n", v.IndexName)
  536. fmt.Printf("IndexCode: %s \n", v.IndexCode)
  537. indexList = append(indexList, v)
  538. if len(indexList) > 500 {
  539. err = addUsdaFasPsdData(indexList)
  540. if err != nil {
  541. return
  542. }
  543. indexList = []*UsdaFasIndex{}
  544. }
  545. }
  546. err = addUsdaFasPsdData(indexList)
  547. if err != nil {
  548. return
  549. }
  550. return
  551. }
  552. func addUsdaFasPsdData(indexList []*UsdaFasIndex) (err error) {
  553. sheetName := "月度供需"
  554. if len(indexList) > 0 {
  555. params := make(map[string]interface{})
  556. params["List"] = indexList
  557. params["TerminalCode"] = ""
  558. result, e := utils.PostEdbLib(params, "usda_fas/handle/excel_data")
  559. if e != nil {
  560. err = fmt.Errorf("sheet :%s PostEdbLib err: %s", sheetName, e.Error())
  561. b, _ := json.Marshal(params)
  562. utils.FileLog.Info(fmt.Sprintf("sheet :%s PostEdbLib err: %s, params: %s", sheetName, e.Error(), string(b)))
  563. return
  564. }
  565. resp := new(utils.BaseEdbLibResponse)
  566. if e := json.Unmarshal(result, &resp); e != nil {
  567. err = fmt.Errorf("sheet :%s json.Unmarshal err: %s", sheetName, e)
  568. utils.FileLog.Info(fmt.Sprintf("sheet :%s json.Unmarshal err: %s", sheetName, e))
  569. return
  570. }
  571. if resp.Ret != 200 {
  572. err = fmt.Errorf("sheet :%s Msg: %s, ErrMsg: %s", sheetName, resp.Msg, resp.ErrMsg)
  573. utils.FileLog.Info(fmt.Sprintf("sheet :%s Msg: %s, ErrMsg: %s", sheetName, resp.Msg, resp.ErrMsg))
  574. return
  575. }
  576. }
  577. return
  578. }