后台各页的整数解析统一到共享助手

- apps/admin-web/src/pages/pageUtils.ts:新增 parsePositiveInteger,用 Number + Number.isSafeInteger,空串 / 非数字 / 小数 / 0 / 负数一律收敛成 0
- 删除 AdminTaskConfigPage、AdminProfileWalletConfigPage、AdminRechargeProductPage、AdminRedeemCodePage 与 adminEditorGenerationPricing 里各自的一份实现,5 个页面统一从 pageUtils 引入,修掉「钱包页拒 1.5、任务页把 1.5 当 1」这类口径不一致
- adminEditorGenerationPricing.test.ts 的引入路径同步改到 pageUtils
This commit is contained in:
2026-09-24 19:07:32 +08:00
parent acdfb8ed73
commit 9bcd8f728b
9 changed files with 20 additions and 36 deletions
@@ -5,9 +5,9 @@ import type {
import {
EDITOR_MODEL3D_ENDPOINT_SECTIONS,
editorModel3dAddOnLabel,
parsePositiveInteger,
updateEditorModel3dEndpointPricing,
} from './adminEditorGenerationPricing';
import { parsePositiveInteger } from './pageUtils';
/**
* 一个模型版本的两个底价字段。两栏只有字段键与展示名不同,用描述表驱动渲染,
@@ -17,9 +17,8 @@ import { AdminEditorGenerationModel3dPricingSection } from './AdminEditorGenerat
import {
buildAdminEditorGenerationPricingRequest,
collectInvalidEditorGenerationPricingLabels,
parsePositiveInteger,
} from './adminEditorGenerationPricing';
import { handlePageError } from './pageUtils';
import { handlePageError, parsePositiveInteger } from './pageUtils';
interface AdminEditorGenerationPricingPageProps {
token: string;
@@ -7,7 +7,7 @@ import {
} from '../api/adminApiClient';
import type { ProfileWalletConfigAdminResponse } from '../api/adminApiTypes';
import { useAdminWriteConfirm } from '../components/useAdminWriteConfirm';
import { handlePageError } from './pageUtils';
import { handlePageError, parsePositiveInteger } from './pageUtils';
interface AdminProfileWalletConfigPageProps {
token: string;
@@ -197,8 +197,3 @@ export function AdminProfileWalletConfigPage({
</section>
);
}
function parsePositiveInteger(value: string) {
const parsed = Number(value);
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : 0;
}
@@ -11,7 +11,7 @@ import type {
ProfileRechargeProductKind,
} from '../api/adminApiTypes';
import { useAdminWriteConfirm } from '../components/useAdminWriteConfirm';
import { handlePageError } from './pageUtils';
import { handlePageError, parsePositiveInteger } from './pageUtils';
interface AdminRechargeProductPageProps {
token: string;
@@ -546,11 +546,6 @@ function formatPrice(priceCents: number) {
return `¥${(priceCents / 100).toFixed(2)}`;
}
function parsePositiveInteger(value: string) {
const parsed = parseInteger(value);
return parsed > 0 ? parsed : 0;
}
function parseNonNegativeInteger(value: string) {
const parsed = parseInteger(value);
return parsed > 0 ? parsed : 0;
@@ -12,7 +12,7 @@ import type {
ProfileRedeemCodeMode,
} from '../api/adminApiTypes';
import { useAdminWriteConfirm } from '../components/useAdminWriteConfirm';
import { handlePageError, splitLines } from './pageUtils';
import { handlePageError, parsePositiveInteger, splitLines } from './pageUtils';
interface AdminRedeemCodePageProps {
token: string;
@@ -422,11 +422,6 @@ export function AdminRedeemCodePage({
);
}
function parsePositiveInteger(value: string) {
const parsed = Number.parseInt(value, 10);
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
}
function redeemModeLabel(value: ProfileRedeemCodeMode) {
return redeemModes.find((item) => item.value === value)?.label ?? value;
}
@@ -19,7 +19,7 @@ import {
filterAdminTrackingEventKeyOptions,
findAdminTrackingEventDefinition,
} from '../config/trackingEventDefinitions';
import { handlePageError } from './pageUtils';
import { handlePageError, parsePositiveInteger } from './pageUtils';
interface AdminTaskConfigPageProps {
token: string;
@@ -571,11 +571,6 @@ export function AdminTaskConfigPage({
);
}
function parsePositiveInteger(value: string) {
const parsed = Number.parseInt(value, 10);
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
}
function parseInteger(value: string) {
const parsed = Number.parseInt(value, 10);
return Number.isFinite(parsed) ? parsed : 0;
@@ -5,8 +5,8 @@ import {
buildAdminEditorGenerationPricingRequest,
collectInvalidEditorGenerationPricingLabels,
editorModel3dAddOnLabel,
parsePositiveInteger,
} from './adminEditorGenerationPricing';
import { parsePositiveInteger } from './pageUtils';
function pricingFixture(): EditorGenerationPricingConfigPayload {
return {
@@ -31,14 +31,6 @@ export function editorModel3dAddOnLabel(addOn: string) {
return EDITOR_MODEL3D_ADD_ON_LABELS[addOn] ?? addOn;
}
/** 输入框文本转整数;空串、非数字、小数、0 与负数一律收敛成 0,交给提交前校验拦住。 */
export function parsePositiveInteger(value: string) {
// 用 Number 而不是 parseIntparseInt 会把 `3.9` 截成 3、`12abc` 截成 12
// 等于把编辑中的半截输入静默当成合法值存下去。
const parsed = Number(value);
return Number.isInteger(parsed) && parsed > 0 ? parsed : 0;
}
export function isPositiveMudPoints(value: number | null | undefined) {
return typeof value === 'number' && Number.isInteger(value) && value >= 1;
}
+13
View File
@@ -1,5 +1,18 @@
import { formatAdminApiError, isAdminApiError } from '../api/adminApiClient';
/**
* 泥点 / 积分类输入框文本转正整数:空串、非数字、小数、0 与负数一律收敛成 0,
* 由各页的提交前校验拦住。
*
* 用 `Number` 而不是 `parseInt``parseInt` 会把 `3.9` 截成 3、`12abc` 截成 12
* 等于把编辑中的半截输入静默当成合法值存下去;再用 `isSafeInteger` 挡掉超出安全整数
* 范围的值(那种值在别处会被静默改写)。后台各页统一用这一份,不再各写一遍。
*/
export function parsePositiveInteger(value: string) {
const parsed = Number(value);
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : 0;
}
export function handlePageError(
error: unknown,
onUnauthorized: (message?: string) => void,