持续模拟
This commit is contained in:
parent
bdd3a99bba
commit
42c88e6282
@ -6,3 +6,22 @@ export async function simulateRegionBroadcast(data: Record<string, any>) {
|
|||||||
data,
|
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 { Page } from '@vben/common-ui';
|
||||||
import { useAccessStore } from '@vben/stores';
|
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 { getAllowedSysOrigins } from '#/views/system/shared';
|
||||||
|
|
||||||
import SystemRegionSelect from './components/system-region-select.vue';
|
import SystemRegionSelect from './components/system-region-select.vue';
|
||||||
@ -12,9 +18,13 @@ import SystemRegionSelect from './components/system-region-select.vue';
|
|||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
|
Checkbox,
|
||||||
Form,
|
Form,
|
||||||
FormItem,
|
FormItem,
|
||||||
Input,
|
Input,
|
||||||
|
InputNumber,
|
||||||
|
Descriptions,
|
||||||
|
DescriptionsItem,
|
||||||
Select,
|
Select,
|
||||||
Space,
|
Space,
|
||||||
TextArea,
|
TextArea,
|
||||||
@ -58,7 +68,24 @@ const form = reactive<Record<string, any>>({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const sending = ref(false);
|
const sending = ref(false);
|
||||||
|
const workerLoading = ref(false);
|
||||||
const resultText = ref('');
|
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');
|
const isLuckyGift = computed(() => form.kind === 'LUCKY_GIFT');
|
||||||
|
|
||||||
@ -74,12 +101,36 @@ watch(
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => form.sysOrigin,
|
() => form.sysOrigin,
|
||||||
() => {
|
(value) => {
|
||||||
form.regionId = '';
|
form.regionId = '';
|
||||||
form.regionCode = '';
|
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) {
|
function handleRegionChange(_value: any, item: Record<string, any> | null) {
|
||||||
form.regionCode = item?.regionCode || item?.code || '';
|
form.regionCode = item?.regionCode || item?.code || '';
|
||||||
}
|
}
|
||||||
@ -143,6 +194,80 @@ async function handleSend() {
|
|||||||
sending.value = false;
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -231,6 +356,114 @@ async function handleSend() {
|
|||||||
placeholder="发送成功后显示服务端返回内容"
|
placeholder="发送成功后显示服务端返回内容"
|
||||||
/>
|
/>
|
||||||
</Card>
|
</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>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -244,4 +477,8 @@ async function handleSend() {
|
|||||||
.result-card {
|
.result-card {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.summary {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user