From e3e06d342b6faaeea6119ffb40fc1fe6c82104d8 Mon Sep 17 00:00:00 2001 From: spark Date: Wed, 22 Jan 2025 17:00:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(backend):=20=E6=B7=BB=E5=8A=A0=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E4=BB=B7=E6=A0=BC=E4=BF=A1=E6=81=AF=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 SearchStockPriceInfo 函数,用于查询股票价格信息 - 更新 NewChatStream 函数,增加股票代码参数- 在前端添加股票代码参数传递 - 优化后端接口测试用例 --- app.go | 4 +-- backend/data/openai_api.go | 48 +++++++++++++++++++++-------- backend/data/openai_api_test.go | 2 +- backend/data/stock_data_api.go | 32 +++++++++++++++++++ backend/data/stock_data_api_test.go | 5 +++ frontend/src/components/stock.vue | 7 +++-- frontend/wailsjs/go/main/App.d.ts | 2 +- frontend/wailsjs/go/main/App.js | 4 +-- 8 files changed, 83 insertions(+), 21 deletions(-) diff --git a/app.go b/app.go index 9de81fc..06d75a4 100644 --- a/app.go +++ b/app.go @@ -377,8 +377,8 @@ func (a *App) NewChat(stock string) string { return data.NewDeepSeekOpenAi().NewChat(stock) } -func (a *App) NewChatStream(stock string) { - msgs := data.NewDeepSeekOpenAi().NewChatStream(stock) +func (a *App) NewChatStream(stock, stockCode string) { + msgs := data.NewDeepSeekOpenAi().NewChatStream(stock, stockCode) for msg := range msgs { runtime.EventsEmit(a.ctx, "newChatStream", msg) } diff --git a/backend/data/openai_api.go b/backend/data/openai_api.go index f981530..2f1a229 100644 --- a/backend/data/openai_api.go +++ b/backend/data/openai_api.go @@ -5,6 +5,7 @@ import ( "encoding/json" "github.com/go-resty/resty/v2" "strings" + "sync" ) // @Author spark @@ -108,7 +109,7 @@ func (o OpenAi) NewChat(stock string) string { //logger.SugaredLogger.Infof("%v", res.Choices[0].Message.Content) return res.Choices[0].Message.Content } -func (o OpenAi) NewChatStream(stock string) <-chan string { +func (o OpenAi) NewChatStream(stock, stockCode string) <-chan string { ch := make(chan string) go func() { defer close(ch) @@ -124,21 +125,42 @@ func (o OpenAi) NewChatStream(stock string) <-chan string { }, } - messages := SearchStockInfo(stock, "depth") - for _, message := range *messages { - msg = append(msg, map[string]interface{}{ - "role": "assistant", - "content": message, - }) - } + wg := &sync.WaitGroup{} - messages = SearchStockInfo(stock, "telegram") - for _, message := range *messages { + wg.Add(3) + go func() { + defer wg.Done() + messages := SearchStockPriceInfo(stockCode) + price := "" + for _, message := range *messages { + price += message + ";" + } msg = append(msg, map[string]interface{}{ "role": "assistant", - "content": message, + "content": stock + "当前价格:" + price, }) - } + }() + go func() { + defer wg.Done() + messages := SearchStockInfo(stock, "depth") + for _, message := range *messages { + msg = append(msg, map[string]interface{}{ + "role": "assistant", + "content": message, + }) + } + }() + go func() { + defer wg.Done() + messages := SearchStockInfo(stock, "telegram") + for _, message := range *messages { + msg = append(msg, map[string]interface{}{ + "role": "assistant", + "content": message, + }) + } + }() + wg.Wait() msg = append(msg, map[string]interface{}{ "role": "user", @@ -157,6 +179,7 @@ func (o OpenAi) NewChatStream(stock string) <-chan string { Post("/chat/completions") if err != nil { + ch <- err.Error() return } defer resp.RawBody().Close() @@ -164,6 +187,7 @@ func (o OpenAi) NewChatStream(stock string) <-chan string { scanner := bufio.NewScanner(resp.RawBody()) for scanner.Scan() { line := scanner.Text() + //logger.SugaredLogger.Infof("Received data: %s", line) if strings.HasPrefix(line, "data: ") { data := strings.TrimPrefix(line, "data: ") if data == "[DONE]" { diff --git a/backend/data/openai_api_test.go b/backend/data/openai_api_test.go index 934ca18..48e084f 100644 --- a/backend/data/openai_api_test.go +++ b/backend/data/openai_api_test.go @@ -8,7 +8,7 @@ import ( func TestNewDeepSeekOpenAiConfig(t *testing.T) { db.Init("../../data/stock.db") ai := NewDeepSeekOpenAi() - res := ai.NewChatStream("闻泰科技") + res := ai.NewChatStream("闻泰科技", "sh600745") for { select { case msg := <-res: diff --git a/backend/data/stock_data_api.go b/backend/data/stock_data_api.go index 4109fc5..ac5f706 100644 --- a/backend/data/stock_data_api.go +++ b/backend/data/stock_data_api.go @@ -510,6 +510,38 @@ func (IndexBasic) TableName() string { return "tushare_index_basic" } +func SearchStockPriceInfo(stockCode string) *[]string { + url := "https://www.cls.cn/stock?code=" + stockCode + // 创建一个 chromedp 上下文 + ctx, cancel := chromedp.NewContext( + context.Background(), + ) + defer cancel() + var htmlContent string + err := chromedp.Run(ctx, + chromedp.Navigate(url), + // 等待页面加载完成,可以根据需要调整等待时间 + chromedp.Sleep(3*time.Second), + chromedp.OuterHTML("html", &htmlContent, chromedp.ByQuery), + ) + if err != nil { + logger.SugaredLogger.Error(err.Error()) + return &[]string{} + } + document, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent)) + if err != nil { + logger.SugaredLogger.Error(err.Error()) + return &[]string{} + } + var messages []string + document.Find("div.quote-text-border,span.quote-price").Each(func(i int, selection *goquery.Selection) { + text := strutil.RemoveNonPrintable(selection.Text()) + logger.SugaredLogger.Info(text) + messages = append(messages, text) + + }) + return &messages +} func SearchStockInfo(stock, msgType string) *[]string { // 创建一个 chromedp 上下文 ctx, cancel := chromedp.NewContext( diff --git a/backend/data/stock_data_api_test.go b/backend/data/stock_data_api_test.go index c0923a4..a0d2d2e 100644 --- a/backend/data/stock_data_api_test.go +++ b/backend/data/stock_data_api_test.go @@ -49,6 +49,11 @@ func TestGetTelegraphSearch(t *testing.T) { logger.SugaredLogger.Info(message) } + //https://www.cls.cn/stock?code=sh600745 +} +func TestGetTelegraphSearch2(t *testing.T) { + SearchStockPriceInfo("sh600745") + } func TestParseFullSingleStockData(t *testing.T) { diff --git a/frontend/src/components/stock.vue b/frontend/src/components/stock.vue index a1be1a7..84f3eca 100644 --- a/frontend/src/components/stock.vue +++ b/frontend/src/components/stock.vue @@ -378,12 +378,13 @@ function SendMessage(result,type){ SendDingDingMessageByType(msg,result["股票代码"],type) } -function aiCheckStock(stock){ +function aiCheckStock(stock,stockCode){ data.airesult="" data.name=stock + data.code=stockCode modalShow4.value=true message.loading("ai检测中...") - NewChatStream(stock) + NewChatStream(stock,stockCode) } function getTypeName(type){ @@ -443,7 +444,7 @@ function getHeight() { 取消关注   - AI分析 + AI分析