package services import ( "encoding/json" "errors" "eta_gn/eta_index_lib/models" "eta_gn/eta_index_lib/utils" "fmt" "github.com/rdlucklib/rdluck_tools/http" "strings" ) func GetEdbDataFromThsDs(stockCode, edbCode, startDate, endDate, edbTerminalCode, extraPars string) (item models.EdbDataFromThs, err error) { terminal, err := GetTerminal(utils.DATA_SOURCE_THS, edbTerminalCode) if err != nil { err = fmt.Errorf("获取同花顺接口配置出错 Err: %s", err) return } if terminal.ServerUrl == "" { err = fmt.Errorf("同花顺接口未配置") return } if edbTerminalCode == "" { // 设置指标与终端关系的缓存 terminalCodeCacheKey := utils.CACHE_EDB_TERMINAL_CODE_URL + stockCode _ = utils.Rc.Put(terminalCodeCacheKey, terminal.TerminalCode, utils.GetTodayLastSecond()) } // 如果没有配置,获取配置的方式是api,那么就走官方接口 if utils.ThsDataMethod == "" || utils.ThsDataMethod == "api" { var token string token, err = GetAccessToken(false, terminal.Value) if err != nil { return } // TEST //token = "23f339e97fac48d8b99024228fafb6f0128cfbb7.signs_NTc2NjQ4MTA5" return getEdbDataFromThsDsHttp(stockCode, edbCode, startDate, endDate, terminal.Value, token, extraPars) } return getEdbDataFromThsDsApp(stockCode, edbCode, startDate, endDate, 0, terminal.ServerUrl, extraPars) } type EdbDataFromThsSdInterface struct { Errorcode int `json:"errorcode"` Errmsg string `json:"errmsg"` Tables []Table `json:"tables"` Datatype []Type `json:"datatype"` InputParams interface{} `json:"inputParams"` DataVol int `json:"dataVol"` Perf int `json:"perf"` } type Table struct { Thscode string `json:"thscode"` Time []string `json:"time"` Table map[string]interface{} `json:"table"` } type StockData struct { THSOpenPriceStock []float64 `json:"ths_open_price_stock"` THSHighPriceStock []float64 `json:"ths_high_price_stock"` THSLowStock []float64 `json:"ths_low_stock"` THSClosePriceStock []float64 `json:"ths_close_price_stock"` THSChgRatioStock []float64 `json:"ths_chg_ratio_stock"` THSChgStock []float64 `json:"ths_chg_stock"` THSVolStock []float64 `json:"ths_vol_stock"` THSPreCloseStock []float64 `json:"ths_pre_close_stock"` THSSwingStock []float64 `json:"ths_swing_stock"` THSTurnoverRatioStock []float64 `json:"ths_turnover_ratio_stock"` THSAmtStock []float64 `json:"ths_amt_stock"` } type Type struct { Itemid string `json:"itemid"` Type string `json:"type"` } // //type Params struct { // Jsonrpc bool `json:"jsonrpc"` // Params []Param `json:"params"` //} // //type Param struct { // Function string `json:"function"` // ID string `json:"id"` // Params []Param2 `json:"params"` //} // //type Param2 struct { // Name string `json:"name"` // System string `json:"system"` // Value string `json:"value"` //} // getEdbDataFromThsDs 获取同花顺接口数据 func getEdbDataFromThsDsApp(stockCode, edbCode, startDate, endDate string, num int, serverUrl, extraPars string) (item models.EdbDataFromThs, err error) { if serverUrl == `` { err = errors.New("同花顺接口未配置") return } thsUrl := serverUrl + `edbInfo/ths/ds?StockCode=%s&EdbCode=%s&StartDate=%s&EndDate=%s&ExtraPars=%s` thsUrl = fmt.Sprintf(thsUrl, stockCode, edbCode, startDate, endDate, extraPars) utils.FileLog.Info("thsUrl:" + thsUrl) body, err := http.Get(thsUrl) utils.FileLog.Info("ths result:" + string(body)) if err != nil { err = errors.New(" Err:" + err.Error() + ";result:" + string(body)) return } if string(body) == "null" { err = errors.New("同花顺数据获取异常:" + err.Error() + ";result:" + string(body)) return } println(string(body)) tablesList := make([]models.Tables, 0) var errCode int64 if strings.Contains(edbCode, ",") { var jsonArray []string if err = json.Unmarshal(body, &jsonArray); err != nil { fmt.Println("json.Unmarshal Err:", err) return } // 解码数组内的每个 JSON 字符串 //var responses []TerminalResponse for _, data := range jsonArray { data = strings.Replace(data, "NaN", "null", -1) tableTimeList := make([]string, 0) tableValueList := make([]float64, 0) var response TerminalResponse if err = json.Unmarshal([]byte(data), &response); err != nil { fmt.Println("json.Unmarshal Err:", err) return } errCode = int64(response.ErrorCode) if response.ErrorCode != 0 { //session has expired,please re-login after using the system //如果是同花顺登录session失效了,那么就重新请求获取数据 if response.ErrorCode == -1020 && num == 0 { return getEdbDataFromThsDsApp(stockCode, edbCode, startDate, endDate, 1, serverUrl, extraPars) } err = errors.New(string(body)) return } for _, stockData := range response.Data { time := stockData["time"].(string) //thsCode := stockData["thscode"].(string) //tableTimeList = append(tableTimeList, time) for k, v := range stockData { if k != "time" && k != "thscode" { if v != nil { tableTimeList = append(tableTimeList, time) tableValueList = append(tableValueList, v.(float64)) } } } } tmpTable := models.Tables{ ID: []string{}, Time: tableTimeList, Value: tableValueList, } tablesList = append(tablesList, tmpTable) } } else { var data string if err = json.Unmarshal(body, &data); err != nil { fmt.Println("json.Unmarshal Err:", err) return } // 解码数组内的每个 JSON 字符串 //var responses []TerminalResponse data = strings.Replace(data, "NaN", "null", -1) tableTimeList := make([]string, 0) tableValueList := make([]float64, 0) var response TerminalResponse if err = json.Unmarshal([]byte(data), &response); err != nil { fmt.Println("json.Unmarshal Err:", err) return } errCode = int64(response.ErrorCode) if response.ErrorCode != 0 { //session has expired,please re-login after using the system //如果是同花顺登录session失效了,那么就重新请求获取数据 if response.ErrorCode == -1020 && num == 0 { return getEdbDataFromThsDsApp(stockCode, edbCode, startDate, endDate, 1, serverUrl, extraPars) } err = errors.New(string(body)) return } for _, stockData := range response.Data { time := stockData["time"].(string) //thsCode := stockData["thscode"].(string) for k, v := range stockData { if k != "time" && k != "thscode" { if v != nil { tableTimeList = append(tableTimeList, time) tableValueList = append(tableValueList, v.(float64)) } } } } tmpTable := models.Tables{ ID: []string{}, Time: tableTimeList, Value: tableValueList, } tablesList = append(tablesList, tmpTable) } item = models.EdbDataFromThs{ DataVol: 0, Errmsg: "", Errorcode: errCode, Perf: "", Tables: tablesList, } //tmpItems := new([]TerminalResponse) //err = json.Unmarshal(body, &tmpItems) //if err != nil { // err = errors.New("GetEdbDataFromThs json.Unmarshal Err:" + err.Error()) // return //} //// 因为table里面的value有的时候返回的是string,有的是float64,所以需要用interface来反射取值 //tablesList := make([]models.Tables, 0) //for _, table := range tmpItems.Tables { // tableIdList := make([]string, 0) // tableTimeList := make([]string, 0) // tableValueList := make([]float64, 0) // // for _, tableId := range table.ID { // tableIdList = append(tableIdList, tableId) // } // for _, tableTime := range table.Time { // tableTimeList = append(tableTimeList, tableTime) // } // // //指标数据 // for _, tmpValue := range table.Value { // var tableValue float64 // if reflect.TypeOf(tmpValue).Kind() == reflect.Float64 { // tableValue = reflect.ValueOf(tmpValue).Float() // } else if reflect.TypeOf(tmpValue).Kind() == reflect.String { // tmpTableValue, tmpErr := decimal.NewFromString(reflect.ValueOf(tmpValue).String()) // if tmpErr != nil { // err = tmpErr // return // } // tableValue, _ = tmpTableValue.Truncate(4).Float64() // } else { // err = errors.New("错误的数据类型" + reflect.TypeOf(tmpValue).String()) // return // } // tableValueList = append(tableValueList, tableValue) // } // tmpTable := models.Tables{ // ID: tableIdList, // Time: tableTimeList, // Value: tableValueList, // } // tablesList = append(tablesList, tmpTable) //} //item = models.EdbDataFromThs{ // DataVol: tmpItems.DataVol, // Errmsg: tmpItems.Errmsg, // Errorcode: tmpItems.Errorcode, // Perf: tmpItems.Perf, // Tables: tablesList, //} return item, nil }