新增查看显示实时彩金池
This commit is contained in:
@@ -0,0 +1,236 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="visible"
|
||||||
|
title="当前彩金池"
|
||||||
|
width="560px"
|
||||||
|
align-center
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<div v-if="loading && !pool" class="flex justify-center py-8">加载中...</div>
|
||||||
|
<template v-else-if="pool">
|
||||||
|
<div class="pool-info mb-4">
|
||||||
|
<div class="flex items-center gap-2 mb-3">
|
||||||
|
<span class="text-gray-500">池子名称:</span>
|
||||||
|
<span>{{ pool.name }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<span class="text-gray-500">池子盈利:</span>
|
||||||
|
<span class="font-mono text-lg" :class="profitAmountClass">{{ displayProfitAmount }}</span>
|
||||||
|
<span class="text-gray-400 text-sm">(实时,不可修改)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
||||||
|
<el-form-item label="安全线" prop="safety_line">
|
||||||
|
<el-input-number
|
||||||
|
v-model="formData.safety_line"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="T1池权重(%)" prop="t1_weight">
|
||||||
|
<el-slider v-model="formData.t1_weight" :min="0" :max="100" :step="1" show-input />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="T2池权重(%)" prop="t2_weight">
|
||||||
|
<el-slider v-model="formData.t2_weight" :min="0" :max="100" :step="1" show-input />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="T3池权重(%)" prop="t3_weight">
|
||||||
|
<el-slider v-model="formData.t3_weight" :min="0" :max="100" :step="1" show-input />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="T4池权重(%)" prop="t4_weight">
|
||||||
|
<el-slider v-model="formData.t4_weight" :min="0" :max="100" :step="1" show-input />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="T5池权重(%)" prop="t5_weight">
|
||||||
|
<el-slider v-model="formData.t5_weight" :min="0" :max="100" :step="1" show-input />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<div class="text-gray-500 text-sm">
|
||||||
|
五个池权重总和:<span :class="weightsSum !== 100 ? 'text-red-500' : ''">{{
|
||||||
|
weightsSum
|
||||||
|
}}</span
|
||||||
|
>% / 100%(须为100%)
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleClose">关闭</el-button>
|
||||||
|
<el-button type="primary" :loading="saving" :disabled="!pool" @click="handleSubmit">
|
||||||
|
保存权重与安全线
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import api from '../../../api/lottery_config/index'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
|
|
||||||
|
interface PoolData {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
safety_line: number
|
||||||
|
t1_weight: number
|
||||||
|
t2_weight: number
|
||||||
|
t3_weight: number
|
||||||
|
t4_weight: number
|
||||||
|
t5_weight: number
|
||||||
|
profit_amount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<{ modelValue: boolean }>()
|
||||||
|
const emit = defineEmits<{ (e: 'update:modelValue', v: boolean): void; (e: 'success'): void }>()
|
||||||
|
|
||||||
|
const visible = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (v) => emit('update:modelValue', v)
|
||||||
|
})
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const saving = ref(false)
|
||||||
|
const pool = ref<PoolData | null>(null)
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
|
||||||
|
const formData = reactive({
|
||||||
|
safety_line: 0,
|
||||||
|
t1_weight: 0,
|
||||||
|
t2_weight: 0,
|
||||||
|
t3_weight: 0,
|
||||||
|
t4_weight: 0,
|
||||||
|
t5_weight: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules: FormRules = {
|
||||||
|
safety_line: [{ required: true, message: '请输入安全线', trigger: 'blur' }],
|
||||||
|
t1_weight: [{ required: true, message: '请输入T1权重', trigger: 'blur' }],
|
||||||
|
t2_weight: [{ required: true, message: '请输入T2权重', trigger: 'blur' }],
|
||||||
|
t3_weight: [{ required: true, message: '请输入T3权重', trigger: 'blur' }],
|
||||||
|
t4_weight: [{ required: true, message: '请输入T4权重', trigger: 'blur' }],
|
||||||
|
t5_weight: [{ required: true, message: '请输入T5权重', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
const weightsSum = computed(
|
||||||
|
() =>
|
||||||
|
formData.t1_weight +
|
||||||
|
formData.t2_weight +
|
||||||
|
formData.t3_weight +
|
||||||
|
formData.t4_weight +
|
||||||
|
formData.t5_weight
|
||||||
|
)
|
||||||
|
|
||||||
|
const displayProfitAmount = computed(() => {
|
||||||
|
const v = pool.value?.profit_amount
|
||||||
|
if (v == null || Number.isNaN(v)) return '-'
|
||||||
|
return Number(v).toFixed(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
const profitAmountClass = computed(() => {
|
||||||
|
const v = pool.value?.profit_amount
|
||||||
|
if (v == null) return ''
|
||||||
|
if (v > 0) return 'text-green-600'
|
||||||
|
if (v < 0) return 'text-red-600'
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
|
||||||
|
let pollTimer: ReturnType<typeof setInterval> | null = null
|
||||||
|
const POLL_INTERVAL = 2000
|
||||||
|
|
||||||
|
async function loadPool() {
|
||||||
|
if (!visible.value) return
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
const res = await api.getCurrentPool()
|
||||||
|
const data = res as unknown as PoolData
|
||||||
|
if (data && typeof data === 'object') {
|
||||||
|
pool.value = data
|
||||||
|
formData.safety_line = data.safety_line ?? 0
|
||||||
|
formData.t1_weight = data.t1_weight ?? 0
|
||||||
|
formData.t2_weight = data.t2_weight ?? 0
|
||||||
|
formData.t3_weight = data.t3_weight ?? 0
|
||||||
|
formData.t4_weight = data.t4_weight ?? 0
|
||||||
|
formData.t5_weight = data.t5_weight ?? 0
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
ElMessage.error(e?.message ?? '获取彩金池失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startPolling() {
|
||||||
|
stopPolling()
|
||||||
|
pollTimer = setInterval(() => {
|
||||||
|
if (!visible.value) {
|
||||||
|
stopPolling()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
api.getCurrentPool().then((res) => {
|
||||||
|
const data = res as unknown as PoolData
|
||||||
|
if (pool.value && data && typeof data === 'object' && data.profit_amount != null) {
|
||||||
|
pool.value.profit_amount = data.profit_amount
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, POLL_INTERVAL)
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopPolling() {
|
||||||
|
if (pollTimer) {
|
||||||
|
clearInterval(pollTimer)
|
||||||
|
pollTimer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
if (!formRef.value || !pool.value) return
|
||||||
|
if (weightsSum.value !== 100) {
|
||||||
|
ElMessage.warning('T1~T5 权重合计须为 100%')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await formRef.value.validate()
|
||||||
|
saving.value = true
|
||||||
|
await api.updateCurrentPool({
|
||||||
|
safety_line: formData.safety_line,
|
||||||
|
t1_weight: formData.t1_weight,
|
||||||
|
t2_weight: formData.t2_weight,
|
||||||
|
t3_weight: formData.t3_weight,
|
||||||
|
t4_weight: formData.t4_weight,
|
||||||
|
t5_weight: formData.t5_weight
|
||||||
|
})
|
||||||
|
ElMessage.success('保存成功')
|
||||||
|
await loadPool()
|
||||||
|
emit('success')
|
||||||
|
} catch (e: any) {
|
||||||
|
if (e?.message) ElMessage.error(e.message)
|
||||||
|
} finally {
|
||||||
|
saving.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
stopPolling()
|
||||||
|
visible.value = false
|
||||||
|
pool.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(open) => {
|
||||||
|
if (open) {
|
||||||
|
loadPool().then(() => startPolling())
|
||||||
|
} else {
|
||||||
|
stopPolling()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
onUnmounted(() => stopPolling())
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.pool-info {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user