export type ParallelKeywayRow = {
kind: "shaft" | "hub";
kindLabel: string;
option: string;
keySize: string;
bMm: number;
hMm: number;
depthMm: number;
remainingMm: number;
standardRange: string;
};
type KeySize = {
bMm: number;
hMm: number;
shaftDepthMm: number;
hubDepthMm: number;
range: string;
minDiameterMm: number;
maxDiameterMm: number;
};
// 按图纸标准尺寸表:直径区间只匹配该区间对应的标准键,不再额外混入相邻规格。
const KEY_SIZES: KeySize[] = [
{ bMm: 4, hMm: 4, shaftDepthMm: 2.5, hubDepthMm: 1.8, range: ">10--12", minDiameterMm: 10, maxDiameterMm: 12 },
{ bMm: 5, hMm: 5, shaftDepthMm: 3, hubDepthMm: 2.3, range: ">12--17", minDiameterMm: 12, maxDiameterMm: 17 },
{ bMm: 6, hMm: 6, shaftDepthMm: 3.5, hubDepthMm: 2.8, range: ">17--22", minDiameterMm: 17, maxDiameterMm: 22 },
{ bMm: 8, hMm: 7, shaftDepthMm: 4, hubDepthMm: 3.3, range: ">22--30", minDiameterMm: 22, maxDiameterMm: 30 },
];
function formatMm(value: number): number {
return Math.round(value * 100) / 100;
}
export function calculateParallelKeyway(diameterMm: number):
| { ok: true; diameterMm: number; rows: ParallelKeywayRow[] }
| { ok: false; error: string } {
if (!Number.isFinite(diameterMm) || diameterMm < 11 || diameterMm > 30) {
return { ok: false, error: "轴/孔直径必须在 11--30 mm 范围内" };
}
const standardIndex = KEY_SIZES.findIndex(
(size) => diameterMm > size.minDiameterMm && diameterMm <= size.maxDiameterMm,
);
if (standardIndex < 0) {
return { ok: false, error: "没有找到对应的平键标准尺寸" };
}
const selected = KEY_SIZES.slice(Math.max(0, standardIndex - 1), standardIndex + 1);
const rows: ParallelKeywayRow[] = [];
selected.forEach((size, index) => {
rows.push({
kind: "shaft",
kindLabel: "轴截面",
option: "轴截面",
keySize: `${size.bMm}×${size.hMm}`,
bMm: size.bMm,
hMm: size.hMm,
depthMm: size.shaftDepthMm,
remainingMm: formatMm(diameterMm - size.shaftDepthMm),
standardRange: size.range,
});
rows.push({
kind: "hub",
kindLabel: "毂孔",
option: "毂孔",
keySize: `${size.bMm}×${size.hMm}`,
bMm: size.bMm,
hMm: size.hMm,
depthMm: size.hubDepthMm,
remainingMm: formatMm(diameterMm + size.hubDepthMm),
standardRange: size.range,
});
});
return { ok: true, diameterMm, rows };
}