fix admin reward group bigint ids

This commit is contained in:
zhx 2026-05-26 20:50:42 +08:00
parent 8043571cec
commit b2fb090fb1
6 changed files with 74 additions and 24 deletions

View File

@ -41,9 +41,11 @@
"@vben/types": "workspace:*", "@vben/types": "workspace:*",
"@vben/utils": "workspace:*", "@vben/utils": "workspace:*",
"@vueuse/core": "catalog:", "@vueuse/core": "catalog:",
"@types/json-bigint": "catalog:",
"ali-oss": "^6.23.0", "ali-oss": "^6.23.0",
"antdv-next": "catalog:", "antdv-next": "catalog:",
"dayjs": "catalog:", "dayjs": "catalog:",
"json-bigint": "catalog:",
"pinia": "catalog:", "pinia": "catalog:",
"sockjs-client": "^1.6.1", "sockjs-client": "^1.6.1",
"stompjs": "^2.3.3", "stompjs": "^2.3.3",

View File

@ -1,3 +1,5 @@
import JsonBigint from 'json-bigint';
import { requestClient } from '#/api/request'; import { requestClient } from '#/api/request';
export interface LegacyPageResult<T = Record<string, any>> { export interface LegacyPageResult<T = Record<string, any>> {
@ -5,6 +7,16 @@ export interface LegacyPageResult<T = Record<string, any>> {
total: number; total: number;
} }
const jsonBigint = JsonBigint({ storeAsString: true });
function parseLegacyBodyWithBigint<T>(raw: string) {
const data = jsonBigint.parse(raw);
if (data?.errorCode === 401 || data?.errorCode !== 0) {
throw new Error(data?.errorMsg || data?.message || 'Error');
}
return data?.body as T;
}
export async function pagePropsSource(params: Record<string, any>) { export async function pagePropsSource(params: Record<string, any>) {
return requestClient.get<LegacyPageResult<Record<string, any>>>( return requestClient.get<LegacyPageResult<Record<string, any>>>(
'/props/source/record/page', '/props/source/record/page',
@ -53,12 +65,18 @@ export async function listNotFamilyBySysOriginType(
} }
export async function pagePropsActivityRewardGroup(params: Record<string, any>) { export async function pagePropsActivityRewardGroup(params: Record<string, any>) {
return requestClient.get<LegacyPageResult<Record<string, any>>>( const response = await requestClient.get<{ data: string }>(
'/props/activity/reward/group/page', '/props/activity/reward/group/page',
{ {
params, params,
responseReturn: 'raw',
responseType: 'text',
transformResponse: [(data) => data],
}, },
); );
return parseLegacyBodyWithBigint<LegacyPageResult<Record<string, any>>>(
response.data,
);
} }
export async function getByGroupId(id: number | string) { export async function getByGroupId(id: number | string) {

View File

@ -1,8 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref, watch } from 'vue'; import { reactive, ref, watch } from 'vue';
import { pagePropsActivityRewardGroup } from '#/api/legacy/props';
import { import {
Button, Button,
Drawer, Drawer,
@ -13,8 +11,10 @@ import {
Table, Table,
} from 'antdv-next'; } from 'antdv-next';
import RewardRow from './reward-row.vue'; import { pagePropsActivityRewardGroup } from '#/api/legacy/props';
import { PROPS_SHELF_STATUS_OPTIONS } from '../shared'; import { PROPS_SHELF_STATUS_OPTIONS } from '../shared';
import RewardRow from './reward-row.vue';
const props = defineProps<{ const props = defineProps<{
open: boolean; open: boolean;
@ -52,6 +52,11 @@ const shelfStatusOptions = PROPS_SHELF_STATUS_OPTIONS.map((item) => ({
value: item.value as any, value: item.value as any,
})); }));
function normalizeID(value: unknown) {
const text = String(value ?? '').trim();
return text && text !== '0' ? text : '';
}
async function loadData(reset = false) { async function loadData(reset = false) {
if (!props.open || !query.sysOrigin) { if (!props.open || !query.sysOrigin) {
return; return;
@ -62,7 +67,10 @@ async function loadData(reset = false) {
loading.value = true; loading.value = true;
try { try {
const result = await pagePropsActivityRewardGroup({ ...query }); const result = await pagePropsActivityRewardGroup({ ...query });
list.value = result.records || []; list.value = (result.records || []).map((item: Record<string, any>) => ({
...item,
id: normalizeID(item.id),
}));
total.value = result.total || 0; total.value = result.total || 0;
} finally { } finally {
loading.value = false; loading.value = false;
@ -156,7 +164,7 @@ watch(
:total="total" :total="total"
show-size-changer show-size-changer
@change="handlePageChange" @change="handlePageChange"
@showSizeChange="handlePageChange" @show-size-change="handlePageChange"
/> />
</div> </div>
</Drawer> </Drawer>

View File

@ -16,8 +16,8 @@ import {
Spin, Spin,
Switch, Switch,
Table, Table,
Tabs,
TabPane, TabPane,
Tabs,
Tag, Tag,
} from 'antdv-next'; } from 'antdv-next';
@ -53,6 +53,15 @@ function createLevel(level = 1, rechargeAmount = 10) {
}; };
} }
function normalizeID(value: unknown) {
const text = String(value ?? '').trim();
return text && text !== '0' ? text : '';
}
function hasPositiveID(value: unknown) {
return /^\d+$/.test(normalizeID(value));
}
function defaultLevels() { function defaultLevels() {
return [createLevel(1, 10), createLevel(2, 50), createLevel(3, 100)]; return [createLevel(1, 10), createLevel(2, 50), createLevel(3, 100)];
} }
@ -170,7 +179,7 @@ function normalizeConfig(result: null | Record<string, any> | undefined) {
level: Number(item.level || index + 1), level: Number(item.level || index + 1),
rechargeAmount: Number.isFinite(rechargeAmount) ? rechargeAmount : 0, rechargeAmount: Number.isFinite(rechargeAmount) ? rechargeAmount : 0,
rechargeAmountCents: Number(item.rechargeAmountCents || 0), rechargeAmountCents: Number(item.rechargeAmountCents || 0),
rewardGroupId: item.rewardGroupId ?? null, rewardGroupId: normalizeID(item.rewardGroupId) || null,
rewardGroupName: String(item.rewardGroupName || ''), rewardGroupName: String(item.rewardGroupName || ''),
rewardItems: Array.isArray(item.rewardItems) ? item.rewardItems : [], rewardItems: Array.isArray(item.rewardItems) ? item.rewardItems : [],
rowKey: createRowKey(item.id || index), rowKey: createRowKey(item.id || index),
@ -254,8 +263,8 @@ function handleRewardGroupSelect(row: Record<string, any>) {
groupPickerOpen.value = false; groupPickerOpen.value = false;
return; return;
} }
target.rewardGroupId = row.id; target.rewardGroupId = normalizeID(row.id) || null;
target.rewardGroupName = row.name; target.rewardGroupName = String(row.name || '');
target.rewardItems = Array.isArray(row.rewardConfigList) ? row.rewardConfigList : []; target.rewardItems = Array.isArray(row.rewardConfigList) ? row.rewardConfigList : [];
groupPickerOpen.value = false; groupPickerOpen.value = false;
} }
@ -271,7 +280,6 @@ function validateBeforeSave() {
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);
const rewardGroupId = Number(item.rewardGroupId || 0);
if (level <= 0) { if (level <= 0) {
message.warning('档位必须大于 0'); message.warning('档位必须大于 0');
return false; return false;
@ -280,7 +288,7 @@ function validateBeforeSave() {
message.warning('首冲金额必须大于 0'); message.warning('首冲金额必须大于 0');
return false; return false;
} }
if (rewardGroupId <= 0) { if (!hasPositiveID(item.rewardGroupId)) {
message.warning('每个档位都需要配置奖励资源组'); message.warning('每个档位都需要配置奖励资源组');
return false; return false;
} }
@ -317,7 +325,7 @@ async function submitForm() {
level: Number(item.level || 0), level: Number(item.level || 0),
rechargeAmount: formatAmount(item.rechargeAmount), rechargeAmount: formatAmount(item.rechargeAmount),
rechargeAmountCents: toAmountCents(item.rechargeAmount), rechargeAmountCents: toAmountCents(item.rechargeAmount),
rewardGroupId: item.rewardGroupId ?? null, rewardGroupId: normalizeID(item.rewardGroupId) || null,
rewardGroupName: String(item.rewardGroupName || ''), rewardGroupName: String(item.rewardGroupName || ''),
})), })),
sysOrigin: selectedSysOrigin.value, sysOrigin: selectedSysOrigin.value,
@ -407,7 +415,7 @@ watch(activeTab, (value) => {
<Button :loading="loading" @click="loadConfig">刷新</Button> <Button :loading="loading" @click="loadConfig">刷新</Button>
</div> </div>
<Tabs v-model:activeKey="activeTab"> <Tabs v-model:active-key="activeTab">
<TabPane key="config" tab="奖励配置"> <TabPane key="config" tab="奖励配置">
<div class="config-row"> <div class="config-row">
<Space align="center" wrap> <Space align="center" wrap>
@ -518,7 +526,7 @@ watch(activeTab, (value) => {
v-if="record.userAvatar" v-if="record.userAvatar"
class="user-avatar" class="user-avatar"
:style="avatarBackgroundStyle(record.userAvatar)" :style="avatarBackgroundStyle(record.userAvatar)"
/> ></div>
<div class="user-main"> <div class="user-main">
<div class="user-name">{{ record.userNickname || '-' }}</div> <div class="user-name">{{ record.userNickname || '-' }}</div>
<div class="sub-text"> <div class="sub-text">

View File

@ -16,8 +16,8 @@ import {
Spin, Spin,
Switch, Switch,
Table, Table,
Tabs,
TabPane, TabPane,
Tabs,
Tag, Tag,
} from 'antdv-next'; } from 'antdv-next';
@ -54,6 +54,15 @@ function createLevel(level = 1, rechargeAmount = 100, rewardGold = 0) {
}; };
} }
function normalizeID(value: unknown) {
const text = String(value ?? '').trim();
return text && text !== '0' ? text : '';
}
function hasPositiveID(value: unknown) {
return /^\d+$/.test(normalizeID(value));
}
function defaultLevels() { function defaultLevels() {
return [ return [
createLevel(1, 100, 0), createLevel(1, 100, 0),
@ -170,7 +179,7 @@ function normalizeConfig(result: null | Record<string, any> | undefined) {
rechargeAmount: Number.isFinite(rechargeAmount) ? rechargeAmount : 0, rechargeAmount: Number.isFinite(rechargeAmount) ? rechargeAmount : 0,
rechargeAmountCents: Number(item.rechargeAmountCents || 0), rechargeAmountCents: Number(item.rechargeAmountCents || 0),
rewardGold: Number(item.rewardGold || 0), rewardGold: Number(item.rewardGold || 0),
rewardGroupId: item.rewardGroupId ?? null, rewardGroupId: normalizeID(item.rewardGroupId) || null,
rewardGroupName: String(item.rewardGroupName || ''), rewardGroupName: String(item.rewardGroupName || ''),
rewardItems: Array.isArray(item.rewardItems) ? item.rewardItems : [], rewardItems: Array.isArray(item.rewardItems) ? item.rewardItems : [],
rowKey: createRowKey(item.id || index), rowKey: createRowKey(item.id || index),
@ -259,8 +268,8 @@ function handleRewardGroupSelect(row: Record<string, any>) {
groupPickerOpen.value = false; groupPickerOpen.value = false;
return; return;
} }
target.rewardGroupId = row.id; target.rewardGroupId = normalizeID(row.id) || null;
target.rewardGroupName = row.name; target.rewardGroupName = String(row.name || '');
target.rewardItems = Array.isArray(row.rewardConfigList) ? row.rewardConfigList : []; target.rewardItems = Array.isArray(row.rewardConfigList) ? row.rewardConfigList : [];
groupPickerOpen.value = false; groupPickerOpen.value = false;
} }
@ -277,7 +286,6 @@ function validateBeforeSave() {
const level = Number(item.level || 0); const level = Number(item.level || 0);
const amountCents = toAmountCents(item.rechargeAmount); const amountCents = toAmountCents(item.rechargeAmount);
const rewardGold = Number(item.rewardGold || 0); const rewardGold = Number(item.rewardGold || 0);
const rewardGroupId = Number(item.rewardGroupId || 0);
if (level <= 0) { if (level <= 0) {
message.warning('档位必须大于 0'); message.warning('档位必须大于 0');
return false; return false;
@ -286,7 +294,7 @@ function validateBeforeSave() {
message.warning('充值金额必须大于 0'); message.warning('充值金额必须大于 0');
return false; return false;
} }
if (rewardGold <= 0 && rewardGroupId <= 0) { if (rewardGold <= 0 && !hasPositiveID(item.rewardGroupId)) {
message.warning('每个档位至少要配置金币或奖励组'); message.warning('每个档位至少要配置金币或奖励组');
return false; return false;
} }
@ -324,7 +332,7 @@ async function submitForm() {
rechargeAmount: formatAmount(item.rechargeAmount), rechargeAmount: formatAmount(item.rechargeAmount),
rechargeAmountCents: toAmountCents(item.rechargeAmount), rechargeAmountCents: toAmountCents(item.rechargeAmount),
rewardGold: Number(item.rewardGold || 0), rewardGold: Number(item.rewardGold || 0),
rewardGroupId: item.rewardGroupId ?? null, rewardGroupId: normalizeID(item.rewardGroupId) || null,
rewardGroupName: String(item.rewardGroupName || ''), rewardGroupName: String(item.rewardGroupName || ''),
})), })),
sysOrigin: selectedSysOrigin.value, sysOrigin: selectedSysOrigin.value,
@ -429,7 +437,7 @@ watch(activeTab, (value) => {
<Button :loading="loading" @click="loadConfig">刷新</Button> <Button :loading="loading" @click="loadConfig">刷新</Button>
</div> </div>
<Tabs v-model:activeKey="activeTab"> <Tabs v-model:active-key="activeTab">
<TabPane key="config" tab="奖励配置"> <TabPane key="config" tab="奖励配置">
<div class="config-row"> <div class="config-row">
<Space align="center" wrap> <Space align="center" wrap>
@ -551,7 +559,7 @@ watch(activeTab, (value) => {
v-if="record.userAvatar" v-if="record.userAvatar"
class="user-avatar" class="user-avatar"
:style="avatarBackgroundStyle(record.userAvatar)" :style="avatarBackgroundStyle(record.userAvatar)"
/> ></div>
<div class="user-main"> <div class="user-main">
<div class="user-name">{{ record.userNickname || '-' }}</div> <div class="user-name">{{ record.userNickname || '-' }}</div>
<div class="sub-text"> <div class="sub-text">

6
pnpm-lock.yaml generated
View File

@ -480,6 +480,9 @@ importers:
apps: apps:
dependencies: dependencies:
'@types/json-bigint':
specifier: 'catalog:'
version: 1.0.4
'@vben/access': '@vben/access':
specifier: workspace:* specifier: workspace:*
version: link:../packages/effects/access version: link:../packages/effects/access
@ -534,6 +537,9 @@ importers:
dayjs: dayjs:
specifier: 'catalog:' specifier: 'catalog:'
version: 1.11.20 version: 1.11.20
json-bigint:
specifier: 'catalog:'
version: 1.0.0
pinia: pinia:
specifier: ^3.0.4 specifier: ^3.0.4
version: 3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)) version: 3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3))