mirror of
https://github.com/ArvinLovegood/go-stock.git
synced 2025-07-19 00:00:09 +08:00
feat(stock):添加美股数据支持
- 新增 StockInfoUS 模型用于存储美股信息 - 实现 IsUSTradingTime 函数判断美股交易时间 - 修改 MonitorStockPrices 函数以支持美股数据 - 更新前端股票组件以适配美股数据 - 优化后端 API 以支持美股实时数据获取和解析
This commit is contained in:
parent
7b3bad4102
commit
fdca30ce3a
45
app.go
45
app.go
@ -11,6 +11,7 @@ import (
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
"github.com/duke-git/lancet/v2/mathutil"
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
"github.com/getlantern/systray"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
@ -104,9 +105,8 @@ func (a *App) domReady(ctx context.Context) {
|
||||
ticker := time.NewTicker(time.Second * time.Duration(interval))
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
if isTradingTime(time.Now()) || IsHKTradingTime(time.Now()) {
|
||||
MonitorStockPrices(a)
|
||||
}
|
||||
MonitorStockPrices(a)
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
@ -229,6 +229,35 @@ func IsHKTradingTime(date time.Time) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsUSTradingTime 判断当前时间是否在美股交易时间内
|
||||
func IsUSTradingTime(date time.Time) bool {
|
||||
// 获取美国东部时区
|
||||
est, err := time.LoadLocation("America/New_York")
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Errorf("加载时区失败: %s", err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
// 将当前时间转换为美国东部时间
|
||||
estTime := date.In(est)
|
||||
|
||||
// 判断是否是周末
|
||||
weekday := estTime.Weekday()
|
||||
if weekday == time.Saturday || weekday == time.Sunday {
|
||||
return false
|
||||
}
|
||||
|
||||
// 获取小时和分钟
|
||||
hour, minute, _ := estTime.Clock()
|
||||
|
||||
// 判断是否在9:30到16:00之间
|
||||
if (hour == 9 && minute >= 30) || (hour >= 10 && hour < 16) || (hour == 16 && minute == 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func MonitorStockPrices(a *App) {
|
||||
dest := &[]data.FollowedStock{}
|
||||
db.Dao.Model(&data.FollowedStock{}).Find(dest)
|
||||
@ -244,6 +273,16 @@ func MonitorStockPrices(a *App) {
|
||||
|
||||
stockInfos := GetStockInfos(*dest...)
|
||||
for _, stockInfo := range *stockInfos {
|
||||
if strutil.HasPrefixAny(stockInfo.Code, []string{"SZ", "SH", "sh", "sz"}) && (!isTradingTime(time.Now())) {
|
||||
continue
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
total += stockInfo.ProfitAmountToday
|
||||
price, _ := convertor.ToFloat(stockInfo.Price)
|
||||
if stockInfo.PrePrice != price {
|
||||
|
@ -13,3 +13,7 @@ func TestIsHKTradingTime(t *testing.T) {
|
||||
f := IsHKTradingTime(time.Now())
|
||||
t.Log(f)
|
||||
}
|
||||
|
||||
func TestIsUSTradingTime(t *testing.T) {
|
||||
t.Log(IsUSTradingTime(time.Now()))
|
||||
}
|
||||
|
@ -2,12 +2,14 @@ package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
"go-stock/backend/db"
|
||||
"go-stock/backend/logger"
|
||||
"go-stock/backend/models"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@ -166,3 +168,143 @@ func TestHk(t *testing.T) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateUSName(t *testing.T) {
|
||||
db.Init("../../data/stock.db")
|
||||
us := &[]models.StockInfoUS{}
|
||||
db.Dao.Model(&models.StockInfoUS{}).Where("name = ?", "").Order("RANDOM()").Find(us)
|
||||
|
||||
for _, us := range *us {
|
||||
crawlerAPI := CrawlerApi{}
|
||||
crawlerBaseInfo := CrawlerBaseInfo{
|
||||
Name: "TestCrawler",
|
||||
Description: "Test Crawler Description",
|
||||
BaseUrl: "https://stock.finance.sina.com.cn",
|
||||
Headers: map[string]string{"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"},
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
crawlerAPI = crawlerAPI.NewCrawler(ctx, crawlerBaseInfo)
|
||||
|
||||
url := fmt.Sprintf("https://stock.finance.sina.com.cn/usstock/quotes/%s.html", us.Code[:len(us.Code)-3])
|
||||
logger.SugaredLogger.Infof("url: %s", url)
|
||||
//waitVisible := "span.quote_title_name"
|
||||
waitVisible := "div.hq_title > h1"
|
||||
|
||||
htmlContent, ok := crawlerAPI.GetHtml(url, waitVisible, true)
|
||||
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
//logger.SugaredLogger.Infof("htmlContent: %s", htmlContent)
|
||||
document, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent))
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Error(err.Error())
|
||||
}
|
||||
name := ""
|
||||
document.Find(waitVisible).Each(func(i int, selection *goquery.Selection) {
|
||||
name = strutil.RemoveNonPrintable(selection.Text())
|
||||
name = strutil.SplitAndTrim(name, " ", "")[0]
|
||||
logger.SugaredLogger.Infof("股票名称-:%s", name)
|
||||
})
|
||||
db.Dao.Model(&models.StockInfoUS{}).Where("code = ?", us.Code).Updates(map[string]interface{}{
|
||||
"name": name,
|
||||
"full_name": name,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
func TestUS(t *testing.T) {
|
||||
db.Init("../../data/stock.db")
|
||||
bytes, err := os.ReadFile("../../build/us.json")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
crawlerAPI := CrawlerApi{}
|
||||
crawlerBaseInfo := CrawlerBaseInfo{
|
||||
Name: "TestCrawler",
|
||||
Description: "Test Crawler Description",
|
||||
BaseUrl: "https://quote.eastmoney.com",
|
||||
Headers: map[string]string{"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"},
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer cancel()
|
||||
crawlerAPI = crawlerAPI.NewCrawler(ctx, crawlerBaseInfo)
|
||||
|
||||
tick := &Tick{}
|
||||
json.Unmarshal(bytes, &tick)
|
||||
for i, datum := range tick.Data {
|
||||
logger.SugaredLogger.Infof("datum: %d, %+v", i, datum)
|
||||
name := ""
|
||||
|
||||
//https://quote.eastmoney.com/us/AAPL.html
|
||||
//https://stock.finance.sina.com.cn/usstock/quotes/goog.html
|
||||
//url := fmt.Sprintf("https://stock.finance.sina.com.cn/usstock/quotes/%s.html", strings.ReplaceAll(datum.C, ".US", ""))
|
||||
////waitVisible := "span.quote_title_name"
|
||||
//waitVisible := "div.hq_title > h1"
|
||||
//
|
||||
//htmlContent, ok := crawlerAPI.GetHtml(url, waitVisible, true)
|
||||
//
|
||||
//if !ok {
|
||||
// continue
|
||||
//}
|
||||
////logger.SugaredLogger.Infof("htmlContent: %s", htmlContent)
|
||||
//document, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent))
|
||||
//if err != nil {
|
||||
// logger.SugaredLogger.Error(err.Error())
|
||||
//}
|
||||
//document.Find(waitVisible).Each(func(i int, selection *goquery.Selection) {
|
||||
// name = strutil.RemoveNonPrintable(selection.Text())
|
||||
// name = strutil.SplitAndTrim(name, " ", "")[0]
|
||||
// logger.SugaredLogger.Infof("股票名称-:%s", name)
|
||||
//})
|
||||
|
||||
us := &models.StockInfoUS{
|
||||
Code: datum.C + ".US",
|
||||
EName: datum.N,
|
||||
FullName: datum.N,
|
||||
Name: name,
|
||||
Exchange: datum.E,
|
||||
Type: datum.T,
|
||||
}
|
||||
db.Dao.Create(us)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUSSINA(t *testing.T) {
|
||||
//https://finance.sina.com.cn/stock/usstock/sector.shtml#cm
|
||||
crawlerAPI := CrawlerApi{}
|
||||
crawlerBaseInfo := CrawlerBaseInfo{
|
||||
Name: "TestCrawler",
|
||||
Description: "Test Crawler Description",
|
||||
BaseUrl: "https://quote.eastmoney.com",
|
||||
Headers: map[string]string{"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"},
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Minute)
|
||||
defer cancel()
|
||||
crawlerAPI = crawlerAPI.NewCrawler(ctx, crawlerBaseInfo)
|
||||
|
||||
html, ok := crawlerAPI.GetHtml("https://finance.sina.com.cn/stock/usstock/sector.shtml#cm", "div#data", false)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
document, err := goquery.NewDocumentFromReader(strings.NewReader(html))
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Error(err.Error())
|
||||
}
|
||||
document.Find("div#data > table >tbody >tr").Each(func(i int, selection *goquery.Selection) {
|
||||
tr := selection.Text()
|
||||
logger.SugaredLogger.Infof("tr: %s", tr)
|
||||
})
|
||||
}
|
||||
|
||||
type Tick struct {
|
||||
Code int `json:"code"`
|
||||
Status string `json:"status"`
|
||||
Data []struct {
|
||||
C string `json:"c"`
|
||||
N string `json:"n"`
|
||||
T string `json:"t"`
|
||||
E string `json:"e"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
@ -449,6 +449,9 @@ func SearchGuShiTongStockInfo(stock string, crawlTimeOut int64) *[]string {
|
||||
if strutil.HasPrefixAny(stock, []string{"SZ", "SH", "sh", "sz"}) {
|
||||
url = "https://gushitong.baidu.com/stock/ab-" + RemoveAllNonDigitChar(stock)
|
||||
}
|
||||
if strutil.HasPrefixAny(stock, []string{"us", "US", "gb_", "gb"}) {
|
||||
url = "https://gushitong.baidu.com/stock/us-" + strings.Replace(stock, "gb_", "", 1)
|
||||
}
|
||||
|
||||
logger.SugaredLogger.Infof("SearchGuShiTongStockInfo搜索股票-%s: %s", stock, url)
|
||||
actions := []chromedp.Action{
|
||||
@ -483,6 +486,10 @@ func GetFinancialReports(stockCode string, crawlTimeOut int64) *[]string {
|
||||
stockCode = strings.ReplaceAll(stockCode, "hk", "")
|
||||
stockCode = strings.ReplaceAll(stockCode, "HK", "")
|
||||
}
|
||||
if strutil.HasPrefixAny(stockCode, []string{"us", "gb_"}) {
|
||||
stockCode = strings.ReplaceAll(stockCode, "us", "")
|
||||
stockCode = strings.ReplaceAll(stockCode, "gb_", "")
|
||||
}
|
||||
|
||||
// 创建一个 chromedp 上下文
|
||||
timeoutCtx, timeoutCtxCancel := context.WithTimeout(context.Background(), time.Duration(crawlTimeOut)*time.Second)
|
||||
|
@ -25,5 +25,6 @@ func TestGetTopNewsList(t *testing.T) {
|
||||
func TestSearchGuShiTongStockInfo(t *testing.T) {
|
||||
SearchGuShiTongStockInfo("hk01810", 60)
|
||||
SearchGuShiTongStockInfo("sh600745", 60)
|
||||
SearchGuShiTongStockInfo("gb_goog", 60)
|
||||
|
||||
}
|
||||
|
@ -283,11 +283,24 @@ func (receiver StockDataApi) GetStockBaseInfo() {
|
||||
}
|
||||
|
||||
func (receiver StockDataApi) GetStockCodeRealTimeData(StockCodes ...string) (*[]StockInfo, error) {
|
||||
|
||||
codes := slice.JoinFunc(StockCodes, ",", func(s string) string {
|
||||
if strings.HasPrefix(s, "us") {
|
||||
s = strings.Replace(s, "us", "gb_", 1)
|
||||
}
|
||||
if strings.HasPrefix(s, "US") {
|
||||
s = strings.Replace(s, "US", "gb_", 1)
|
||||
}
|
||||
return strings.ToLower(s)
|
||||
})
|
||||
|
||||
url := fmt.Sprintf(sinaStockUrl, time.Now().Unix(), codes)
|
||||
//logger.SugaredLogger.Infof("GetStockCodeRealTimeData %s", url)
|
||||
resp, err := receiver.client.R().
|
||||
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(), slice.Join(StockCodes, ",")))
|
||||
Get(url)
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Error(err.Error())
|
||||
return &[]StockInfo{}, err
|
||||
@ -391,6 +404,9 @@ func (receiver StockDataApi) GetStockList(key string) []StockBasic {
|
||||
var result3 []models.StockInfoHK
|
||||
db.Dao.Model(&models.StockInfoHK{}).Where("name like ? or code like ?", "%"+key+"%", "%"+key+"%").Find(&result3)
|
||||
|
||||
var result4 []models.StockInfoUS
|
||||
db.Dao.Model(&models.StockInfoUS{}).Where("name like ? or code like ?", "%"+key+"%", "%"+key+"%").Find(&result4)
|
||||
|
||||
for _, item := range result2 {
|
||||
result = append(result, StockBasic{
|
||||
TsCode: item.TsCode,
|
||||
@ -409,6 +425,14 @@ func (receiver StockDataApi) GetStockList(key string) []StockBasic {
|
||||
Market: "HK",
|
||||
})
|
||||
}
|
||||
for _, item := range result4 {
|
||||
result = append(result, StockBasic{
|
||||
TsCode: item.Code,
|
||||
Name: item.Name,
|
||||
Fullname: item.Name,
|
||||
Market: "US",
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@ -436,6 +460,9 @@ func ParseFullSingleStockData(data string) (*StockInfo, error) {
|
||||
if strutil.ContainsAny(datas[0], []string{"hq_str_hk"}) {
|
||||
result, err = ParseHKStockData(datas)
|
||||
}
|
||||
if strutil.ContainsAny(datas[0], []string{"hq_str_gb"}) {
|
||||
result, err = ParseUSStockData(datas)
|
||||
}
|
||||
|
||||
//logger.SugaredLogger.Infof("股票数据解析完成: %v", result)
|
||||
marshal, err := json.Marshal(result)
|
||||
@ -452,6 +479,65 @@ func ParseFullSingleStockData(data string) (*StockInfo, error) {
|
||||
return stockInfo, nil
|
||||
}
|
||||
|
||||
func ParseUSStockData(datas []string) (map[string]string, error) {
|
||||
code := strings.Split(datas[0], "hq_str_")[1]
|
||||
result := make(map[string]string)
|
||||
parts := strutil.SplitAndTrim(datas[1], ",", "\"", ";")
|
||||
//parts := strings.Split(data, ",")
|
||||
if len(parts) < 30 {
|
||||
return nil, fmt.Errorf("invalid data format")
|
||||
}
|
||||
/*
|
||||
谷歌, 0
|
||||
170.2100, 1 现价
|
||||
-2.57, 2 涨跌幅
|
||||
2025-02-28 09:38:50, 3 时间
|
||||
-4.4900, 4 涨跌额
|
||||
175.9400, 5 今日开盘价
|
||||
176.5900, 6 区间
|
||||
169.7520, 7 区间
|
||||
208.7000, 8 52周区间
|
||||
130.9500, 9 52周区间
|
||||
25930485, 10 成交量
|
||||
17083496, 11 10日均量
|
||||
2074859900000, 12 市值
|
||||
8.13, 13 每股收益
|
||||
20.940000 , 14 市盈率
|
||||
0.00, 15
|
||||
0.00, 16
|
||||
0.20, 17
|
||||
0.00, 18
|
||||
12190000000, 19
|
||||
71, 20
|
||||
170.2000, 21 盘后
|
||||
-0.01, 22
|
||||
-0.01, 23
|
||||
Feb 27 07:59PM EST, 24
|
||||
Feb 27 04:00PM EST, 25
|
||||
174.7000, 26 前收盘
|
||||
2917444, 27
|
||||
1, 28
|
||||
2025, 29
|
||||
4456143849.0000, 30
|
||||
176.1200, 31
|
||||
163.7039, 32
|
||||
496605933.1411, 33
|
||||
170.2100, 34 现价
|
||||
174.7000 35 前收盘
|
||||
*/
|
||||
result["股票代码"] = code
|
||||
result["股票名称"] = parts[0]
|
||||
result["今日开盘价"] = parts[5]
|
||||
result["昨日收盘价"] = parts[26]
|
||||
result["今日最高价"] = parts[6]
|
||||
result["今日最低价"] = parts[7]
|
||||
result["当前价格"] = parts[1]
|
||||
result["日期"] = strutil.SplitAndTrim(parts[3], " ", "")[0]
|
||||
result["时间"] = strutil.SplitAndTrim(parts[3], " ", "")[1]
|
||||
logger.SugaredLogger.Infof("美股股票数据解析完成: %v", result)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func ParseHKStockData(datas []string) (map[string]string, error) {
|
||||
code := strings.Split(datas[0], "hq_str_")[1]
|
||||
result := make(map[string]string)
|
||||
|
@ -26,14 +26,15 @@ func TestGetTelegraph(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetFinancialReports(t *testing.T) {
|
||||
GetFinancialReports("sz000802", 30)
|
||||
//GetFinancialReports("sz000802", 30)
|
||||
//GetFinancialReports("hk00927", 30)
|
||||
GetFinancialReports("gb_aapl", 30)
|
||||
|
||||
}
|
||||
|
||||
func TestGetTelegraphSearch(t *testing.T) {
|
||||
//url := "https://www.cls.cn/searchPage?keyword=%E9%97%BB%E6%B3%B0%E7%A7%91%E6%8A%80&type=telegram"
|
||||
messages := SearchStockInfo("新 希 望", "telegram", 30)
|
||||
messages := SearchStockInfo("谷歌", "telegram", 30)
|
||||
for _, message := range *messages {
|
||||
logger.SugaredLogger.Info(message)
|
||||
}
|
||||
@ -82,7 +83,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"))
|
||||
Get(fmt.Sprintf(sinaStockUrl, time.Now().Unix(), "sh600584,sz000938,hk01810,hk00856,gb_aapl"))
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Error(err.Error())
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ var SensitiveWords = strings.Split("戊边、戍边、戌边、边防、李鹏
|
||||
func ReplaceSensitiveWords(text string) string {
|
||||
for _, word := range SensitiveWords {
|
||||
if strings.Contains(text, word) {
|
||||
text = strings.ReplaceAll(text, word, "*")
|
||||
text = strings.ReplaceAll(text, word, "")
|
||||
}
|
||||
}
|
||||
return text
|
||||
|
@ -176,6 +176,21 @@ func (receiver StockInfoHK) TableName() string {
|
||||
return "stock_base_info_hk"
|
||||
}
|
||||
|
||||
type StockInfoUS struct {
|
||||
gorm.Model
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
FullName string `json:"fullName"`
|
||||
EName string `json:"eName"`
|
||||
Exchange string `json:"exchange"`
|
||||
Type string `json:"type"`
|
||||
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag"`
|
||||
}
|
||||
|
||||
func (receiver StockInfoUS) TableName() string {
|
||||
return "stock_base_info_us"
|
||||
}
|
||||
|
||||
type Resp struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
|
@ -10,12 +10,12 @@ import {
|
||||
} from '../wailsjs/runtime'
|
||||
import {h, ref} from "vue";
|
||||
import { RouterLink } from 'vue-router'
|
||||
import {darkTheme, NIcon, NText,} from 'naive-ui'
|
||||
import {darkTheme, NGradientText, NIcon, NText,} from 'naive-ui'
|
||||
import {
|
||||
SettingsOutline,
|
||||
ReorderTwoOutline,
|
||||
ExpandOutline,
|
||||
PowerOutline, LogoGithub, MoveOutline, WalletOutline, StarOutline,
|
||||
PowerOutline, LogoGithub, MoveOutline, WalletOutline, StarOutline, AlarmOutline, SparklesOutline,
|
||||
} from '@vicons/ionicons5'
|
||||
const content = ref('数据来源于网络,仅供参考;投资有风险,入市需谨慎')
|
||||
const isFullscreen = ref(false)
|
||||
@ -36,7 +36,7 @@ const menuOptions = ref([
|
||||
},
|
||||
}
|
||||
},
|
||||
{ default: () => '我的自选',}
|
||||
{ default: () => '股票自选',}
|
||||
),
|
||||
key: 'stock',
|
||||
icon: renderIcon(StarOutline),
|
||||
@ -49,6 +49,29 @@ const menuOptions = ref([
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
NGradientText,
|
||||
{
|
||||
type: 'warning',
|
||||
style: {
|
||||
'text-decoration': 'line-through',
|
||||
}
|
||||
},
|
||||
{ default: () => '基金自选' }
|
||||
),
|
||||
key: 'fund',
|
||||
icon: renderIcon(SparklesOutline),
|
||||
children:[
|
||||
{
|
||||
label: ()=> h(NText, {type:realtimeProfit.value>0?'error':'success'},{ default: () => '敬请期待!'}),
|
||||
key: 'realtimeProfit',
|
||||
show: realtimeProfit.value,
|
||||
icon: renderIcon(AlarmOutline),
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
|
@ -465,7 +465,7 @@ function search(code,name){
|
||||
//window.open("https://www.cls.cn/stock?code="+code)
|
||||
//window.open("https://quote.eastmoney.com/"+code+".html")
|
||||
//window.open("https://finance.sina.com.cn/realstock/company/"+code+"/nc.shtml")
|
||||
window.open("https://www.iwencai.com/unifiedwap/result?w="+code)
|
||||
window.open("https://www.iwencai.com/unifiedwap/result?w="+name)
|
||||
//window.open("https://www.iwencai.com/chat/?question="+code)
|
||||
}, 500)
|
||||
}
|
||||
@ -486,16 +486,34 @@ function showFenshi(code,name){
|
||||
data.code=code
|
||||
data.name=name
|
||||
data.fenshiURL='http://image.sinajs.cn/newchart/min/n/'+data.code+'.gif'+"?t="+Date.now()
|
||||
|
||||
if(code.startsWith('hk')){
|
||||
data.fenshiURL='http://image.sinajs.cn/newchart/hk_stock/min/'+data.code.replace("hk","")+'.gif'+"?t="+Date.now()
|
||||
}
|
||||
if(code.startsWith('gb_')){
|
||||
data.fenshiURL='http://image.sinajs.cn/newchart/usstock/min/'+data.code.replace("gb_","")+'.gif'+"?t="+Date.now()
|
||||
}
|
||||
|
||||
modalShow2.value=true
|
||||
}
|
||||
function showK(code,name){
|
||||
data.code=code
|
||||
data.name=name
|
||||
data.kURL='http://image.sinajs.cn/newchart/daily/n/'+data.code+'.gif'+"?t="+Date.now()
|
||||
if(code.startsWith('hk')){
|
||||
data.kURL='http://image.sinajs.cn/newchart/hk_stock/daily/'+data.code.replace("hk","")+'.gif'+"?t="+Date.now()
|
||||
}
|
||||
if(code.startsWith('gb_')){
|
||||
data.kURL='http://image.sinajs.cn/newchart/usstock/daily/'+data.code.replace("gb_","")+'.gif'+"?t="+Date.now()
|
||||
}
|
||||
//https://image.sinajs.cn/newchart/usstock/daily/dji.gif
|
||||
//https://image.sinajs.cn/newchart/hk_stock/daily/06030.gif?1740729404273
|
||||
modalShow3.value=true
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function updateCostPriceAndVolumeNew(code,price,volume,alarm,formModel){
|
||||
|
||||
if(formModel.sort){
|
||||
|
Loading…
x
Reference in New Issue
Block a user