Compare commits

...

9 Commits

Author SHA1 Message Date
ArvinLovegood
6dff9d95c4 build:更新Go依赖并升级到Go1.25
- 更新 golang.org/x/sys从 v0.33.0 到 v0.35.0
- 更新 sonic、sonic/loader、base64x、cpuid、arch 等多个依赖库
- 将 Go 版本从 1.24升级到 1.25
2025-08-26 11:28:49 +08:00
ArvinLovegood
06967420f8 feat(app):添加股票基础信息自动检查功能
- 在应用启动时检查股票基础信息是否为空
- 如果为空,则自动调用 CheckStockBaseInfo 方法获取数据
-每天凌晨 2 点定时检查股票基础信息
2025-08-26 10:45:17 +08:00
ArvinLovegood
6f4eb0ac86 refactor(backend): 移除未使用的导入语句
- 删除了 "C" 的导入语句,该语句在代码中未被使用
- 优化代码结构,提高代码的可读性和维护性
2025-08-24 20:11:57 +08:00
ArvinLovegood
f59255cc6c style:调整 Windows特定代码的构建标签
- 在 alert_windows_api.go 和 alert_windows_api_test.go 文件中添加额外的 +build windows 标签
- 优化代码结构,提高代码的可读性和可维护性
2025-08-24 16:29:57 +08:00
ArvinLovegood
4f4fa46338 refactor(app):优化代码结构和功能
- 调整导入顺序,提高代码可读性
- 使用 cron 定时任务替代直接调用检查更新方法
- 在前端 App.vue 中添加名站优选市场选项
-调整主窗口高度
-优化股票情感分析数据处理
2025-08-24 15:46:55 +08:00
SparkMemory
05bf35fdf4 Merge pull request #99 from CodeNoobLH/dev
feat(frontend): 添加股票分组拖拽排序功能
2025-08-24 14:35:21 +08:00
浓睡不消残酒
567c81ae7c feat(frontend): 添加股票分组拖拽排序功能
- 在前端实现股票分组的拖拽排序功能
- 新增后端接口支持分组排序的更新
- 优化数据库操作,确保分组顺序的正确性和唯一性
- 修复了一些与分组列表相关的小问题
2025-08-22 15:10:47 +08:00
SparkMemory
86f4e54d13 Merge pull request #97 from CodeNoobLH/dev
feat(frontend): 增加关注股票功能并优化表格显示- 在指标选股组件中添加关注股票功能
2025-08-16 21:36:50 +08:00
浓睡不消残酒
71e6ff4233 feat(frontend): 增加关注股票功能并优化表格显示- 在 SelectStock 组件中添加关注股票功能
- 实现股票关注逻辑,包括检查是否已关注
- 优化表格宽度计算,确保适配不同屏幕
- 在表格中添加操作列,用于关注股票
2025-08-14 18:13:24 +08:00
15 changed files with 625 additions and 224 deletions

View File

@@ -50,7 +50,7 @@ jobs:
build-name: ${{ matrix.build.name }}
build-platform: ${{ matrix.build.platform }}
package: true
go-version: '1.24'
go-version: '1.25'
build-tags: ${{ github.ref_name }}
build-commit-message: ${{ steps.get_commit_message.outputs.commit_message }}
build-statement: ${{ env.OFFICIAL_STATEMENT }}

24
app.go
View File

