feat(admin): 管理端列表分页、控制台图表与赛事导入
- 玩家/代理/赛事/注单/审计列表分页,默认每页 10 条,无页面滚动条布局 - ECharts 控制台概览、注单管理中文化与列宽优化 - zhibo 赛事字段迁移与导入,玩家编辑可改所属代理 - 管理端 API 分页与 dashboard 统计接口 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import api from '../api';
|
||||
import { ElMessage } from 'element-plus';
|
||||
@@ -22,25 +22,105 @@ async function confirm() {
|
||||
if (!preview.value?.batch) return;
|
||||
await api.post(`/admin/settlement/${(preview.value.batch as { id: string }).id}/confirm`);
|
||||
ElMessage.success('结算已确认');
|
||||
preview.value = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h2>赛事结算 #{{ route.params.id }}</h2>
|
||||
<el-form inline style="margin: 16px 0">
|
||||
<el-input-number v-model="score.htHome" :min="0" />
|
||||
<el-input-number v-model="score.htAway" :min="0" />
|
||||
<span>半场</span>
|
||||
<el-input-number v-model="score.ftHome" :min="0" />
|
||||
<el-input-number v-model="score.ftAway" :min="0" />
|
||||
<span>全场</span>
|
||||
<el-button @click="recordScore">录入比分</el-button>
|
||||
<el-button type="primary" @click="previewSettlement">生成预览</el-button>
|
||||
</el-form>
|
||||
<el-card v-if="preview">
|
||||
<p>单关注单: {{ preview.singleBetCount }}</p>
|
||||
<p>预计派彩: {{ preview.totalPayout }}</p>
|
||||
<p>退款: {{ preview.totalRefund }}</p>
|
||||
<el-button type="success" @click="confirm">确认结算</el-button>
|
||||
<div class="page-header">
|
||||
<h2 class="page-title">赛事结算</h2>
|
||||
<span class="page-id"># {{ route.params.id }}</span>
|
||||
</div>
|
||||
|
||||
<el-card class="tool-card" shadow="never">
|
||||
<div class="score-section">
|
||||
<div class="score-block">
|
||||
<div class="score-title">半场比分</div>
|
||||
<div class="score-inputs">
|
||||
<el-input-number v-model="score.htHome" :min="0" controls-position="right" style="width: 100px" />
|
||||
<span class="score-sep">—</span>
|
||||
<el-input-number v-model="score.htAway" :min="0" controls-position="right" style="width: 100px" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-block">
|
||||
<div class="score-title">全场比分</div>
|
||||
<div class="score-inputs">
|
||||
<el-input-number v-model="score.ftHome" :min="0" controls-position="right" style="width: 100px" />
|
||||
<span class="score-sep">—</span>
|
||||
<el-input-number v-model="score.ftAway" :min="0" controls-position="right" style="width: 100px" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-row">
|
||||
<el-button @click="recordScore">录入比分</el-button>
|
||||
<el-button type="primary" @click="previewSettlement">生成结算预览</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card v-if="preview" class="preview-card" shadow="never">
|
||||
<div class="preview-title">结算预览</div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<div class="pstat">
|
||||
<div class="pstat-value">{{ preview.singleBetCount }}</div>
|
||||
<div class="pstat-label">单关注单数</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="pstat">
|
||||
<div class="pstat-value pstat-green">{{ preview.totalPayout }}</div>
|
||||
<div class="pstat-label">预计派彩</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="pstat">
|
||||
<div class="pstat-value pstat-orange">{{ preview.totalRefund }}</div>
|
||||
<div class="pstat-label">退款金额</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-button type="success" @click="confirm" style="margin-top: 24px">确认结算</el-button>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.page-header { display: flex; align-items: baseline; gap: 12px; margin-bottom: 20px; }
|
||||
.page-title { font-size: 20px; font-weight: 700; color: #e0e0e0; }
|
||||
.page-id { font-size: 14px; color: #3a3a3a; font-family: monospace; }
|
||||
.tool-card { margin-bottom: 16px; border-radius: 12px; }
|
||||
.preview-card { border-radius: 12px; }
|
||||
|
||||
.score-section {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.score-block { }
|
||||
.score-title {
|
||||
font-size: 13px;
|
||||
color: #3a3a3a;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.score-inputs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.score-sep {
|
||||
font-size: 18px;
|
||||
color: #ccc;
|
||||
font-weight: 300;
|
||||
}
|
||||
.action-row {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.preview-title { font-size: 15px; font-weight: 600; color: #e0e0e0; margin-bottom: 16px; }
|
||||
.pstat { padding: 16px; background: #f9f9fb; border-radius: 10px; text-align: center; }
|
||||
.pstat-value { font-size: 26px; font-weight: 700; color: #e0e0e0; }
|
||||
.pstat-green { color: var(--green-glow); text-shadow: 0 0 20px rgba(47, 181, 106, 0.35); }
|
||||
.pstat-orange { color: #c85a00; }
|
||||
.pstat-label { font-size: 12px; color: #3a3a3a; margin-top: 4px; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user