mirror of
https://github.com/ArvinLovegood/go-stock.git
synced 2025-07-19 00:00:09 +08:00
feat(data): 添加指数信息获取功能
- 在 StockDataApi 中新增 GetIndexBasic 方法,用于获取指数信息 - 在数据库中添加 index_basic 表并进行自动迁移- 优化 GetStockBaseInfo 方法,使用 map 结构处理字段- 增加 GetIndexBasic 的单元测试
This commit is contained in:
parent
15120c98da
commit
f35847823b
@ -9,6 +9,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/duke-git/lancet/v2/convertor"
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
"github.com/duke-git/lancet/v2/strutil"
|
"github.com/duke-git/lancet/v2/strutil"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
"go-stock/backend/db"
|
"go-stock/backend/db"
|
||||||
@ -162,15 +163,63 @@ func NewStockDataApi() *StockDataApi {
|
|||||||
client: resty.New(),
|
client: resty.New(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetIndexBasic 获取指数信息
|
||||||
|
func (receiver StockDataApi) GetIndexBasic() {
|
||||||
|
res := &TushareStockBasicResponse{}
|
||||||
|
fields := "ts_code,name,market,publisher,category,base_date,base_point,list_date,fullname,index_type,weight_rule,desc"
|
||||||
|
resp, err := receiver.client.R().
|
||||||
|
SetHeader("content-type", "application/json").
|
||||||
|
SetBody(&TushareRequest{
|
||||||
|
ApiName: "index_basic",
|
||||||
|
Token: TushareToken,
|
||||||
|
Params: nil,
|
||||||
|
Fields: fields}).
|
||||||
|
SetResult(res).
|
||||||
|
Post(tushare_api_url)
|
||||||
|
if err != nil {
|
||||||
|
logger.SugaredLogger.Error(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if res.Code != 0 {
|
||||||
|
logger.SugaredLogger.Error(res.Msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ioutil.WriteFile("index_basic.json", resp.Body(), 0666)
|
||||||
|
|
||||||
|
for _, item := range res.Data.Items {
|
||||||
|
data := map[string]any{}
|
||||||
|
for _, field := range strings.Split(fields, ",") {
|
||||||
|
logger.SugaredLogger.Infof("field: %s", field)
|
||||||
|
idx := slice.IndexOf(res.Data.Fields, field)
|
||||||
|
if idx == -1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
data[field] = item[idx]
|
||||||
|
}
|
||||||
|
index := &IndexBasic{}
|
||||||
|
jsonData, _ := json.Marshal(data)
|
||||||
|
err := json.Unmarshal(jsonData, index)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
db.Dao.Model(&IndexBasic{}).FirstOrCreate(index, &IndexBasic{TsCode: index.TsCode}).Updates(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// map转换为结构体
|
||||||
|
|
||||||
func (receiver StockDataApi) GetStockBaseInfo() {
|
func (receiver StockDataApi) GetStockBaseInfo() {
|
||||||
res := &TushareStockBasicResponse{}
|
res := &TushareStockBasicResponse{}
|
||||||
|
fields := "ts_code,symbol,name,area,industry,cnspell,market,list_date,act_name,act_ent_type,fullname,exchange,list_status,curr_type,enname,delist_date,is_hs"
|
||||||
resp, err := receiver.client.R().
|
resp, err := receiver.client.R().
|
||||||
SetHeader("content-type", "application/json").
|
SetHeader("content-type", "application/json").
|
||||||
SetBody(&TushareRequest{
|
SetBody(&TushareRequest{
|
||||||
ApiName: "stock_basic",
|
ApiName: "stock_basic",
|
||||||
Token: TushareToken,
|
Token: TushareToken,
|
||||||
Params: nil,
|
Params: nil,
|
||||||
Fields: "*",
|
Fields: fields,
|
||||||
}).
|
}).
|
||||||
SetResult(res).
|
SetResult(res).
|
||||||
Post(tushare_api_url)
|
Post(tushare_api_url)
|
||||||
@ -187,25 +236,21 @@ func (receiver StockDataApi) GetStockBaseInfo() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, item := range res.Data.Items {
|
for _, item := range res.Data.Items {
|
||||||
ID, _ := convertor.ToInt(item[6])
|
|
||||||
stock := &StockBasic{}
|
stock := &StockBasic{}
|
||||||
stock.Exchange = convertor.ToString(item[0])
|
data := map[string]any{}
|
||||||
stock.IsHs = convertor.ToString(item[1])
|
for _, field := range strings.Split(fields, ",") {
|
||||||
stock.Name = convertor.ToString(item[2])
|
logger.SugaredLogger.Infof("field: %s", field)
|
||||||
stock.Industry = convertor.ToString(item[3])
|
idx := slice.IndexOf(res.Data.Fields, field)
|
||||||
stock.ListStatus = convertor.ToString(item[4])
|
if idx == -1 {
|
||||||
stock.ActName = convertor.ToString(item[5])
|
continue
|
||||||
stock.ID = uint(ID)
|
}
|
||||||
stock.CurrType = convertor.ToString(item[7])
|
data[field] = item[idx]
|
||||||
stock.Area = convertor.ToString(item[8])
|
}
|
||||||
stock.ListDate = convertor.ToString(item[9])
|
jsonData, _ := json.Marshal(data)
|
||||||
stock.DelistDate = convertor.ToString(item[10])
|
err := json.Unmarshal(jsonData, stock)
|
||||||
stock.ActEntType = convertor.ToString(item[11])
|
if err != nil {
|
||||||
stock.TsCode = convertor.ToString(item[12])
|
continue
|
||||||
stock.Symbol = convertor.ToString(item[13])
|
}
|
||||||
stock.Cnspell = convertor.ToString(item[14])
|
|
||||||
stock.Fullname = convertor.ToString(item[20])
|
|
||||||
stock.Ename = convertor.ToString(item[21])
|
|
||||||
db.Dao.Model(&StockBasic{}).FirstOrCreate(stock, &StockBasic{TsCode: stock.TsCode}).Updates(stock)
|
db.Dao.Model(&StockBasic{}).FirstOrCreate(stock, &StockBasic{TsCode: stock.TsCode}).Updates(stock)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,3 +417,24 @@ func ParseFullSingleStockData(data string) (*StockInfo, error) {
|
|||||||
|
|
||||||
return stockInfo, nil
|
return stockInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IndexBasic struct {
|
||||||
|
gorm.Model
|
||||||
|
TsCode string `json:"ts_code" gorm:"index"`
|
||||||
|
Symbol string `json:"symbol" gorm:"index"`
|
||||||
|
Name string `json:"name" gorm:"index"`
|
||||||
|
FullName string `json:"fullname"`
|
||||||
|
IndexType string `json:"index_type"`
|
||||||
|
IndexCategory string `json:"category"`
|
||||||
|
Market string `json:"market"`
|
||||||
|
ListDate string `json:"list_date"`
|
||||||
|
BaseDate string `json:"base_date"`
|
||||||
|
BasePoint float64 `json:"base_point"`
|
||||||
|
Publisher string `json:"publisher"`
|
||||||
|
WeightRule string `json:"weight_rule"`
|
||||||
|
DESC string `json:"desc"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (IndexBasic) TableName() string {
|
||||||
|
return "tushare_index_basic"
|
||||||
|
}
|
||||||
|
@ -77,3 +77,9 @@ func TestFollowedList(t *testing.T) {
|
|||||||
t.Log(stockDataApi.GetFollowList())
|
t.Log(stockDataApi.GetFollowList())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStockDataApi_GetIndexBasic(t *testing.T) {
|
||||||
|
db.Init("../../data/stock.db")
|
||||||
|
stockDataApi := NewStockDataApi()
|
||||||
|
stockDataApi.GetIndexBasic()
|
||||||
|
}
|
||||||
|
2
main.go
2
main.go
@ -35,11 +35,13 @@ func main() {
|
|||||||
db.Dao.AutoMigrate(&data.StockInfo{})
|
db.Dao.AutoMigrate(&data.StockInfo{})
|
||||||
db.Dao.AutoMigrate(&data.StockBasic{})
|
db.Dao.AutoMigrate(&data.StockBasic{})
|
||||||
db.Dao.AutoMigrate(&data.FollowedStock{})
|
db.Dao.AutoMigrate(&data.FollowedStock{})
|
||||||
|
db.Dao.AutoMigrate(&data.IndexBasic{})
|
||||||
|
|
||||||
if stocksBin != nil && len(stocksBin) > 0 {
|
if stocksBin != nil && len(stocksBin) > 0 {
|
||||||
go initStockData()
|
go initStockData()
|
||||||
}
|
}
|
||||||
go data.NewStockDataApi().GetStockBaseInfo()
|
go data.NewStockDataApi().GetStockBaseInfo()
|
||||||
|
go data.NewStockDataApi().GetIndexBasic()
|
||||||
|
|
||||||
// Create an instance of the app structure
|
// Create an instance of the app structure
|
||||||
app := NewApp()
|
app := NewApp()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user