refactor(frontend):重构前端关注列表和美股股票价格更新逻辑

(当前美股功能处于 测试阶段,可能不稳定。)
- 修改 GetFollowList 接口返回类型为 any
- 优化关注列表中美国股票代码处理逻辑
- 增加股票价格更新时的盘前盘后信息
- 调整股票数据解析和处理逻辑
This commit is contained in:
ArvinLovegood 2025-03-01 12:42:00 +08:00
parent 826a29cd8c
commit ce91b2e532
5 changed files with 59 additions and 70 deletions

21
app.go
View File

@ -279,15 +279,16 @@ func MonitorStockPrices(a *App) {
if strutil.HasPrefixAny(stockInfo.Code, []string{"hk", "HK"}) && (!IsHKTradingTime(time.Now())) {
continue
}
if strutil.HasPrefixAny(stockInfo.Code, []string{"us", "US", "gb_"}) && (!IsUSTradingTime(time.Now())) {
continue
}
//if strutil.HasPrefixAny(stockInfo.Code, []string{"us", "US", "gb_"}) && (!IsUSTradingTime(time.Now())) {
// continue
//}
total += stockInfo.ProfitAmountToday
price, _ := convertor.ToFloat(stockInfo.Price)
if stockInfo.PrePrice != price {
//total += stockInfo.ProfitAmountToday
//price, _ := convertor.ToFloat(stockInfo.Price)
//if stockInfo.PrePrice != price {
logger.SugaredLogger.Infof("-----------------------股票代码: %s, 股票名称: %s, 股票价格: %s,盘前盘后:%s", stockInfo.Code, stockInfo.Name, stockInfo.Price, stockInfo.BA)
go runtime.EventsEmit(a.ctx, "stock_price", stockInfo)
}
//}
}
if total != 0 {
title := "go-stock " + time.Now().Format(time.DateTime) + fmt.Sprintf(" %.2f¥", total)
@ -307,6 +308,10 @@ func GetStockInfos(follows ...data.FollowedStock) *[]data.StockInfo {
stockData, _ := data.NewStockDataApi().GetStockCodeRealTimeData(stockCodes...)
for _, info := range *stockData {
v, ok := slice.FindBy(follows, func(idx int, follow data.FollowedStock) bool {
if strutil.HasPrefixAny(follow.StockCode, []string{"US", "us"}) {
return strings.ToLower(strings.Replace(follow.StockCode, "us", "gb_", 1)) == info.Code
}
return follow.StockCode == info.Code
})
if ok {
@ -453,7 +458,7 @@ func (a *App) UnFollow(stockCode string) string {
return data.NewStockDataApi().UnFollow(stockCode)
}
func (a *App) GetFollowList() []data.FollowedStock {
func (a *App) GetFollowList() *[]data.FollowedStock {
return data.NewStockDataApi().GetFollowList()
}

View File

@ -73,6 +73,8 @@ type StockInfo struct {
A4V string `json:"卖四申报"`
A5P string `json:"卖五报价"`
A5V string `json:"卖五申报"`
Market string `json:"市场"`
BA string `json:"盘前盘后"`
//以下是字段值需二次计算
ChangePercent float64 `json:"changePercent"` //涨跌幅
@ -315,6 +317,7 @@ func (receiver StockDataApi) GetStockCodeRealTimeData(StockCodes ...string) (*[]
for _, data := range dataStr {
//logger.SugaredLogger.Info(data)
stockData, err := ParseFullSingleStockData(data)
logger.SugaredLogger.Infof("GetStockCodeRealTimeData %v", stockData)
if err != nil {
logger.SugaredLogger.Error(err.Error())
continue
@ -360,11 +363,21 @@ func (receiver StockDataApi) Follow(stockCode string) string {
}
func (receiver StockDataApi) UnFollow(stockCode string) string {
if strutil.HasPrefixAny(stockCode, []string{"gb_"}) {
stockCode = strings.ToUpper(stockCode)
stockCode = strings.Replace(stockCode, "gb_", "us", 1)
stockCode = strings.Replace(stockCode, "GB_", "us", 1)
}
db.Dao.Model(&FollowedStock{}).Where("stock_code = ?", stockCode).Delete(&FollowedStock{})
return "取消关注成功"
}
func (receiver StockDataApi) SetCostPriceAndVolume(price float64, volume int64, stockCode string) string {
if strutil.HasPrefixAny(stockCode, []string{"gb_"}) {
stockCode = strings.ToUpper(stockCode)
stockCode = strings.Replace(stockCode, "gb_", "us", 1)
stockCode = strings.Replace(stockCode, "GB_", "us", 1)
}
err := db.Dao.Model(&FollowedStock{}).Where("stock_code = ?", stockCode).Update("cost_price", price).Update("volume", volume).Error
if err != nil {
logger.SugaredLogger.Error(err.Error())
@ -374,6 +387,11 @@ func (receiver StockDataApi) SetCostPriceAndVolume(price float64, volume int64,
}
func (receiver StockDataApi) SetAlarmChangePercent(val, alarmPrice float64, stockCode string) string {
if strutil.HasPrefixAny(stockCode, []string{"gb_"}) {
stockCode = strings.ToUpper(stockCode)
stockCode = strings.Replace(stockCode, "gb_", "us", 1)
stockCode = strings.Replace(stockCode, "GB_", "us", 1)
}
err := db.Dao.Model(&FollowedStock{}).Where("stock_code = ?", stockCode).Updates(&map[string]any{
"alarm_change_percent": val,
"alarm_price": alarmPrice,
@ -386,11 +404,16 @@ func (receiver StockDataApi) SetAlarmChangePercent(val, alarmPrice float64, stoc
}
func (receiver StockDataApi) SetStockSort(sort int64, stockCode string) {
if strutil.HasPrefixAny(stockCode, []string{"gb_"}) {
stockCode = strings.ToUpper(stockCode)
stockCode = strings.Replace(stockCode, "gb_", "us", 1)
stockCode = strings.Replace(stockCode, "GB_", "us", 1)
}
db.Dao.Model(&FollowedStock{}).Where("stock_code = ?", stockCode).Update("sort", sort)
}
func (receiver StockDataApi) GetFollowList() []FollowedStock {
var result []FollowedStock
func (receiver StockDataApi) GetFollowList() *[]FollowedStock {
var result *[]FollowedStock
db.Dao.Model(&FollowedStock{}).Order("sort asc,time desc").Find(&result)
return result
}
@ -427,7 +450,7 @@ func (receiver StockDataApi) GetStockList(key string) []StockBasic {
}
for _, item := range result4 {
result = append(result, StockBasic{
TsCode: item.Code,
TsCode: strings.ToLower(strings.Replace(item.Code, "us", "gb_", 1)),
Name: item.Name,
Fullname: item.Name,
Market: "US",
@ -469,9 +492,11 @@ func ParseFullSingleStockData(data string) (*StockInfo, error) {
if err != nil {
return nil, err
}
logger.SugaredLogger.Infof("股票数据解析完成marshal: %s", marshal)
stockInfo := &StockInfo{}
err = json.Unmarshal(marshal, &stockInfo)
if err != nil {
logger.SugaredLogger.Errorf("json.Unmarshal error:%s", err.Error())
return nil, err
}
//logger.SugaredLogger.Infof("股票数据解析完成stockInfo: %+v", stockInfo)
@ -509,7 +534,7 @@ func ParseUSStockData(datas []string) (map[string]string, error) {
0.00, 18
12190000000, 19
71, 20
170.2000, 21
170.2000, 21 前盘
-0.01, 22
-0.01, 23
Feb 27 07:59PM EST, 24
@ -532,9 +557,10 @@ func ParseUSStockData(datas []string) (map[string]string, error) {
result["今日最高价"] = parts[6]
result["今日最低价"] = parts[7]
result["当前价格"] = parts[1]
result["盘前盘后"] = parts[21]
result["日期"] = strutil.SplitAndTrim(parts[3], " ", "")[0]
result["时间"] = strutil.SplitAndTrim(parts[3], " ", "")[1]
//logger.SugaredLogger.Infof("美股股票数据解析完成: %v", result)
logger.SugaredLogger.Infof("美股股票数据解析完成: %v", result)
return result, nil
}

View File

@ -122,7 +122,11 @@ onBeforeMount(()=>{
GetFollowList().then(result => {
followList.value = result
for (const followedStock of result) {
if(followedStock.StockCode.startsWith("us")){
followedStock.StockCode="gb_"+ followedStock.StockCode.replace("us", "").toLowerCase()
}
if (!stocks.value.includes(followedStock.StockCode)) {
console.log("followList",followedStock.StockCode)
stocks.value.push(followedStock.StockCode)
}
}
@ -192,7 +196,6 @@ EventsOn("showSearch",(data)=>{
})
EventsOn("stock_price",(data)=>{
//console.log("stock_price",data[''])
updateData(data)
})
@ -390,6 +393,8 @@ function getStockList(value){
}
async function updateData(result) {
console.log("stock_price",result['日期'],result['时间'],result['股票代码'],result['股票名称'],result['当前价格'],result['盘前盘后'])
if(result["当前价格"]<=0){
result["当前价格"]=result["卖一报价"]
}
@ -474,7 +479,7 @@ function setStock(code,name){
//console.log("res:",res)
formModel.value.name=name
formModel.value.code=code
formModel.value.volume=res[0].Volume
formModel.value.volume=res[0].Volume?res[0].Volume:0
formModel.value.costPrice=res[0].CostPrice
formModel.value.alarm=res[0].AlarmChangePercent
formModel.value.alarmPrice=res[0].AlarmPrice
@ -759,6 +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-text>
<n-text style="padding-left: 10px;" :type="result.type">
<n-number-animation :duration="1000" :precision="3" :from="0" :to="result.changePercent" />%
@ -783,6 +789,7 @@ AI赋能股票分析自选股行情获取成本盈亏展示涨跌报警
</n-gi>
</n-grid>
<template #header-extra>
<n-tag size="small" :bordered="false">{{result['股票代码']}}</n-tag>&nbsp;
<n-button size="tiny" secondary type="primary" @click="removeMonitor(result['股票代码'],result['股票名称'],result.key)">
取消关注

View File

@ -13,7 +13,7 @@ export function GetAIResponseResult(arg1:string):Promise<models.AIResponseResult
export function GetConfig():Promise<data.Settings>;
export function GetFollowList():Promise<Array<data.FollowedStock>>;
export function GetFollowList():Promise<any>;
export function GetStockList(arg1:string):Promise<Array<data.StockBasic>>;

View File

@ -1,58 +1,5 @@
export namespace data {
export class FollowedStock {
StockCode: string;
Name: string;
Volume: number;
CostPrice: number;
Price: number;
PriceChange: number;
ChangePercent: number;
AlarmChangePercent: number;
AlarmPrice: number;
// Go type: time
Time: any;
Sort: number;
IsDel: number;
static createFrom(source: any = {}) {
return new FollowedStock(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.StockCode = source["StockCode"];
this.Name = source["Name"];
this.Volume = source["Volume"];
this.CostPrice = source["CostPrice"];
this.Price = source["Price"];
this.PriceChange = source["PriceChange"];
this.ChangePercent = source["ChangePercent"];
this.AlarmChangePercent = source["AlarmChangePercent"];
this.AlarmPrice = source["AlarmPrice"];
this.Time = this.convertValues(source["Time"], null);
this.Sort = source["Sort"];
this.IsDel = source["IsDel"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Settings {
ID: number;
// Go type: time
@ -245,6 +192,8 @@ export namespace data {
"卖四申报": string;
"卖五报价": string;
"卖五申报": string;
"市场": string;
"盘前盘后": string;
changePercent: number;
changePrice: number;
highRate: number;
@ -302,6 +251,8 @@ export namespace data {
this["卖四申报"] = source["卖四申报"];
this["卖五报价"] = source["卖五报价"];
this["卖五申报"] = source["卖五申报"];
this["市场"] = source["市场"];
this["盘前盘后"] = source["盘前盘后"];
this.changePercent = source["changePercent"];
this.changePrice = source["changePrice"];
this.highRate = source["highRate"];