You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { roundHalfUp } from "@/lib/math";
const KG_TO_LB = 2.20462;
const CM_TO_IN = 2.54;
/** API 可接受的重量单位canonical */
export type ApiWeightUnit = "lb" | "kg" | "t";
/** API 可接受的尺寸单位canonical */
export type ApiDimUnit = "in" | "cm" | "m";
/**
* 重量单位别名。
* 刻意不收录 ton/tons北美常指 short ton(2000lb),与公制吨(1000kg)歧义。
* 公制吨请用 t / tonne / tonnes。
*/
const WEIGHT_UNIT_ALIASES: Record<string, ApiWeightUnit> = {
lb: "lb",
lbs: "lb",
pound: "lb",
pounds: "lb",
kg: "kg",
kilogram: "kg",
kilograms: "kg",
t: "t",
tonne: "t",
tonnes: "t",
};
/** ton/tons 歧义提示(不参与换算) */
export function weightUnitAmbiguousMessage(raw: string): string | null {
const key = raw.trim().toLowerCase();
if (key === "ton" || key === "tons") {
return "重量单位 ton/tons 有歧义(美制短吨 vs 公制吨),请使用 t 或 tonne";
}
return null;
}
const DIM_UNIT_ALIASES: Record<string, ApiDimUnit> = {
in: "in",
inch: "in",
inches: "in",
cm: "cm",
centimeter: "cm",
centimeters: "cm",
m: "m",
meter: "m",
meters: "m",
};
/** 解析 API 重量单位(大小写不敏感,支持常见别名) */
export function normalizeWeightUnit(raw: string): ApiWeightUnit | null {
return WEIGHT_UNIT_ALIASES[raw.trim().toLowerCase()] ?? null;
}
/** 解析 API 尺寸单位(大小写不敏感,支持常见别名) */
export function normalizeDimUnit(raw: string): ApiDimUnit | null {
return DIM_UNIT_ALIASES[raw.trim().toLowerCase()] ?? null;
}
/** kg → lbROUND_HALF_UP 保留 2 位GD-13 */
export function kgToLb(kg: number): number {
return roundHalfUp(kg * KG_TO_LB, 2);
}
/** 公制吨 → lb1 t = 1000 kg */
export function tToLb(t: number): number {
return kgToLb(t * 1000);
}
/** lb → kg */
export function lbToKg(lb: number): number {
return roundHalfUp(lb / KG_TO_LB, 2);
}
/** cm → inROUND_HALF_UP 保留 2 位GD-13内部哈希/展示用) */
export function cmToIn(cm: number): number {
return roundHalfUp(cm / CM_TO_IN, 2);
}
/** m → in经 cm 换算) */
export function mToIn(m: number): number {
return cmToIn(m * 100);
}
/** in → cm */
export function inToCm(inches: number): number {
return roundHalfUp(inches * CM_TO_IN, 2);
}
/** 任意 API 重量单位 → lb未取整供 toAxelWholePounds 使用) */
export function weightValueToLb(value: number, unit: ApiWeightUnit): number {
if (unit === "kg") {
return kgToLb(value);
}
if (unit === "t") {
return tToLb(value);
}
return value;
}
/** 任意 API 尺寸单位 → in未取整供 toAxelWholeInches 使用) */
export function dimValueToIn(value: number, unit: ApiDimUnit): number {
if (unit === "cm") {
return cmToIn(value);
}
if (unit === "m") {
return mToIn(value);
}
return value;
}
/** MotherShip axel/quote 与 RPA 表单要求英寸为正整数(向上取整) */
export function toAxelWholeInches(inches: number): number {
return Math.max(1, Math.ceil(inches - Number.EPSILON));
}
/** MotherShip axel/quote 要求磅为正整数(向上取整) */
export function toAxelWholePounds(lb: number): number {
return Math.max(1, Math.ceil(lb - Number.EPSILON));
}