[冗余代码]移除游戏配置中一键测试功能
This commit is contained in:
@@ -95,22 +95,5 @@ export default {
|
|||||||
}>({
|
}>({
|
||||||
url: '/core/dice/reward_config/DiceRewardConfig/createRewardReference'
|
url: '/core/dice/reward_config/DiceRewardConfig/createRewardReference'
|
||||||
})
|
})
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 权重配比测试:按当前配置模拟 N 次抽奖,返回各 grid_number 落点次数
|
|
||||||
* @param test_count 100 | 500 | 1000
|
|
||||||
* @param save_record 是否保存到 dice_reward_config_record
|
|
||||||
* @param lottery_config_id 奖池配置ID(DiceLotteryPoolConfig),用于设定 T1-T5 档位概率;不传则使用 type=0 或均等
|
|
||||||
*/
|
|
||||||
runWeightTest(params: {
|
|
||||||
test_count: number
|
|
||||||
save_record?: boolean
|
|
||||||
lottery_config_id?: number | null
|
|
||||||
}) {
|
|
||||||
return request.post<{ data: { counts: Record<string, number>; record_id: number | null } }>({
|
|
||||||
url: '/core/dice/reward_config/DiceRewardConfig/runWeightTest',
|
|
||||||
data: params
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,6 @@
|
|||||||
>
|
>
|
||||||
创建奖励对照
|
创建奖励对照
|
||||||
</ElButton>
|
</ElButton>
|
||||||
<ElButton
|
|
||||||
v-permission="'dice:reward_config:index:index'"
|
|
||||||
type="success"
|
|
||||||
@click="weightTestVisible = true"
|
|
||||||
v-ripple
|
|
||||||
>
|
|
||||||
测试中奖
|
|
||||||
</ElButton>
|
|
||||||
</ElSpace>
|
</ElSpace>
|
||||||
</template>
|
</template>
|
||||||
</ArtTableHeader>
|
</ArtTableHeader>
|
||||||
@@ -68,8 +60,6 @@
|
|||||||
:data="dialogData"
|
:data="dialogData"
|
||||||
@success="refreshData"
|
@success="refreshData"
|
||||||
/>
|
/>
|
||||||
<!-- 权重配比测试弹窗 -->
|
|
||||||
<WeightTestDialog v-model="weightTestVisible" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -80,9 +70,7 @@
|
|||||||
import api from '../../api/reward_config/index'
|
import api from '../../api/reward_config/index'
|
||||||
import TableSearch from './modules/table-search.vue'
|
import TableSearch from './modules/table-search.vue'
|
||||||
import EditDialog from './modules/edit-dialog.vue'
|
import EditDialog from './modules/edit-dialog.vue'
|
||||||
import WeightTestDialog from './modules/weight-test-dialog.vue'
|
|
||||||
|
|
||||||
const weightTestVisible = ref(false)
|
|
||||||
const createRewardLoading = ref(false)
|
const createRewardLoading = ref(false)
|
||||||
|
|
||||||
async function handleCreateRewardReference() {
|
async function handleCreateRewardReference() {
|
||||||
|
|||||||
@@ -1,227 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-dialog
|
|
||||||
v-model="visible"
|
|
||||||
title="权重配比测试"
|
|
||||||
width="720px"
|
|
||||||
align-center
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
destroy-on-close
|
|
||||||
@close="handleClose"
|
|
||||||
>
|
|
||||||
<div v-if="!result" class="test-form">
|
|
||||||
<el-form :model="form" label-width="120px">
|
|
||||||
<el-form-item label="奖池配置">
|
|
||||||
<el-select
|
|
||||||
v-model="form.lottery_config_id"
|
|
||||||
placeholder="选择 T1-T5 档位概率来源,不选则使用默认"
|
|
||||||
clearable
|
|
||||||
style="width: 320px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="opt in lotteryConfigOptions"
|
|
||||||
:key="opt.id"
|
|
||||||
:label="opt.name"
|
|
||||||
:value="opt.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
<div class="form-tip">
|
|
||||||
{{
|
|
||||||
selectedTierSummary || '选定奖池的 t1_weight~t5_weight 将作为测试时 T1-T5 的抽取概率'
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="测试次数">
|
|
||||||
<el-radio-group v-model="form.test_count">
|
|
||||||
<el-radio :value="100">100 次</el-radio>
|
|
||||||
<el-radio :value="500">500 次</el-radio>
|
|
||||||
<el-radio :value="1000">1000 次</el-radio>
|
|
||||||
<el-radio :value="5000">5000 次</el-radio>
|
|
||||||
<el-radio :value="10000">10000 次</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="保存记录">
|
|
||||||
<el-switch v-model="form.save_record" />
|
|
||||||
<span class="form-tip">保存到「测试记录表」便于后续对比</span>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
<div v-else class="test-result">
|
|
||||||
<div class="result-summary">
|
|
||||||
共模拟 <strong>{{ form.test_count }}</strong> 次抽奖,落点分布如下:
|
|
||||||
</div>
|
|
||||||
<div class="chart-wrap">
|
|
||||||
<ArtBarChart
|
|
||||||
x-axis-name="色子点数 (grid_number)"
|
|
||||||
:x-axis-data="chartLabels"
|
|
||||||
:data="chartData"
|
|
||||||
height="320px"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-if="result.record_id" class="record-tip"
|
|
||||||
>已保存至测试记录,记录 ID:{{ result.record_id }}</div
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<template v-if="!result">
|
|
||||||
<el-button @click="handleClose">取消</el-button>
|
|
||||||
<el-button type="primary" :loading="submitting" @click="handleRun">开始测试</el-button>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<el-button type="primary" @click="handleReset">再测一次</el-button>
|
|
||||||
<el-button @click="handleClose">关闭</el-button>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import api from '../../../api/reward_config/index'
|
|
||||||
import lotteryConfigApi from '../../../api/lottery_pool_config/index'
|
|
||||||
import ArtBarChart from '@/components/core/charts/art-bar-chart/index.vue'
|
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
|
|
||||||
const GRID_NUMBERS = [
|
|
||||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
|
||||||
30
|
|
||||||
]
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
modelValue: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Emits {
|
|
||||||
(e: 'update:modelValue', value: boolean): void
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
modelValue: false
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits<Emits>()
|
|
||||||
|
|
||||||
const visible = computed({
|
|
||||||
get: () => props.modelValue,
|
|
||||||
set: (v) => emit('update:modelValue', v)
|
|
||||||
})
|
|
||||||
|
|
||||||
const form = ref({
|
|
||||||
lottery_config_id: null as number | null,
|
|
||||||
test_count: 100 as 100 | 500 | 1000 | 5000 | 10000,
|
|
||||||
save_record: true
|
|
||||||
})
|
|
||||||
|
|
||||||
const lotteryConfigOptions = ref<
|
|
||||||
Array<{
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
t1_weight: number
|
|
||||||
t2_weight: number
|
|
||||||
t3_weight: number
|
|
||||||
t4_weight: number
|
|
||||||
t5_weight: number
|
|
||||||
}>
|
|
||||||
>([])
|
|
||||||
const submitting = ref(false)
|
|
||||||
const result = ref<{ counts: Record<string, number>; record_id: number | null } | null>(null)
|
|
||||||
|
|
||||||
const selectedLotteryConfig = computed(
|
|
||||||
() => lotteryConfigOptions.value.find((opt) => opt.id === form.value.lottery_config_id) || null
|
|
||||||
)
|
|
||||||
|
|
||||||
const selectedTierSummary = computed(() => {
|
|
||||||
const opt = selectedLotteryConfig.value
|
|
||||||
if (!opt) return ''
|
|
||||||
const t1 = opt.t1_weight
|
|
||||||
const t2 = opt.t2_weight
|
|
||||||
const t3 = opt.t3_weight
|
|
||||||
const t4 = opt.t4_weight
|
|
||||||
const t5 = opt.t5_weight
|
|
||||||
const total = t1 + t2 + t3 + t4 + t5
|
|
||||||
if (!total) {
|
|
||||||
return `当前奖池 T1-T5 权重:T1=${t1} T2=${t2} T3=${t3} T4=${t4} T5=${t5}(总和为 0,测试时会按均等档位概率)`
|
|
||||||
}
|
|
||||||
const p = (v: number) => ((v / total) * 100).toFixed(1)
|
|
||||||
return `当前奖池 T1-T5 权重:T1=${t1} (${p(t1)}%),T2=${t2} (${p(t2)}%),T3=${t3} (${p(t3)}%),T4=${t4} (${p(t4)}%),T5=${t5} (${p(t5)}%)`
|
|
||||||
})
|
|
||||||
|
|
||||||
const chartLabels = computed(() => GRID_NUMBERS.map((n) => String(n)))
|
|
||||||
|
|
||||||
const chartData = computed(() => {
|
|
||||||
if (!result.value?.counts) return GRID_NUMBERS.map(() => 0)
|
|
||||||
const counts = result.value.counts
|
|
||||||
return GRID_NUMBERS.map((n) => {
|
|
||||||
const v = counts[String(n)] ?? counts[n]
|
|
||||||
return typeof v === 'number' && !Number.isNaN(v) ? v : 0
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
async function loadLotteryOptions() {
|
|
||||||
try {
|
|
||||||
const list = await lotteryConfigApi.getOptions()
|
|
||||||
lotteryConfigOptions.value = Array.isArray(list) ? list : []
|
|
||||||
} catch {
|
|
||||||
lotteryConfigOptions.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleRun() {
|
|
||||||
submitting.value = true
|
|
||||||
result.value = null
|
|
||||||
try {
|
|
||||||
const res = await api.runWeightTest({
|
|
||||||
test_count: form.value.test_count,
|
|
||||||
save_record: form.value.save_record,
|
|
||||||
lottery_config_id: form.value.lottery_config_id ?? undefined
|
|
||||||
})
|
|
||||||
const data = (res as any)?.data ?? res
|
|
||||||
result.value = {
|
|
||||||
counts: data.counts ?? {},
|
|
||||||
record_id: data.record_id ?? null
|
|
||||||
}
|
|
||||||
} catch (e: any) {
|
|
||||||
ElMessage.error(e?.message ?? '测试请求失败')
|
|
||||||
} finally {
|
|
||||||
submitting.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleReset() {
|
|
||||||
result.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleClose() {
|
|
||||||
visible.value = false
|
|
||||||
result.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(visible, (open) => {
|
|
||||||
if (open) {
|
|
||||||
loadLotteryOptions()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.test-form {
|
|
||||||
padding: 8px 0;
|
|
||||||
}
|
|
||||||
.form-tip {
|
|
||||||
margin-left: 8px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
}
|
|
||||||
.test-result {
|
|
||||||
padding: 8px 0;
|
|
||||||
}
|
|
||||||
.result-summary {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.chart-wrap {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
.record-tip {
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Reference in New Issue
Block a user