持续模拟
This commit is contained in:
parent
bdd3a99bba
commit
42c88e6282
@ -6,3 +6,22 @@ export async function simulateRegionBroadcast(data: Record<string, any>) {
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getRegionBroadcastWorkerStatus() {
|
||||
return requestClient.get<Record<string, any>>(
|
||||
'/go/operate/region-broadcast/worker/status',
|
||||
);
|
||||
}
|
||||
|
||||
export async function startRegionBroadcastWorker(data: Record<string, any>) {
|
||||
return requestClient.post<Record<string, any>>(
|
||||
'/go/operate/region-broadcast/worker/start',
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
export async function stopRegionBroadcastWorker() {
|
||||
return requestClient.post<Record<string, any>>(
|
||||
'/go/operate/region-broadcast/worker/stop',
|
||||
);
|
||||
}
|
||||
|
||||
@ -4,7 +4,13 @@ import { computed, reactive, ref, watch } from 'vue';
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { simulateRegionBroadcast } from '#/api/legacy/region-broadcast';
|
||||
import {
|
||||
getRegionBroadcastWorkerStatus,
|
||||
simulateRegionBroadcast,
|
||||
startRegionBroadcastWorker,
|
||||
stopRegionBroadcastWorker,
|
||||
} from '#/api/legacy/region-broadcast';
|
||||
import { regionConfigTable } from '#/api/legacy/system';
|
||||
import { getAllowedSysOrigins } from '#/views/system/shared';
|
||||
|
||||
import SystemRegionSelect from './components/system-region-select.vue';
|
||||
@ -12,9 +18,13 @@ import SystemRegionSelect from './components/system-region-select.vue';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Checkbox,
|
||||
Form,
|
||||
FormItem,
|
||||
Input,
|
||||
InputNumber,
|
||||
Descriptions,
|
||||
DescriptionsItem,
|
||||
Select,
|
||||
Space,
|
||||
TextArea,
|
||||
@ -58,7 +68,24 @@ const form = reactive<Record<string, any>>({
|
||||
});
|
||||
|
||||
const sending = ref(false);
|
||||
const workerLoading = ref(false);
|
||||
const resultText = ref('');
|
||||
const regionLoading = ref(false);
|
||||
const regionOptions = ref<Array<Record<string, any>>>([]);
|
||||
const workerStatus = ref<Record<string, any>>({});
|
||||
const workerForm = reactive<Record<string, any>>({
|
||||
betAmounts: '100,200,500,1000',
|
||||
enableGameWin: true,
|
||||
enableLuckyGift: true,
|
||||
gameWinAmounts: '1000,2000,5000,10000',
|
||||
giftCandyOptions: '100,200,500',
|
||||
giftQuantityOptions: '1,5,10',
|
||||
luckyGiftWinAmounts: '1000,2000,5000,10000',
|
||||
maxDelaySeconds: 20,
|
||||
minDelaySeconds: 0,
|
||||
multiples: '10,20,50,100',
|
||||
regionCodes: [] as string[],
|
||||
});
|
||||
|
||||
const isLuckyGift = computed(() => form.kind === 'LUCKY_GIFT');
|
||||
|
||||
@ -74,12 +101,36 @@ watch(
|
||||
|
||||
watch(
|
||||
() => form.sysOrigin,
|
||||
() => {
|
||||
(value) => {
|
||||
form.regionId = '';
|
||||
form.regionCode = '';
|
||||
workerForm.regionCodes = [];
|
||||
if (value) {
|
||||
void loadRegions();
|
||||
void refreshWorkerStatus();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
async function loadRegions() {
|
||||
if (!form.sysOrigin) {
|
||||
regionOptions.value = [];
|
||||
return;
|
||||
}
|
||||
regionLoading.value = true;
|
||||
try {
|
||||
const list = await regionConfigTable({ sysOrigin: form.sysOrigin });
|
||||
regionOptions.value = (list || [])
|
||||
.map((item) => ({
|
||||
label: item.regionName || item.regionCode || item.code || String(item.id),
|
||||
value: item.regionCode || item.code || '',
|
||||
}))
|
||||
.filter((item) => item.value);
|
||||
} finally {
|
||||
regionLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleRegionChange(_value: any, item: Record<string, any> | null) {
|
||||
form.regionCode = item?.regionCode || item?.code || '';
|
||||
}
|
||||
@ -143,6 +194,80 @@ async function handleSend() {
|
||||
sending.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function parseIntList(value: any) {
|
||||
return String(value || '')
|
||||
.split(/[,,\s]+/)
|
||||
.map((item) => Number(item.trim()))
|
||||
.filter((item) => Number.isFinite(item) && item > 0)
|
||||
.map((item) => Math.trunc(item));
|
||||
}
|
||||
|
||||
function parseFloatList(value: any) {
|
||||
return String(value || '')
|
||||
.split(/[,,\s]+/)
|
||||
.map((item) => Number(item.trim()))
|
||||
.filter((item) => Number.isFinite(item) && item > 0);
|
||||
}
|
||||
|
||||
function buildWorkerPayload() {
|
||||
return {
|
||||
betAmounts: parseIntList(workerForm.betAmounts),
|
||||
enableGameWin: Boolean(workerForm.enableGameWin),
|
||||
enableLuckyGift: Boolean(workerForm.enableLuckyGift),
|
||||
gameWinAmounts: parseIntList(workerForm.gameWinAmounts),
|
||||
giftCandyOptions: parseIntList(workerForm.giftCandyOptions),
|
||||
giftQuantityOptions: parseIntList(workerForm.giftQuantityOptions),
|
||||
luckyGiftWinAmounts: parseIntList(workerForm.luckyGiftWinAmounts),
|
||||
maxDelaySeconds: Number(workerForm.maxDelaySeconds || 0),
|
||||
minDelaySeconds: Number(workerForm.minDelaySeconds || 0),
|
||||
multiples: parseFloatList(workerForm.multiples),
|
||||
regionCodes: workerForm.regionCodes || [],
|
||||
sysOrigin: form.sysOrigin,
|
||||
};
|
||||
}
|
||||
|
||||
async function refreshWorkerStatus() {
|
||||
workerLoading.value = true;
|
||||
try {
|
||||
workerStatus.value = (await getRegionBroadcastWorkerStatus()) || {};
|
||||
} finally {
|
||||
workerLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStartWorker() {
|
||||
const payload = buildWorkerPayload();
|
||||
if (!payload.sysOrigin) {
|
||||
message.warning('请选择系统来源');
|
||||
return;
|
||||
}
|
||||
if (!payload.regionCodes.length) {
|
||||
message.warning('请至少选择一个区域');
|
||||
return;
|
||||
}
|
||||
if (!payload.enableGameWin && !payload.enableLuckyGift) {
|
||||
message.warning('请至少开启一种飘屏');
|
||||
return;
|
||||
}
|
||||
workerLoading.value = true;
|
||||
try {
|
||||
workerStatus.value = (await startRegionBroadcastWorker(payload)) || {};
|
||||
message.success('持续模拟已启动');
|
||||
} finally {
|
||||
workerLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStopWorker() {
|
||||
workerLoading.value = true;
|
||||
try {
|
||||
workerStatus.value = (await stopRegionBroadcastWorker()) || {};
|
||||
message.success('持续模拟已停止');
|
||||
} finally {
|
||||
workerLoading.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -231,6 +356,114 @@ async function handleSend() {
|
||||
placeholder="发送成功后显示服务端返回内容"
|
||||
/>
|
||||
</Card>
|
||||
|
||||
<Card class="result-card" title="持续模拟">
|
||||
<Form layout="vertical">
|
||||
<div class="form-grid">
|
||||
<FormItem label="区域" required>
|
||||
<Select
|
||||
v-model:value="workerForm.regionCodes"
|
||||
:loading="regionLoading"
|
||||
:options="regionOptions"
|
||||
mode="multiple"
|
||||
placeholder="可多选"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="随机间隔">
|
||||
<Space>
|
||||
<InputNumber
|
||||
v-model:value="workerForm.minDelaySeconds"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
addon-after="秒"
|
||||
/>
|
||||
<InputNumber
|
||||
v-model:value="workerForm.maxDelaySeconds"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
addon-after="秒"
|
||||
/>
|
||||
</Space>
|
||||
</FormItem>
|
||||
<FormItem label="飘屏开关">
|
||||
<Space>
|
||||
<Checkbox v-model:checked="workerForm.enableLuckyGift">
|
||||
幸运礼物
|
||||
</Checkbox>
|
||||
<Checkbox v-model:checked="workerForm.enableGameWin">
|
||||
游戏盈利
|
||||
</Checkbox>
|
||||
</Space>
|
||||
</FormItem>
|
||||
<FormItem label="中奖倍数">
|
||||
<Input v-model:value="workerForm.multiples" placeholder="10,20,50" />
|
||||
</FormItem>
|
||||
<FormItem label="游戏中奖金额">
|
||||
<Input
|
||||
v-model:value="workerForm.gameWinAmounts"
|
||||
placeholder="1000,2000,5000"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="幸运礼物中奖金额">
|
||||
<Input
|
||||
v-model:value="workerForm.luckyGiftWinAmounts"
|
||||
placeholder="1000,2000,5000"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="投注金额">
|
||||
<Input v-model:value="workerForm.betAmounts" placeholder="100,200,500" />
|
||||
</FormItem>
|
||||
<FormItem label="礼物单价">
|
||||
<Input
|
||||
v-model:value="workerForm.giftCandyOptions"
|
||||
placeholder="100,200,500"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="礼物数量">
|
||||
<Input
|
||||
v-model:value="workerForm.giftQuantityOptions"
|
||||
placeholder="1,5,10"
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
|
||||
<Space>
|
||||
<Button :loading="workerLoading" type="primary" @click="handleStartWorker">
|
||||
启动持续模拟
|
||||
</Button>
|
||||
<Button :loading="workerLoading" danger @click="handleStopWorker">
|
||||
停止
|
||||
</Button>
|
||||
<Button :loading="workerLoading" @click="refreshWorkerStatus">
|
||||
刷新状态
|
||||
</Button>
|
||||
</Space>
|
||||
</Form>
|
||||
|
||||
<Descriptions bordered class="summary" size="small">
|
||||
<DescriptionsItem label="状态">
|
||||
{{ workerStatus.running ? '运行中' : '已停止' }}
|
||||
</DescriptionsItem>
|
||||
<DescriptionsItem label="下次间隔">
|
||||
{{ workerStatus.nextDelaySec ?? 0 }} 秒
|
||||
</DescriptionsItem>
|
||||
<DescriptionsItem label="总发送">
|
||||
{{ workerStatus.totalCount ?? 0 }}
|
||||
</DescriptionsItem>
|
||||
<DescriptionsItem label="幸运礼物">
|
||||
{{ workerStatus.luckyGiftCount ?? 0 }}
|
||||
</DescriptionsItem>
|
||||
<DescriptionsItem label="游戏盈利">
|
||||
{{ workerStatus.gameWinCount ?? 0 }}
|
||||
</DescriptionsItem>
|
||||
<DescriptionsItem label="最后执行">
|
||||
{{ workerStatus.lastRunAt || '-' }}
|
||||
</DescriptionsItem>
|
||||
<DescriptionsItem label="最后错误">
|
||||
{{ workerStatus.lastError || '-' }}
|
||||
</DescriptionsItem>
|
||||
</Descriptions>
|
||||
</Card>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
@ -244,4 +477,8 @@ async function handleSend() {
|
||||
.result-card {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.summary {
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user