feat(stock):添加盘前盘后涨跌幅功能

- 在 StockData 结构中添加盘前盘后涨跌幅字段
- 修改 ParseFullSingleStockData 函数,解析盘前盘后涨跌幅数据
- 更新前端模型和组件,显示盘前盘后涨跌幅信息
- 调整弹幕位置,优化界面布局
This commit is contained in:
ArvinLovegood 2025-03-04 23:21:03 +08:00
parent adcde5efcc
commit 0864806770
5 changed files with 44 additions and 13 deletions

16
app.go
View File

@ -233,14 +233,14 @@ func IsHKTradingTime(date time.Time) bool {
func IsUSTradingTime(date time.Time) bool {
// 获取美国东部时区
est, err := time.LoadLocation("America/New_York")
var estTime time.Time
if err != nil {
logger.SugaredLogger.Errorf("加载时区失败: %s", err.Error())
return false
estTime = date.Add(time.Hour * -12)
} else {
// 将当前时间转换为美国东部时间
estTime = date.In(est)
}
// 将当前时间转换为美国东部时间
estTime := date.In(est)
// 判断是否是周末
weekday := estTime.Weekday()
if weekday == time.Saturday || weekday == time.Sunday {
@ -392,14 +392,14 @@ func addStockFollowData(follow data.FollowedStock, stockData *data.StockInfo) {
//开盘价
//openPrice, _ := convertor.ToFloat(stockData.Open)
if price > 0 {
if price > 0 && preClosePrice > 0 {
stockData.ChangePrice = mathutil.RoundToFloat(price-preClosePrice, 2)
stockData.ChangePercent = mathutil.RoundToFloat(mathutil.Div(price-preClosePrice, preClosePrice)*100, 3)
}
if highPrice > 0 {
if highPrice > 0 && preClosePrice > 0 {
stockData.HighRate = mathutil.RoundToFloat(mathutil.Div(highPrice-preClosePrice, preClosePrice)*100, 3)
}
if lowPrice > 0 {
if lowPrice > 0 && preClosePrice > 0 {
stockData.LowRate = mathutil.RoundToFloat(mathutil.Div(lowPrice-preClosePrice, preClosePrice)*100, 3)
}
if follow.CostPrice > 0 && follow.Volume > 0 {

View File

@ -75,6 +75,7 @@ type StockInfo struct {
A5V string `json:"卖五申报"`
Market string `json:"市场"`
BA string `json:"盘前盘后"`
BAChange string `json:"盘前盘后涨跌幅"`
//以下是字段值需二次计算
ChangePercent float64 `json:"changePercent"` //涨跌幅
@ -490,6 +491,7 @@ func ParseFullSingleStockData(data string) (*StockInfo, error) {
//logger.SugaredLogger.Infof("股票数据解析完成: %v", result)
marshal, err := json.Marshal(result)
if err != nil {
logger.SugaredLogger.Errorf("json.Marshal error:%s", err.Error())
return nil, err
}
//logger.SugaredLogger.Infof("股票数据解析完成marshal: %s", marshal)
@ -535,7 +537,7 @@ func ParseUSStockData(datas []string) (map[string]string, error) {
12190000000, 19
71, 20
170.2000, 21 盘前盘后盘
-0.01, 22
-0.01, 22 盘前盘后涨跌幅
-0.01, 23
Feb 27 07:59PM EST, 24
Feb 27 04:00PM EST, 25
@ -553,11 +555,12 @@ func ParseUSStockData(datas []string) (map[string]string, error) {
result["股票代码"] = code
result["股票名称"] = parts[0]
result["今日开盘价"] = parts[5]
result["昨日收盘价"] = parts[26]
result["昨日收盘价"] = parts[len(parts)-1]
result["今日最高价"] = parts[6]
result["今日最低价"] = parts[7]
result["当前价格"] = parts[1]
result["盘前盘后"] = parts[21]
result["盘前盘后涨跌幅"] = parts[22]
result["日期"] = strutil.SplitAndTrim(parts[3], " ", "")[0]
result["时间"] = strutil.SplitAndTrim(parts[3], " ", "")[1]
logger.SugaredLogger.Infof("美股股票数据解析完成: %v", result)

View File

@ -85,7 +85,7 @@ func TestParseFullSingleStockData(t *testing.T) {
SetHeader("Host", "hq.sinajs.cn").
SetHeader("Referer", "https://finance.sina.com.cn/").
SetHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0").
Get(fmt.Sprintf(sinaStockUrl, time.Now().Unix(), "sh600584,sz000938,hk01810,hk00856,gb_aapl"))
Get(fmt.Sprintf(sinaStockUrl, time.Now().Unix(), "sh600584,sz000938,hk01810,hk00856,gb_aapl,gb_tsla"))
if err != nil {
logger.SugaredLogger.Error(err.Error())
}
@ -99,6 +99,32 @@ func TestParseFullSingleStockData(t *testing.T) {
}
logger.SugaredLogger.Infof("%+#v", stockData)
}
result, er := ParseFullSingleStockData("var hq_str_gb_tsla = \"特斯拉,268.8472,-5.55,2025-03-04 22:52:56,-15.8028,270.9300,278.2800,268.1000,488.5400,138.8030,23618295,88214389,864751599149,2.23,120.550000,0.00,0.00,0.00,0.00,3216517037,61,0.0000,0.00,0.00,,Mar 04 09:52AM EST,284.6500,0,1,2025,6458502467.0000,0.0000,0.0000,0.0000,0.0000,284.6500\";")
if er != nil {
logger.SugaredLogger.Error(er.Error())
}
logger.SugaredLogger.Infof("%+#v", result)
marshal, err := json.Marshal(result)
if err != nil {
logger.SugaredLogger.Errorf("json.Marshal error:%s", err.Error())
}
logger.SugaredLogger.Infof("json:%s", string(marshal))
stockInfo := &StockInfo{}
err = json.Unmarshal(marshal, &stockInfo)
if err != nil {
logger.SugaredLogger.Errorf("json.Unmarshal error:%s", err.Error())
}
logger.SugaredLogger.Infof("%+#v", stockInfo)
stockData := stockInfo
db.Init("../../data/stock.db")
var count int64
db.Dao.Model(&StockInfo{}).Where("code = ?", stockData.Code).Count(&count)
if count == 0 {
db.Dao.Model(&StockInfo{}).Create(stockData)
} else {
db.Dao.Model(&StockInfo{}).Where("code = ?", stockData.Code).Updates(stockData)
}
}
func TestNewStockDataApi(t *testing.T) {

View File

@ -756,7 +756,7 @@ AI赋能股票分析自选股行情获取成本盈亏展示涨跌报警
</script>
<template>
<vue-danmaku v-model:danmus="danmus" style="height:100px; width:100%;z-index: 9;position:absolute; top: 30%; pointer-events: none;" ></vue-danmaku>
<vue-danmaku v-model:danmus="danmus" style="height:100px; width:100%;z-index: 9;position:absolute; top: 400px; pointer-events: none;" ></vue-danmaku>
<n-grid :x-gap="8" :cols="3" :y-gap="8" >
<n-gi v-for="result in sortedResults" style="margin-left: 2px" onmouseover="this.style.border='1px solid #3498db' " onmouseout="this.style.border='0px'">
<n-card :data-code="result['股票代码']" :bordered="false" :title="result['股票名称']" :closable="false" @close="removeMonitor(result['股票代码'],result['股票名称'],result.key)">
@ -764,7 +764,7 @@ AI赋能股票分析自选股行情获取成本盈亏展示涨跌报警
<n-gi>
<n-text :type="result.type" >
<n-number-animation :duration="1000" :precision="2" :from="result['上次当前价格']" :to="Number(result['当前价格'])" />
<n-tag size="small" :bordered="false" v-if="result['盘前盘后']">({{result['盘前盘后']}})</n-tag>
<n-tag size="small" :type="result.type" :bordered="false" v-if="result['盘前盘后']">({{result['盘前盘后']}} {{result['盘前盘后涨跌幅']}}%)</n-tag>
</n-text>
<n-text style="padding-left: 10px;" :type="result.type">
<n-number-animation :duration="1000" :precision="3" :from="0" :to="result.changePercent" />%

View File

@ -194,6 +194,7 @@ export namespace data {
"卖五申报": string;
"市场": string;
"盘前盘后": string;
"盘前盘后涨跌幅": string;
changePercent: number;
changePrice: number;
highRate: number;
@ -253,6 +254,7 @@ export namespace data {
this["卖五申报"] = source["卖五申报"];
this["市场"] = source["市场"];
this["盘前盘后"] = source["盘前盘后"];
this["盘前盘后涨跌幅"] = source["盘前盘后涨跌幅"];
this.changePercent = source["changePercent"];
this.changePrice = source["changePrice"];
this.highRate = source["highRate"];