1. 特色方模块

This commit is contained in:
李琦
2026-07-03 12:35:47 +08:00
parent f18916f9d5
commit 178b9a7c09
3 changed files with 103 additions and 58 deletions

View File

@@ -51,10 +51,10 @@
<view class="fs-28 font-bold text-gray">
{{ (specialPrescriptionRecord.special_prescription && specialPrescriptionRecord.special_prescription.name) || '特色方' }}
</view>
<view class="fs-24 color-sub m-t-8">
<view class="fs-24 color-sub">
剂量{{ specialPrescriptionRecord.dose_count }}
</view>
<view class="m-t-8">
<view class="">
<u-tag
v-if="Number(specialPrescriptionRecord.status) === 0"
text="待导入"

View File

@@ -2,6 +2,55 @@
* 处方价格计算工具类
* 职责:统一管理处方价格计算逻辑
*/
/**
* 与后端 format_price 一致:第三位小数非 0 则分位进 1再保留两位小数
*/
export function formatPriceLikeBackend(value) {
const price = parseFloat(value || 0);
if (Number.isNaN(price)) {
return 0;
}
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 下向零截断 */
function bcmulScale(a, b, scale) {
const product = parseFloat(a || 0) * parseFloat(b || 0);
const factor = 10 ** scale;
return Math.trunc(product * factor) / factor;
}
/** 模拟 PHP bcadd 在指定 scale 下向零截断 */
function bcaddScale(a, b, scale) {
const sum = a + b;
const factor = 10 ** scale;
return Math.trunc(sum * factor) / factor;
}
/**
* 中药商品总价(与 PrescriptionService::createChineseReprice 一致)
*/
export function calculateChineseMedicineProductPriceLikeBackend(drugs, dosage = 7) {
if (!drugs || drugs.length === 0) {
return 0;
}
const dose = parseFloat(dosage || 0);
let total = 0;
for (const drug of drugs) {
const linePerDose = bcmulScale(drug.price, drug.number ?? 1, 3);
const lineTotal = bcmulScale(dose, linePerDose, 3);
total = bcaddScale(total, lineTotal, 3);
}
return formatPriceLikeBackend(total);
}
export class PrescriptionCalculator {
/**
* 计算中药商品总价
@@ -10,14 +59,7 @@ export class PrescriptionCalculator {
* @returns {number} 商品总价
*/
static calculateChineseMedicineProductPrice(drugs, dosage = 7) {
if (!drugs || drugs.length === 0) {
return 0;
}
return drugs.reduce((sum, drug) => {
const price = parseFloat(drug.price || 0);
const quantity = parseFloat(drug.number || 1);
return sum + (price * quantity * dosage);
}, 0);
return calculateChineseMedicineProductPriceLikeBackend(drugs, dosage);
}
static isValidBuyPrice(value) {

View File

@@ -38,6 +38,54 @@
</view>
</view>
<!-- 特色方信息 -->
<view v-if="infoList.special_prescription_patient_record" class="modern-card">
<view class="card-title">特色方</view>
<view class="special-rx-info flex-row flex-ali-center">
<u-image
v-if="infoList.special_prescription_patient_record.special_prescription && infoList.special_prescription_patient_record.special_prescription.cover_image"
width="96rpx"
height="96rpx"
border-radius="12"
:src="infoList.special_prescription_patient_record.special_prescription.cover_image"
/>
<view class="flex-1 m-l-16">
<view class="info-value font-bold">
{{ (infoList.special_prescription_patient_record.special_prescription && infoList.special_prescription_patient_record.special_prescription.name) || '特色方' }}
</view>
<view class="info-row" style="border-bottom: none; padding: 8rpx 0 0;">
<text class="info-label">剂量</text>
<text class="info-value">{{ infoList.special_prescription_patient_record.dose_count }} </text>
</view>
<view class="-8">
<u-tag
v-if="Number(infoList.special_prescription_patient_record.status) === 0"
text="待导入"
type="warning"
size="mini"
/>
<u-tag
v-else-if="Number(infoList.special_prescription_patient_record.status) === 1"
text="已应用"
type="success"
size="mini"
/>
<u-tag v-else text="已完成" type="info" size="mini" />
</view>
</view>
</view>
<view class="m-t-24">
<u-button
type="primary"
shape="circle"
:custom-style="{ backgroundColor: '#6ACDBB', color: '#fff', border: 'none' }"
@click="goImportSpecialPrescription"
>
导入
</u-button>
</view>
</view>
<!-- 挂号信息 -->
<view class="modern-card">
<view class="card-title">挂号信息</view>
@@ -67,54 +115,6 @@
</view>
</view>
<!-- 特色方信息 -->
<view v-if="infoList.special_prescription_patient_record" class="modern-card">
<view class="card-title">特色方</view>
<view class="special-rx-info flex-row flex-ali-center">
<u-image
v-if="infoList.special_prescription_patient_record.special_prescription && infoList.special_prescription_patient_record.special_prescription.cover_image"
width="96rpx"
height="96rpx"
border-radius="12"
:src="infoList.special_prescription_patient_record.special_prescription.cover_image"
/>
<view class="flex-1 m-l-16">
<view class="info-value font-bold">
{{ (infoList.special_prescription_patient_record.special_prescription && infoList.special_prescription_patient_record.special_prescription.name) || '特色方' }}
</view>
<view class="info-row" style="border-bottom: none; padding: 8rpx 0 0;">
<text class="info-label">剂量</text>
<text class="info-value">{{ infoList.special_prescription_patient_record.dose_count }} </text>
</view>
<view class="m-t-8">
<u-tag
v-if="Number(infoList.special_prescription_patient_record.status) === 0"
text="待导入"
type="warning"
size="mini"
/>
<u-tag
v-else-if="Number(infoList.special_prescription_patient_record.status) === 1"
text="已应用"
type="success"
size="mini"
/>
<u-tag v-else text="已完成" type="info" size="mini" />
</view>
</view>
</view>
<view class="m-t-24">
<u-button
type="primary"
shape="circle"
:custom-style="{ backgroundColor: '#6ACDBB', color: '#fff', border: 'none' }"
@click="goImportSpecialPrescription"
>
导入
</u-button>
</view>
</view>
<!-- 健康信息 -->
<view class="modern-card">
<view class="card-title">健康信息</view>
@@ -485,6 +485,9 @@ export default {
if (this.apiOk(res)) {
this.$toast('已接诊');
this.getList()
if (infoList.special_prescription_patient_record) {
return;
}
setTimeout(() => {
let url = `/subPackages/sub_workbench/prescription_v2/index?register_id=${e}`;
if (pid) url += `&patient_id=${pid}`;