feat: improve stock detail view and update docs

This commit is contained in:
wanghep
2026-05-02 18:27:36 +08:00
parent a492c73cc6
commit 597aef1271
21 changed files with 1739 additions and 1481 deletions

View File

@ -7,7 +7,7 @@ import StockDetailScreen from './components/StockDetailScreen.vue'
import TraderDetailScreen from './components/TraderDetailScreen.vue'
import WarningCenterScreen from './components/WarningCenterScreen.vue'
import { useDashboardData } from './composables/useDashboardData'
import type { WarningItem } from './types'
import type { StockSearchItem, WarningItem } from './types'
const dashboard = useDashboardData()
@ -15,6 +15,11 @@ type PageKey = 'home' | 'trader' | 'stock' | 'warning'
const currentPage = shallowRef<PageKey>('home')
const selectedTraderId = computed(() => dashboard.selectedTraderId.value)
const stockSearchQuery = shallowRef('')
const stockSearchResults = shallowRef<StockSearchItem[]>([])
const stockSearchLoading = shallowRef(false)
let stockSearchTimer: ReturnType<typeof window.setTimeout> | null = null
let latestStockSearchToken = 0
const navItems: Array<{ key: PageKey; label: string }> = [
{ key: 'home', label: '首页总控台' },
@ -64,6 +69,12 @@ async function handleSelectStock(stockCode: string) {
navigate('stock')
}
async function handleSearchSelectStock(stock: Pick<StockSearchItem, 'stock_code' | 'stock_name'>) {
stockSearchQuery.value = stock.stock_name
stockSearchResults.value = []
await handleSelectStock(stock.stock_code)
}
async function handleSelectWarningInCenter(warning: WarningItem) {
await dashboard.selectWarning(warning)
}
@ -105,11 +116,47 @@ onMounted(() => {
onUnmounted(() => {
window.removeEventListener('hashchange', syncPageFromHash)
if (stockSearchTimer !== null) {
window.clearTimeout(stockSearchTimer)
}
})
watch(currentPage, (page) => {
void ensurePageData(page)
})
watch(stockSearchQuery, (nextQuery) => {
const keyword = nextQuery.trim()
if (stockSearchTimer !== null) {
window.clearTimeout(stockSearchTimer)
stockSearchTimer = null
}
if (!keyword) {
stockSearchResults.value = []
stockSearchLoading.value = false
return
}
stockSearchTimer = window.setTimeout(() => {
const currentToken = ++latestStockSearchToken
stockSearchLoading.value = true
void dashboard
.searchStocks(keyword, 8)
.then((results) => {
if (currentToken !== latestStockSearchToken) return
stockSearchResults.value = results
})
.catch(() => {
if (currentToken !== latestStockSearchToken) return
stockSearchResults.value = []
})
.finally(() => {
if (currentToken !== latestStockSearchToken) return
stockSearchLoading.value = false
})
}, 180)
})
</script>
<template>
@ -123,7 +170,12 @@ watch(currentPage, (page) => {
:status="dashboard.status.value"
:nav-items="navItems"
:current-page="currentPage"
:search-query="stockSearchQuery"
:search-results="stockSearchResults"
:search-loading="stockSearchLoading"
@navigate="navigate"
@update-search-query="stockSearchQuery = $event"
@select-stock="handleSearchSelectStock"
/>
<div v-if="dashboard.isBooting.value" class="loading-state">