diff --git a/app_common.go b/app_common.go
index a73a611..587be55 100644
--- a/app_common.go
+++ b/app_common.go
@@ -31,3 +31,20 @@ func (a App) EMDictCode(code string) []any {
func (a App) AnalyzeSentiment(text string) data.SentimentResult {
return data.AnalyzeSentiment(text)
}
+
+func (a App) HotStock(marketType string) *[]models.HotItem {
+ return data.NewMarketNewsApi().XUEQIUHotStock(50, marketType)
+}
+
+func (a App) HotEvent(size int) *[]models.HotEvent {
+ if size <= 0 {
+ size = 10
+ }
+ return data.NewMarketNewsApi().HotEvent(size)
+}
+func (a App) HotTopic(size int) []any {
+ if size <= 0 {
+ size = 10
+ }
+ return data.NewMarketNewsApi().HotTopic(size)
+}
diff --git a/backend/data/market_news_api.go b/backend/data/market_news_api.go
index d1e5938..ff74b2a 100644
--- a/backend/data/market_news_api.go
+++ b/backend/data/market_news_api.go
@@ -574,3 +574,72 @@ func (m MarketNewsApi) TradingViewNews() *[]models.TVNews {
json.Unmarshal(items, TVNews)
return TVNews
}
+
+func (m MarketNewsApi) XUEQIUHotStock(size int, marketType string) *[]models.HotItem {
+ url := fmt.Sprintf("https://stock.xueqiu.com/v5/stock/hot_stock/list.json?page=1&size=%d&_type=%s&type=%s", size, marketType, marketType)
+ res := &models.XUEQIUHot{}
+ _, err := resty.New().SetTimeout(time.Duration(30)*time.Second).R().
+ SetHeader("Host", "stock.xueqiu.com").
+ SetHeader("Origin", "https://xueqiu.com").
+ SetHeader("Referer", "https://xueqiu.com/").
+ SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:140.0) Gecko/20100101 Firefox/140.0").
+ SetHeader("Cookie", "cookiesu=2617378771242871; s=c2121pp1u71; device_id=237a58584ec58d8e4d4e1040700a644f1; Hm_lvt_1db88642e346389874251b5a1eded6e3=1744100219,1744599115; xq_a_token=b7259d09435458cc3f1a963479abb270a1a016ce; xqat=b7259d09435458cc3f1a963479abb270a1a016ce; xq_r_token=28108bfa1d92ac8a46bbb57722633746218621a3; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTc1MjU0MTk4OCwiY3RtIjoxNzUwMjMwNjA2NzI0LCJjaWQiOiJkOWQwbjRBWnVwIn0.kU_fz0luJoE7nr-K4UrNUi5-mAG-vMdXtuC4mUKIppILId4UpF70LB70yunxGiNSw6tPFR3-hyLvztKAHtekCUTm3XjUl5b3tEDP-ZUVqHnWXO_5hoeMI8h-Cfx6ZGlIr5x3icvTPkT0OV5CD5A33-ZDTKhKPf-DhJ_-m7CG5GbX4MseOBeMXuLUQUiYHPKhX1QUc0GTGrCzi8Mki0z49D0LVqCSgbsx3UGfowOOyx85_cXb4OAFvIjwbs2p0o_h-ibIT0ngVkkAyEDetVvlcZ_bkardhseCB7k9BEMgH2z8ihgkVxyy3P0degLmDUruhmqn5uZOCi1pVBDvCv9lBg; u=261737877124287; ssxmod_itna=QuG=D5AKiKDIqCqGKi7G7DgmmPlSDWFqKGHDyx4YK0CDmxjKiddDUQivnb8xpnQcGyGYoYhoqEeDBubrDSxD67DK4GTm+ogiw1o3B=xedQHDgBtN=7/i1K53N+rOjquLMU=kbqYxB3DExGkqj0tPi4DxaPD5xDTDWeDGDD3DnnsDQKDRx0kL0oDIxD1D0bmHUEvh38mDYePLmOmDYPYx94Y8KoDeEgsD7HUl/vIGGEAqjLPFegXLD0HolCqr4DCid1qDm+ECfkjDn9sD0KP8fn+CRoDv=tYr4ibx+o=W+8vstf9mjGe3cXseWdBmoFrmf4DA3bFAxnAxD7vYxADaDoerDGHPoxHF+PKGPtDKmiqQGeB5qbi4eg4KDHKDe3DeG0qeEP9xVUoHDDWMYYM0ICr4FBimBDM7D0x4QOECmhul5QCN/m5/74lGm=7x9Wp7A+i7xQ7wlMD4D; ssxmod_itna2=QuG=D5AKiKDIqCqGKi7G7DgmmPlSDWFqKGHDyx4YK0CDmxjKiddDUQivnb8xpnQcGyGYoYhoqoDirSDhPmGD24GajjDuGE3m7or4DlxOSGewHl6iaus2Q62SRX5CFjCds6ltF9xy6iaUuB262UkhRA8UXST=4/b+y3kGKzlGE8T29FA008ljy9jXXC7f7m7QsK667mlUooWrofk=qGZjxtcUrN1NtuAnne1hj+rQP5UnlFkxf+o7VjmatH7u7bCDlbTt3cz6CH9Fl4vye16W/ellc8I3Q37W7ZwiLGD/zPpZcnd2nsqqo/+zRbKAmz4plzwaDqGUe7f9E+P0IFRKqpRv+buQFHBSpcbwND7Q+9XWmnjI2UwKd98jIS3gPXwxvbx4OuiyH8gZ+OEt7DgE/AY/9W4VxDZrlFWyWnC4y4/I0IpAfaGKpbPmauKbkqawqv93vSf+9HamGe0Dt2PNgT3yiEB4vQP2/DdVpcGBOjFujWoHP32OshLPYI20LRCKddwEGkKqPzPwKPc3X5zuB=w2fUdtwKsAW5kQtsl8clNwjC5uDYrxR0h9xaj0xmD+YuI3GPT7xYTalRImPj2wL2=+91a304xa4bTWtP=dLGARhb/efRi0uktaz8i8C04G0x/ZWUzqRza8GGU=FfRfvb4GZM/q2rVsl0nLvRjGeAKgocLouyXs/uwZu3YxbAx30qCbjG1A533zAxIeIgD=0VAc3ixD").
+ SetResult(res).
+ Get(url)
+ if err != nil {
+ logger.SugaredLogger.Errorf("XUEQIUHotStock err:%s", err.Error())
+ return &[]models.HotItem{}
+ }
+ logger.SugaredLogger.Infof("XUEQIUHotStock:%+v", res)
+ return &res.Data.Items
+}
+
+func (m MarketNewsApi) HotEvent(size int) *[]models.HotEvent {
+ events := &[]models.HotEvent{}
+ url := fmt.Sprintf("https://xueqiu.com/hot_event/list.json?count=%d", size)
+ resp, err := resty.New().SetTimeout(time.Duration(30)*time.Second).R().
+ SetHeader("Host", "xueqiu.com").
+ SetHeader("Origin", "https://xueqiu.com").
+ SetHeader("Referer", "https://xueqiu.com/").
+ SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:140.0) Gecko/20100101 Firefox/140.0").
+ SetHeader("Cookie", "cookiesu=2617378771242871; s=c2121pp1u71; device_id=237a58584ec58d8e4d4e1040700a644f1; Hm_lvt_1db88642e346389874251b5a1eded6e3=1744100219,1744599115; xq_a_token=b7259d09435458cc3f1a963479abb270a1a016ce; xqat=b7259d09435458cc3f1a963479abb270a1a016ce; xq_r_token=28108bfa1d92ac8a46bbb57722633746218621a3; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTc1MjU0MTk4OCwiY3RtIjoxNzUwMjMwNjA2NzI0LCJjaWQiOiJkOWQwbjRBWnVwIn0.kU_fz0luJoE7nr-K4UrNUi5-mAG-vMdXtuC4mUKIppILId4UpF70LB70yunxGiNSw6tPFR3-hyLvztKAHtekCUTm3XjUl5b3tEDP-ZUVqHnWXO_5hoeMI8h-Cfx6ZGlIr5x3icvTPkT0OV5CD5A33-ZDTKhKPf-DhJ_-m7CG5GbX4MseOBeMXuLUQUiYHPKhX1QUc0GTGrCzi8Mki0z49D0LVqCSgbsx3UGfowOOyx85_cXb4OAFvIjwbs2p0o_h-ibIT0ngVkkAyEDetVvlcZ_bkardhseCB7k9BEMgH2z8ihgkVxyy3P0degLmDUruhmqn5uZOCi1pVBDvCv9lBg; u=261737877124287; ssxmod_itna=QuG=D5AKiKDIqCqGKi7G7DgmmPlSDWFqKGHDyx4YK0CDmxjKiddDUQivnb8xpnQcGyGYoYhoqEeDBubrDSxD67DK4GTm+ogiw1o3B=xedQHDgBtN=7/i1K53N+rOjquLMU=kbqYxB3DExGkqj0tPi4DxaPD5xDTDWeDGDD3DnnsDQKDRx0kL0oDIxD1D0bmHUEvh38mDYePLmOmDYPYx94Y8KoDeEgsD7HUl/vIGGEAqjLPFegXLD0HolCqr4DCid1qDm+ECfkjDn9sD0KP8fn+CRoDv=tYr4ibx+o=W+8vstf9mjGe3cXseWdBmoFrmf4DA3bFAxnAxD7vYxADaDoerDGHPoxHF+PKGPtDKmiqQGeB5qbi4eg4KDHKDe3DeG0qeEP9xVUoHDDWMYYM0ICr4FBimBDM7D0x4QOECmhul5QCN/m5/74lGm=7x9Wp7A+i7xQ7wlMD4D; ssxmod_itna2=QuG=D5AKiKDIqCqGKi7G7DgmmPlSDWFqKGHDyx4YK0CDmxjKiddDUQivnb8xpnQcGyGYoYhoqoDirSDhPmGD24GajjDuGE3m7or4DlxOSGewHl6iaus2Q62SRX5CFjCds6ltF9xy6iaUuB262UkhRA8UXST=4/b+y3kGKzlGE8T29FA008ljy9jXXC7f7m7QsK667mlUooWrofk=qGZjxtcUrN1NtuAnne1hj+rQP5UnlFkxf+o7VjmatH7u7bCDlbTt3cz6CH9Fl4vye16W/ellc8I3Q37W7ZwiLGD/zPpZcnd2nsqqo/+zRbKAmz4plzwaDqGUe7f9E+P0IFRKqpRv+buQFHBSpcbwND7Q+9XWmnjI2UwKd98jIS3gPXwxvbx4OuiyH8gZ+OEt7DgE/AY/9W4VxDZrlFWyWnC4y4/I0IpAfaGKpbPmauKbkqawqv93vSf+9HamGe0Dt2PNgT3yiEB4vQP2/DdVpcGBOjFujWoHP32OshLPYI20LRCKddwEGkKqPzPwKPc3X5zuB=w2fUdtwKsAW5kQtsl8clNwjC5uDYrxR0h9xaj0xmD+YuI3GPT7xYTalRImPj2wL2=+91a304xa4bTWtP=dLGARhb/efRi0uktaz8i8C04G0x/ZWUzqRza8GGU=FfRfvb4GZM/q2rVsl0nLvRjGeAKgocLouyXs/uwZu3YxbAx30qCbjG1A533zAxIeIgD=0VAc3ixD").
+ Get(url)
+ if err != nil {
+ logger.SugaredLogger.Errorf("HotEvent err:%s", err.Error())
+ return events
+ }
+ logger.SugaredLogger.Infof("HotEvent:%s", resp.Body())
+ respMap := map[string]any{}
+ err = json.Unmarshal(resp.Body(), &respMap)
+ items, err := json.Marshal(respMap["list"])
+ if err != nil {
+ return events
+ }
+ json.Unmarshal(items, events)
+ return events
+
+}
+
+func (m MarketNewsApi) HotTopic(size int) []any {
+ url := "https://gubatopic.eastmoney.com/interface/GetData.aspx?path=newtopic/api/Topic/HomePageListRead"
+ resp, err := resty.New().SetTimeout(time.Duration(30)*time.Second).R().
+ SetHeader("Host", "gubatopic.eastmoney.com").
+ SetHeader("Origin", "https://gubatopic.eastmoney.com").
+ SetHeader("Referer", "https://gubatopic.eastmoney.com/").
+ SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:140.0) Gecko/20100101 Firefox/140.0").
+ SetFormData(map[string]string{
+ "param": fmt.Sprintf("ps=%d&p=1&type=0", size),
+ "path": "newtopic/api/Topic/HomePageListRead",
+ "env": "2",
+ }).
+ Post(url)
+ if err != nil {
+ logger.SugaredLogger.Errorf("HotTopic err:%s", err.Error())
+ return []any{}
+ }
+ logger.SugaredLogger.Infof("HotTopic:%s", resp.Body())
+ respMap := map[string]any{}
+ err = json.Unmarshal(resp.Body(), &respMap)
+ return respMap["re"].([]any)
+
+}
diff --git a/backend/data/market_news_api_test.go b/backend/data/market_news_api_test.go
index 01d489b..d6279bd 100644
--- a/backend/data/market_news_api_test.go
+++ b/backend/data/market_news_api_test.go
@@ -108,3 +108,30 @@ func TestTradingViewNews(t *testing.T) {
logger.SugaredLogger.Debugf("value: %+v", a)
}
}
+
+func TestXUEQIUHotStock(t *testing.T) {
+ db.Init("../../data/stock.db")
+ res := NewMarketNewsApi().XUEQIUHotStock(50, "10")
+ for _, a := range *res {
+ logger.SugaredLogger.Debugf("value: %+v", a)
+ }
+
+}
+
+func TestHotEvent(t *testing.T) {
+ db.Init("../../data/stock.db")
+ res := NewMarketNewsApi().HotEvent(50)
+ for _, a := range *res {
+ logger.SugaredLogger.Debugf("value: %+v", a)
+ }
+
+}
+
+func TestHotTopic(t *testing.T) {
+ db.Init("../../data/stock.db")
+ res := NewMarketNewsApi().HotTopic(10)
+ for _, a := range res {
+ logger.SugaredLogger.Debugf("value: %+v", a)
+ }
+
+}
diff --git a/backend/models/models.go b/backend/models/models.go
index f513055..10d237b 100644
--- a/backend/models/models.go
+++ b/backend/models/models.go
@@ -317,3 +317,48 @@ type TVNews struct {
LogoId string `json:"logo_id"`
} `json:"provider"`
}
+
+type XUEQIUHot struct {
+ Data struct {
+ Items []HotItem `json:"items"`
+ ItemsSize int `json:"items_size"`
+ } `json:"data"`
+ ErrorCode int `json:"error_code"`
+ ErrorDescription string `json:"error_description"`
+}
+
+type HotItem struct {
+ Type int `json:"type"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Value float64 `json:"value"`
+ Increment int `json:"increment"`
+ RankChange int `json:"rank_change"`
+ HasExist interface{} `json:"has_exist"`
+ Symbol string `json:"symbol"`
+ Percent float64 `json:"percent"`
+ Current float64 `json:"current"`
+ Chg float64 `json:"chg"`
+ Exchange string `json:"exchange"`
+ StockType int `json:"stock_type"`
+ SubType string `json:"sub_type"`
+ Ad int `json:"ad"`
+ AdId interface{} `json:"ad_id"`
+ ContentId interface{} `json:"content_id"`
+ Page interface{} `json:"page"`
+ Model interface{} `json:"model"`
+ Location interface{} `json:"location"`
+ TradeSession interface{} `json:"trade_session"`
+ CurrentExt interface{} `json:"current_ext"`
+ PercentExt interface{} `json:"percent_ext"`
+}
+
+type HotEvent struct {
+ PicSize interface{} `json:"pic_size"`
+ Tag string `json:"tag"`
+ Id int `json:"id"`
+ Pic string `json:"pic"`
+ Hot int `json:"hot"`
+ StatusCount int `json:"status_count"`
+ Content string `json:"content"`
+}
diff --git a/frontend/src/components/HotEvents.vue b/frontend/src/components/HotEvents.vue
new file mode 100644
index 0000000..8571f3f
--- /dev/null
+++ b/frontend/src/components/HotEvents.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+ 雪球热门
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/components/HotStockList.vue b/frontend/src/components/HotStockList.vue
new file mode 100644
index 0000000..5f978c5
--- /dev/null
+++ b/frontend/src/components/HotStockList.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ 股票名称
+ 涨跌幅
+ 当前价格
+ 热度
+ 热度变化
+ 排名变化
+
+
+
+
+
+
+
+ {{item.name}} {{item.code}}
+
+
+
+
+ {{item.percent}}%
+ {{item.current}}
+ {{item.value}}
+ {{item.increment}}
+ {{item.rank_change}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/components/HotTopics.vue b/frontend/src/components/HotTopics.vue
new file mode 100644
index 0000000..6a3850f
--- /dev/null
+++ b/frontend/src/components/HotTopics.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+ 股吧热门
+
+
+
+
+
+
+
+
+
+
+ {{v.name}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/components/KLineChart.vue b/frontend/src/components/KLineChart.vue
index 5791430..e1889c1 100644
--- a/frontend/src/components/KLineChart.vue
+++ b/frontend/src/components/KLineChart.vue
@@ -60,7 +60,7 @@ function handleKLine(code,name){
////console.log("values",values)
let option = {
title: {
- text: name,
+ text: name+" "+code,
left: '20px',
textStyle: {
color: darkTheme?'#ccc':'#456'
diff --git a/frontend/src/components/market.vue b/frontend/src/components/market.vue
index 7944673..c41038e 100644
--- a/frontend/src/components/market.vue
+++ b/frontend/src/components/market.vue
@@ -26,6 +26,9 @@ import StockResearchReportList from "./StockResearchReportList.vue";
import StockNoticeList from "./StockNoticeList.vue";
import LongTigerRankList from "./LongTigerRankList.vue";
import IndustryResearchReportList from "./IndustryResearchReportList.vue";
+import HotStockList from "./HotStockList.vue";
+import HotEvents from "./HotEvents.vue";
+import HotTopics from "./HotTopics.vue";
const route = useRoute()
const icon = ref('https://raw.githubusercontent.com/ArvinLovegood/go-stock/master/build/appicon.png');
@@ -557,8 +560,32 @@ function ReFlesh(source) {
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
>;
export function Greet(arg1:string):Promise;
+export function HotEvent(arg1:number):Promise;
+
+export function HotStock(arg1:string):Promise;
+
+export function HotTopic(arg1:number):Promise>;
+
export function IndustryResearchReport(arg1:string):Promise>;
export function LongTigerRank(arg1:string):Promise;
diff --git a/frontend/wailsjs/go/main/App.js b/frontend/wailsjs/go/main/App.js
index 27d7441..0e93c54 100644
--- a/frontend/wailsjs/go/main/App.js
+++ b/frontend/wailsjs/go/main/App.js
@@ -126,6 +126,18 @@ export function Greet(arg1) {
return window['go']['main']['App']['Greet'](arg1);
}
+export function HotEvent(arg1) {
+ return window['go']['main']['App']['HotEvent'](arg1);
+}
+
+export function HotStock(arg1) {
+ return window['go']['main']['App']['HotStock'](arg1);
+}
+
+export function HotTopic(arg1) {
+ return window['go']['main']['App']['HotTopic'](arg1);
+}
+
export function IndustryResearchReport(arg1) {
return window['go']['main']['App']['IndustryResearchReport'](arg1);
}