feat: improve stock detail view and update docs
This commit is contained in:
@ -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">
|
||||
|
||||
Reference in New Issue
Block a user