Files
gao-customer-h5/src/utils/eventValue.ts
T
2026-08-30 00:54:52 +08:00

90 lines
2.7 KiB
TypeScript

import type { EventItem } from "@/types/EventItem";
/**
* 返回事件数值单位的前端文案。
* 后端仍使用 CENT 表示金额分,前端统一按元展示和录入。
*/
export function getEventValueUnitText(valueUnit?: EventItem["valueUnit"]): string {
if (valueUnit === "CENT") {
return "元";
}
if (valueUnit === "COUNT") {
return "次";
}
return "未配置单位";
}
/**
* 获取事件数值输入提示。
*/
export function getEventNumberValuePlaceholder(event: EventItem): string {
if (event.valueUnit === "CENT") {
return event.requireValue ? "金额(元),最多两位小数" : "金额(元),可留空,最多两位小数";
}
return event.requireValue ? "次数,必须是大于等于 0 的整数" : "次数,可留空,必须是大于等于 0 的整数";
}
/**
* 将前端输入的事件数值转换为后端要求的整数。
* 金额使用字符串拆分后转换为分,避免直接使用浮点数放大导致精度误差。
*/
export function resolveEventNumberValue(event: EventItem, valueText: string): number | undefined {
const normalizedValue = valueText.trim();
if (!normalizedValue) {
return undefined;
}
if (event.valueUnit === "CENT") {
return resolveCentValue(normalizedValue);
}
if (!/^\d+$/.test(normalizedValue)) {
return undefined;
}
const value = Number(normalizedValue);
return Number.isSafeInteger(value) ? value : undefined;
}
/**
* 将后端返回的整数分转换为前端金额文案。
*/
export function formatEventNumberValue(event: EventItem | undefined, value?: number | null): string {
if (value === undefined || value === null) {
return "-";
}
if (event?.valueUnit !== "CENT") {
return `${value}${event?.valueUnit === "COUNT" ? " 次" : ""}`;
}
return `${formatCentValue(value)} 元`;
}
/**
* 将金额字符串转换为分,最多保留两位小数。
*/
export function resolveCentValue(valueText: string): number | undefined {
const match = /^(\d+)(?:\.(\d{0,2}))?$/.exec(valueText);
if (!match) {
return undefined;
}
const integerText = match[1];
const decimalText = (match[2] || "").padEnd(2, "0");
const centValue = BigInt(integerText) * 100n + BigInt(decimalText || "0");
if (centValue > BigInt(Number.MAX_SAFE_INTEGER)) {
return undefined;
}
return Number(centValue);
}
/**
* 将整数分格式化为不带单位的元字符串。
*/
export function formatCentValue(value: number): string {
if (!Number.isSafeInteger(value) || value < 0) {
return "";
}
const centText = String(value);
const yuanText = centText.length < 3 ? "0" : centText.slice(0, -2);
const decimalText = centText.slice(-2).padStart(2, "0").replace(/0+$/, "");
return `${yuanText}${decimalText ? `.${decimalText}` : ""}`;
}