Compare commits

..

5 Commits

Author SHA1 Message Date
ArvinLovegood
b1b34d950b feat(notify):新增只提醒红字或关注个股新闻的设置
- 在 App 中实现只推送红字或关注个股新闻的逻辑
- 在前端添加 enableOnlyPushRedNews 配置项
- 更新后端设置 API 以支持新功能
2025-07-28 18:22:37 +08:00
ArvinLovegood
83aa4331ad feat(notify):新增只提醒红字或关注个股新闻的设置
- 在 App 中实现只推送红字或关注个股新闻的逻辑
- 在前端添加 enableOnlyPushRedNews 配置项
- 更新后端设置 API 以支持新功能
2025-07-28 18:02:33 +08:00
ArvinLovegood
d4d3c44cf4 refactor(data):优化市场行情信息获取和展示
- 调整市场指数行情的展示格式和内容,增加更多指数信息
- 修改财联社电报的新闻列表获取参数,增加随机性
- 更新测试用例,增加对新功能的测试
2025-07-25 16:52:12 +08:00
ArvinLovegood
81a9cc5927 style(frontend):禁止界面拖拽
- 在多个组件中将 --wails-draggable 属性从 drag 改为 no-drag
- 这包括 about、App、market、settings 和 stock 组件
2025-07-24 17:17:50 +08:00
ArvinLovegood
3fc89a85da feat(ai):AI分析默认使用配置的第一个AI
- 在 market.vue 和 stock.vue 组件中,获取 AI 配置后设置了第一个配置的 ID
- 这个改动确保了在组件初始化时有一个默认的 AI 配置被选中
2025-07-23 12:35:05 +08:00
11 changed files with 68 additions and 23 deletions

21
app.go
View File

