refactor(backend):优化日志输出和接口调用

- 移除不必要的日志输出,减少日志噪音
- 优化 OpenAI API 调用逻辑,改进消息构建方式
- 注释掉部分不必要的代码,提高代码可读性
- 更新 README 中的 DeepSeek 相关信息
This commit is contained in:
ArvinLovegood 2025-03-31 16:39:13 +08:00
parent 7b625e2e80
commit 51aae0539c
9 changed files with 134 additions and 87 deletions

View File

@ -31,7 +31,7 @@ QQ交流群[点击链接加入群聊【go-stock交流群】491605333](http
| [Ollama](https://ollama.com/) | ✅ | 本地大模型运行平台 | | [Ollama](https://ollama.com/) | ✅ | 本地大模型运行平台 |
| [LMStudio](https://lmstudio.ai/) | ✅ | 本地大模型运行平台 | | [LMStudio](https://lmstudio.ai/) | ✅ | 本地大模型运行平台 |
| [AnythingLLM](https://anythingllm.com/) | ✅ | 本地知识库 | | [AnythingLLM](https://anythingllm.com/) | ✅ | 本地知识库 |
| [DeepSeek](https://www.deepseek.com/) | ✅ | deepseek-reasoner模型测试有问题,可通过本地模型或聚合模型平台使用 | | [DeepSeek](https://www.deepseek.com/) | ✅ | deepseek-reasoner,deepseek-chat |
| [大模型聚合平台](https://cloud.siliconflow.cn/i/foufCerk) | ✅ | 如:[硅基流动](https://cloud.siliconflow.cn/i/foufCerk)[火山方舟](https://www.volcengine.com/experience/ark?utm_term=202502dsinvite&ac=DSASUQY5&rc=IJSE43PZ) | | [大模型聚合平台](https://cloud.siliconflow.cn/i/foufCerk) | ✅ | 如:[硅基流动](https://cloud.siliconflow.cn/i/foufCerk)[火山方舟](https://www.volcengine.com/experience/ark?utm_term=202502dsinvite&ac=DSASUQY5&rc=IJSE43PZ) |
### <span style="color: #568DF4;">各位亲爱的朋友们,如果您对这个项目感兴趣,请先给我一个<i style="color: #EA2626;">star</i>吧,谢谢!</span>💕 ### <span style="color: #568DF4;">各位亲爱的朋友们,如果您对这个项目感兴趣,请先给我一个<i style="color: #EA2626;">star</i>吧,谢谢!</span>💕

2
app.go
View File

@ -380,7 +380,7 @@ func MonitorStockPrices(a *App) {
total += stockInfo.ProfitAmountToday total += stockInfo.ProfitAmountToday
price, _ := convertor.ToFloat(stockInfo.Price) price, _ := convertor.ToFloat(stockInfo.Price)
if stockInfo.PrePrice != price { if stockInfo.PrePrice != price {
logger.SugaredLogger.Infof("-----------------------股票代码: %s, 股票名称: %s, 股票价格: %s,盘前盘后:%s", stockInfo.Code, stockInfo.Name, stockInfo.Price, stockInfo.BA) //logger.SugaredLogger.Infof("-----------------------股票代码: %s, 股票名称: %s, 股票价格: %s,盘前盘后:%s", stockInfo.Code, stockInfo.Name, stockInfo.Price, stockInfo.BA)
go runtime.EventsEmit(a.ctx, "stock_price", stockInfo) go runtime.EventsEmit(a.ctx, "stock_price", stockInfo)
} }
} }

View File

@ -32,7 +32,7 @@ func (c *CrawlerApi) NewCrawler(ctx context.Context, crawlerBaseInfo CrawlerBase
func (c *CrawlerApi) GetHtml(url, waitVisible string, headless bool) (string, bool) { func (c *CrawlerApi) GetHtml(url, waitVisible string, headless bool) (string, bool) {
htmlContent := "" htmlContent := ""
path := getConfig().BrowserPath path := getConfig().BrowserPath
logger.SugaredLogger.Infof("Browser path:%s", path) //logger.SugaredLogger.Infof("Browser path:%s", path)
if path != "" { if path != "" {
pctx, pcancel := chromedp.NewExecAllocator( pctx, pcancel := chromedp.NewExecAllocator(
c.crawlerCtx, c.crawlerCtx,
@ -95,7 +95,7 @@ func (c *CrawlerApi) GetHtml(url, waitVisible string, headless bool) (string, bo
func (c *CrawlerApi) GetHtmlWithNoCancel(url, waitVisible string, headless bool) (html string, ok bool, parent context.CancelFunc, child context.CancelFunc) { func (c *CrawlerApi) GetHtmlWithNoCancel(url, waitVisible string, headless bool) (html string, ok bool, parent context.CancelFunc, child context.CancelFunc) {
htmlContent := "" htmlContent := ""
path := getConfig().BrowserPath path := getConfig().BrowserPath
logger.SugaredLogger.Infof("BrowserPath :%s", path) //logger.SugaredLogger.Infof("BrowserPath :%s", path)
var parentCancel context.CancelFunc var parentCancel context.CancelFunc
var childCancel context.CancelFunc var childCancel context.CancelFunc
var pctx context.Context var pctx context.Context
@ -163,7 +163,7 @@ func (c *CrawlerApi) GetHtmlWithActions(actions *[]chromedp.Action, headless boo
*actions = append(*actions, chromedp.InnerHTML("body", &htmlContent)) *actions = append(*actions, chromedp.InnerHTML("body", &htmlContent))
path := getConfig().BrowserPath path := getConfig().BrowserPath
logger.SugaredLogger.Infof("GetHtmlWithActions path:%s", path) //logger.SugaredLogger.Infof("GetHtmlWithActions path:%s", path)
if path != "" { if path != "" {
pctx, pcancel := chromedp.NewExecAllocator( pctx, pcancel := chromedp.NewExecAllocator(
c.crawlerCtx, c.crawlerCtx,

View File

@ -22,7 +22,7 @@ func NewDingDingAPI() *DingDingAPI {
func (DingDingAPI) SendDingDingMessage(message string) string { func (DingDingAPI) SendDingDingMessage(message string) string {
if getConfig().DingPushEnable == false { if getConfig().DingPushEnable == false {
logger.SugaredLogger.Info("钉钉推送未开启") //logger.SugaredLogger.Info("钉钉推送未开启")
return "钉钉推送未开启" return "钉钉推送未开启"
} }
// 发送钉钉消息 // 发送钉钉消息

View File

@ -107,7 +107,7 @@ func (f *FundApi) CrawlFundBasic(fundCode string) (*FundBasic, error) {
crawler = crawler.NewCrawler(ctx, crawler.crawlerBaseInfo) crawler = crawler.NewCrawler(ctx, crawler.crawlerBaseInfo)
url := fmt.Sprintf("%s/%s.html", crawler.crawlerBaseInfo.BaseUrl, fundCode) url := fmt.Sprintf("%s/%s.html", crawler.crawlerBaseInfo.BaseUrl, fundCode)
logger.SugaredLogger.Infof("CrawlFundBasic url:%s", url) //logger.SugaredLogger.Infof("CrawlFundBasic url:%s", url)
// 使用现有爬虫框架解析页面 // 使用现有爬虫框架解析页面
htmlContent, ok := crawler.GetHtml(url, ".merchandiseDetail", true) htmlContent, ok := crawler.GetHtml(url, ".merchandiseDetail", true)
@ -124,14 +124,14 @@ func (f *FundApi) CrawlFundBasic(fundCode string) (*FundBasic, error) {
// 解析基础信息 // 解析基础信息
name := doc.Find(".merchandiseDetail .fundDetail-tit").First().Text() name := doc.Find(".merchandiseDetail .fundDetail-tit").First().Text()
fund.Name = strings.TrimSpace(strutil.ReplaceWithMap(name, map[string]string{"查看相关ETF>": ""})) fund.Name = strings.TrimSpace(strutil.ReplaceWithMap(name, map[string]string{"查看相关ETF>": ""}))
logger.SugaredLogger.Infof("基金名称:%s", fund.Name) //logger.SugaredLogger.Infof("基金名称:%s", fund.Name)
doc.Find(".infoOfFund table td ").Each(func(i int, s *goquery.Selection) { doc.Find(".infoOfFund table td ").Each(func(i int, s *goquery.Selection) {
text := strutil.RemoveWhiteSpace(s.Text(), true) text := strutil.RemoveWhiteSpace(s.Text(), true)
logger.SugaredLogger.Infof("基金信息:%+v", text) //logger.SugaredLogger.Infof("基金信息:%+v", text)
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
logger.SugaredLogger.Errorf("panic: %v", r) //logger.SugaredLogger.Errorf("panic: %v", r)
} }
}() }()
splitEx := strutil.SplitEx(text, "", true) splitEx := strutil.SplitEx(text, "", true)
@ -161,19 +161,19 @@ func (f *FundApi) CrawlFundBasic(fundCode string) (*FundBasic, error) {
//获取基金净值涨跌幅信息 //获取基金净值涨跌幅信息
doc.Find(".dataOfFund dl > dd").Each(func(i int, s *goquery.Selection) { doc.Find(".dataOfFund dl > dd").Each(func(i int, s *goquery.Selection) {
text := strutil.RemoveWhiteSpace(s.Text(), true) text := strutil.RemoveWhiteSpace(s.Text(), true)
logger.SugaredLogger.Infof("净值涨跌幅信息:%+v", text) //logger.SugaredLogger.Infof("净值涨跌幅信息:%+v", text)
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
logger.SugaredLogger.Errorf("panic: %v", r) //logger.SugaredLogger.Errorf("panic: %v", r)
} }
}() }()
splitEx := strutil.SplitAndTrim(text, "", "%") splitEx := strutil.SplitAndTrim(text, "", "%")
toFloat, err1 := convertor.ToFloat(splitEx[1]) toFloat, err1 := convertor.ToFloat(splitEx[1])
if err1 != nil { if err1 != nil {
logger.SugaredLogger.Errorf("转换失败:%+v", err) //logger.SugaredLogger.Errorf("转换失败:%+v", err)
return return
} }
logger.SugaredLogger.Infof("净值涨跌幅信息:%+v", toFloat) //logger.SugaredLogger.Infof("净值涨跌幅信息:%+v", toFloat)
if strutil.ContainsAny(text, []string{"近1月"}) { if strutil.ContainsAny(text, []string{"近1月"}) {
fund.NetGrowth1 = &toFloat fund.NetGrowth1 = &toFloat
} }
@ -199,17 +199,17 @@ func (f *FundApi) CrawlFundBasic(fundCode string) (*FundBasic, error) {
fund.NetGrowthAll = &toFloat fund.NetGrowthAll = &toFloat
} }
}) })
doc.Find(".dataOfFund dl > dd.dataNums,.dataOfFund dl > dt").Each(func(i int, s *goquery.Selection) { //doc.Find(".dataOfFund dl > dd.dataNums,.dataOfFund dl > dt").Each(func(i int, s *goquery.Selection) {
text := s.Text() // //text := s.Text()
defer func() { // defer func() {
if r := recover(); r != nil { // if r := recover(); r != nil {
logger.SugaredLogger.Errorf("panic: %v", r) // //logger.SugaredLogger.Errorf("panic: %v", r)
} // }
}() // }()
logger.SugaredLogger.Infof("净值信息:%+v", text) // //logger.SugaredLogger.Infof("净值信息:%+v", text)
}) //})
logger.SugaredLogger.Infof("基金信息:%+v", fund) //logger.SugaredLogger.Infof("基金信息:%+v", fund)
count := int64(0) count := int64(0)
db.Dao.Model(fund).Where("code=?", fund.Code).Count(&count) db.Dao.Model(fund).Where("code=?", fund.Code).Count(&count)
@ -275,7 +275,7 @@ func (f *FundApi) UnFollowFund(fundCode string) string {
func (f *FundApi) AllFund() { func (f *FundApi) AllFund() {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
logger.SugaredLogger.Errorf("AllFund panic: %v", r) //logger.SugaredLogger.Errorf("AllFund panic: %v", r)
} }
}() }()
@ -296,7 +296,7 @@ func (f *FundApi) AllFund() {
cnt++ cnt++
name := text[0] name := text[0]
str := strutil.SplitAndTrim(name, "", "", "") str := strutil.SplitAndTrim(name, "", "", "")
logger.SugaredLogger.Infof("%d,基金信息 code:%s,name:%s", cnt, str[0], str[1]) //logger.SugaredLogger.Infof("%d,基金信息 code:%s,name:%s", cnt, str[0], str[1])
//go f.CrawlFundBasic(str[0]) //go f.CrawlFundBasic(str[0])
fund := &FundBasic{ fund := &FundBasic{
Code: str[0], Code: str[0],
@ -337,11 +337,11 @@ func (f *FundApi) CrawlFundNetEstimatedUnit(code string) {
} }
if response.StatusCode() == 200 { if response.StatusCode() == 200 {
htmlContent := string(response.Body()) htmlContent := string(response.Body())
logger.SugaredLogger.Infof("htmlContent:%s", htmlContent) //logger.SugaredLogger.Infof("htmlContent:%s", htmlContent)
if strings.Contains(htmlContent, "jsonpgz") { if strings.Contains(htmlContent, "jsonpgz") {
htmlContent = strutil.Trim(htmlContent, "jsonpgz(", ");") htmlContent = strutil.Trim(htmlContent, "jsonpgz(", ");")
htmlContent = strutil.Trim(htmlContent, ");") htmlContent = strutil.Trim(htmlContent, ");")
logger.SugaredLogger.Infof("基金净值信息:%s", htmlContent) //logger.SugaredLogger.Infof("基金净值信息:%s", htmlContent)
err := json.Unmarshal([]byte(htmlContent), &fundNetUnitValue) err := json.Unmarshal([]byte(htmlContent), &fundNetUnitValue)
if err != nil { if err != nil {
logger.SugaredLogger.Errorf("json.Unmarshal error:%s", err.Error()) logger.SugaredLogger.Errorf("json.Unmarshal error:%s", err.Error())
@ -365,7 +365,7 @@ func (f *FundApi) CrawlFundNetEstimatedUnit(code string) {
func (f *FundApi) CrawlFundNetUnitValue(code string) { func (f *FundApi) CrawlFundNetUnitValue(code string) {
// var fundNetUnitValue FundNetUnitValue // var fundNetUnitValue FundNetUnitValue
url := fmt.Sprintf("http://hq.sinajs.cn/rn=%d&list=f_%s", time.Now().UnixMilli(), code) url := fmt.Sprintf("http://hq.sinajs.cn/rn=%d&list=f_%s", time.Now().UnixMilli(), code)
logger.SugaredLogger.Infof("url:%s", url) //logger.SugaredLogger.Infof("url:%s", url)
response, err := f.client.SetTimeout(time.Duration(f.config.CrawlTimeOut)*time.Second).R(). response, err := f.client.SetTimeout(time.Duration(f.config.CrawlTimeOut)*time.Second).R().
SetHeader("Host", "hq.sinajs.cn"). SetHeader("Host", "hq.sinajs.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"). 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").
@ -377,12 +377,12 @@ func (f *FundApi) CrawlFundNetUnitValue(code string) {
} }
if response.StatusCode() == 200 { if response.StatusCode() == 200 {
data := string(GB18030ToUTF8(response.Body())) data := string(GB18030ToUTF8(response.Body()))
logger.SugaredLogger.Infof("data:%s", data) //logger.SugaredLogger.Infof("data:%s", data)
datas := strutil.SplitAndTrim(data, "=", "\"") datas := strutil.SplitAndTrim(data, "=", "\"")
if len(datas) >= 2 { if len(datas) >= 2 {
//codex := strings.Split(datas[0], "hq_str_f_")[1] //codex := strings.Split(datas[0], "hq_str_f_")[1]
parts := strutil.SplitAndTrim(datas[1], ",", "\"") parts := strutil.SplitAndTrim(datas[1], ",", "\"")
logger.SugaredLogger.Infof("parts:%s", parts) //logger.SugaredLogger.Infof("parts:%s", parts)
val, err := convertor.ToFloat(parts[1]) val, err := convertor.ToFloat(parts[1])
if err != nil { if err != nil {
logger.SugaredLogger.Errorf("err:%s", err.Error()) logger.SugaredLogger.Errorf("err:%s", err.Error())

View File

@ -167,9 +167,14 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
market.WriteString(getZSInfo("创业板指数", "sz399006", 30) + "\n") market.WriteString(getZSInfo("创业板指数", "sz399006", 30) + "\n")
market.WriteString(getZSInfo("上证综合指数", "sh000001", 30) + "\n") market.WriteString(getZSInfo("上证综合指数", "sh000001", 30) + "\n")
market.WriteString(getZSInfo("沪深300指数", "sh000300", 30) + "\n") market.WriteString(getZSInfo("沪深300指数", "sh000300", 30) + "\n")
//logger.SugaredLogger.Infof("NewChatStream getZSInfo=\n%s", market.String())
msg = append(msg, map[string]interface{}{ msg = append(msg, map[string]interface{}{
"role": "user", "role": "user",
"content": "大盘指数情况如下:\n" + market.String(), "content": "市场指数",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
"content": "市场指数情况如下:\n" + market.String(),
}) })
}() }()
@ -184,6 +189,10 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
K := NewTushareApi(getConfig()).GetDaily(code, startDate, endDate, o.CrawlTimeOut) K := NewTushareApi(getConfig()).GetDaily(code, startDate, endDate, o.CrawlTimeOut)
msg = append(msg, map[string]interface{}{ msg = append(msg, map[string]interface{}{
"role": "user", "role": "user",
"content": stock + "日K数据",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
"content": stock + "日K数据如下\n" + K, "content": stock + "日K数据如下\n" + K,
}) })
}() }()
@ -208,6 +217,10 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
} }
msg = append(msg, map[string]interface{}{ msg = append(msg, map[string]interface{}{
"role": "user", "role": "user",
"content": stock + "股价数据",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
"content": "\n## " + stock + "股价数据:\n" + price, "content": "\n## " + stock + "股价数据:\n" + price,
}) })
}() }()
@ -231,9 +244,13 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取股票财报失败,分析结果可能不准确") go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取股票财报失败,分析结果可能不准确")
return return
} }
msg = append(msg, map[string]interface{}{
"role": "user",
"content": stock + "财报数据",
})
for _, message := range *messages { for _, message := range *messages {
msg = append(msg, map[string]interface{}{ msg = append(msg, map[string]interface{}{
"role": "user", "role": "assistant",
"content": stock + message, "content": stock + message,
}) })
} }
@ -248,12 +265,19 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
//go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取市场资讯失败,分析结果可能不准确") //go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取市场资讯失败,分析结果可能不准确")
return return
} }
var messageText strings.Builder
for _, message := range *messages { for _, message := range *messages {
msg = append(msg, map[string]interface{}{ messageText.WriteString(message + "\n")
"role": "user",
"content": message,
})
} }
msg = append(msg, map[string]interface{}{
"role": "user",
"content": "市场资讯",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
"content": messageText.String(),
})
messages = GetTopNewsList(o.CrawlTimeOut) messages = GetTopNewsList(o.CrawlTimeOut)
if messages == nil || len(*messages) == 0 { if messages == nil || len(*messages) == 0 {
logger.SugaredLogger.Error("获取新闻资讯失败") logger.SugaredLogger.Error("获取新闻资讯失败")
@ -261,12 +285,18 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
//go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取新闻资讯失败,分析结果可能不准确") //go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取新闻资讯失败,分析结果可能不准确")
return return
} }
var newsText strings.Builder
for _, message := range *messages { for _, message := range *messages {
msg = append(msg, map[string]interface{}{ newsText.WriteString(message + "\n")
"role": "user",
"content": message,
})
} }
msg = append(msg, map[string]interface{}{
"role": "user",
"content": "新闻资讯",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
"content": newsText.String(),
})
}() }()
//go func() { //go func() {
@ -294,12 +324,18 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
//go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取股票电报资讯失败,分析结果可能不准确") //go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取股票电报资讯失败,分析结果可能不准确")
return return
} }
var newsText strings.Builder
for _, message := range *messages { for _, message := range *messages {
msg = append(msg, map[string]interface{}{ newsText.WriteString(message + "\n")
"role": "user",
"content": message,
})
} }
msg = append(msg, map[string]interface{}{
"role": "user",
"content": stock + "相关新闻资讯",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
"content": newsText.String(),
})
}() }()
go func() { go func() {
@ -316,12 +352,18 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
//go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取股势通资讯失败,分析结果可能不准确") //go runtime.EventsEmit(o.ctx, "warnMsg", "❗获取股势通资讯失败,分析结果可能不准确")
return return
} }
var newsText strings.Builder
for _, message := range *messages { for _, message := range *messages {
msg = append(msg, map[string]interface{}{ newsText.WriteString(message + "\n")
"role": "user",
"content": message,
})
} }
msg = append(msg, map[string]interface{}{
"role": "user",
"content": stock + "相关新闻资讯",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
"content": newsText.String(),
})
}() }()
wg.Wait() wg.Wait()
@ -329,6 +371,10 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
"role": "user", "role": "user",
"content": question, "content": question,
}) })
//reqJson, _ := json.Marshal(msg)
//logger.SugaredLogger.Errorf("Stream request: \n%s", reqJson)
client := resty.New() client := resty.New()
client.SetBaseURL(strutil.Trim(o.BaseUrl)) client.SetBaseURL(strutil.Trim(o.BaseUrl))
client.SetHeader("Authorization", "Bearer "+o.ApiKey) client.SetHeader("Authorization", "Bearer "+o.ApiKey)
@ -365,7 +411,7 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
scanner := bufio.NewScanner(body) scanner := bufio.NewScanner(body)
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := scanner.Text()
logger.SugaredLogger.Infof("Received data: %s", line) //logger.SugaredLogger.Infof("Received data: %s", line)
if strings.HasPrefix(line, "data:") { if strings.HasPrefix(line, "data:") {
data := strutil.Trim(strings.TrimPrefix(line, "data:")) data := strutil.Trim(strings.TrimPrefix(line, "data:"))
if data == "[DONE]" { if data == "[DONE]" {
@ -396,7 +442,7 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
"content": content, "content": content,
} }
logger.SugaredLogger.Infof("Content data: %s", content) //logger.SugaredLogger.Infof("Content data: %s", content)
} }
if reasoningContent := choice.Delta.ReasoningContent; reasoningContent != "" { if reasoningContent := choice.Delta.ReasoningContent; reasoningContent != "" {
//ch <- reasoningContent //ch <- reasoningContent
@ -408,7 +454,7 @@ func (o OpenAi) NewChatStream(stock, stockCode, userQuestion string, sysPromptId
"content": reasoningContent, "content": reasoningContent,
} }
logger.SugaredLogger.Infof("ReasoningContent data: %s", reasoningContent) //logger.SugaredLogger.Infof("ReasoningContent data: %s", reasoningContent)
} }
if choice.FinishReason == "stop" { if choice.FinishReason == "stop" {
return return
@ -482,7 +528,7 @@ func SearchGuShiTongStockInfo(stock string, crawlTimeOut int64) *[]string {
url = "https://gushitong.baidu.com/stock/us-" + strings.Replace(stock, "gb_", "", 1) url = "https://gushitong.baidu.com/stock/us-" + strings.Replace(stock, "gb_", "", 1)
} }
logger.SugaredLogger.Infof("SearchGuShiTongStockInfo搜索股票-%s: %s", stock, url) //logger.SugaredLogger.Infof("SearchGuShiTongStockInfo搜索股票-%s: %s", stock, url)
actions := []chromedp.Action{ actions := []chromedp.Action{
chromedp.Navigate(url), chromedp.Navigate(url),
chromedp.WaitVisible("div.cos-tab"), chromedp.WaitVisible("div.cos-tab"),
@ -503,9 +549,9 @@ func SearchGuShiTongStockInfo(stock string, crawlTimeOut int64) *[]string {
document.Find("div.finance-hover,div.list-date").Each(func(i int, selection *goquery.Selection) { document.Find("div.finance-hover,div.list-date").Each(func(i int, selection *goquery.Selection) {
text := strutil.RemoveWhiteSpace(selection.Text(), false) text := strutil.RemoveWhiteSpace(selection.Text(), false)
messages = append(messages, ReplaceSensitiveWords(text)) messages = append(messages, ReplaceSensitiveWords(text))
logger.SugaredLogger.Infof("SearchGuShiTongStockInfo搜索到消息-%s: %s", "", text) //logger.SugaredLogger.Infof("SearchGuShiTongStockInfo搜索到消息-%s: %s", "", text)
}) })
logger.SugaredLogger.Infof("messages:%d", len(messages)) //logger.SugaredLogger.Infof("messages:%d", len(messages))
} }
return &messages return &messages
} }
@ -527,7 +573,7 @@ func GetFinancialReports(stockCode string, crawlTimeOut int64) *[]string {
} }
logger.SugaredLogger.Infof("GetFinancialReports搜索股票-%s: %s", stockCode, url) //logger.SugaredLogger.Infof("GetFinancialReports搜索股票-%s: %s", stockCode, url)
crawlerAPI := CrawlerApi{} crawlerAPI := CrawlerApi{}
crawlerBaseInfo := CrawlerBaseInfo{ crawlerBaseInfo := CrawlerBaseInfo{
@ -570,7 +616,7 @@ func GetTelegraphList(crawlTimeOut int64) *[]string {
} }
var telegraph []string var telegraph []string
document.Find("div.telegraph-content-box").Each(func(i int, selection *goquery.Selection) { document.Find("div.telegraph-content-box").Each(func(i int, selection *goquery.Selection) {
logger.SugaredLogger.Info(selection.Text()) //logger.SugaredLogger.Info(selection.Text())
telegraph = append(telegraph, ReplaceSensitiveWords(selection.Text())) telegraph = append(telegraph, ReplaceSensitiveWords(selection.Text()))
}) })
return &telegraph return &telegraph
@ -592,7 +638,7 @@ func GetTopNewsList(crawlTimeOut int64) *[]string {
} }
var telegraph []string var telegraph []string
document.Find("div.home-article-title a,div.home-article-rec a").Each(func(i int, selection *goquery.Selection) { document.Find("div.home-article-title a,div.home-article-rec a").Each(func(i int, selection *goquery.Selection) {
logger.SugaredLogger.Info(selection.Text()) //logger.SugaredLogger.Info(selection.Text())
telegraph = append(telegraph, ReplaceSensitiveWords(selection.Text())) telegraph = append(telegraph, ReplaceSensitiveWords(selection.Text()))
}) })
return &telegraph return &telegraph

View File

@ -2,13 +2,14 @@ package data
import ( import (
"context" "context"
"go-stock/backend/db"
"testing" "testing"
) )
func TestNewDeepSeekOpenAiConfig(t *testing.T) { func TestNewDeepSeekOpenAiConfig(t *testing.T) {
//db.Init("../../data/stock.db") db.Init("../../data/stock.db")
ai := NewDeepSeekOpenAi(context.TODO()) ai := NewDeepSeekOpenAi(context.TODO())
res := ai.NewChatStream("上海贝岭", "sh600171", "分析以上股票资金流入信息,找出适合买入的股票,给出具体操作建议", nil) res := ai.NewChatStream("上海贝岭", "sh600171", "上海贝岭分析和总结", nil)
for { for {
select { select {
case msg := <-res: case msg := <-res:

View File

@ -267,7 +267,7 @@ func (receiver StockDataApi) GetStockBaseInfo() {
stock := &StockBasic{} stock := &StockBasic{}
data := map[string]any{} data := map[string]any{}
for _, field := range strings.Split(fields, ",") { for _, field := range strings.Split(fields, ",") {
logger.SugaredLogger.Infof("field: %s", field) //logger.SugaredLogger.Infof("field: %s", field)
idx := slice.IndexOf(res.Data.Fields, field) idx := slice.IndexOf(res.Data.Fields, field)
if idx == -1 { if idx == -1 {
continue continue
@ -318,7 +318,7 @@ func (receiver StockDataApi) GetStockCodeRealTimeData(StockCodes ...string) (*[]
for _, data := range dataStr { for _, data := range dataStr {
//logger.SugaredLogger.Info(data) //logger.SugaredLogger.Info(data)
stockData, err := ParseFullSingleStockData(data) stockData, err := ParseFullSingleStockData(data)
logger.SugaredLogger.Infof("GetStockCodeRealTimeData %v", stockData) //logger.SugaredLogger.Infof("GetStockCodeRealTimeData %v", stockData)
if err != nil { if err != nil {
logger.SugaredLogger.Error(err.Error()) logger.SugaredLogger.Error(err.Error())
continue continue
@ -341,7 +341,7 @@ func (receiver StockDataApi) GetStockCodeRealTimeData(StockCodes ...string) (*[]
} }
func (receiver StockDataApi) Follow(stockCode string) string { func (receiver StockDataApi) Follow(stockCode string) string {
logger.SugaredLogger.Infof("Follow %s", stockCode) //logger.SugaredLogger.Infof("Follow %s", stockCode)
stockInfos, err := receiver.GetStockCodeRealTimeData(stockCode) stockInfos, err := receiver.GetStockCodeRealTimeData(stockCode)
if err != nil || len(*stockInfos) == 0 { if err != nil || len(*stockInfos) == 0 {
logger.SugaredLogger.Error(err) logger.SugaredLogger.Error(err)
@ -351,7 +351,7 @@ func (receiver StockDataApi) Follow(stockCode string) string {
maxSort := int64(0) maxSort := int64(0)
db.Dao.Model(&FollowedStock{}).Raw("select max(sort) as sort from followed_stock").Scan(&maxSort) db.Dao.Model(&FollowedStock{}).Raw("select max(sort) as sort from followed_stock").Scan(&maxSort)
logger.SugaredLogger.Infof("Follow-maxSort %v", maxSort) //logger.SugaredLogger.Infof("Follow-maxSort %v", maxSort)
stockInfo := (*stockInfos)[0] stockInfo := (*stockInfos)[0]
price, _ := convertor.ToFloat(stockInfo.Price) price, _ := convertor.ToFloat(stockInfo.Price)
@ -531,7 +531,7 @@ func ParseUSStockData(datas []string) (map[string]string, error) {
result := make(map[string]string) result := make(map[string]string)
parts := strutil.SplitAndTrim(datas[1], ",", "\"", ";") parts := strutil.SplitAndTrim(datas[1], ",", "\"", ";")
//parts := strings.Split(data, ",") //parts := strings.Split(data, ",")
logger.SugaredLogger.Infof("股票数据解析完成: parts:%d", len(parts)) //logger.SugaredLogger.Infof("股票数据解析完成: parts:%d", len(parts))
if len(parts) < 35 { if len(parts) < 35 {
return nil, fmt.Errorf("invalid data format") return nil, fmt.Errorf("invalid data format")
} }
@ -590,7 +590,7 @@ func ParseUSStockData(datas []string) (map[string]string, error) {
result["盘前盘后涨跌幅"] = parts[22] result["盘前盘后涨跌幅"] = parts[22]
result["日期"] = strutil.SplitAndTrim(parts[3], " ", "")[0] result["日期"] = strutil.SplitAndTrim(parts[3], " ", "")[0]
result["时间"] = strutil.SplitAndTrim(parts[3], " ", "")[1] result["时间"] = strutil.SplitAndTrim(parts[3], " ", "")[1]
logger.SugaredLogger.Infof("美股股票数据解析完成: %v", result) //logger.SugaredLogger.Infof("美股股票数据解析完成: %v", result)
return result, nil return result, nil
} }
@ -749,16 +749,16 @@ func GetRealTimeStockPriceInfo(ctx context.Context, stockCode string) (price, pr
priceTime := "" priceTime := ""
document, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent)) document, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent))
if err != nil { if err != nil {
logger.SugaredLogger.Errorf("GetRealTimeStockPriceInfo error: %v", err) //logger.SugaredLogger.Errorf("GetRealTimeStockPriceInfo error: %v", err)
} }
document.Find("div.zxj").Each(func(i int, selection *goquery.Selection) { document.Find("div.zxj").Each(func(i int, selection *goquery.Selection) {
price = selection.Text() price = selection.Text()
logger.SugaredLogger.Infof("股票代码: %s, 当前价格: %s", stockCode, price) //logger.SugaredLogger.Infof("股票代码: %s, 当前价格: %s", stockCode, price)
}) })
document.Find("span.quote_title_time").Each(func(i int, selection *goquery.Selection) { document.Find("span.quote_title_time").Each(func(i int, selection *goquery.Selection) {
priceTime = selection.Text() priceTime = selection.Text()
logger.SugaredLogger.Infof("股票代码: %s, 当前价格时间: %s", stockCode, priceTime) //logger.SugaredLogger.Infof("股票代码: %s, 当前价格时间: %s", stockCode, priceTime)
}) })
return price, priceTime return price, priceTime
} }
@ -814,25 +814,25 @@ func getUSStockPriceInfo(stockCode string, crawlTimeOut int64) *[]string {
stockPriceTime := "" stockPriceTime := ""
document.Find("div.hq_title >h1").Each(func(i int, selection *goquery.Selection) { document.Find("div.hq_title >h1").Each(func(i int, selection *goquery.Selection) {
stockName = strutil.RemoveNonPrintable(selection.Text()) stockName = strutil.RemoveNonPrintable(selection.Text())
logger.SugaredLogger.Infof("股票名称-:%s", stockName) //logger.SugaredLogger.Infof("股票名称-:%s", stockName)
}) })
document.Find("#hqPrice").Each(func(i int, selection *goquery.Selection) { document.Find("#hqPrice").Each(func(i int, selection *goquery.Selection) {
stockPrice = strutil.RemoveNonPrintable(selection.Text()) stockPrice = strutil.RemoveNonPrintable(selection.Text())
logger.SugaredLogger.Infof("现价: %s", stockPrice) //logger.SugaredLogger.Infof("现价: %s", stockPrice)
}) })
document.Find("div.hq_time").Each(func(i int, selection *goquery.Selection) { document.Find("div.hq_time").Each(func(i int, selection *goquery.Selection) {
stockPriceTime = strutil.RemoveNonPrintable(selection.Text()) stockPriceTime = strutil.RemoveNonPrintable(selection.Text())
logger.SugaredLogger.Infof("时间: %s", stockPriceTime) //logger.SugaredLogger.Infof("时间: %s", stockPriceTime)
}) })
messages = append(messages, fmt.Sprintf("%s:%s现价%s", stockPriceTime, stockName, stockPrice)) messages = append(messages, fmt.Sprintf("%s:%s现价%s", stockPriceTime, stockName, stockPrice))
logger.SugaredLogger.Infof("股票: %s", messages) //logger.SugaredLogger.Infof("股票: %s", messages)
document.Find("div#hqDetails >table tbody tr").Each(func(i int, selection *goquery.Selection) { document.Find("div#hqDetails >table tbody tr").Each(func(i int, selection *goquery.Selection) {
text := strutil.RemoveNonPrintable(selection.Text()) text := strutil.RemoveNonPrintable(selection.Text())
logger.SugaredLogger.Infof("股票名称-%s: %s", stockName, text) //logger.SugaredLogger.Infof("股票名称-%s: %s", stockName, text)
messages = append(messages, text) messages = append(messages, text)
}) })
@ -866,25 +866,25 @@ func getHKStockPriceInfo(stockCode string, crawlTimeOut int64) *[]string {
stockPriceTime := "" stockPriceTime := ""
document.Find("#stock_cname").Each(func(i int, selection *goquery.Selection) { document.Find("#stock_cname").Each(func(i int, selection *goquery.Selection) {
stockName = strutil.RemoveNonPrintable(selection.Text()) stockName = strutil.RemoveNonPrintable(selection.Text())
logger.SugaredLogger.Infof("股票名称-:%s", stockName) //logger.SugaredLogger.Infof("股票名称-:%s", stockName)
}) })
document.Find("#mts_stock_hk_price").Each(func(i int, selection *goquery.Selection) { document.Find("#mts_stock_hk_price").Each(func(i int, selection *goquery.Selection) {
stockPrice = strutil.RemoveNonPrintable(selection.Text()) stockPrice = strutil.RemoveNonPrintable(selection.Text())
logger.SugaredLogger.Infof("现价: %s", stockPrice) //logger.SugaredLogger.Infof("现价: %s", stockPrice)
}) })
document.Find("#mts_stock_hk_time").Each(func(i int, selection *goquery.Selection) { document.Find("#mts_stock_hk_time").Each(func(i int, selection *goquery.Selection) {
stockPriceTime = strutil.RemoveNonPrintable(selection.Text()) stockPriceTime = strutil.RemoveNonPrintable(selection.Text())
logger.SugaredLogger.Infof("时间: %s", stockPriceTime) //logger.SugaredLogger.Infof("时间: %s", stockPriceTime)
}) })
messages = append(messages, fmt.Sprintf("%s:%s现价%s", stockPriceTime, stockName, stockPrice)) messages = append(messages, fmt.Sprintf("%s:%s现价%s", stockPriceTime, stockName, stockPrice))
logger.SugaredLogger.Infof("股票: %s", messages) //logger.SugaredLogger.Infof("股票: %s", messages)
document.Find(".deta_hqContainer >.deta03 li").Each(func(i int, selection *goquery.Selection) { document.Find(".deta_hqContainer >.deta03 li").Each(func(i int, selection *goquery.Selection) {
text := strutil.RemoveNonPrintable(selection.Text()) text := strutil.RemoveNonPrintable(selection.Text())
logger.SugaredLogger.Infof("股票名称-%s: %s", stockName, text) //logger.SugaredLogger.Infof("股票名称-%s: %s", stockName, text)
messages = append(messages, text) messages = append(messages, text)
}) })
@ -967,7 +967,7 @@ func SearchStockInfo(stock, msgType string, crawlTimeOut int64) *[]string {
defer timeoutCtxCancel() defer timeoutCtxCancel()
crawler = crawler.NewCrawler(timeoutCtx, crawler.crawlerBaseInfo) crawler = crawler.NewCrawler(timeoutCtx, crawler.crawlerBaseInfo)
url := fmt.Sprintf("https://www.cls.cn/searchPage?keyword=%s&type=%s", RemoveAllBlankChar(stock), msgType) url := fmt.Sprintf("https://www.cls.cn/searchPage?keyword=%s&type=%s", RemoveAllBlankChar(stock), msgType)
logger.SugaredLogger.Infof("SearchStockInfo url:%s", url) //logger.SugaredLogger.Infof("SearchStockInfo url:%s", url)
waitVisible := ".search-telegraph-list,.subject-interest-list" waitVisible := ".search-telegraph-list,.subject-interest-list"
htmlContent, ok := crawler.GetHtml(url, waitVisible, true) htmlContent, ok := crawler.GetHtml(url, waitVisible, true)
if !ok { if !ok {
@ -982,7 +982,7 @@ func SearchStockInfo(stock, msgType string, crawlTimeOut int64) *[]string {
document.Find(waitVisible).Each(func(i int, selection *goquery.Selection) { document.Find(waitVisible).Each(func(i int, selection *goquery.Selection) {
text := strutil.RemoveNonPrintable(selection.Text()) text := strutil.RemoveNonPrintable(selection.Text())
messages = append(messages, ReplaceSensitiveWords(text)) messages = append(messages, ReplaceSensitiveWords(text))
logger.SugaredLogger.Infof("搜索到消息-%s: %s", msgType, text) //logger.SugaredLogger.Infof("搜索到消息-%s: %s", msgType, text)
}) })
return &messages return &messages
} }
@ -1020,7 +1020,7 @@ func SearchStockInfoByCode(stock string) *[]string {
text := strutil.RemoveNonPrintable(selection.Text()) text := strutil.RemoveNonPrintable(selection.Text())
if strings.Contains(text, stock) { if strings.Contains(text, stock) {
messages = append(messages, text) messages = append(messages, text)
logger.SugaredLogger.Infof("搜索到消息: %s", text) //logger.SugaredLogger.Infof("搜索到消息: %s", text)
} }
}) })
return &messages return &messages
@ -1039,7 +1039,7 @@ func checkChromeOnWindows() (string, bool) {
} }
defer key.Close() defer key.Close()
path, _, err := key.GetStringValue("Path") path, _, err := key.GetStringValue("Path")
logger.SugaredLogger.Infof("Chrome安装路径%s", path) //logger.SugaredLogger.Infof("Chrome安装路径%s", path)
if err != nil { if err != nil {
return "", false return "", false
} }
@ -1063,7 +1063,7 @@ func CheckBrowserOnWindows() (string, bool) {
} }
defer key.Close() defer key.Close()
path, _, err := key.GetStringValue("Path") path, _, err := key.GetStringValue("Path")
logger.SugaredLogger.Infof("Edge安装路径%s", path) //logger.SugaredLogger.Infof("Edge安装路径%s", path)
if err != nil { if err != nil {
return "", false return "", false
} }

View File

@ -29,12 +29,12 @@ func NewTushareApi(config *Settings) *TushareApi {
// GetDaily tushare A股日线行情 // GetDaily tushare A股日线行情
func (receiver TushareApi) GetDaily(tsCode, startDate, endDate string, crawlTimeOut int64) string { func (receiver TushareApi) GetDaily(tsCode, startDate, endDate string, crawlTimeOut int64) string {
logger.SugaredLogger.Debugf("tushare daily request: ts_code=%s, start_date=%s, end_date=%s", tsCode, startDate, endDate) //logger.SugaredLogger.Debugf("tushare daily request: ts_code=%s, start_date=%s, end_date=%s", tsCode, startDate, endDate)
fields := "ts_code,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount" fields := "ts_code,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount"
resp := &TushareStockBasicResponse{} resp := &TushareStockBasicResponse{}
stockType := getStockType(tsCode) stockType := getStockType(tsCode)
tsCodeNEW := getTsCode(tsCode) tsCodeNEW := getTsCode(tsCode)
logger.SugaredLogger.Debugf("tushare daily request: %s,tsCode:%s,tsCodeNEW:%s", stockType, tsCode, tsCodeNEW) //logger.SugaredLogger.Debugf("tushare daily request: %s,tsCode:%s,tsCodeNEW:%s", stockType, tsCode, tsCodeNEW)
_, err := receiver.client.SetTimeout(time.Duration(crawlTimeOut)*time.Second).R(). _, err := receiver.client.SetTimeout(time.Duration(crawlTimeOut)*time.Second).R().
SetHeader("content-type", "application/json"). SetHeader("content-type", "application/json").
SetBody(&TushareRequest{ SetBody(&TushareRequest{
@ -66,7 +66,7 @@ func (receiver TushareApi) GetDaily(tsCode, startDate, endDate string, crawlTime
res += t + "\n" res += t + "\n"
} }
} }
logger.SugaredLogger.Debugf("tushare response: %s", res) //logger.SugaredLogger.Debugf("tushare response: %s", res)
return res return res
} }