refactor(frontend):重构前端路由并优化设置页面布局

- 修改路由配置,使用 createWebHashHistory 替代 createWebHistory- 重命名部分组件以提高代码一致性
- 优化设置页面布局,使用卡片组件分类显示不同设置项
- 调整提示词模板展示方式,增加警告提示
This commit is contained in:
ArvinLovegood 2025-07-07 10:50:08 +08:00
parent c65d0b79f4
commit b5843bcdb8
3 changed files with 97 additions and 44 deletions

View File

@ -44,9 +44,9 @@ const enableNews = ref(false)
const contentStyle = ref("") const contentStyle = ref("")
const enableFund = ref(false) const enableFund = ref(false)
const enableDarkTheme = ref(null) const enableDarkTheme = ref(null)
const content = ref('数据来源于网络,仅供参考;投资有风险,入市需谨慎\n\n未经授权,禁止商业目的!') const content = ref('未经授权,禁止商业目的!\n\n数据来源于网络,仅供参考;投资有风险,入市需谨慎')
const isFullscreen = ref(false) const isFullscreen = ref(false)
const activeKey = ref('') const activeKey = ref('stock')
const containerRef = ref({}) const containerRef = ref({})
const realtimeProfit = ref(0) const realtimeProfit = ref(0)
const telegraph = ref([]) const telegraph = ref([])
@ -64,7 +64,10 @@ const menuOptions = ref([
groupId: 0, groupId: 0,
}, },
params: {}, params: {},
} },
onClick: () => {
activeKey.value = 'stock'
},
}, },
{default: () => '股票自选',} {default: () => '股票自选',}
), ),
@ -79,6 +82,7 @@ const menuOptions = ref([
href: '#', href: '#',
type: 'info', type: 'info',
onClick: () => { onClick: () => {
activeKey.value = 'stock'
//console.log("push",item) //console.log("push",item)
router.push({ router.push({
name: 'stock', name: 'stock',
@ -114,6 +118,7 @@ const menuOptions = ref([
params: {} params: {}
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '市场快讯'}) EventsEmit("changeMarketTab", {ID: 0, name: '市场快讯'})
}, },
}, },
@ -135,6 +140,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '市场快讯'}) EventsEmit("changeMarketTab", {ID: 0, name: '市场快讯'})
}, },
}, },
@ -156,6 +162,7 @@ const menuOptions = ref([
}, },
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '全球股指'}) EventsEmit("changeMarketTab", {ID: 0, name: '全球股指'})
}, },
}, },
@ -177,6 +184,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '指标行情'}) EventsEmit("changeMarketTab", {ID: 0, name: '指标行情'})
}, },
}, },
@ -198,6 +206,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '行业排名'}) EventsEmit("changeMarketTab", {ID: 0, name: '行业排名'})
}, },
}, },
@ -219,6 +228,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '个股资金流向'}) EventsEmit("changeMarketTab", {ID: 0, name: '个股资金流向'})
}, },
}, },
@ -240,6 +250,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '龙虎榜'}) EventsEmit("changeMarketTab", {ID: 0, name: '龙虎榜'})
}, },
}, },
@ -261,6 +272,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '个股研报'}) EventsEmit("changeMarketTab", {ID: 0, name: '个股研报'})
}, },
}, },
@ -282,6 +294,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '公司公告'}) EventsEmit("changeMarketTab", {ID: 0, name: '公司公告'})
}, },
}, },
@ -303,6 +316,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '行业研究'}) EventsEmit("changeMarketTab", {ID: 0, name: '行业研究'})
}, },
}, },
@ -324,6 +338,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '当前热门'}) EventsEmit("changeMarketTab", {ID: 0, name: '当前热门'})
}, },
}, },
@ -345,6 +360,7 @@ const menuOptions = ref([
} }
}, },
onClick: () => { onClick: () => {
activeKey.value = 'market'
EventsEmit("changeMarketTab", {ID: 0, name: '指标选股'}) EventsEmit("changeMarketTab", {ID: 0, name: '指标选股'})
}, },
}, },
@ -362,8 +378,13 @@ const menuOptions = ref([
{ {
to: { to: {
name: 'fund', name: 'fund',
params: {}, query: {
} name: '基金自选',
},
},
onClick: () => {
activeKey.value = 'fund'
},
}, },
{default: () => '基金自选',} {default: () => '基金自选',}
), ),
@ -386,7 +407,12 @@ const menuOptions = ref([
{ {
to: { to: {
name: 'settings', name: 'settings',
params: {} query: {
name:"设置",
},
onClick: () => {
activeKey.value = 'settings'
},
} }
}, },
{default: () => '设置'} {default: () => '设置'}
@ -401,8 +427,13 @@ const menuOptions = ref([
{ {
to: { to: {
name: 'about', name: 'about',
params: {} query: {
} name:"关于",
}
},
onClick: () => {
activeKey.value = 'about'
},
}, },
{default: () => '关于'} {default: () => '关于'}
), ),
@ -451,6 +482,7 @@ function renderIcon(icon) {
} }
function toggleFullscreen(e) { function toggleFullscreen(e) {
activeKey.value = 'full'
//console.log(e) //console.log(e)
if (isFullscreen.value) { if (isFullscreen.value) {
WindowUnfullscreen() WindowUnfullscreen()

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import {computed, onBeforeUnmount, onMounted, ref} from "vue"; import {h, onBeforeUnmount, onMounted, ref} from "vue";
import { import {
AddPrompt, DelPrompt, AddPrompt, DelPrompt,
ExportConfig, ExportConfig,
@ -9,7 +9,7 @@ import {
SendDingDingMessageByType, SendDingDingMessageByType,
UpdateConfig UpdateConfig
} from "../../wailsjs/go/main/App"; } from "../../wailsjs/go/main/App";
import {useMessage} from "naive-ui"; import {NTag, useMessage} from "naive-ui";
import {data, models} from "../../wailsjs/go/models"; import {data, models} from "../../wailsjs/go/models";
import {EventsEmit} from "../../wailsjs/runtime"; import {EventsEmit} from "../../wailsjs/runtime";
const message = useMessage() const message = useMessage()
@ -267,12 +267,13 @@ function deletePrompt(ID){
</script> </script>
<template> <template>
<n-flex justify="left" style="margin-top: 12px;padding-left: 12px;"> <n-flex justify="left" style="text-align: left">
<n-form ref="formRef" :label-placement="'left'" :label-align="'left'" > <n-form ref="formRef" :label-placement="'left'" :label-align="'left'" >
<n-grid :cols="24" :x-gap="24" style="text-align: left" :layout-shift-disabled="true"> <n-card :title="()=> h(NTag, { type: 'primary',bordered:false },()=> '基础设置')" size="small" >
<n-gi :span="24"> <n-grid :cols="24" :x-gap="24" style="text-align: left" >
<n-text type="success" style="font-size: 25px;font-weight: bold">基础设置</n-text> <!-- <n-gi :span="24">-->
</n-gi> <!-- <n-text type="success" style="font-size: 25px;font-weight: bold">基础设置</n-text>-->
<!-- </n-gi>-->
<n-form-item-gi :span="10" label="Tushare &nbsp;&nbsp;Token" path="tushareToken" > <n-form-item-gi :span="10" label="Tushare &nbsp;&nbsp;Token" path="tushareToken" >
<n-input type="text" placeholder="Tushare api token" v-model:value="formValue.tushareToken" clearable /> <n-input type="text" placeholder="Tushare api token" v-model:value="formValue.tushareToken" clearable />
</n-form-item-gi> </n-form-item-gi>
@ -296,11 +297,14 @@ function deletePrompt(ID){
<n-switch v-model:value="formValue.enableFund" /> <n-switch v-model:value="formValue.enableFund" />
</n-form-item-gi> </n-form-item-gi>
</n-grid> </n-grid>
</n-card>
<n-card :title="()=> h(NTag, { type: 'primary',bordered:false },()=> '通知设置')" size="small" >
<n-grid :cols="24" :x-gap="24" style="text-align: left"> <n-grid :cols="24" :x-gap="24" style="text-align: left">
<n-gi :span="24"> <!-- <n-gi :span="24">-->
<n-text type="success" style="font-size: 25px;font-weight: bold">通知设置</n-text> <!-- <n-text type="success" style="font-size: 25px;font-weight: bold">通知设置</n-text>-->
</n-gi> <!-- </n-gi>-->
<n-form-item-gi :span="4" label="钉钉推送:" path="dingPush.enable" > <n-form-item-gi :span="4" label="钉钉推送:" path="dingPush.enable" >
<n-switch v-model:value="formValue.dingPush.enable" /> <n-switch v-model:value="formValue.dingPush.enable" />
</n-form-item-gi> </n-form-item-gi>
@ -321,11 +325,13 @@ function deletePrompt(ID){
<n-button type="primary" @click="sendTestNotice">发送测试通知</n-button> <n-button type="primary" @click="sendTestNotice">发送测试通知</n-button>
</n-form-item-gi> </n-form-item-gi>
</n-grid> </n-grid>
</n-card>
<n-card :title="()=> h(NTag, { type: 'primary',bordered:false },()=> 'AI设置')" size="small" >
<n-grid :cols="24" :x-gap="24" style="text-align: left;"> <n-grid :cols="24" :x-gap="24" style="text-align: left;">
<n-gi :span="24"> <!-- <n-gi :span="24">-->
<n-text type="success" style="font-size: 25px;font-weight: bold">OpenAI设置</n-text> <!-- <n-text type="success" style="font-size: 25px;font-weight: bold">OpenAI设置</n-text>-->
</n-gi> <!-- </n-gi>-->
<n-form-item-gi :span="3" label="AI诊股" path="openAI.enable" > <n-form-item-gi :span="3" label="AI诊股" path="openAI.enable" >
<n-switch v-model:value="formValue.openAI.enable" /> <n-switch v-model:value="formValue.openAI.enable" />
</n-form-item-gi> </n-form-item-gi>
@ -376,28 +382,38 @@ function deletePrompt(ID){
/> />
</n-form-item-gi> </n-form-item-gi>
</n-grid> </n-grid>
<n-gi :span="24"> <n-grid :cols="24">
<n-gi :span="24">
<n-space justify="center"> <n-space justify="center">
<n-button type="warning" @click="managePrompts"> <n-button type="warning" @click="managePrompts">
添加提示词模板 添加提示词模板
</n-button> </n-button>
<n-button type="primary" @click="saveConfig"> <n-button type="primary" @click="saveConfig">
保存 保存
</n-button> </n-button>
<n-button type="info" @click="exportConfig"> <n-button type="info" @click="exportConfig">
导出 导出
</n-button> </n-button>
<n-button type="error" @click="importConfig"> <n-button type="error" @click="importConfig">
导入 导入
</n-button> </n-button>
</n-space> </n-space>
</n-gi> </n-gi>
<n-gi :span="24" v-if="promptTemplates.length>0" type="warning">
<n-flex justify="start" style="margin-top: 4px" >
<n-text type="warning" >
<n-flex justify="left" >
<n-tag :bordered="false" type="warning" > 提示词模板:</n-tag>
<n-tag size="medium" secondary v-if="promptTemplates.length>0" v-for="prompt in promptTemplates" closable @close="deletePrompt(prompt.ID)" @click="editPrompt(prompt)" :title="prompt.content"
:type="prompt.type==='模型系统Prompt'?'success':'info'" :bordered="false"> {{ prompt.name }}
</n-tag>
</n-flex>
</n-text>
</n-flex>
</n-gi>
</n-grid>
</n-card>
</n-form> </n-form>
<n-gi :span="24" v-if="promptTemplates.length>0" v-for="prompt in promptTemplates" >
<n-flex justify="start">
<n-tag closable @close="deletePrompt(prompt.ID)" @click="editPrompt(prompt)" :title="prompt.content" :type="prompt.type==='模型系统Prompt'?'success':'info'" :bordered="false"> {{prompt.name}} </n-tag>
</n-flex>
</n-gi>
</n-flex> </n-flex>
<n-modal v-model:show="showManagePromptsModal" closable :mask-closable="false"> <n-modal v-model:show="showManagePromptsModal" closable :mask-closable="false">
<n-card <n-card
@ -442,5 +458,9 @@ function deletePrompt(ID){
</template> </template>
<style scoped> <style scoped>
.cardHeaderClass{
font-size: 16px;
font-weight: bold;
color: red;
}
</style> </style>

View File

@ -2,21 +2,22 @@ import {createMemoryHistory, createRouter, createWebHashHistory, createWebHistor
import stockView from '../components/stock.vue' import stockView from '../components/stock.vue'
import settingsView from '../components/settings.vue' import settingsView from '../components/settings.vue'
import about from "../components/about.vue"; import aboutView from "../components/about.vue";
import fundView from "../components/fund.vue"; import fundView from "../components/fund.vue";
import market from "../components/market.vue"; import marketView from "../components/market.vue";
const routes = [ const routes = [
{ path: '/', component: stockView,name: 'stock'}, { path: '/', component: stockView,name: 'stock'},
{ path: '/fund', component: fundView,name: 'fund' }, { path: '/fund', component: fundView,name: 'fund' },
{ path: '/settings', component: settingsView,name: 'settings' }, { path: '/settings', component: settingsView,name: 'settings' },
{ path: '/about', component: about,name: 'about' }, { path: '/about', component: aboutView,name: 'about' },
{ path: '/market', component: market,name: 'market' }, { path: '/market', component: marketView,name: 'market' },
] ]
const router = createRouter({ const router = createRouter({
history: createWebHistory(), //history: createWebHistory(),
history: createWebHashHistory(),
routes, routes,
}) })