111 lines
5.3 KiB
Vue
111 lines
5.3 KiB
Vue
<script setup lang="ts">
|
||
import { onBeforeUnmount, onMounted } from 'vue';
|
||
import { useSettingsStore, type PriceAdjust, type PriceTone } from '@/stores/settings';
|
||
|
||
const emit = defineEmits<{ (e: 'close'): void }>();
|
||
const settings = useSettingsStore();
|
||
|
||
// ---------- 分类:行情配色 ----------
|
||
const TONES: { key: PriceTone; label: string; desc: string; up: string; down: string }[] = [
|
||
{ key: 'red-up', label: '红涨绿跌', desc: 'A 股风格', up: '#FE354B', down: '#1EBE72' },
|
||
{ key: 'green-up', label: '绿涨红跌', desc: '美股风格', up: '#1EBE72', down: '#FE354B' },
|
||
];
|
||
|
||
// ---------- 分类:K线复权 ----------
|
||
const ADJUSTS: { key: PriceAdjust; label: string; desc: string }[] = [
|
||
{ key: 'bfq', label: '不复权', desc: '原始价格,含除权跳空' },
|
||
{ key: 'qfq', label: '前复权', desc: '以最新价为基准,看趋势最常用' },
|
||
{ key: 'hfq', label: '后复权', desc: '以上市价为基准,看累计涨幅' },
|
||
];
|
||
|
||
function onKeydown(e: KeyboardEvent) {
|
||
if (e.key === 'Escape') emit('close');
|
||
}
|
||
onMounted(() => window.addEventListener('keydown', onKeydown));
|
||
onBeforeUnmount(() => window.removeEventListener('keydown', onKeydown));
|
||
</script>
|
||
|
||
<template>
|
||
<div class="fixed inset-0 z-50 grid place-items-center bg-black/60 p-4 backdrop-blur-sm" @click.self="emit('close')">
|
||
<div class="w-full max-w-md rounded-lg border border-[#26272E] bg-[#101014] shadow-xl shadow-black/60" role="dialog" aria-label="设置">
|
||
<!-- 头部 -->
|
||
<div class="flex items-center justify-between border-b border-[#1E2026] px-5 py-3.5">
|
||
<h2 class="text-sm font-semibold text-[#E8EAED]">设置</h2>
|
||
<button
|
||
type="button"
|
||
class="rounded p-1 text-[#9BA3AE] transition-colors hover:bg-[#1E2026] hover:text-[#E8EAED]"
|
||
title="关闭 (Esc)"
|
||
@click="emit('close')"
|
||
>
|
||
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M18 6L6 18M6 6l12 12" /></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 分类一:行情配色 -->
|
||
<div class="px-5 py-4">
|
||
<div class="text-[13px] font-medium tracking-wide text-[#A8AFB8]">行情配色</div>
|
||
<p class="mt-1 text-[13px] text-[#9BA3AE]">设置全站涨跌颜色,立即生效并自动记住。</p>
|
||
|
||
<div class="mt-3 grid grid-cols-2 gap-3">
|
||
<button
|
||
v-for="t in TONES"
|
||
:key="t.key"
|
||
type="button"
|
||
class="rounded-lg border p-3 text-left transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
|
||
:class="settings.priceTone === t.key
|
||
? 'border-blue-500 bg-blue-500/15 ring-1 ring-blue-500'
|
||
: 'border-[#26272E] hover:border-[#3A3D46]'"
|
||
@click="settings.setPriceTone(t.key)"
|
||
>
|
||
<div class="flex items-center justify-between">
|
||
<span class="text-sm font-medium text-[#E8EAED]">{{ t.label }}</span>
|
||
<span
|
||
v-if="settings.priceTone === t.key"
|
||
class="grid h-4 w-4 place-items-center rounded-full bg-blue-600 text-white"
|
||
>
|
||
<svg class="h-2.5 w-2.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5" /></svg>
|
||
</span>
|
||
</div>
|
||
<div class="mt-1 text-[13px] text-[#9BA3AE]">{{ t.desc }}</div>
|
||
<!-- 效果预览 -->
|
||
<div class="mt-2.5 flex items-baseline gap-3 font-mono text-sm">
|
||
<span :style="{ color: t.up }">+2.50%</span>
|
||
<span :style="{ color: t.down }">-1.30%</span>
|
||
</div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 分类二:K线复权 -->
|
||
<div class="border-t border-[#1E2026] px-5 py-4">
|
||
<div class="text-[13px] font-medium tracking-wide text-[#A8AFB8]">K线复权</div>
|
||
<p class="mt-1 text-[13px] text-[#9BA3AE]">个股详情 K 线的默认口径;浮层内也可随时切换。</p>
|
||
|
||
<div class="mt-3 grid grid-cols-3 gap-3">
|
||
<button
|
||
v-for="a in ADJUSTS"
|
||
:key="a.key"
|
||
type="button"
|
||
class="rounded-lg border p-3 text-left transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
|
||
:class="settings.priceAdjust === a.key
|
||
? 'border-blue-500 bg-blue-500/15 ring-1 ring-blue-500'
|
||
: 'border-[#26272E] hover:border-[#3A3D46]'"
|
||
@click="settings.setPriceAdjust(a.key)"
|
||
>
|
||
<div class="flex items-center justify-between">
|
||
<span class="text-sm font-medium text-[#E8EAED]">{{ a.label }}</span>
|
||
<span
|
||
v-if="settings.priceAdjust === a.key"
|
||
class="grid h-4 w-4 place-items-center rounded-full bg-blue-600 text-white"
|
||
>
|
||
<svg class="h-2.5 w-2.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5" /></svg>
|
||
</span>
|
||
</div>
|
||
<div class="mt-1 text-[13px] text-[#9BA3AE]">{{ a.desc }}</div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|