66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import type { RingCalculatorInput, RingCalculatorResult } from '../types/calculator'
|
||
|
||
/**
|
||
* 校验计算器输入,所有数值字段必须为非负数
|
||
* @throws Error 如果任意字段为负数
|
||
*/
|
||
export function validateInput(input: RingCalculatorInput): void {
|
||
const fields: Array<[keyof RingCalculatorInput, string]> = [
|
||
['goldWeight', '金重'],
|
||
['mainStoneWeight', '主石重'],
|
||
['sideStoneWeight', '副石重'],
|
||
['lossRate', '损耗'],
|
||
['moldGoldPrice', '倒模金价'],
|
||
['mainStoneUnitPrice', '主石单价'],
|
||
['sideStoneUnitPrice', '副石单价'],
|
||
['sideStoneCount', '副石粒数'],
|
||
['microSettingFee', '微镶费'],
|
||
['mainStoneSettingFee', '主石镶费'],
|
||
['threeDFee', '3D起板费'],
|
||
['basicLaborCost', '基本工费'],
|
||
['otherCost', '其他费用'],
|
||
]
|
||
|
||
for (const [key, label] of fields) {
|
||
if (input[key] < 0) {
|
||
throw new Error(`${label}不能为负数`)
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 钻戒计算器核心计算函数
|
||
*
|
||
* 公式:
|
||
* - 净金重(g) = 金重(g) - 主石重(ct)×0.2 - 副石重(ct)×0.2
|
||
* - 含耗重(g) = 净金重(g) × 损耗
|
||
* - 金值(元) = 含耗重(g) × 倒模金价(元)
|
||
* - 主石总价(元) = 主石重(ct) × 主石单价(元)
|
||
* - 副石总价(元) = 副石重(ct) × 副石单价(元)
|
||
* - 微镶总价(元) = 副石粒数(p) × 微镶费(元)
|
||
* - 总价 = 金值 + 主石总价 + 副石总价 + 主石镶费 + 微镶总价 + 3D起板费 + 基本工费 + 其他费用
|
||
*/
|
||
export function calculateRing(input: RingCalculatorInput): RingCalculatorResult {
|
||
validateInput(input)
|
||
|
||
const netGoldWeight = input.goldWeight - input.mainStoneWeight * 0.2 - input.sideStoneWeight * 0.2
|
||
const weightWithLoss = netGoldWeight * input.lossRate
|
||
const goldValue = weightWithLoss * input.moldGoldPrice
|
||
const mainStoneTotal = input.mainStoneWeight * input.mainStoneUnitPrice
|
||
const sideStoneTotal = input.sideStoneWeight * input.sideStoneUnitPrice
|
||
const microSettingTotal = input.sideStoneCount * input.microSettingFee
|
||
const totalPrice = goldValue + mainStoneTotal + sideStoneTotal
|
||
+ input.mainStoneSettingFee + microSettingTotal
|
||
+ input.threeDFee + input.basicLaborCost + input.otherCost
|
||
|
||
return {
|
||
netGoldWeight,
|
||
weightWithLoss,
|
||
goldValue,
|
||
mainStoneTotal,
|
||
sideStoneTotal,
|
||
microSettingTotal,
|
||
totalPrice,
|
||
}
|
||
}
|