90 lines
2.7 KiB
TypeScript
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}` : ""}`;
|
|
}
|