feat: 全屏个股详情预览 + Tailwind 改版 + 账号鉴权
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import Button from 'primevue/button';
|
||||
import type { ScreenerSyncStatus } from '@/api/types';
|
||||
|
||||
const props = defineProps<{ status: ScreenerSyncStatus | null }>();
|
||||
@@ -15,7 +14,7 @@ function fmtDate(s?: string | null) {
|
||||
const freshness = computed(() => {
|
||||
const s = props.status;
|
||||
if (!s) return { tone: 'none', text: '正在检查数据状态…' };
|
||||
if (!s.ready) return { tone: 'warn', text: '全市场数据尚未同步,请先点击右侧「同步数据」' };
|
||||
if (!s.ready) return { tone: 'warn', text: '全市场数据尚未同步,请先点击右侧「同步市场数据」' };
|
||||
const snapMissing = s.stats.snapshot_rows === 0;
|
||||
const d = s.stats.dates;
|
||||
const base = `数据截至 ${fmtDate(s.last_trade_date)} · 共 ${d} 个交易日 · ${s.stats.stocks} 只股票`;
|
||||
@@ -25,32 +24,41 @@ const freshness = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="sync-bar">
|
||||
<span :class="freshness.tone === 'ok' ? 'ok' : freshness.tone === 'warn' ? 'warn' : ''">
|
||||
<i class="pi" :class="freshness.tone === 'ok' ? 'pi-check-circle' : 'pi-info-circle'" style="margin-right: 5px;"></i>
|
||||
<div class="mt-4 flex flex-wrap items-center gap-x-4 gap-y-2 rounded-xl border border-slate-200 bg-white px-4 py-3 text-[13px] text-slate-600">
|
||||
<span :class="freshness.tone === 'ok' ? 'text-emerald-600' : freshness.tone === 'warn' ? 'text-amber-600' : 'text-slate-400'">
|
||||
<svg class="mr-1 inline h-4 w-4 align-[-3px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<template v-if="freshness.tone === 'ok'">
|
||||
<path d="M22 11.1V12a10 10 0 11-5.9-9.1" />
|
||||
<path d="M22 4L12 14l-3-3-7 7" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<path d="M12 16v-4M12 8h.01" />
|
||||
</template>
|
||||
</svg>
|
||||
{{ freshness.text }}
|
||||
</span>
|
||||
|
||||
<template v-if="status && status.running">
|
||||
<span class="sync-progress">
|
||||
<i class="pi pi-spin pi-spinner"></i>
|
||||
<span class="txt">{{ status.step || '同步中…' }}({{ status.done_days }}/{{ status.total_days }})</span>
|
||||
<span class="flex min-w-[200px] flex-1 items-center gap-2">
|
||||
<svg class="h-4 w-4 shrink-0 animate-spin text-blue-500" viewBox="0 0 24 24" fill="none"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" /><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" /></svg>
|
||||
<span class="whitespace-nowrap text-xs text-slate-500">{{ status.step || '同步中…' }}({{ status.done_days }}/{{ status.total_days }})</span>
|
||||
<span class="h-1.5 flex-1 overflow-hidden rounded-full bg-slate-100">
|
||||
<span class="block h-full rounded-full bg-blue-500 transition-all" :style="{ width: (status.total_days ? Math.min(100, (status.done_days / status.total_days) * 100) : 0) + '%' }" />
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="spacer"></span>
|
||||
<Button
|
||||
label="同步市场数据"
|
||||
icon="pi pi-refresh"
|
||||
size="small"
|
||||
severity="secondary"
|
||||
:disabled="status?.running"
|
||||
@click="emit('sync')"
|
||||
/>
|
||||
<span class="flex-1"></span>
|
||||
<button type="button" class="btn-ghost shrink-0 disabled:opacity-50" :disabled="status?.running" @click="emit('sync')">
|
||||
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 11-2.6-6.4M21 3v6h-6" /></svg>
|
||||
同步市场数据
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<div v-if="status && status.error" class="warn" style="flex-basis: 100%; margin-top: 4px;">
|
||||
<i class="pi pi-exclamation-triangle" style="margin-right: 5px;"></i>{{ status.error }}
|
||||
<div v-if="status && status.error" class="w-full text-amber-600">
|
||||
<svg class="mr-1 inline h-4 w-4 align-[-3px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 3.9L1.8 18a2 2 0 001.7 3h17a2 2 0 001.7-3L13.7 3.9a2 2 0 00-3.4 0z" /><path d="M12 9v4M12 17h.01" /></svg>
|
||||
{{ status.error }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user