Files
gamegroup2/frontend/src/components/bet/SettleBetDialog.vue
T
congsh 60ad9a04cd feat: phase 4 - 积分竞猜和游戏黑名单 v0.3.0
竞猜功能:发起竞猜、下注、关闭、开奖、奖池分配
黑名单功能:标记游戏、按原因/严重程度筛选、详情展开
修复:双重结算、TOCTOU竞态、订阅泄漏、选项选择兼容性

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 00:21:43 +08:00

132 lines
2.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 { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { settleBet } from '@/api/bets'
import type { BetOption } from '@/types'
const visible = defineModel<boolean>({ default: false })
const props = defineProps<{
betId: string
options: BetOption[]
}>()
const emit = defineEmits<{
settled: []
}>()
const selectedOption = ref('')
const loading = ref(false)
function handleOpen() {
selectedOption.value = ''
}
async function handleSettle() {
if (!selectedOption.value) {
ElMessage.warning('请选择正确选项')
return
}
loading.value = true
try {
await settleBet(props.betId, selectedOption.value)
visible.value = false
ElMessage.success('开奖成功')
emit('settled')
} catch (error: any) {
ElMessage.error(error.message || '开奖失败')
} finally {
loading.value = false
}
}
</script>
<template>
<el-dialog
v-model="visible"
title="开奖"
width="420px"
@open="handleOpen"
>
<div class="settle-form">
<p class="settle-form__hint">请选择正确的选项来结算竞猜</p>
<el-radio-group v-model="selectedOption" class="settle-form__options">
<div
v-for="option in options"
:key="option.id"
class="settle-form__option"
>
<el-radio :value="option.id">
{{ option.content }}
</el-radio>
</div>
</el-radio-group>
</div>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<button
class="settle-form__submit"
:disabled="loading || !selectedOption"
@click="handleSettle"
>
{{ loading ? '结算中...' : '确认开奖' }}
</button>
</template>
</el-dialog>
</template>
<style scoped>
.settle-form {
display: flex;
flex-direction: column;
gap: 16px;
}
.settle-form__hint {
margin: 0;
font-size: 14px;
color: var(--gg-text-secondary);
}
.settle-form__options {
display: flex;
flex-direction: column;
gap: 10px;
}
.settle-form__option {
padding: 10px 14px;
border: 1px solid var(--gg-border);
border-radius: var(--gg-radius-sm);
transition: border-color 0.2s;
}
.settle-form__option:hover {
border-color: var(--gg-primary-light);
}
.settle-form__submit {
padding: 8px 20px;
border: none;
border-radius: var(--gg-radius-sm);
background: var(--gg-gradient);
color: #fff;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: opacity 0.2s;
}
.settle-form__submit:hover {
opacity: 0.85;
}
.settle-form__submit:disabled {
opacity: 0.6;
cursor: not-allowed;
}
</style>