zhongji_smm.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. package index_data
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "eta/eta_bridge/global"
  7. models "eta/eta_bridge/models/edb"
  8. "eta/eta_bridge/models/response"
  9. "eta/eta_bridge/services/alarm_msg"
  10. "eta/eta_bridge/utils"
  11. "fmt"
  12. "io"
  13. "io/ioutil"
  14. "mime/multipart"
  15. netHttp "net/http"
  16. "net/url"
  17. "strconv"
  18. "strings"
  19. "time"
  20. )
  21. // getEdbDataFromSmmHttp 通过url获取SMM的普通数据
  22. func getEdbDataFromSmmHttp(edbCode, token string) (smmBaseDataAll []*models.BaseFromSmmData, err error) {
  23. thsUrl := `https://datapro-api.smm.cn/dapi/quota/data_origin`
  24. //发送创建请求
  25. dataMap := map[string]io.Reader{
  26. "token": strings.NewReader("18815284804"),
  27. "request_source": strings.NewReader("18815284804"),
  28. "quota_ids": strings.NewReader("18815284804"),
  29. "start_date": strings.NewReader("18815284804"),
  30. "end_date": strings.NewReader("18815284804"),
  31. }
  32. body, err, _ := smmPostCurl(thsUrl, dataMap, 0, token)
  33. if err != nil {
  34. return
  35. }
  36. tmpItems := new(response.SmmResponse)
  37. err = json.Unmarshal(body, &tmpItems)
  38. if err != nil {
  39. err = errors.New("GetEdbDataFromSmm json.Unmarshal Err:" + err.Error())
  40. return
  41. }
  42. if tmpItems.Code != 0 {
  43. err = errors.New(tmpItems.Msg)
  44. return
  45. }
  46. for _, quota := range tmpItems.Quota {
  47. for _, v := range quota.Data {
  48. createTime, e := time.Parse(v.Create, utils.FormatDateTime)
  49. if e != nil {
  50. err = errors.New("GetEdbDataFromSmm time.Parse Err:" + e.Error())
  51. return
  52. }
  53. item := &models.BaseFromSmmData{
  54. IndexCode: quota.QuotaID,
  55. DataTime: v.Date,
  56. Value: v.Value,
  57. CreateTime: createTime,
  58. ModifyTime: createTime,
  59. DataTimestamp: createTime.UnixNano() / 1e6,
  60. }
  61. fmt.Println(item)
  62. }
  63. }
  64. return
  65. }
  66. // smmPostCurl post请求同花顺接口
  67. func smmPostCurl(urlStr string, dataMap map[string]io.Reader, num int, token string) (body []byte, err error, errMsg string) {
  68. logMsg := ``
  69. defer func() {
  70. if err != nil {
  71. if logMsg != `` {
  72. errMsg = logMsg
  73. go alarm_msg.SendAlarmMsg("post请求SMM接口失败,ERR:"+err.Error()+";errMsg:"+errMsg, 3)
  74. }
  75. }
  76. }()
  77. // 创建一个新的buffer,用于存储请求体
  78. var reqBody bytes.Buffer
  79. writer := multipart.NewWriter(&reqBody)
  80. // 添加Form-data参数
  81. for key, value := range dataMap {
  82. part, e := writer.CreateFormFile(key, key)
  83. if e != nil {
  84. err = e
  85. fmt.Println("Error creating form file:", err)
  86. return
  87. }
  88. _, err = io.Copy(part, value)
  89. if err != nil {
  90. fmt.Println("Error copying file content:", err)
  91. return
  92. }
  93. }
  94. // 关闭multipart writer
  95. writer.Close()
  96. // 发送POST请求
  97. req, err := netHttp.NewRequest("POST", urlStr, &reqBody)
  98. if err != nil {
  99. fmt.Println("Error creating request:", err)
  100. return
  101. }
  102. req.Header.Set("Content-Type", writer.FormDataContentType())
  103. client := &netHttp.Client{}
  104. resp, err := client.Do(req)
  105. if err != nil {
  106. fmt.Println("Error sending request:", err)
  107. return
  108. }
  109. defer resp.Body.Close()
  110. // 处理响应
  111. fmt.Println("Response Status:", resp.Status)
  112. body, err = ioutil.ReadAll(resp.Body)
  113. if err != nil {
  114. fmt.Println("Error reading response body:", err)
  115. return
  116. }
  117. global.LOG.Info("SMM刷新token:" + string(body))
  118. var response response.SmmResponse
  119. err = json.Unmarshal(body, &response)
  120. if err != nil {
  121. global.LOG.Info("post Err:", err.Error(), ";url:", urlStr, ";response:", string(body))
  122. err = errors.New("Unmarshal Err:" + err.Error())
  123. return
  124. }
  125. global.LOG.Info(fmt.Sprint("post request url:", urlStr, ";token:", token, ";response:", string(body)))
  126. logMsg = fmt.Sprint("post request url:", urlStr, ";token:", token, ";response:", string(body))
  127. //如果是token失效,同时只是第一次请求(没有尝试强制刷新token,那么重新请求)
  128. if utils.InArrayByInt([]int{-10020001, -10020002}, int(response.Code)) && num <= 0 {
  129. //token失效
  130. token, err = refreshSmmAccessToken()
  131. if err != nil {
  132. return
  133. }
  134. num++
  135. return smmPostCurl(urlStr, dataMap, num, token)
  136. } else if response.Code != 0 {
  137. global.LOG.Info(fmt.Sprint("post data err:", response.Msg, ";url:", urlStr, ";response:", string(body)))
  138. err = errors.New(response.Msg)
  139. return
  140. }
  141. return
  142. }
  143. // GetSmmAccessToken 获取accessToken
  144. func GetSmmAccessToken(isRefresh bool) (token string, err error) {
  145. defer func() {
  146. if err != nil {
  147. go alarm_msg.SendAlarmMsg("获取SMM的token失败,ERR:"+err.Error(), 3)
  148. }
  149. }()
  150. redisKey := utils.CACHE_EDB_SMM_SERVER_TOKEN
  151. token, redisErr := global.Rc.RedisString(redisKey)
  152. //如果从redis中accessToken 获取失败或者token为空了,再或者需要强制刷新了,那么重新获取accessToken
  153. if redisErr != nil || token == `` || isRefresh {
  154. token, _ = refreshSmmAccessToken()
  155. return
  156. }
  157. return
  158. }
  159. // refreshSmmAccessToken 强制刷新获取accessToken
  160. func refreshSmmAccessToken() (token string, err error) {
  161. defer func() {
  162. if err != nil {
  163. go alarm_msg.SendAlarmMsg("刷新SMM的token失败;ERR:"+err.Error(), 3)
  164. }
  165. }()
  166. tokenInfo, tmpErr := getSmmAccessToken()
  167. if tmpErr != nil {
  168. err = tmpErr
  169. return
  170. }
  171. token = tokenInfo.Token
  172. //token存入redis
  173. redisKey := utils.CACHE_EDB_SMM_SERVER_TOKEN
  174. err = global.Rc.Put(redisKey, token, time.Hour*24*7)
  175. if err != nil {
  176. err = fmt.Errorf("获取SMM的token成功;SMM token存入redis失败,ERR:%s", err.Error())
  177. return
  178. }
  179. return
  180. }
  181. type GetSmmTokenResp struct {
  182. Code int `json:"code"`
  183. Msg string `json:"msg"`
  184. Data SmmTokenData `json:"data"`
  185. }
  186. type SmmTokenData struct {
  187. Token string `json:"token"`
  188. }
  189. // getSmmAccessToken token内部请求接口
  190. func getSmmAccessToken() (tokenData SmmTokenData, err error) {
  191. defer func() {
  192. if err != nil {
  193. go alarm_msg.SendAlarmMsg("更新SMM的token失败;ERR:"+err.Error(), 3)
  194. }
  195. }()
  196. // 准备Form-data参数
  197. formData := url.Values{
  198. "user_name": {global.CONFIG.Smm.Username},
  199. "password": {utils.MD5(global.CONFIG.Smm.Password)},
  200. "source": {"datapro"},
  201. }
  202. url := "https://datapro-api.smm.cn/dapi/user/auth"
  203. // 创建一个新的buffer,用于存储请求体
  204. var body bytes.Buffer
  205. writer := multipart.NewWriter(&body)
  206. // 关闭multipart writer
  207. writer.Close()
  208. // 发送POST请求
  209. req, err := netHttp.NewRequest("POST", url, bytes.NewBufferString(formData.Encode()))
  210. if err != nil {
  211. fmt.Println("Error creating request:", err)
  212. return
  213. }
  214. // 设置请求头
  215. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  216. client := &netHttp.Client{}
  217. resp, err := client.Do(req)
  218. if err != nil {
  219. fmt.Println("Error sending request:", err)
  220. return
  221. }
  222. defer resp.Body.Close()
  223. // 处理响应
  224. fmt.Println("Response Status:", resp.Status)
  225. bodyContent, err := ioutil.ReadAll(resp.Body)
  226. if err != nil {
  227. fmt.Println("Error reading response body:", err)
  228. return
  229. }
  230. global.LOG.Info("SMM刷新token:" + string(bodyContent))
  231. var tokenResp GetSmmTokenResp
  232. err = json.Unmarshal(bodyContent, &tokenResp)
  233. if err != nil {
  234. err = errors.New("Unmarshal Err:" + err.Error())
  235. return
  236. }
  237. if tokenResp.Code != 0 {
  238. err = errors.New("getAccessToken err:" + tokenResp.Msg)
  239. return
  240. }
  241. tokenData = tokenResp.Data
  242. return
  243. }
  244. // GetEdbDataListFromSmmHttp 通过url获取SMM的普通数据
  245. func GetEdbDataListFromSmmHttp(page, pageSize int, token string) (body []byte, err error) {
  246. smmUrl := `https://datapro-api.smm.cn/dapi/quota/quota_list?`
  247. //发送创建请求
  248. dataMap := url.Values{
  249. "page": {strconv.Itoa(page)},
  250. "page_size": {strconv.Itoa(pageSize)},
  251. "token": {token},
  252. }
  253. // 构建完整的URL,将查询参数附加到URL中
  254. smmUrl += dataMap.Encode()
  255. // 发送GET请求
  256. resp, err := netHttp.Get(smmUrl)
  257. if err != nil {
  258. fmt.Println("Error sending request:", err)
  259. return
  260. }
  261. defer resp.Body.Close()
  262. // 读取响应的内容
  263. body, err = ioutil.ReadAll(resp.Body)
  264. if err != nil {
  265. fmt.Println("Error reading response:", err)
  266. return
  267. }
  268. str := string(body)
  269. fmt.Println("body:", str)
  270. return
  271. }
  272. // GetEdbDataFromSmmHttp 通过url获取SMM的普通数据
  273. func GetEdbDataFromSmmHttp(edbCodes, token string) (body []byte, err error) {
  274. smmUrl := `https://datapro-api.smm.cn/dapi/quota/data_origin`
  275. // 准备form-data参数
  276. data := url.Values{}
  277. data.Set("token", token)
  278. data.Set("request_source", "API")
  279. data.Set("quota_ids", edbCodes)
  280. // 发送POST请求
  281. req, err := netHttp.NewRequest("POST", smmUrl, strings.NewReader(data.Encode()))
  282. if err != nil {
  283. fmt.Println("Error creating request:", err)
  284. return
  285. }
  286. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  287. client := &netHttp.Client{}
  288. resp, err := client.Do(req)
  289. if err != nil {
  290. fmt.Println("Error sending request:", err)
  291. return
  292. }
  293. defer resp.Body.Close()
  294. // 读取响应的内容
  295. body, err = ioutil.ReadAll(resp.Body)
  296. if err != nil {
  297. fmt.Println("Error reading response:", err)
  298. return
  299. }
  300. str := string(body)
  301. fmt.Println("body:", str)
  302. return
  303. }
  304. // GetEdbLatestDataFromSmmHttp 通过url获取SMM的更新数据
  305. func GetEdbLatestDataFromSmmHttp(edbCodes, token string, lastTime int64) (body []byte, err error) {
  306. smmUrl := `https://datapro-api.smm.cn/dapi/quota/data_latest`
  307. // 准备form-data参数
  308. data := url.Values{}
  309. data.Set("token", token)
  310. data.Set("request_source", "API")
  311. data.Set("quota_ids", edbCodes)
  312. data.Set("last_time", strconv.FormatInt(lastTime, 10))
  313. // 发送POST请求
  314. req, err := netHttp.NewRequest("POST", smmUrl, strings.NewReader(data.Encode()))
  315. if err != nil {
  316. fmt.Println("Error creating request:", err)
  317. return
  318. }
  319. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  320. client := &netHttp.Client{}
  321. resp, err := client.Do(req)
  322. if err != nil {
  323. fmt.Println("Error sending request:", err)
  324. return
  325. }
  326. defer resp.Body.Close()
  327. // 读取响应的内容
  328. body, err = ioutil.ReadAll(resp.Body)
  329. if err != nil {
  330. fmt.Println("Error reading response:", err)
  331. return
  332. }
  333. str := string(body)
  334. fmt.Println("body:", str)
  335. return
  336. }