package index_data import ( "bytes" "encoding/json" "errors" "eta/eta_bridge/global" models "eta/eta_bridge/models/edb" "eta/eta_bridge/models/response" "eta/eta_bridge/services/alarm_msg" "eta/eta_bridge/utils" "fmt" "io" "io/ioutil" "mime/multipart" netHttp "net/http" "net/url" "strconv" "strings" "time" ) // getEdbDataFromSmmHttp 通过url获取SMM的普通数据 func getEdbDataFromSmmHttp(edbCode, token string) (smmBaseDataAll []*models.BaseFromSmmData, err error) { thsUrl := `https://datapro-api.smm.cn/dapi/quota/data_origin` //发送创建请求 dataMap := map[string]io.Reader{ "token": strings.NewReader("18815284804"), "request_source": strings.NewReader("18815284804"), "quota_ids": strings.NewReader("18815284804"), "start_date": strings.NewReader("18815284804"), "end_date": strings.NewReader("18815284804"), } body, err, _ := smmPostCurl(thsUrl, dataMap, 0, token) if err != nil { return } tmpItems := new(response.SmmResponse) err = json.Unmarshal(body, &tmpItems) if err != nil { err = errors.New("GetEdbDataFromSmm json.Unmarshal Err:" + err.Error()) return } if tmpItems.Code != 0 { err = errors.New(tmpItems.Msg) return } for _, quota := range tmpItems.Quota { for _, v := range quota.Data { createTime, e := time.Parse(v.Create, utils.FormatDateTime) if e != nil { err = errors.New("GetEdbDataFromSmm time.Parse Err:" + e.Error()) return } item := &models.BaseFromSmmData{ IndexCode: quota.QuotaID, DataTime: v.Date, Value: v.Value, CreateTime: createTime, ModifyTime: createTime, DataTimestamp: createTime.UnixNano() / 1e6, } fmt.Println(item) } } return } // smmPostCurl post请求同花顺接口 func smmPostCurl(urlStr string, dataMap map[string]io.Reader, num int, token string) (body []byte, err error, errMsg string) { logMsg := `` defer func() { if err != nil { if logMsg != `` { errMsg = logMsg go alarm_msg.SendAlarmMsg("post请求SMM接口失败,ERR:"+err.Error()+";errMsg:"+errMsg, 3) } } }() // 创建一个新的buffer,用于存储请求体 var reqBody bytes.Buffer writer := multipart.NewWriter(&reqBody) // 添加Form-data参数 for key, value := range dataMap { part, e := writer.CreateFormFile(key, key) if e != nil { err = e fmt.Println("Error creating form file:", err) return } _, err = io.Copy(part, value) if err != nil { fmt.Println("Error copying file content:", err) return } } // 关闭multipart writer writer.Close() // 发送POST请求 req, err := netHttp.NewRequest("POST", urlStr, &reqBody) if err != nil { fmt.Println("Error creating request:", err) return } req.Header.Set("Content-Type", writer.FormDataContentType()) client := &netHttp.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() // 处理响应 fmt.Println("Response Status:", resp.Status) body, err = ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response body:", err) return } global.LOG.Info("SMM刷新token:" + string(body)) var response response.SmmResponse err = json.Unmarshal(body, &response) if err != nil { global.LOG.Info("post Err:", err.Error(), ";url:", urlStr, ";response:", string(body)) err = errors.New("Unmarshal Err:" + err.Error()) return } global.LOG.Info(fmt.Sprint("post request url:", urlStr, ";token:", token, ";response:", string(body))) logMsg = fmt.Sprint("post request url:", urlStr, ";token:", token, ";response:", string(body)) //如果是token失效,同时只是第一次请求(没有尝试强制刷新token,那么重新请求) if utils.InArrayByInt([]int{-10020001, -10020002}, int(response.Code)) && num <= 0 { //token失效 token, err = refreshSmmAccessToken() if err != nil { return } num++ return smmPostCurl(urlStr, dataMap, num, token) } else if response.Code != 0 { global.LOG.Info(fmt.Sprint("post data err:", response.Msg, ";url:", urlStr, ";response:", string(body))) err = errors.New(response.Msg) return } return } // GetSmmAccessToken 获取accessToken func GetSmmAccessToken(isRefresh bool) (token string, err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("获取SMM的token失败,ERR:"+err.Error(), 3) } }() redisKey := utils.CACHE_EDB_SMM_SERVER_TOKEN token, redisErr := global.Rc.RedisString(redisKey) //如果从redis中accessToken 获取失败或者token为空了,再或者需要强制刷新了,那么重新获取accessToken if redisErr != nil || token == `` || isRefresh { token, _ = refreshSmmAccessToken() return } return } // refreshSmmAccessToken 强制刷新获取accessToken func refreshSmmAccessToken() (token string, err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("刷新SMM的token失败;ERR:"+err.Error(), 3) } }() tokenInfo, tmpErr := getSmmAccessToken() if tmpErr != nil { err = tmpErr return } token = tokenInfo.Token //token存入redis redisKey := utils.CACHE_EDB_SMM_SERVER_TOKEN err = global.Rc.Put(redisKey, token, time.Hour*24*7) if err != nil { err = fmt.Errorf("获取SMM的token成功;SMM token存入redis失败,ERR:%s", err.Error()) return } return } type GetSmmTokenResp struct { Code int `json:"code"` Msg string `json:"msg"` Data SmmTokenData `json:"data"` } type SmmTokenData struct { Token string `json:"token"` } // getSmmAccessToken token内部请求接口 func getSmmAccessToken() (tokenData SmmTokenData, err error) { defer func() { if err != nil { go alarm_msg.SendAlarmMsg("更新SMM的token失败;ERR:"+err.Error(), 3) } }() // 准备Form-data参数 formData := url.Values{ "user_name": {global.CONFIG.Smm.Username}, "password": {utils.MD5(global.CONFIG.Smm.Password)}, "source": {"datapro"}, } url := "https://datapro-api.smm.cn/dapi/user/auth" // 创建一个新的buffer,用于存储请求体 var body bytes.Buffer writer := multipart.NewWriter(&body) // 关闭multipart writer writer.Close() // 发送POST请求 req, err := netHttp.NewRequest("POST", url, bytes.NewBufferString(formData.Encode())) if err != nil { fmt.Println("Error creating request:", err) return } // 设置请求头 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") client := &netHttp.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() // 处理响应 fmt.Println("Response Status:", resp.Status) bodyContent, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response body:", err) return } global.LOG.Info("SMM刷新token:" + string(bodyContent)) var tokenResp GetSmmTokenResp err = json.Unmarshal(bodyContent, &tokenResp) if err != nil { err = errors.New("Unmarshal Err:" + err.Error()) return } if tokenResp.Code != 0 { err = errors.New("getAccessToken err:" + tokenResp.Msg) return } tokenData = tokenResp.Data return } // GetEdbDataListFromSmmHttp 通过url获取SMM的普通数据 func GetEdbDataListFromSmmHttp(page, pageSize int, token string) (body []byte, err error) { smmUrl := `https://datapro-api.smm.cn/dapi/quota/quota_list?` //发送创建请求 dataMap := url.Values{ "page": {strconv.Itoa(page)}, "page_size": {strconv.Itoa(pageSize)}, "token": {token}, } // 构建完整的URL,将查询参数附加到URL中 smmUrl += dataMap.Encode() // 发送GET请求 resp, err := netHttp.Get(smmUrl) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() // 读取响应的内容 body, err = ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response:", err) return } str := string(body) fmt.Println("body:", str) return } // GetEdbDataFromSmmHttp 通过url获取SMM的普通数据 func GetEdbDataFromSmmHttp(edbCodes, token string) (body []byte, err error) { smmUrl := `https://datapro-api.smm.cn/dapi/quota/data_origin` // 准备form-data参数 data := url.Values{} data.Set("token", token) data.Set("request_source", "API") data.Set("quota_ids", edbCodes) // 发送POST请求 req, err := netHttp.NewRequest("POST", smmUrl, strings.NewReader(data.Encode())) if err != nil { fmt.Println("Error creating request:", err) return } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") client := &netHttp.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() // 读取响应的内容 body, err = ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response:", err) return } str := string(body) fmt.Println("body:", str) return } // GetEdbLatestDataFromSmmHttp 通过url获取SMM的更新数据 func GetEdbLatestDataFromSmmHttp(edbCodes, token string, lastTime int64) (body []byte, err error) { smmUrl := `https://datapro-api.smm.cn/dapi/quota/data_latest` // 准备form-data参数 data := url.Values{} data.Set("token", token) data.Set("request_source", "API") data.Set("quota_ids", edbCodes) data.Set("last_time", strconv.FormatInt(lastTime, 10)) // 发送POST请求 req, err := netHttp.NewRequest("POST", smmUrl, strings.NewReader(data.Encode())) if err != nil { fmt.Println("Error creating request:", err) return } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") client := &netHttp.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() // 读取响应的内容 body, err = ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response:", err) return } str := string(body) fmt.Println("body:", str) return }