mirror of
https://github.com/ArvinLovegood/go-stock.git
synced 2025-07-19 00:00:09 +08:00
- 在 MarketNewsApi 中添加 TopStocksRankingList 方法,实现 top stocks 排行榜数据的获取和解析 - 更新 App.vue 中的 content 文本,增加未经授权禁止商业用途的声明- 在 market_news_api_test.go 中添加 TopStocksRankingList 的测试用例
518 lines
13 KiB
Vue
518 lines
13 KiB
Vue
<script setup>
|
|
import {
|
|
EventsEmit,
|
|
EventsOff,
|
|
EventsOn,
|
|
Quit,
|
|
WindowFullscreen,
|
|
WindowHide,
|
|
WindowUnfullscreen
|
|
} from '../wailsjs/runtime'
|
|
import {h, onBeforeMount, onBeforeUnmount, onMounted, ref} from "vue";
|
|
import {RouterLink, useRouter} from 'vue-router'
|
|
import {darkTheme, NIcon, NText,} from 'naive-ui'
|
|
import {
|
|
AlarmOutline,
|
|
AnalyticsOutline,
|
|
BarChartSharp,
|
|
ExpandOutline,
|
|
Flame,
|
|
LogoGithub,
|
|
NewspaperOutline,
|
|
NewspaperSharp,
|
|
PowerOutline,
|
|
ReorderTwoOutline,
|
|
SettingsOutline,
|
|
SparklesOutline,
|
|
StarOutline,
|
|
Wallet,
|
|
} from '@vicons/ionicons5'
|
|
import {GetConfig, GetGroupList} from "../wailsjs/go/main/App";
|
|
|
|
const router = useRouter()
|
|
const loading = ref(true)
|
|
const loadingMsg = ref("加载数据中...")
|
|
const enableNews = ref(false)
|
|
const contentStyle = ref("")
|
|
const enableFund = ref(false)
|
|
const enableDarkTheme = ref(null)
|
|
const content = ref('数据来源于网络,仅供参考;投资有风险,入市需谨慎\n\n未经授权,禁止商业目的!')
|
|
const isFullscreen = ref(false)
|
|
const activeKey = ref('')
|
|
const containerRef = ref({})
|
|
const realtimeProfit = ref(0)
|
|
const telegraph = ref([])
|
|
const groupList = ref([])
|
|
const menuOptions = ref([
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
to: {
|
|
name: 'stock',
|
|
query: {
|
|
groupName: '全部',
|
|
groupId: 0,
|
|
},
|
|
params: {},
|
|
}
|
|
},
|
|
{default: () => '股票自选',}
|
|
),
|
|
key: 'stock',
|
|
icon: renderIcon(StarOutline),
|
|
children: [
|
|
{
|
|
label: () =>
|
|
h(
|
|
'a',
|
|
{
|
|
href: '#',
|
|
type: 'info',
|
|
onClick: () => {
|
|
//console.log("push",item)
|
|
router.push({
|
|
name: 'stock',
|
|
query: {
|
|
groupName: '全部',
|
|
groupId: 0,
|
|
},
|
|
})
|
|
EventsEmit("changeTab", {ID: 0, name: '全部'})
|
|
},
|
|
to: {
|
|
name: 'stock',
|
|
query: {
|
|
groupName: '全部',
|
|
groupId: 0,
|
|
},
|
|
}
|
|
},
|
|
{default: () => '全部',}
|
|
),
|
|
key: 0,
|
|
}
|
|
],
|
|
},
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
href: '#',
|
|
to: {
|
|
name: 'market',
|
|
params: {}
|
|
},
|
|
onClick: () => {
|
|
EventsEmit("changeMarketTab", {ID: 0, name: '市场快讯'})
|
|
},
|
|
},
|
|
{default: () => '市场行情'}
|
|
),
|
|
key: 'market',
|
|
icon: renderIcon(NewspaperOutline),
|
|
children: [
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
href: '#',
|
|
to: {
|
|
name: 'market',
|
|
query: {
|
|
name: "市场快讯",
|
|
}
|
|
},
|
|
onClick: () => {
|
|
EventsEmit("changeMarketTab", {ID: 0, name: '市场快讯'})
|
|
},
|
|
},
|
|
{default: () => '市场快讯',}
|
|
),
|
|
key: 'market1',
|
|
icon: renderIcon(NewspaperSharp),
|
|
},
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
href: '#',
|
|
to: {
|
|
name: 'market',
|
|
query: {
|
|
name: "全球股指",
|
|
},
|
|
},
|
|
onClick: () => {
|
|
EventsEmit("changeMarketTab", {ID: 0, name: '全球股指'})
|
|
},
|
|
},
|
|
{default: () => '全球股指',}
|
|
),
|
|
key: 'market2',
|
|
icon: renderIcon(BarChartSharp),
|
|
},
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
href: '#',
|
|
to: {
|
|
name: 'market',
|
|
query: {
|
|
name: "指标行情",
|
|
}
|
|
},
|
|
onClick: () => {
|
|
EventsEmit("changeMarketTab", {ID: 0, name: '指标行情'})
|
|
},
|
|
},
|
|
{default: () => '指标行情',}
|
|
),
|
|
key: 'market3',
|
|
icon: renderIcon(AnalyticsOutline),
|
|
},
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
href: '#',
|
|
to: {
|
|
name: 'market',
|
|
query: {
|
|
name: "行业排名",
|
|
}
|
|
},
|
|
onClick: () => {
|
|
EventsEmit("changeMarketTab", {ID: 0, name: '行业排名'})
|
|
},
|
|
},
|
|
{default: () => '行业排名',}
|
|
),
|
|
key: 'market4',
|
|
icon: renderIcon(Flame),
|
|
},
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
href: '#',
|
|
to: {
|
|
name: 'market',
|
|
query: {
|
|
name: "个股资金流向",
|
|
}
|
|
},
|
|
onClick: () => {
|
|
EventsEmit("changeMarketTab", {ID: 0, name: '个股资金流向'})
|
|
},
|
|
},
|
|
{default: () => '个股资金流向',}
|
|
),
|
|
key: 'market5',
|
|
icon: renderIcon(Wallet),
|
|
}
|
|
]
|
|
},
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
to: {
|
|
name: 'fund',
|
|
params: {},
|
|
}
|
|
},
|
|
{default: () => '基金自选',}
|
|
),
|
|
show: enableFund.value,
|
|
key: 'fund',
|
|
icon: renderIcon(SparklesOutline),
|
|
children: [
|
|
{
|
|
label: () => h(NText, {type: realtimeProfit.value > 0 ? 'error' : 'success'}, {default: () => '功能完善中!'}),
|
|
key: 'realtimeProfit',
|
|
show: realtimeProfit.value,
|
|
icon: renderIcon(AlarmOutline),
|
|
},
|
|
]
|
|
},
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
to: {
|
|
name: 'settings',
|
|
params: {}
|
|
}
|
|
},
|
|
{default: () => '设置'}
|
|
),
|
|
key: 'settings',
|
|
icon: renderIcon(SettingsOutline),
|
|
},
|
|
{
|
|
label: () =>
|
|
h(
|
|
RouterLink,
|
|
{
|
|
to: {
|
|
name: 'about',
|
|
params: {}
|
|
}
|
|
},
|
|
{default: () => '关于'}
|
|
),
|
|
key: 'about',
|
|
icon: renderIcon(LogoGithub),
|
|
},
|
|
{
|
|
label: () => h("a", {
|
|
href: '#',
|
|
onClick: toggleFullscreen,
|
|
title: '全屏 Ctrl+F 退出全屏 Esc',
|
|
}, {default: () => isFullscreen.value ? '取消全屏' : '全屏'}),
|
|
key: 'full',
|
|
icon: renderIcon(ExpandOutline),
|
|
},
|
|
{
|
|
label: () => h("a", {
|
|
href: '#',
|
|
onClick: WindowHide,
|
|
title: '隐藏到托盘区 Ctrl+H',
|
|
}, {default: () => '隐藏到托盘区'}),
|
|
key: 'hide',
|
|
icon: renderIcon(ReorderTwoOutline),
|
|
},
|
|
// {
|
|
// label: ()=> h("a", {
|
|
// href: 'javascript:void(0)',
|
|
// style: 'cursor: move;',
|
|
// onClick: toggleStartMoveWindow,
|
|
// }, { default: () => '移动' }),
|
|
// key: 'move',
|
|
// icon: renderIcon(MoveOutline),
|
|
// },
|
|
{
|
|
label: () => h("a", {
|
|
href: '#',
|
|
onClick: Quit,
|
|
}, {default: () => '退出程序'}),
|
|
key: 'exit',
|
|
icon: renderIcon(PowerOutline),
|
|
},
|
|
])
|
|
|
|
function renderIcon(icon) {
|
|
return () => h(NIcon, null, {default: () => h(icon)})
|
|
}
|
|
|
|
function toggleFullscreen(e) {
|
|
//console.log(e)
|
|
if (isFullscreen.value) {
|
|
WindowUnfullscreen()
|
|
//e.target.innerHTML = '全屏'
|
|
} else {
|
|
WindowFullscreen()
|
|
// e.target.innerHTML = '取消全屏'
|
|
}
|
|
isFullscreen.value = !isFullscreen.value
|
|
}
|
|
|
|
// const drag = ref(false)
|
|
// const lastPos= ref({x:0,y:0})
|
|
// function toggleStartMoveWindow(e) {
|
|
// drag.value=!drag.value
|
|
// lastPos.value={x:e.clientX,y:e.clientY}
|
|
// }
|
|
// function dragstart(e) {
|
|
// if (drag.value) {
|
|
// let x=e.clientX-lastPos.value.x
|
|
// let y=e.clientY-lastPos.value.y
|
|
// WindowGetPosition().then((pos) => {
|
|
// WindowSetPosition(pos.x+x,pos.y+y)
|
|
// })
|
|
// }
|
|
// }
|
|
// window.addEventListener('mousemove', dragstart)
|
|
|
|
EventsOn("realtime_profit", (data) => {
|
|
realtimeProfit.value = data
|
|
})
|
|
EventsOn("telegraph", (data) => {
|
|
telegraph.value = data
|
|
})
|
|
|
|
EventsOn("loadingMsg", (data) => {
|
|
if(data==="done"){
|
|
loadingMsg.value = "加载完成..."
|
|
EventsEmit("loadingDone", "app")
|
|
loading.value = false
|
|
}else{
|
|
loading.value = true
|
|
loadingMsg.value = data
|
|
}
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
EventsOff("realtime_profit")
|
|
EventsOff("loadingMsg")
|
|
EventsOff("telegraph")
|
|
})
|
|
|
|
window.onerror = function (msg, source, lineno, colno, error) {
|
|
// 将错误信息发送给后端
|
|
EventsEmit("frontendError", {
|
|
page: "App.vue",
|
|
message: msg,
|
|
source: source,
|
|
lineno: lineno,
|
|
colno: colno,
|
|
error: error ? error.stack : null,
|
|
});
|
|
return true;
|
|
};
|
|
|
|
onBeforeMount(() => {
|
|
GetGroupList().then(result => {
|
|
groupList.value = result
|
|
menuOptions.value.map((item) => {
|
|
//console.log(item)
|
|
if (item.key === 'stock') {
|
|
item.children.push(...groupList.value.map(item => {
|
|
return {
|
|
label: () =>
|
|
h(
|
|
'a',
|
|
{
|
|
href: '#',
|
|
type: 'info',
|
|
onClick: () => {
|
|
//console.log("push",item)
|
|
router.push({
|
|
name: 'stock',
|
|
query: {
|
|
groupName: item.name,
|
|
groupId: item.ID,
|
|
},
|
|
})
|
|
setTimeout(() => {
|
|
EventsEmit("changeTab", item)
|
|
}, 100)
|
|
},
|
|
to: {
|
|
name: 'stock',
|
|
query: {
|
|
groupName: item.name,
|
|
groupId: item.ID,
|
|
},
|
|
}
|
|
},
|
|
{default: () => item.name,}
|
|
),
|
|
key: item.ID,
|
|
}
|
|
}))
|
|
}
|
|
})
|
|
})
|
|
|
|
|
|
GetConfig().then((res) => {
|
|
//console.log(res)
|
|
enableFund.value = res.enableFund
|
|
|
|
menuOptions.value.filter((item) => {
|
|
if (item.key === 'fund') {
|
|
item.show = res.enableFund
|
|
}
|
|
})
|
|
|
|
if (res.darkTheme) {
|
|
enableDarkTheme.value = darkTheme
|
|
} else {
|
|
enableDarkTheme.value = null
|
|
}
|
|
})
|
|
})
|
|
|
|
onMounted(() => {
|
|
contentStyle.value = "max-height: calc(92vh);overflow: hidden"
|
|
GetConfig().then((res) => {
|
|
if (res.enableNews) {
|
|
enableNews.value = true
|
|
}
|
|
enableFund.value = res.enableFund
|
|
})
|
|
})
|
|
|
|
</script>
|
|
<template>
|
|
<n-config-provider ref="containerRef" :theme="enableDarkTheme">
|
|
<n-message-provider>
|
|
<n-notification-provider>
|
|
<n-modal-provider>
|
|
<n-dialog-provider>
|
|
<n-watermark
|
|
:content="content"
|
|
cross
|
|
selectable
|
|
:font-size="16"
|
|
:line-height="16"
|
|
:width="500"
|
|
:height="400"
|
|
:x-offset="50"
|
|
:y-offset="150"
|
|
:rotate="-15"
|
|
>
|
|
<n-flex>
|
|
<n-grid x-gap="12" :cols="1">
|
|
<n-gi>
|
|
<n-spin :show="loading">
|
|
<template #description>
|
|
{{ loadingMsg }}
|
|
</template>
|
|
<n-marquee :speed="100" style="position: relative;top:0;z-index: 19;width: 100%"
|
|
v-if="(telegraph.length>0)&&(enableNews)">
|
|
<n-tag type="warning" v-for="item in telegraph" style="margin-right: 10px">
|
|
{{ item }}
|
|
</n-tag>
|
|
</n-marquee>
|
|
<n-scrollbar :style="contentStyle">
|
|
<n-skeleton v-if="loading" height="calc(100vh)" />
|
|
<RouterView/>
|
|
</n-scrollbar>
|
|
</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-menu style="font-size: 18px;"
|
|
v-model:value="activeKey"
|
|
mode="horizontal"
|
|
:options="menuOptions"
|
|
responsive
|
|
/>
|
|
</n-card>
|
|
</n-gi>
|
|
</n-grid>
|
|
</n-flex>
|
|
</n-watermark>
|
|
</n-dialog-provider>
|
|
</n-modal-provider>
|
|
</n-notification-provider>
|
|
</n-message-provider>
|
|
</n-config-provider>
|
|
</template>
|
|
<style>
|
|
|
|
</style>
|