@@ -7,8 +7,6 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/duke-git/lancet/v2/cryptor"
"github.com/inconshreveable/go-update"
"go-stock/backend/data"
"go-stock/backend/db"
"go-stock/backend/logger"
@@ -18,6 +16,9 @@ import (
"strings"
"time"
"github.com/duke-git/lancet/v2/cryptor"
"github.com/inconshreveable/go-update"
"github.com/PuerkitoBio/goquery"
"github.com/coocood/freecache"
"github.com/duke-git/lancet/v2/convertor"
@@ -464,7 +465,16 @@ func (a *App) domReady(ctx context.Context) {
//检查新版本
go func() {
a.CheckUpdate(0)
a.CheckStockBaseInfo(a.ctx)
count := int64(0)
db.Dao.Model(&data.StockBasic{}).Count(&count)
if count <= 0 {
go a.CheckStockBaseInfo(a.ctx)
}
a.cron.AddFunc("0 0 2 * * *", func() {
logger.SugaredLogger.Errorf("Checking for updates...")
a.CheckStockBaseInfo(a.ctx)
})
a.cron.AddFunc("30 05 8,12,20 * * *", func() {
logger.SugaredLogger.Errorf("Checking for updates...")
a.CheckUpdate(0)
@@ -1219,6 +1229,14 @@ func (a *App) GetGroupList() []data.Group {
return data.NewStockGroupApi(db.Dao).GetGroupList()
}
func (a *App) UpdateGroupSort(id int, newSort int) bool {
return data.NewStockGroupApi(db.Dao).UpdateGroupSort(id, newSort)
}
func (a *App) InitializeGroupSort() bool {
return data.NewStockGroupApi(db.Dao).InitializeGroupSort()
}
func (a *App) GetGroupStockList(groupId int) []data.GroupStock {
return data.NewStockGroupApi(db.Dao).GetGroupStockByGroupId(groupId)
}

View File

@@ -1,11 +1,12 @@
//go:build windows
// +build windows
package data
import "C"
import (
"github.com/go-toast/toast"
"go-stock/backend/logger"
"github.com/go-toast/toast"
)
// AlertWindowsApi @Author spark

View File

@@ -1,11 +1,13 @@
//go:build windows
// +build windows
package data
import (
"github.com/go-toast/toast"
"go-stock/backend/logger"
"testing"
"github.com/go-toast/toast"
)
// @Author spark

View File

@@ -419,6 +419,15 @@ func (receiver StockDataApi) Follow(stockCode string) string {
}
stockCode = strings.ToLower(stockCode)
// 检查是否已经关注过该股票
var existingStock FollowedStock
result := db.Dao.Model(&FollowedStock{}).Where("stock_code = ? AND is_del = ?", stockCode, 0).First(&existingStock)
if result.Error == nil {
// 股票已经关注过
return "已经关注了"
}
maxSort := int64(0)
db.Dao.Model(&FollowedStock{}).Raw("select max(sort) as sort from followed_stock").Scan(&maxSort)

View File

@@ -39,17 +39,74 @@ func NewStockGroupApi(dao *gorm.DB) *StockGroupApi {
}
func (receiver StockGroupApi) AddGroup(group Group) bool {
err := receiver.dao.Where("name = ?", group.Name).FirstOrCreate(&group).Updates(&Group{
Name: group.Name,
Sort: group.Sort,
}).Error
// 检查是否已存在相同sort的组
var existingGroup Group
err := receiver.dao.Where("sort = ?", group.Sort).First(&existingGroup).Error
// 如果存在相同sort的组则将该组及之后的所有组向后移动一位
if err == nil {
// 处理sort冲突将相同sort值及之后的所有组向后移动一位
receiver.dao.Model(&Group{}).Where("sort >= ?", group.Sort).Update("sort", gorm.Expr("sort + ?", 1))
}
// 创建新组
err = receiver.dao.Create(&group).Error
return err == nil
}
func (receiver StockGroupApi) GetGroupList() []Group {
var groups []Group
receiver.dao.Find(&groups)
receiver.dao.Order("sort ASC").Find(&groups)
return groups
}
func (receiver StockGroupApi) UpdateGroupSort(id int, newSort int) bool {
// First, get the current group to check if it exists
var currentGroup Group
if err := receiver.dao.First(&currentGroup, id).Error; err != nil {
return false
}
// If the new sort is the same as current, no need to update
if currentGroup.Sort == newSort {
return true
}
// Get all groups ordered by sort
var allGroups []Group
receiver.dao.Order("sort ASC").Find(&allGroups)
// Adjust sort numbers to make space for the new sort value
if newSort > currentGroup.Sort {
// Moving down: decrease sort of groups between old and new position
receiver.dao.Model(&Group{}).Where("sort > ? AND sort <= ? AND id != ?", currentGroup.Sort, newSort, id).Update("sort", gorm.Expr("sort - ?", 1))
} else {
// Moving up: increase sort of groups between new and old position
receiver.dao.Model(&Group{}).Where("sort >= ? AND sort < ? AND id != ?", newSort, currentGroup.Sort, id).Update("sort", gorm.Expr("sort + ?", 1))
}
// Update the target group's sort
err := receiver.dao.Model(&Group{}).Where("id = ?", id).Update("sort", newSort).Error
return err == nil
}
// InitializeGroupSort initializes sort order for all groups based on created time
func (receiver StockGroupApi) InitializeGroupSort() bool {
// Get all groups ordered by created time
var groups []Group
err := receiver.dao.Order("created_at ASC").Find(&groups).Error
if err != nil {
return false
}
// Update each group with new sort value based on their position
for i, group := range groups {
newSort := i + 1
err := receiver.dao.Model(&Group{}).Where("id = ?", group.ID).Update("sort", newSort).Error
if err != nil {
return false
}
}
return true
}
func (receiver StockGroupApi) GetGroupStockByGroupId(groupId int) []GroupStock {
var stockGroup []GroupStock
receiver.dao.Preload("GroupInfo").Where("group_id = ?", groupId).Find(&stockGroup)

View File

@@ -3,10 +3,11 @@ package data
import (
"bufio"
"fmt"
"github.com/go-ego/gse"
"go-stock/backend/logger"
"os"
"strings"
"github.com/go-ego/gse"
)
// 金融情感词典,包含股票市场相关的专业词汇

View File

@@ -28,7 +28,7 @@ import {
Wallet, WarningOutline,
} from '@vicons/ionicons5'
import {AnalyzeSentiment, GetConfig, GetGroupList,GetVersionInfo} from "../wailsjs/go/main/App";
import {Dragon, Fire, Gripfire, Robot} from "@vicons/fa";
import {Dragon, Fire, FirefoxBrowser, Gripfire, Robot} from "@vicons/fa";
import {ReportSearch} from "@vicons/tabler";
import {LocalFireDepartmentRound} from "@vicons/material";
import {BoxSearch20Regular, CommentNote20Filled} from "@vicons/fluent";
@@ -369,6 +369,28 @@ const menuOptions = ref([
key: 'market11',
icon: renderIcon(BoxSearch20Regular),
},
{
label: () =>
h(
RouterLink,
{
href: '#',
to: {
name: 'market',
query: {
name: "名站优选",
}
},
onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '名站优选'})
},
},
{default: () => '名站优选',}
),
key: 'market12',
icon: renderIcon(FirefoxBrowser),
},
]
},
{

View File

@@ -1,9 +1,10 @@
<script setup lang="ts">
import {h, onBeforeMount, onMounted, onUnmounted, ref} from 'vue'
import {SearchStock, GetHotStrategy, OpenURL} from "../../wailsjs/go/main/App";
import {SearchStock, GetHotStrategy, OpenURL, Follow, GetFollowList} from "../../wailsjs/go/main/App";
import {useMessage, NText, NTag, NButton} from 'naive-ui'
import {Environment} from "../../wailsjs/runtime"
import {RefreshCircleSharp} from "@vicons/ionicons5";
import {EventsEmit} from "../../wailsjs/runtime";
const message = useMessage()
const search = ref('')
@@ -11,6 +12,32 @@ const columns = ref([])
const dataList = ref([])
const hotStrategy = ref([])
const traceInfo = ref('')
const tableScrollX = ref(2800) // 默认滚动宽度
// 计算表格总宽度
function calculateTableWidth(cols) {
let totalWidth = 0;
cols.forEach(col => {
if (col.children && col.children.length > 0) {
// 有子列的情况
let childrenWidth = 0;
col.children.forEach(child => {
childrenWidth += child.width || child.minWidth || 100;
});
// 取标题列宽度和子列总宽度的较大值
totalWidth += Math.max(col.width || col.minWidth || 200, childrenWidth);
} else {
// 没有子列的情况
totalWidth += col.width || col.minWidth || 120;
}
});
// 加上操作列的宽度
totalWidth += 100;
return Math.max(totalWidth, 1200); // 最小宽度1200
}
function Search() {
if (!search.value) {
@@ -71,11 +98,32 @@ function Search() {
}
},
}
}
})
columns.value.push({
title: '操作',
key: 'actions',
width: 80,
fixed: 'right', // 固定在右侧
render: (row) => {
return h(
NButton,
{
strong: true,
tertiary: true,
size: 'small',
type: 'warning', // 橙色按钮
style: 'font-size: 14px; padding: 0 10px;', // 稍微大一点的按钮
onClick: () => handleFollow(row)
},
{ default: () => '关注' }
)
}
});
dataList.value = res.data.result.dataList
console.log("sss"+columns.value. length)
// 计算并设置表格宽度
tableScrollX.value = calculateTableWidth(columns.value);
} else {
message.error(res.msg)
}
@@ -84,6 +132,18 @@ function Search() {
})
}
// 修改handleFollow方法使用stock.vue的AddStock逻辑
function handleFollow(row) {
let code=row.MARKET_SHORT_NAME.toLowerCase()+row.SECURITY_CODE
Follow(code).then(result => {
if (result === "关注成功") {
message.success(result)
} else {
message.error(result)
}
});
}
function isNumeric(value) {
return !isNaN(parseFloat(value)) && isFinite(value);
}
@@ -188,7 +248,7 @@ function openCenteredWindow(url, width, height) {
:columns="columns"
:data="dataList"
:pagination="{pageSize: 10}"
:scroll-x="1800"
:scroll-x="tableScrollX"
:render-cell="(value, rowData, column) => {
if(column.key=='SECURITY_CODE'||column.key=='SERIAL'){

View File

@@ -1,10 +1,11 @@
<script setup>
import {computed, h, onBeforeMount, onBeforeUnmount, onMounted, reactive, ref} from 'vue'
import {computed, h, nextTick, onBeforeMount, onBeforeUnmount, onMounted, reactive, ref, watch} from 'vue'
import * as echarts from 'echarts';
import {
AddGroup,
AddStockGroup,
Follow,
GetAiConfigs,
GetAIResponseResult,
GetConfig,
GetFollowList,
@@ -15,11 +16,15 @@ import {
GetStockMinutePriceLineData,
GetVersionInfo,
Greet,
InitializeGroupSort,
NewChatStream,
OpenURL,
RemoveGroup,
RemoveStockGroup,
SaveAIResponseResult,
SaveAsMarkdown,
SaveImage,
SaveWordFile,
SendDingDingMessageByType,
SetAlarmChangePercent,
SetCostPriceAndVolume,
@@ -27,10 +32,7 @@ import {
SetStockSort,
ShareAnalysis,
UnFollow,
OpenURL,
SaveImage,
SaveWordFile,
GetAiConfigs
UpdateGroupSort
} from '../../wailsjs/go/main/App'
import {
NAvatar,
@@ -68,7 +70,6 @@ import vueDanmaku from 'vue3-danmaku'
import {keys, padStart} from "lodash";
import {useRoute, useRouter} from 'vue-router'
import MoneyTrend from "./moneyTrend.vue";
import {TaskTools} from "@vicons/carbon";
import StockSparkLine from "./stockSparkLine.vue";
const route = useRoute()
@@ -170,22 +171,137 @@ const sortedResults = computed(() => {
const groupResults = computed(() => {
const group = {}
for (const key in sortedResults.value) {
if (stocks.value.includes(sortedResults.value[key]['股票代码'])) {
group[key] = sortedResults.value[key]
if (currentGroupId.value === 0) {
return sortedResults.value
} else {
for (const key in sortedResults.value) {
if (stocks.value.includes(sortedResults.value[key]['股票代码'])) {
group[key] = sortedResults.value[key]
}
}
return group
}
return group
})
const showPopover = ref(false)
// 拖拽相关变量
const dragSourceIndex = ref(null)
const dragTargetIndex = ref(null)
// 拖拽处理函数
function handleTabDragStart(event, name) {
// "全部"标签name=0不应该触发拖拽
if (name === 0) {
event.preventDefault();
return;
}
dragSourceIndex.value = name;
event.dataTransfer.effectAllowed = 'move';
event.target.classList.add('tab-dragging');
}
function handleTabDragOver(event) {
event.preventDefault()
event.dataTransfer.dropEffect = 'move'
}
function handleTabDragEnter(event, name) {
event.preventDefault();
// "全部"标签name=0不应该作为拖拽目标
if (name > 0) {
dragTargetIndex.value = name;
if (event.target.classList) {
// 查找最近的标签元素并添加高亮样式
let tabElement = event.target.closest('.n-tabs-tab');
if (tabElement) {
tabElement.classList.add('tab-drag-over');
}
}
}
}
function handleTabDragLeave(event) {
// 查找最近的标签元素并移除高亮样式
let tabElement = event.target.closest('.n-tabs-tab')
if (tabElement && tabElement.classList) {
tabElement.classList.remove('tab-drag-over')
}
// 不要重置 dragTargetIndex因为可能会在元素间快速移动
}
function handleTabDrop(event) {
event.preventDefault();
// 移除所有高亮样式
const tabs = document.querySelectorAll('.n-tabs-tab');
tabs.forEach(tab => {
tab.classList.remove('tab-drag-over');
});
if (dragSourceIndex.value !== null && dragTargetIndex.value !== null &&
dragSourceIndex.value !== dragTargetIndex.value) {
// 确保索引有效(排除"全部"选项卡)
if (dragSourceIndex.value > 0 && dragTargetIndex.value > 0) {
// 查找源分组和目标分组
const sourceGroup = groupList.value.find(g => g.ID === dragSourceIndex.value);
const targetGroup = groupList.value.find(g => g.ID === dragTargetIndex.value);
if (sourceGroup && targetGroup) {
// 计算新的位置序号使用目标分组的sort值
const newSortPosition = targetGroup.sort;
// 调用后端API更新组排序
UpdateGroupSort(sourceGroup.ID, newSortPosition).then(result => {
if (result) {
message.success('分组排序更新成功');
// 重新获取分组列表以更新界面
GetGroupList().then(result => {
groupList.value = result;
});
} else {
message.error('分组排序更新失败');
}
}).catch(error => {
message.error('分组排序更新失败: ' + error.message);
});
}
}
}
// 重置状态
dragSourceIndex.value = null;
dragTargetIndex.value = null;
}
function handleTabDragEnd(event) {
// 移除所有高亮样式
const tabs = document.querySelectorAll('.n-tabs-tab')
tabs.forEach(tab => {
tab.classList.remove('tab-drag-over', 'tab-dragging')
})
dragSourceIndex.value = null
dragTargetIndex.value = null
}
onBeforeMount(() => {
GetGroupList().then(result => {
groupList.value = result
if (route.query.groupId) {
message.success("切换分组:" + route.query.groupName)
currentGroupId.value = Number(route.query.groupId)
//console.log("route.params",route.query)
// 检查是否存在相同的序号
const sorts = result.map(item => item.sort);
const uniqueSorts = new Set(sorts);
// 如果存在重复的序号,则重新初始化序号
if (sorts.length !== uniqueSorts.size) {
// 调用InitializeGroupSort重新初始化序号
// 然后重新获取分组列表
fetchGroupList();
} else {
// 没有重复序号,继续正常流程
if (route.query.groupId) {
message.success("切换分组:" + route.query.groupName)
currentGroupId.value = Number(route.query.groupId)
}
}
})
GetStockList("").then(result => {
@@ -214,20 +330,168 @@ onBeforeMount(() => {
sysPromptOptions.value = promptTemplates.value.filter(item => item.type === '模型系统Prompt')
userPromptOptions.value = promptTemplates.value.filter(item => item.type === '模型用户Prompt')
//console.log("userPromptOptions",userPromptOptions.value)
//console.log("sysPromptOptions",sysPromptOptions.value)
})
GetAiConfigs().then(res=>{
GetAiConfigs().then(res => {
aiConfigs.value = res
data.aiConfigId =res[0].ID
data.aiConfigId = res[0].ID
})
EventsOn("loadingDone", (data) => {
message.loading("刷新股票基础数据...")
GetStockList("").then(result => {
stockList.value = result
options.value = result.map(item => {
return {
label: item.name + " - " + item.ts_code,
value: item.ts_code
}
})
})
})
EventsOn("refresh", (data) => {
message.success(data)
})
EventsOn("showSearch", (data) => {
addBTN.value = data === 1;
})
EventsOn("stock_price", (data) => {
updateData(data)
})
EventsOn("refreshFollowList", (data) => {
WindowReload()
})
EventsOn("newChatStream", async (msg) => {
data.loading = false
if (msg === "DONE") {
SaveAIResponseResult(data.code, data.name, data.airesult, data.chatId, data.question, data.aiConfigId)
message.info("AI分析完成")
message.destroyAll()
} else {
if (msg.chatId) {
data.chatId = msg.chatId
}
if (msg.question) {
data.question = msg.question
}
if (msg.content) {
data.airesult = data.airesult + msg.content
}
if (msg.extraContent) {
data.airesult = data.airesult + msg.extraContent
}
}
})
EventsOn("changeTab", async (msg) => {
currentGroupId.value = Number(msg.ID)
nextTick(() => {
updateTab(currentGroupId.value);
});
})
EventsOn("updateVersion", async (msg) => {
const githubTimeStr = msg.published_at;
// 创建一个 Date 对象
const utcDate = new Date(githubTimeStr);
// 获取本地时间
const date = new Date(utcDate.getTime());
const year = date.getFullYear();
// getMonth 返回值是 0 - 11所以要加 1
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
notify.info({
avatar: () =>
h(NAvatar, {
size: 'small',
round: false,
src: icon.value
}),
title: '发现新版本: ' + msg.tag_name,
content: () => {
//return h(MdPreview, {theme:'dark',modelValue:msg.commit?.message}, null)
return h('div', {
style: {
'text-align': 'left',
'font-size': '14px',
}
}, {default: () => msg.commit?.message})
},
duration: 5000,
meta: "发布时间:" + formattedDate,
action: () => {
return h(NButton, {
type: 'primary',
size: 'small',
onClick: () => {
Environment().then(env => {
switch (env.platform) {
case 'windows':
window.open(msg.html_url)
break
default :
OpenURL(msg.html_url)
}
})
}
}, {default: () => '查看'})
}
})
})
EventsOn("warnMsg", async (msg) => {
notify.error({
avatar: () =>
h(NAvatar, {
size: 'small',
round: false,
src: icon.value
}),
title: '警告',
duration: 5000,
content: () => {
return h('div', {
style: {
'text-align': 'left',
'font-size': '14px',
}
}, {default: () => msg})
},
})
})
})
onMounted(() => {
message.loading("Loading...")
nextTick(() => {
initDraggableTabs();
});
// 监听分组列表变化,重新初始化拖拽
const unwatch = watch(groupList, () => {
nextTick(() => {
initDraggableTabs();
});
});
// 在组件卸载时清理监听器
onBeforeUnmount(() => {
unwatch();
});
message.loading("Loading...")
GetFollowList(currentGroupId.value).then(result => {
followList.value = result
@@ -246,7 +510,6 @@ onMounted(() => {
message.destroyAll()
})
GetVersionInfo().then((res) => {
icon.value = res.icon;
});
@@ -272,6 +535,48 @@ onMounted(() => {
//console.log('WebSocket 连接已关闭');
};
})
// 清理拖拽事件监听器
// 清理拖拽事件监听器
function cleanupDraggableTabs() {
const tabs = document.querySelectorAll('.n-tabs-tab');
tabs.forEach((tab) => {
// 移除所有可能的拖拽事件监听器
tab.removeEventListener('dragstart', handleTabDragStart);
tab.removeEventListener('dragover', handleTabDragOver);
tab.removeEventListener('dragenter', handleTabDragEnter);
tab.removeEventListener('dragleave', handleTabDragLeave);
tab.removeEventListener('drop', handleTabDrop);
tab.removeEventListener('dragend', handleTabDragEnd);
// 移除draggable属性
tab.removeAttribute('draggable');
});
}
// 初始化可拖拽选项卡
function initDraggableTabs() {
// 移除之前可能添加的事件监听器
cleanupDraggableTabs();
// 添加拖拽事件监听器到选项卡元素
setTimeout(() => {
const tabs = document.querySelectorAll('.n-tabs-tab');
tabs.forEach((tab, index) => {
const dataIndex = tab.getAttribute('data-name');
const name = parseInt(dataIndex);
// 只为分组标签name > 0添加拖拽功能
if (name > 0) {
tab.setAttribute('draggable', 'true');
tab.addEventListener('dragstart', (e) => handleTabDragStart(e, name));
tab.addEventListener('dragover', handleTabDragOver);
tab.addEventListener('dragenter', (e) => handleTabDragEnter(e, name));
tab.addEventListener('dragleave', handleTabDragLeave);
tab.addEventListener('drop', handleTabDrop);
tab.addEventListener('dragend', handleTabDragEnd);
}
});
}, 100);
}
onBeforeUnmount(() => {
// //console.log(`the component is now unmounted.`)
@@ -290,146 +595,9 @@ onBeforeUnmount(() => {
EventsOff("updateVersion")
EventsOff("warnMsg")
EventsOff("loadingDone")
})
EventsOn("loadingDone", (data) => {
message.loading("刷新股票基础数据...")
GetStockList("").then(result => {
stockList.value = result
options.value = result.map(item => {
return {
label: item.name + " - " + item.ts_code,
value: item.ts_code
}
})
})
})
cleanupDraggableTabs()
EventsOn("refresh", (data) => {
message.success(data)
})
EventsOn("showSearch", (data) => {
addBTN.value = data === 1;
})
EventsOn("stock_price", (data) => {
updateData(data)
})
EventsOn("refreshFollowList", (data) => {
WindowReload()
})
EventsOn("newChatStream", async (msg) => {
////console.log("newChatStream:->",data.airesult)
data.loading = false
////console.log(msg)
if (msg === "DONE") {
SaveAIResponseResult(data.code, data.name, data.airesult, data.chatId, data.question,data.aiConfigId)
message.info("AI分析完成")
message.destroyAll()
} else {
if (msg.chatId) {
data.chatId = msg.chatId
}
if (msg.question) {
data.question = msg.question
}
if (msg.content) {
data.airesult = data.airesult + msg.content
}
if (msg.extraContent) {
data.airesult = data.airesult + msg.extraContent
}
}
})
EventsOn("changeTab", async (msg) => {
//console.log("changeTab",msg)
currentGroupId.value = msg.ID
updateTab(currentGroupId.value)
})
EventsOn("updateVersion", async (msg) => {
const githubTimeStr = msg.published_at;
// 创建一个 Date 对象
const utcDate = new Date(githubTimeStr);
// 获取本地时间
const date = new Date(utcDate.getTime());
const year = date.getFullYear();
// getMonth 返回值是 0 - 11所以要加 1
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
//console.log("GitHub UTC 时间:", utcDate);
//console.log("转换后的本地时间:", formattedDate);
notify.info({
avatar: () =>
h(NAvatar, {
size: 'small',
round: false,
src: icon.value
}),
title: '发现新版本: ' + msg.tag_name,
content: () => {
//return h(MdPreview, {theme:'dark',modelValue:msg.commit?.message}, null)
return h('div', {
style: {
'text-align': 'left',
'font-size': '14px',
}
}, {default: () => msg.commit?.message})
},
duration: 5000,
meta: "发布时间:" + formattedDate,
action: () => {
return h(NButton, {
type: 'primary',
size: 'small',
onClick: () => {
Environment().then(env => {
switch (env.platform) {
case 'windows':
window.open(msg.html_url)
break
default :
OpenURL(msg.html_url)
}
})
}
}, {default: () => '查看'})
}
})
})
EventsOn("warnMsg", async (msg) => {
notify.error({
avatar: () =>
h(NAvatar, {
size: 'small',
round: false,
src: icon.value
}),
title: '警告',
duration: 5000,
content: () => {
return h('div', {
style: {
'text-align': 'left',
'font-size': '14px',
}
}, {default: () => msg})
},
})
})
//判断是否是A股交易时间
@@ -452,6 +620,23 @@ function isTradingTime() {
return false;
}
// 添加一个获取分组列表的函数,用于处理初始化逻辑
function fetchGroupList() {
InitializeGroupSort().then(initResult => {
if (initResult) {
GetGroupList().then(result => {
groupList.value = result
if (route.query.groupId) {
message.success("切换分组:" + route.query.groupName)
currentGroupId.value = Number(route.query.groupId)
}
})
} else {
message.error("初始化分组序号失败")
}
})
}
function AddStock() {
if (!data?.code) {
message.error("请输入有效股票代码");
@@ -1395,7 +1580,7 @@ function aiReCheckStock(stock, stockCode) {
//
//message.info("sysPromptId:"+data.sysPromptId)
NewChatStream(stock, stockCode, data.question,data.aiConfigId, data.sysPromptId, enableTools.value)
NewChatStream(stock, stockCode, data.question, data.aiConfigId, data.sysPromptId, enableTools.value)
}
function aiCheckStock(stock, stockCode) {
@@ -1499,14 +1684,14 @@ function saveAsImage(name, code) {
}
async function saveCanvasImage(name) {
const element = document.querySelector('.md-editor-preview'); // 要截图的 DOM 节点
const element = document.querySelector('.md-editor-preview'); // 要截图的 DOM 节点
const canvas = await html2canvas(element)
const dataUrl = canvas.toDataURL('image/png') // base64 格式
const base64 = dataUrl.replace(/^data:image\/png;base64,/, '')
// 调用 Go 后端保存文件Wails 绑定方法)
await SaveImage(name,base64).then(result => {
await SaveImage(name, base64).then(result => {
message.success(result)
})
}
@@ -1568,7 +1753,7 @@ AI赋能股票分析自选股行情获取成本盈亏展示涨跌报警
`
// landscape就是横着的portrait是竖着的默认是竖屏portrait。
const blob = await asBlob(value, {orientation: 'portrait'})
const { platform } = await Environment()
const {platform} = await Environment()
switch (platform) {
case 'windows':
const a = document.createElement('a')
@@ -1580,13 +1765,13 @@ AI赋能股票分析自选股行情获取成本盈亏展示涨跌报警
a.remove()
break
default:
const arrayBuffer = await blob.arrayBuffer()
const uint8Array = new Uint8Array(arrayBuffer)
const binary = uint8Array.reduce((data, byte) => data + String.fromCharCode(byte), '')
const base64 = btoa(binary)
await SaveWordFile(`${data.name}[${data.code}]-ai-analysis-result.docx`, base64).then(result => {
message.success(result)
})
const arrayBuffer = await blob.arrayBuffer()
const uint8Array = new Uint8Array(arrayBuffer)
const binary = uint8Array.reduce((data, byte) => data + String.fromCharCode(byte), '')
const base64 = btoa(binary)
await SaveWordFile(`${data.name}[${data.code}]-ai-analysis-result.docx`, base64).then(result => {
message.success(result)
})
}
}
@@ -1649,9 +1834,11 @@ function AddStockGroupInfo(groupId, code, name) {
function updateTab(name) {
stocks.value = []
currentGroupId.value = Number(name)
GetFollowList(currentGroupId.value).then(result => {
const tabId= Number(name)
currentGroupId.value = tabId;
GetFollowList(tabId).then(result => {
followList.value = result
for (const followedStock of result) {
if (followedStock.StockCode.startsWith("us")) {
followedStock.StockCode = "gb_" + followedStock.StockCode.replace("us", "").toLowerCase()
@@ -1724,8 +1911,9 @@ function searchStockReport(stockCode) {
</template>
</vue-danmaku>
<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="'全部'">
:value="String(currentGroupId)" @add="addTab" @update:value="updateTab" placement="top" @close="(key)=>{delTab(key)}">
<n-tab-pane closable name="0" :tab="'全部'">
<n-grid :x-gap="8" :cols="3" :y-gap="8">
<n-gi :id="result['股票代码']+'_gi'" v-for="result in sortedResults" style="margin-left: 2px;">
<n-card :data-sort="result.sort" :id="result['股票代码']" :data-code="result['股票代码']" :bordered="true"
@@ -1864,7 +2052,7 @@ function searchStockReport(stockCode) {
</n-gi>
</n-grid>
</n-tab-pane>
<n-tab-pane closable v-for="group in groupList" :group-id="group.ID" :name="group.ID" :tab="group.name">
<n-tab-pane closable v-for="group in groupList" :group-id="group.ID" :name="String(group.ID)" :tab="group.name">
<n-grid :x-gap="8" :cols="3" :y-gap="8">
<n-gi :id="result['股票代码']+'_gi'" v-for="result in groupResults" style="margin-left: 2px;">
<n-card :data-sort="result.sort" :id="result['股票代码']" :data-code="result['股票代码']" :bordered="true"
@@ -2011,6 +2199,7 @@ function searchStockReport(stockCode) {
</n-grid>
</n-tab-pane>
</n-tabs>
<div style="position: fixed;bottom: 18px;right:5px;z-index: 10;width: 400px">
<!-- <n-card :bordered="false">-->
<n-input-group>
@@ -2228,4 +2417,38 @@ function searchStockReport(stockCode) {
border-color: red;
}
}
</style>
/* 所有标签的通用样式 */
:deep(.n-tabs-nav .n-tabs-tab) {
position: relative;
cursor: pointer;
}
/* 可拖拽标签的样式 */
:deep(.n-tabs-nav .n-tabs-tab[draggable="true"]) {
user-select: none;
cursor: move;
}
.tab-drag-over {
background-color: #e6f7ff !important;
border: 2px dashed #1890ff !important;
transform: scale(1.02);
transition: all 0.2s ease;
z-index: 10;
}
.tab-drag-over::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
}
.tab-dragging {
opacity: 0.5;
}
</style>

View File

@@ -88,6 +88,8 @@ export function HotTopic(arg1:number):Promise<Array<any>>;
export function IndustryResearchReport(arg1:string):Promise<Array<any>>;
export function InitializeGroupSort():Promise<boolean>;
export function InvestCalendarTimeLine(arg1:string):Promise<Array<any>>;
export function LongTigerRank(arg1:string):Promise<any>;
@@ -139,3 +141,5 @@ export function UnFollow(arg1:string):Promise<string>;
export function UnFollowFund(arg1:string):Promise<string>;
export function UpdateConfig(arg1:data.SettingConfig):Promise<string>;
export function UpdateGroupSort(arg1:number,arg2:number):Promise<boolean>;

View File

@@ -170,6 +170,10 @@ export function IndustryResearchReport(arg1) {
return window['go']['main']['App']['IndustryResearchReport'](arg1);
}
export function InitializeGroupSort() {
return window['go']['main']['App']['InitializeGroupSort']();
}
export function InvestCalendarTimeLine(arg1) {
return window['go']['main']['App']['InvestCalendarTimeLine'](arg1);
}
@@ -273,3 +277,7 @@ export function UnFollowFund(arg1) {
export function UpdateConfig(arg1) {
return window['go']['main']['App']['UpdateConfig'](arg1);
}
export function UpdateGroupSort(arg1, arg2) {
return window['go']['main']['App']['UpdateGroupSort'](arg1, arg2);
}

12
go.mod
View File

@@ -28,7 +28,7 @@ require (
github.com/wailsapp/wails/v2 v2.10.1
go.uber.org/zap v1.27.0
golang.org/x/net v0.38.0
golang.org/x/sys v0.33.0
golang.org/x/sys v0.35.0
golang.org/x/text v0.26.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gorm.io/gorm v1.25.12
@@ -40,12 +40,12 @@ require (
git.sr.ht/~jackmordaunt/go-toast v1.1.2 // indirect
github.com/andybalholm/cascadia v1.3.3 // indirect
github.com/bep/debounce v1.2.1 // indirect
github.com/bytedance/sonic v1.13.2 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/bytedance/sonic v1.14.0 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb // indirect
github.com/chromedp/sysutil v1.1.0 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250804062529-6e67726a4b3f // indirect
github.com/cohesion-org/deepseek-go v1.3.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -72,7 +72,7 @@ require (
github.com/joho/godotenv v1.5.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/labstack/echo/v4 v4.13.3 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
@@ -119,7 +119,7 @@ require (
github.com/wailsapp/mimetype v1.4.1 // indirect
github.com/yargevad/filepathx v1.0.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/arch v0.11.0 // indirect
golang.org/x/arch v0.20.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect

29
go.sum
View File

@@ -16,11 +16,10 @@ github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqR
github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/bytedance/mockey v1.2.14 h1:KZaFgPdiUwW+jOWFieo3Lr7INM1P+6adO3hxZhDswY8=
github.com/bytedance/mockey v1.2.14/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY=
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
@@ -32,8 +31,8 @@ github.com/chromedp/chromedp v0.11.2/go.mod h1:lr8dFRLKsdTTWb75C/Ttol2vnBKOSnt0B
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/cloudwego/eino v0.4.1 h1:Jy9KWpCvd+Z75oIynhHsT9dEECUuCW8IPZlVjHgVu9s=
github.com/cloudwego/eino v0.4.1/go.mod h1:wUjz990apdsaOraOXdh6CdhVXq8DJsOvLsVlxNTcNfY=
github.com/cloudwego/eino-ext/components/model/ark v0.1.19 h1:XYnOeszXA28T1gxYOpTIjOjLCPO2gjexK+ShSan9u/8=
@@ -44,7 +43,6 @@ github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250804092122-8845
github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250804092122-8845979a2228/go.mod h1:3uBZ/GzJzh1izfY2w62282FZrQG3ISs6T/jTmmPffvE=
github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250804062529-6e67726a4b3f h1:J1tQBg6RDftrtm3vsv+ozlupdlNV+WGslpXiTDr/2xI=
github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250804062529-6e67726a4b3f/go.mod h1:4EBgz8+68n1iuKyWC37Tu9NG1WJkPm+yLxvyLik28Us=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cohesion-org/deepseek-go v1.3.2 h1:WTZ/2346KFYca+n+DL5p+Ar1RQxF2w/wGkU4jDvyXaQ=
github.com/cohesion-org/deepseek-go v1.3.2/go.mod h1:bOVyKj38r90UEYZFrmJOzJKPxuAh8sIzHOCnLOpiXeI=
github.com/coocood/freecache v1.2.4 h1:UdR6Yz/X1HW4fZOuH0Z94KwG851GWOSknua5VUbb/5M=
@@ -162,10 +160,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -343,8 +339,8 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4=
golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -413,8 +409,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -512,4 +508,3 @@ modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=

17
main.go
View File

@@ -5,6 +5,14 @@ import (
"embed"
"encoding/json"
"fmt"
"go-stock/backend/data"
"go-stock/backend/db"
log "go-stock/backend/logger"
"go-stock/backend/models"
"os"
"runtime/debug"
"strings"
"github.com/duke-git/lancet/v2/slice"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/logger"
@@ -13,13 +21,6 @@ import (
"github.com/wailsapp/wails/v2/pkg/options/mac"
"github.com/wailsapp/wails/v2/pkg/options/windows"
"github.com/wailsapp/wails/v2/pkg/runtime"
"go-stock/backend/data"
"go-stock/backend/db"
log "go-stock/backend/logger"
"go-stock/backend/models"
"os"
"runtime/debug"
"strings"
)
//go:embed frontend/dist
@@ -125,7 +126,7 @@ func main() {
err = wails.Run(&options.App{
Title: "go-stockAI赋能股票分析✨",
Width: width * 4 / 5,
Height: 950,
Height: 920,
MinWidth: minWidth,
MinHeight: minHeight,
//MaxWidth: width,