Files
thebet365/apps/player/src/components/desktop/DesktopCashbackDetailModal.vue
mars 9abfbfcedd feat(player): theme-3 PC 列表弹窗详情与收件箱样式修复
投注/资金/充值/返水列表改为 theme-3 实心弹窗,修复收件箱背景、左侧裁切与滚动。
2026-07-10 17:01:53 +08:00

148 lines
3.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import DesktopDetailModalShell from './DesktopDetailModalShell.vue';
import { formatMoney, formatMoneyCompact } from '../../utils/localeDisplay';
import type { CashbackRecord } from '../../utils/cashback';
const props = defineProps<{
visible: boolean;
record: CashbackRecord | null;
}>();
const emit = defineEmits<{
'update:visible': [value: boolean];
}>();
const { t, locale } = useI18n();
function formatPeriod(start: string, end: string) {
const opts: Intl.DateTimeFormatOptions = { month: '2-digit', day: '2-digit' };
const s = new Date(start).toLocaleDateString(locale.value, opts);
const e = new Date(end).toLocaleDateString(locale.value, opts);
return `${s} ${e}`;
}
function formatRate(rate: string) {
const n = parseFloat(rate);
if (!Number.isFinite(n)) return rate;
return `${(n * 100).toFixed(2)}%`;
}
function formatTime(value: string | null) {
if (!value) return '—';
return new Date(value).toLocaleString(locale.value, {
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false,
});
}
</script>
<template>
<DesktopDetailModalShell
:visible="visible"
:title="t('cashback.title')"
@update:visible="emit('update:visible', $event)"
>
<template v-if="record">
<div class="hero">
<div class="amount-hero">{{ formatMoney(record.amount, locale) }}</div>
<div class="batch-no">{{ record.batchNo }}</div>
</div>
<div class="detail-rows">
<div class="detail-row">
<span class="row-label">{{ t('cashback.period') }}</span>
<span class="row-val">{{ formatPeriod(record.periodStart, record.periodEnd) }}</span>
</div>
<div class="detail-row">
<span class="row-label">{{ t('cashback.effective_stake') }}</span>
<span class="row-val">{{ formatMoneyCompact(record.effectiveStake, locale) }}</span>
</div>
<div class="detail-row">
<span class="row-label">{{ t('cashback.rate') }}</span>
<span class="row-val">{{ formatRate(record.rate) }}</span>
</div>
<div class="detail-row">
<span class="row-label">{{ t('wallet.time') }}</span>
<span class="row-val muted">{{ formatTime(record.confirmedAt ?? record.createdAt) }}</span>
</div>
</div>
</template>
<div v-else class="state">{{ t('common.not_found') }}</div>
</DesktopDetailModalShell>
</template>
<style scoped>
.state {
display: flex;
align-items: center;
justify-content: center;
padding: 48px 20px;
color: var(--text-muted);
font-size: 13px;
}
.hero {
padding: 20px 20px 16px;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
background: #162d36;
}
.amount-hero {
font-size: 30px;
font-weight: 800;
font-variant-numeric: tabular-nums;
font-family: 'SF Mono', 'Consolas', monospace;
color: var(--primary-light);
line-height: 1.1;
}
.batch-no {
margin-top: 6px;
font-family: 'SF Mono', 'Consolas', monospace;
font-size: 12px;
font-weight: 700;
color: var(--text-muted);
}
.detail-rows {
padding: 4px 0 12px;
background: #1a323c;
}
.detail-row {
display: flex;
gap: 16px;
padding: 11px 20px;
border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.detail-row:last-child {
border-bottom: none;
}
.row-label {
width: 108px;
flex-shrink: 0;
font-size: 12px;
color: var(--text-muted);
font-weight: 600;
}
.row-val {
flex: 1;
font-size: 13px;
font-weight: 700;
color: var(--text);
}
.row-val.muted {
color: var(--text-muted);
font-weight: 600;
}
</style>