首冲奖励配置

This commit is contained in:
zhx 2026-05-28 15:01:01 +08:00
parent a62e5a65a5
commit 2ef1aa24ea

View File

@ -42,6 +42,7 @@ function createRowKey(seed?: number | string) {
function createLevel(level = 1, rechargeAmount = 10) { function createLevel(level = 1, rechargeAmount = 10) {
return { return {
enabled: true, enabled: true,
googleProductId: '',
id: null, id: null,
level, level,
rechargeAmount, rechargeAmount,
@ -85,6 +86,7 @@ const form = reactive<Record<string, any>>({
enabled: false, enabled: false,
id: 0, id: 0,
levelConfigs: defaultLevels(), levelConfigs: defaultLevels(),
minAppVersion: '',
sysOrigin: '', sysOrigin: '',
updateTime: '', updateTime: '',
}); });
@ -93,6 +95,7 @@ const levelColumns = [
{ dataIndex: 'enabled', key: 'enabled', title: '启用', width: 90 }, { dataIndex: 'enabled', key: 'enabled', title: '启用', width: 90 },
{ dataIndex: 'level', key: 'level', title: '档位', width: 110 }, { dataIndex: 'level', key: 'level', title: '档位', width: 110 },
{ dataIndex: 'rechargeAmount', key: 'rechargeAmount', title: '首冲金额', width: 180 }, { dataIndex: 'rechargeAmount', key: 'rechargeAmount', title: '首冲金额', width: 180 },
{ dataIndex: 'googleProductId', key: 'googleProductId', title: '谷歌商品ID', width: 240 },
{ dataIndex: 'rewardGroup', key: 'rewardGroup', title: '奖励资源组', width: 420 }, { dataIndex: 'rewardGroup', key: 'rewardGroup', title: '奖励资源组', width: 420 },
{ dataIndex: 'actions', key: 'actions', title: '操作', width: 100 }, { dataIndex: 'actions', key: 'actions', title: '操作', width: 100 },
]; ];
@ -163,6 +166,7 @@ function normalizeConfig(result: null | Record<string, any> | undefined) {
form.configured = Boolean(value.configured); form.configured = Boolean(value.configured);
form.enabled = Boolean(value.enabled); form.enabled = Boolean(value.enabled);
form.id = value.id || 0; form.id = value.id || 0;
form.minAppVersion = String(value.minAppVersion || '');
form.sysOrigin = String(value.sysOrigin || selectedSysOrigin.value || ''); form.sysOrigin = String(value.sysOrigin || selectedSysOrigin.value || '');
form.updateTime = String(value.updateTime || ''); form.updateTime = String(value.updateTime || '');
const levels = Array.isArray(value.levelConfigs) && value.levelConfigs.length > 0 const levels = Array.isArray(value.levelConfigs) && value.levelConfigs.length > 0
@ -175,6 +179,7 @@ function normalizeConfig(result: null | Record<string, any> | undefined) {
); );
return { return {
enabled: item.enabled !== false, enabled: item.enabled !== false,
googleProductId: String(item.googleProductId || ''),
id: item.id ?? null, id: item.id ?? null,
level: Number(item.level || index + 1), level: Number(item.level || index + 1),
rechargeAmount: Number.isFinite(rechargeAmount) ? rechargeAmount : 0, rechargeAmount: Number.isFinite(rechargeAmount) ? rechargeAmount : 0,
@ -277,6 +282,7 @@ function validateBeforeSave() {
} }
const seenLevels = new Set<string>(); const seenLevels = new Set<string>();
const seenAmounts = new Set<string>(); const seenAmounts = new Set<string>();
const seenGoogleProductIds = new Set<string>();
for (const item of levels) { for (const item of levels) {
const level = Number(item.level || 0); const level = Number(item.level || 0);
const amountCents = toAmountCents(item.rechargeAmount); const amountCents = toAmountCents(item.rechargeAmount);
@ -300,6 +306,14 @@ function validateBeforeSave() {
message.warning('首冲金额不能重复'); message.warning('首冲金额不能重复');
return false; return false;
} }
const googleProductId = String(item.googleProductId || '').trim();
if (googleProductId) {
if (seenGoogleProductIds.has(googleProductId)) {
message.warning('谷歌商品ID不能重复');
return false;
}
seenGoogleProductIds.add(googleProductId);
}
seenLevels.add(String(level)); seenLevels.add(String(level));
seenAmounts.add(String(amountCents)); seenAmounts.add(String(amountCents));
} }
@ -307,6 +321,10 @@ function validateBeforeSave() {
message.warning('启用配置时至少要启用一个首冲奖励档位'); message.warning('启用配置时至少要启用一个首冲奖励档位');
return false; return false;
} }
if (form.enabled && !String(form.minAppVersion || '').trim()) {
message.warning('启用配置时需要填写最低App版本');
return false;
}
return true; return true;
} }
@ -321,6 +339,7 @@ async function submitForm() {
id: form.id || 0, id: form.id || 0,
levelConfigs: (form.levelConfigs || []).map((item: Record<string, any>) => ({ levelConfigs: (form.levelConfigs || []).map((item: Record<string, any>) => ({
enabled: item.enabled !== false, enabled: item.enabled !== false,
googleProductId: String(item.googleProductId || '').trim(),
id: item.id || 0, id: item.id || 0,
level: Number(item.level || 0), level: Number(item.level || 0),
rechargeAmount: formatAmount(item.rechargeAmount), rechargeAmount: formatAmount(item.rechargeAmount),
@ -328,6 +347,7 @@ async function submitForm() {
rewardGroupId: normalizeID(item.rewardGroupId) || null, rewardGroupId: normalizeID(item.rewardGroupId) || null,
rewardGroupName: String(item.rewardGroupName || ''), rewardGroupName: String(item.rewardGroupName || ''),
})), })),
minAppVersion: String(form.minAppVersion || '').trim(),
sysOrigin: selectedSysOrigin.value, sysOrigin: selectedSysOrigin.value,
}); });
message.success('保存成功'); message.success('保存成功');
@ -421,6 +441,13 @@ watch(activeTab, (value) => {
<Space align="center" wrap> <Space align="center" wrap>
<span class="field-label">启用</span> <span class="field-label">启用</span>
<Switch v-model:checked="form.enabled" /> <Switch v-model:checked="form.enabled" />
<span class="field-label">最低App版本</span>
<Input
v-model:value="form.minAppVersion"
allow-clear
placeholder="例如 1.5.0"
style="width: 160px"
/>
<span class="sub-text">更新时间{{ form.updateTime || '-' }}</span> <span class="sub-text">更新时间{{ form.updateTime || '-' }}</span>
</Space> </Space>
</div> </div>
@ -431,7 +458,7 @@ watch(activeTab, (value) => {
:loading="loading" :loading="loading"
:pagination="false" :pagination="false"
row-key="rowKey" row-key="rowKey"
:scroll="{ x: 900 }" :scroll="{ x: 1140 }"
> >
<template #bodyCell="{ column, index, record }"> <template #bodyCell="{ column, index, record }">
<template v-if="column.key === 'enabled'"> <template v-if="column.key === 'enabled'">
@ -453,6 +480,14 @@ watch(activeTab, (value) => {
style="width: 140px" style="width: 140px"
/> />
</template> </template>
<template v-else-if="column.key === 'googleProductId'">
<Input
v-model:value="record.googleProductId"
allow-clear
placeholder="Google商品ID"
style="width: 200px"
/>
</template>
<template v-else-if="column.key === 'rewardGroup'"> <template v-else-if="column.key === 'rewardGroup'">
<div class="reward-group-cell"> <div class="reward-group-cell">
<Space wrap> <Space wrap>