初始化足球投注平台 MVP Monorepo
包含 NestJS 后端、三端前端、Prisma 数据模型、结算引擎测试与 PRD 文档。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
62
apps/player/src/views/MyBetsView.vue
Normal file
62
apps/player/src/views/MyBetsView.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import api from '../api';
|
||||
|
||||
const bets = ref<{ items: Bet[]; total: number }>({ items: [], total: 0 });
|
||||
|
||||
interface Bet {
|
||||
betNo: string;
|
||||
betType: string;
|
||||
stake: string;
|
||||
totalOdds: string;
|
||||
potentialReturn: string;
|
||||
actualReturn: string;
|
||||
status: string;
|
||||
placedAt: string;
|
||||
selections: Array<{ selectionNameSnapshot: string; odds: string; resultStatus?: string }>;
|
||||
}
|
||||
|
||||
onMounted(load);
|
||||
|
||||
async function load() {
|
||||
const { data } = await api.get('/player/bets');
|
||||
bets.value = data.data;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h2>我的投注</h2>
|
||||
<div v-for="bet in bets.items" :key="bet.betNo" class="card bet-card">
|
||||
<div class="bet-header">
|
||||
<span class="bet-no">{{ bet.betNo }}</span>
|
||||
<span :class="['status', bet.status.toLowerCase()]">{{ bet.status }}</span>
|
||||
</div>
|
||||
<div v-for="(sel, i) in bet.selections" :key="i" class="sel">
|
||||
{{ sel.selectionNameSnapshot }} @ {{ sel.odds }}
|
||||
<span v-if="sel.resultStatus"> → {{ sel.resultStatus }}</span>
|
||||
</div>
|
||||
<div class="bet-footer">
|
||||
<span>{{ bet.betType }} · 投注 {{ bet.stake }}</span>
|
||||
<span v-if="bet.status === 'WON'">返还 {{ bet.actualReturn }}</span>
|
||||
<span v-else-if="bet.status === 'PENDING'">预计 {{ bet.potentialReturn }}</span>
|
||||
</div>
|
||||
<div class="time">{{ new Date(bet.placedAt).toLocaleString() }}</div>
|
||||
</div>
|
||||
<div v-if="!bets.items.length" class="empty">暂无投注</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
h2 { margin-bottom: 16px; }
|
||||
.bet-header { display: flex; justify-content: space-between; margin-bottom: 8px; }
|
||||
.bet-no { font-size: 12px; color: var(--text-muted); }
|
||||
.status { font-size: 12px; font-weight: 600; }
|
||||
.status.pending { color: #ff9800; }
|
||||
.status.won { color: var(--primary); }
|
||||
.status.lost { color: var(--danger); }
|
||||
.sel { font-size: 13px; margin-bottom: 4px; }
|
||||
.bet-footer { font-size: 13px; margin-top: 8px; display: flex; justify-content: space-between; }
|
||||
.time { font-size: 11px; color: var(--text-muted); margin-top: 4px; }
|
||||
.empty { text-align: center; color: var(--text-muted); padding: 40px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user