diff --git a/subPackages/special-prescription/detail.vue b/subPackages/special-prescription/detail.vue index 720da53..b808f2a 100644 --- a/subPackages/special-prescription/detail.vue +++ b/subPackages/special-prescription/detail.vue @@ -135,6 +135,7 @@ import { getSpecialPrescriptionDetailApi, saveSpecialPrescriptionRegisterContext, } from '@/request/api/specialPrescription' +import { calculateSpecialPrescriptionEstimatedTotal } from '@/utils/formatPrice' export default { data() { @@ -166,8 +167,10 @@ export default { if (this.detail.price_available === false) { return '0.00' } - const price = parseFloat(this.detail.price_per_dose) || 0 - return (price * this.doseCount).toFixed(2) + return calculateSpecialPrescriptionEstimatedTotal( + this.detail.price_per_dose, + this.doseCount, + ) }, }, onLoad(e) { diff --git a/utils/formatPrice.js b/utils/formatPrice.js new file mode 100644 index 0000000..d7f17e4 --- /dev/null +++ b/utils/formatPrice.js @@ -0,0 +1,65 @@ +/** + * 与后端 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)) +}