@@ -256,7 +256,7 @@ func (a *App) CheckUpdate(flag int) {
}
go runtime.EventsEmit(a.ctx, "newsPush", map[string]any{
"time": "发现新版本:" + releaseVersion.TagName,
"isRed": false,
"isRed": true,
"source": "go-stock",
"content": fmt.Sprintf("%s", commit.Message),
})
@@ -299,7 +299,7 @@ func (a *App) CheckUpdate(flag int) {
if flag == 1 {
go runtime.EventsEmit(a.ctx, "newsPush", map[string]any{
"time": "当前版本:" + Version,
"isRed": false,
"isRed": true,
"source": "go-stock",
"content": "当前版本无更新",
})
@@ -545,10 +545,21 @@ func (a *App) CheckStockBaseInfo(ctx context.Context) {
}
func (a *App) NewsPush(news *[]models.Telegraph) {
follows := data.NewStockDataApi().GetFollowList(0)
stockNames := slice.Map(*follows, func(index int, item data.FollowedStock) string {
return item.Name
})
for _, telegraph := range *news {
//if telegraph.IsRed {
go runtime.EventsEmit(a.ctx, "newsPush", telegraph)
go data.NewAlertWindowsApi("go-stock", telegraph.Source+" "+telegraph.Time, telegraph.Content, string(icon)).SendNotification()
if a.GetConfig().EnableOnlyPushRedNews {
if telegraph.IsRed || strutil.ContainsAny(telegraph.Content, stockNames) {
go runtime.EventsEmit(a.ctx, "newsPush", telegraph)
}
} else {
go runtime.EventsEmit(a.ctx, "newsPush", telegraph)
}
//go data.NewAlertWindowsApi("go-stock", telegraph.Source+" "+telegraph.Time, telegraph.Content, string(icon)).SendNotification()
//}
}
}

View File

@@ -115,7 +115,7 @@ func TestTradingViewNews(t *testing.T) {
db.Init("../../data/stock.db")
resp := NewMarketNewsApi().TradingViewNews()
for _, a := range *resp {
logger.SugaredLogger.Debugf("value: %s", a.Title)
logger.SugaredLogger.Debugf("value: %+v", a)
}
}

View File

@@ -219,17 +219,24 @@ func (o *OpenAi) NewSummaryStockNewsStreamWithTools(userQuestion string, sysProm
go func() {
defer wg.Done()
var market strings.Builder
market.WriteString(getZSInfo("上证指数", "sh000001", 30) + "\n")
market.WriteString(getZSInfo("深证成指", "sz399001", 30) + "\n")
market.WriteString(getZSInfo("创业板指数", "sz399006", 30) + "\n")
market.WriteString(getZSInfo("上证综合指数", "sh000001", 30) + "\n")
market.WriteString(getZSInfo("科创50", "sh000688", 30) + "\n")
market.WriteString(getZSInfo("沪深300指数", "sh000300", 30) + "\n")
market.WriteString(getZSInfo("中证银行", "sz399986", 30) + "\n")
market.WriteString(getZSInfo("科创芯片", "sh000685", 30) + "\n")
market.WriteString(getZSInfo("上证医药", "sh000037", 30) + "\n")
market.WriteString(getZSInfo("证券龙头", "sz399437", 30) + "\n")
market.WriteString(getZSInfo("中证白酒", "sz399997", 30) + "\n")
//logger.SugaredLogger.Infof("NewChatStream getZSInfo=\n%s", market.String())
msg = append(msg, map[string]interface{}{
"role": "user",
"content": "当前市场指数行情",
"content": "当前市场/大盘/行业/指数行情",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
"content": "当前市场指数行情情况如下:\n" + market.String(),
"content": "当前市场/大盘/行业/指数行情如下:\n" + market.String(),
})
}()
@@ -275,7 +282,7 @@ func (o *OpenAi) NewSummaryStockNewsStreamWithTools(userQuestion string, sysProm
}
msg = append(msg, map[string]interface{}{
"role": "user",
"content": "外媒全球新闻资讯",
"content": "全球新闻资讯",
})
msg = append(msg, map[string]interface{}{
"role": "assistant",
@@ -302,7 +309,7 @@ func (o *OpenAi) NewSummaryStockNewsStreamWithTools(userQuestion string, sysProm
}()
wg.Wait()
news := NewMarketNewsApi().GetNewsList("财联社电报", random.RandInt(50, 150))
news := NewMarketNewsApi().GetNewsList("财联社电报", random.RandInt(100, 500))
messageText := strings.Builder{}
for _, telegraph := range *news {
messageText.WriteString("## " + telegraph.Time + ":" + "\n")
@@ -378,9 +385,16 @@ func (o *OpenAi) NewSummaryStockNewsStream(userQuestion string, sysPromptId *int
go func() {
defer wg.Done()
var market strings.Builder
market.WriteString(getZSInfo("上证指数", "sh000001", 30) + "\n")
market.WriteString(getZSInfo("深证成指", "sz399001", 30) + "\n")
market.WriteString(getZSInfo("创业板指数", "sz399006", 30) + "\n")
market.WriteString(getZSInfo("上证综合指数", "sh000001", 30) + "\n")
market.WriteString(getZSInfo("科创50", "sh000688", 30) + "\n")
market.WriteString(getZSInfo("沪深300指数", "sh000300", 30) + "\n")
market.WriteString(getZSInfo("中证银行", "sz399986", 30) + "\n")
market.WriteString(getZSInfo("科创芯片", "sh000685", 30) + "\n")
market.WriteString(getZSInfo("上证医药", "sh000037", 30) + "\n")
market.WriteString(getZSInfo("证券龙头", "sz399437", 30) + "\n")
market.WriteString(getZSInfo("中证白酒", "sz399997", 30) + "\n")
//logger.SugaredLogger.Infof("NewChatStream getZSInfo=\n%s", market.String())
msg = append(msg, map[string]interface{}{
"role": "user",

View File

@@ -57,3 +57,9 @@ func TestSearchGuShiTongStockInfo(t *testing.T) {
SearchGuShiTongStockInfo("gb_goog", 60)
}
func TestGetZSInfo(t *testing.T) {
db.Init("../../data/stock.db")
getZSInfo("中证银行", "sz399986", 30)
getZSInfo("科创50", "sh000688", 30)
}

View File

@@ -31,6 +31,7 @@ type Settings struct {
BrowserPoolSize int `json:"browserPoolSize"`
EnableFund bool `json:"enableFund"`
EnablePushNews bool `json:"enablePushNews"`
EnableOnlyPushRedNews bool `json:"enableOnlyPushRedNews"`
SponsorCode string `json:"sponsorCode"`
HttpProxy string `json:"httpProxy"`
HttpProxyEnabled bool `json:"httpProxyEnabled"`
@@ -100,6 +101,7 @@ func UpdateConfig(s *SettingConfig) string {
"dark_theme": s.DarkTheme,
"enable_fund": s.EnableFund,
"enable_push_news": s.EnablePushNews,
"enable_only_push_red_news": s.EnableOnlyPushRedNews,
"sponsor_code": s.SponsorCode,
"http_proxy": s.HttpProxy,
"http_proxy_enabled": s.HttpProxyEnabled,

View File

@@ -702,7 +702,7 @@ onMounted(() => {
</n-spin>
</n-gi>
<n-gi style="position: fixed;bottom:0;z-index: 9;width: 100%;">
<n-card size="small" style="--wails-draggable:drag">
<n-card size="small" style="--wails-draggable:no-drag">
<n-menu style="font-size: 18px;"
v-model:value="activeKey"
mode="horizontal"

View File

@@ -104,7 +104,7 @@ EventsOn("updateVersion",async (msg) => {
</script>
<template>
<n-space vertical size="large" style="--wails-draggable:drag">
<n-space vertical size="large" style="--wails-draggable:no-drag">
<!-- 软件描述 -->
<n-card size="large">
<n-divider title-placement="center">关于软件</n-divider>

View File

@@ -102,6 +102,7 @@ onBeforeMount(() => {
GetAiConfigs().then(res=>{
aiConfigs.value = res
aiConfigId.value = res[0].ID
})
GetTelegraphList("财联社电报").then((res) => {
@@ -317,7 +318,7 @@ function ReFlesh(source) {
<template>
<n-card>
<n-tabs type="line" animated @update-value="updateTab" :value="nowTab" style="--wails-draggable:drag">
<n-tabs type="line" animated @update-value="updateTab" :value="nowTab" style="--wails-draggable:no-drag">
<n-tab-pane name="市场快讯" tab="市场快讯">
<n-grid :cols="2" :y-gap="0">
<n-gi>

View File

@@ -41,6 +41,7 @@ const formValue = ref({
darkTheme: true,
enableFund: false,
enablePushNews: false,
enableOnlyPushRedNews: false,
sponsorCode: "",
httpProxy:"",
httpProxyEnabled:false,
@@ -98,9 +99,11 @@ onMounted(() => {
formValue.value.darkTheme = res.darkTheme
formValue.value.enableFund = res.enableFund
formValue.value.enablePushNews = res.enablePushNews
formValue.value.enableOnlyPushRedNews = res.enableOnlyPushRedNews
formValue.value.sponsorCode = res.sponsorCode
formValue.value.httpProxy=res.httpProxy;
formValue.value.httpProxyEnabled=res.httpProxyEnabled;
})
GetPromptTemplates("", "").then(res => {
@@ -135,6 +138,7 @@ function saveConfig() {
darkTheme: formValue.value.darkTheme,
enableFund: formValue.value.enableFund,
enablePushNews: formValue.value.enablePushNews,
enableOnlyPushRedNews: formValue.value.enableOnlyPushRedNews,
sponsorCode: formValue.value.sponsorCode,
httpProxy:formValue.value.httpProxy,
httpProxyEnabled:formValue.value.httpProxyEnabled,
@@ -223,6 +227,7 @@ function importConfig() {
formValue.value.darkTheme = config.darkTheme
formValue.value.enableFund = config.enableFund
formValue.value.enablePushNews = config.enablePushNews
formValue.value.enableOnlyPushRedNews = config.enableOnlyPushRedNews
formValue.value.sponsorCode = config.sponsorCode
formValue.value.httpProxy=config.httpProxy
formValue.value.httpProxyEnabled=config.httpProxyEnabled
@@ -291,7 +296,7 @@ function deletePrompt(ID) {
</script>
<template>
<n-flex justify="left" style="text-align: left; --wails-draggable:drag">
<n-flex justify="left" style="text-align: left; --wails-draggable:no-drag">
<n-form ref="formRef" :label-placement="'left'" :label-align="'left'">
<n-space vertical size="large">
<n-card :title="() => h(NTag, { type: 'primary', bordered: false }, () => '基础设置')" size="small">
@@ -329,21 +334,25 @@ function deletePrompt(ID) {
<n-card :title="() => h(NTag, { type: 'primary', bordered: false }, () => '通知设置')" size="small">
<n-grid :cols="24" :x-gap="24" style="text-align: left">
<n-form-item-gi :span="4" label="钉钉推送:" path="dingPush.enable">
<n-form-item-gi :span="3" label="钉钉推送:" path="dingPush.enable">
<n-switch v-model:value="formValue.dingPush.enable"/>
</n-form-item-gi>
<n-form-item-gi :span="4" label="本地推送:" path="localPush.enable">
<n-form-item-gi :span="3" label="本地推送:" path="localPush.enable">
<n-switch v-model:value="formValue.localPush.enable"/>
</n-form-item-gi>
<n-form-item-gi :span="4" label="弹幕功能:" path="enableDanmu">
<n-form-item-gi :span="3" label="弹幕功能:" path="enableDanmu">
<n-switch v-model:value="formValue.enableDanmu"/>
</n-form-item-gi>
<n-form-item-gi :span="4" label="显示滚动快讯:" path="enableNews">
<n-form-item-gi :span="3" label="显示滚动快讯:" path="enableNews">
<n-switch v-model:value="formValue.enableNews"/>
</n-form-item-gi>
<n-form-item-gi :span="4" label="市场资讯提醒:" path="enablePushNews">
<n-form-item-gi :span="3" label="市场资讯提醒:" path="enablePushNews">
<n-switch v-model:value="formValue.enablePushNews"/>
</n-form-item-gi>
<n-form-item-gi v-if="formValue.enablePushNews" :span="4" label="只提醒红字或关注个股的新闻:" path="enableOnlyPushRedNews">
<n-switch v-model:value="formValue.enableOnlyPushRedNews"/>
</n-form-item-gi>
<n-form-item-gi :span="22" v-if="formValue.dingPush.enable" label="钉钉机器人接口地址:"
path="dingPush.dingRobot">
<n-input placeholder="请输入钉钉机器人接口地址" v-model:value="formValue.dingPush.dingRobot"/>
@@ -461,7 +470,6 @@ function deletePrompt(ID) {
</n-grid>
</n-card>
</n-space>
</n-form>
</n-flex>

View File

@@ -220,6 +220,7 @@ onBeforeMount(() => {
GetAiConfigs().then(res=>{
aiConfigs.value = res
data.aiConfigId =res[0].ID
})
})
@@ -1722,7 +1723,7 @@ function searchStockReport(stockCode) {
</n-gradient-text>
</template>
</vue-danmaku>
<n-tabs type="card" style="--wails-draggable:drag" animated addable :data-currentGroupId="currentGroupId"
<n-tabs type="card" style="--wails-draggable:no-drag" animated addable :data-currentGroupId="currentGroupId"
:value="currentGroupId" @add="addTab" @update-value="updateTab" placement="top" @close="(key)=>{delTab(key)}">
<n-tab-pane :name="0" :tab="'全部'">
<n-grid :x-gap="8" :cols="3" :y-gap="8">

View File

@@ -389,6 +389,7 @@ export namespace data {
browserPoolSize: number;
enableFund: boolean;
enablePushNews: boolean;
enableOnlyPushRedNews: boolean;
sponsorCode: string;
httpProxy: string;
httpProxyEnabled: boolean;
@@ -423,6 +424,7 @@ export namespace data {
this.browserPoolSize = source["browserPoolSize"];
this.enableFund = source["enableFund"];
this.enablePushNews = source["enablePushNews"];
this.enableOnlyPushRedNews = source["enableOnlyPushRedNews"];
this.sponsorCode = source["sponsorCode"];
this.httpProxy = source["httpProxy"];
this.httpProxyEnabled = source["httpProxyEnabled"];