初始化足球投注平台 MVP Monorepo

包含 NestJS 后端、三端前端、Prisma 数据模型、结算引擎测试与 PRD 文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 14:35:48 +08:00
commit 14e49374ac
118 changed files with 15944 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import api from '../api';
import { ElMessage } from 'element-plus';
const router = useRouter();
const matches = ref<unknown[]>([]);
const form = ref({
leagueId: '',
homeTeamId: '',
awayTeamId: '',
startTime: '',
});
onMounted(load);
async function load() {
const { data } = await api.get('/admin/matches');
matches.value = data.data;
}
async function create() {
await api.post('/admin/matches', form.value);
ElMessage.success('赛事已创建');
load();
}
async function publish(id: string) {
await api.post(`/admin/matches/${id}/publish`);
await api.post(`/admin/matches/${id}/markets/templates`, {
marketTypes: ['FT_1X2', 'FT_HANDICAP', 'FT_OVER_UNDER', 'FT_ODD_EVEN'],
});
ElMessage.success('已发布并生成盘口');
load();
}
async function close(id: string) {
await api.post(`/admin/matches/${id}/close`);
ElMessage.success('已封盘');
load();
}
function settle(id: string) {
router.push(`/settlement/${id}`);
}
</script>
<template>
<h2>赛事管理</h2>
<el-card style="margin-bottom: 16px">
<el-form inline>
<el-input v-model="form.leagueId" placeholder="联赛ID" style="width: 100px" />
<el-input v-model="form.homeTeamId" placeholder="主队ID" style="width: 100px" />
<el-input v-model="form.awayTeamId" placeholder="客队ID" style="width: 100px" />
<el-input v-model="form.startTime" placeholder="开赛时间 ISO" style="width: 200px" />
<el-button type="primary" @click="create">创建赛事</el-button>
</el-form>
</el-card>
<el-table :data="matches">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="status" label="状态" />
<el-table-column label="开赛时间">
<template #default="{ row }">{{ new Date((row as { startTime: string }).startTime).toLocaleString() }}</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template #default="{ row }">
<el-button v-if="(row as { status: string }).status === 'DRAFT'" size="small" @click="publish((row as { id: string }).id)">发布</el-button>
<el-button v-if="(row as { status: string }).status === 'PUBLISHED'" size="small" @click="close((row as { id: string }).id)">封盘</el-button>
<el-button size="small" type="warning" @click="settle((row as { id: string }).id)">结算</el-button>
</template>
</el-table-column>
</el-table>
</template>