/** * 与后端 format_price / PrescriptionService 计价口径一致的价格工具 */ /** * 安全解析价格为数字 * @param {*} value 价格原始值 * @returns {number} 有效数字,无效时返回 0 */ export function parsePriceValue(value) { if (value === null || value === undefined || value === '') { return 0 } const num = Number(value) return Number.isFinite(num) ? num : 0 } /** * 与后端 format_price 一致:第三位小数非 0 则分位进 1,再保留两位小数 * @param {*} value 待格式化的价格 * @returns {number} 进位后的两位小数价格 */ export function formatPriceLikeBackend(value) { const price = parsePriceValue(value) let milli = Math.round(price * 1000) if (milli % 10 > 0) { milli += 10 } milli -= milli % 10 return Math.round((milli / 1000) * 100) / 100 // return milli / 1000 } /** * 模拟 PHP bcmul 在指定 scale 下向零截断 * @param {*} a 乘数 * @param {*} b 被乘数 * @param {number} scale 小数位数 * @returns {number} 截断后的乘积 */ export function bcmulScale(a, b, scale) { const product = parsePriceValue(a) * parsePriceValue(b) const factor = 10 ** scale return Math.trunc(product * factor) / factor } /** * 格式化为两位小数字符串,供页面展示 * @param {*} value 价格 * @returns {string} 如 "12.35" */ export function formatPriceDisplay(value) { return formatPriceLikeBackend(value).toFixed(2) } /** * 特色方预估总价:每剂单价 × 贴数,对齐 bcmath 3 位乘法 + format_price 进位 * @param {*} pricePerDose 每剂单价(接口 price_per_dose) * @param {*} doseCount 贴数 * @returns {string} 两位小数的预估金额字符串 */ export function calculateSpecialPrescriptionEstimatedTotal(pricePerDose, doseCount) { const total = bcmulScale(doseCount, pricePerDose, 3) return formatPriceDisplay(formatPriceLikeBackend(total)) }