diff --git a/apps/web-antd/src/store/prescription.ts b/apps/web-antd/src/store/prescription.ts index 25f1bf4a..326dec7c 100644 --- a/apps/web-antd/src/store/prescription.ts +++ b/apps/web-antd/src/store/prescription.ts @@ -22,6 +22,11 @@ import { calcTotalMarginPercent, isSeeRateEnabled, } from '#/utils/chinesePrescriptionMargin'; +import { calculateProcessingFee, parsePriceValue } from '#/utils/formatPrice'; +import { + applySingleChildProcessRuleAutoSelect, + resolveProcessRuleLoadedLevel, +} from '#/utils/processRuleCascade'; import { getRegisterStoreInfo as getRegisterStoreInfoPharmacy } from '#/views/doctor/online-consultation/api'; import { getRegisterStoreInfo as getRegisterStoreInfoClinic } from '#/views/doctor/online-consultation-clinic/api'; import traditionalJson from '#/views/business/chat/config/traditional.json'; @@ -121,31 +126,16 @@ export const usePrescriptionStore = defineStore('prescription', () => { ); }); - const processRulePrice = ref(0); - const calcMethod = ref(0); - const processingFee = computed(() => { - if (ruleType.value === 1) return 0; - if (currentDrugs.value.length === 0) return 0; - + if (ruleType.value !== 2 || currentDrugs.value.length === 0) return 0; const processRule = childProcessRuleList.value.find( (item) => item.id === childProcessRuleId.value, ); - if (!processRule) return 0; - - calcMethod.value = processRule.calc_method; - processRulePrice.value = processRule.price; - - if (calcMethod.value === 1) return processRulePrice.value; - if (calcMethod.value === 2) return processRulePrice.value * dosage.value; - if (calcMethod.value === 3) { - const totalNumber = currentDrugs.value.reduce( - (sum, drug) => sum + drug.number, - 0, - ); - return processRulePrice.value * dosage.value * totalNumber; - } - return 0; + const totalQty = currentDrugs.value.reduce( + (sum, drug) => sum + parsePriceValue(drug.number ?? 1), + 0, + ); + return calculateProcessingFee(processRule, dosage.value, totalQty); }); const totalCost = computed(() => { @@ -393,6 +383,38 @@ export const usePrescriptionStore = defineStore('prescription', () => { } else { childProcessRuleList.value = res; } + await applySingleChildProcessRuleAutoSelect( + resolveProcessRuleLoadedLevel(pid, ruleId), + { + ruleType: ruleType.value, + processRuleId: processRuleId.value, + childProcessRuleId: childProcessRuleId.value, + processRuleNoteId: processRuleNoteId.value, + processRuleList: processRuleList.value, + childProcessRuleList: childProcessRuleList.value, + processRuleNoteList: processRuleNoteList.value, + load: getProcessRuleListData, + setProcessRuleId: (id) => { + processRuleId.value = id; + }, + setChildProcessRuleId: (id) => { + childProcessRuleId.value = id; + }, + setProcessRuleNoteId: (id) => { + processRuleNoteId.value = id; + }, + clearBelowProcessRule: () => { + childProcessRuleId.value = undefined; + processRuleNoteId.value = undefined; + childProcessRuleList.value = []; + processRuleNoteList.value = []; + }, + clearBelowChild: () => { + processRuleNoteId.value = undefined; + processRuleNoteList.value = []; + }, + }, + ); console.log('获取加工规则成功'); } catch (error) { console.error('获取加工规则失败:', error); @@ -796,6 +818,62 @@ export const usePrescriptionStore = defineStore('prescription', () => { packageMethodId.value = id; }; + /** + * 中药配置变更(标签选择,对齐移动端级联逻辑) + */ + const handleChineseConfigChange = async (payload: { + ruleType?: number; + packageMethodId?: number | null; + processRuleId?: number | null; + childProcessRuleId?: number | null; + processRuleNoteId?: number | null; + dosage?: number; + dayDosage?: number; + }) => { + const oldRuleType = ruleType.value; + const oldProcessRuleId = processRuleId.value; + const oldChildProcessRuleId = childProcessRuleId.value; + + if (payload.ruleType === 2 && payload.ruleType !== oldRuleType) { + if (processRuleList.value.length === 0) { + await getProcessRuleListData(); + } + } + if (payload.ruleType === 1 && oldRuleType === 2) { + processRuleId.value = undefined; + childProcessRuleId.value = undefined; + processRuleNoteId.value = undefined; + processRuleList.value = []; + childProcessRuleList.value = []; + processRuleNoteList.value = []; + } + if (payload.processRuleId != null && payload.processRuleId !== oldProcessRuleId) { + childProcessRuleId.value = undefined; + processRuleNoteId.value = undefined; + childProcessRuleList.value = []; + processRuleNoteList.value = []; + } + if (payload.childProcessRuleId != null && payload.childProcessRuleId !== oldChildProcessRuleId) { + processRuleNoteId.value = undefined; + processRuleNoteList.value = []; + } + + if (payload.ruleType != null) ruleType.value = payload.ruleType; + if (payload.packageMethodId !== undefined) packageMethodId.value = payload.packageMethodId ?? 2; + if (payload.processRuleId !== undefined) processRuleId.value = payload.processRuleId ?? undefined; + if (payload.childProcessRuleId !== undefined) childProcessRuleId.value = payload.childProcessRuleId ?? undefined; + if (payload.processRuleNoteId !== undefined) processRuleNoteId.value = payload.processRuleNoteId ?? undefined; + if (payload.dosage != null) dosage.value = payload.dosage; + if (payload.dayDosage != null) dayDosage.value = payload.dayDosage; + + if (payload.processRuleId != null && payload.processRuleId !== oldProcessRuleId) { + await getProcessRuleListData(payload.processRuleId); + } + if (payload.childProcessRuleId != null && payload.childProcessRuleId !== oldChildProcessRuleId) { + await getProcessRuleListData(0, payload.childProcessRuleId); + } + }; + // 中药相冲检查 const checkChineseMedicineConflict = async () => { if (activeCategory.value === 2) { @@ -897,7 +975,7 @@ export const usePrescriptionStore = defineStore('prescription', () => { child_process_rule_id: childProcessRuleId.value, process_rule_type: ruleType.value, prescription_type: activeCategory.value, - processing_fee: processRulePrice.value, + processing_fee: processingFee.value, dosage: dosage.value, day_dosage: dayDosage.value, doctor_second_sign: doctorSecondSignValue, @@ -958,7 +1036,6 @@ export const usePrescriptionStore = defineStore('prescription', () => { diagnosis.value = ''; medicalAdvice.value = ''; packageMethodId.value = 2; - processRulePrice.value = 0; dosage.value = 7; dayDosage.value = 2; newDrugInfo.value = {}; @@ -1084,6 +1161,7 @@ export const usePrescriptionStore = defineStore('prescription', () => { selectProcessRuleNot, selectProcessRuleNotCommit, selectPackageMethod, + handleChineseConfigChange, checkChineseMedicineConflict, sendPrescription, resetForm, diff --git a/apps/web-antd/src/store/usePrescription.ts b/apps/web-antd/src/store/usePrescription.ts index 15f6442a..d6000890 100644 --- a/apps/web-antd/src/store/usePrescription.ts +++ b/apps/web-antd/src/store/usePrescription.ts @@ -2,6 +2,7 @@ import { computed, ref, nextTick } from "vue" import { message, notification } from "ant-design-vue" import { debounce } from "lodash-es" +import { calculateProcessingFee, parsePriceValue } from '#/utils/formatPrice' import { addWestPrescription, checkChineseMedicineConflictApi, @@ -75,26 +76,14 @@ export const usePrescriptionStore = () => { return currentDrugs.value.reduce((sum, drug) => sum + drug.price * (drug.select_number || 1), 0) }) - const processRulePrice = ref(0) - const calcMethod = ref(0) - const processingFee = computed(() => { - if (ruleType.value === 1) return 0 - if (currentDrugs.value.length === 0) return 0 - + if (ruleType.value !== 2 || currentDrugs.value.length === 0) return 0 const processRule = childProcessRuleList.value.find((item) => item.id === childProcessRuleId.value) - if (!processRule) return 0 - - calcMethod.value = processRule.calc_method - processRulePrice.value = processRule.price - - if (calcMethod.value === 1) return processRulePrice.value - if (calcMethod.value === 2) return processRulePrice.value * dosage.value - if (calcMethod.value === 3) { - const totalNumber = currentDrugs.value.reduce((sum, drug) => sum + drug.number, 0) - return processRulePrice.value * dosage.value * totalNumber - } - return 0 + const totalQty = currentDrugs.value.reduce( + (sum, drug) => sum + parsePriceValue(drug.number ?? 1), + 0, + ) + return calculateProcessingFee(processRule, dosage.value, totalQty) }) const totalCost = computed(() => { @@ -548,7 +537,7 @@ export const usePrescriptionStore = () => { child_process_rule_id: childProcessRuleId.value, process_rule_type: ruleType.value, prescription_type: activeCategory.value, - processing_fee: processRulePrice.value, + processing_fee: processingFee.value, dosage: dosage.value, day_dosage: dayDosage.value, doctor_second_sign: doctorSecondSignValue, @@ -569,7 +558,6 @@ export const usePrescriptionStore = () => { diagnosis.value = "" medicalAdvice.value = "" packageMethodId.value = 2 - processRulePrice.value = 0 dosage.value = 7 dayDosage.value = 2 newDrugInfo.value = {} diff --git a/apps/web-antd/src/utils/formatPrice.ts b/apps/web-antd/src/utils/formatPrice.ts index 9bd55c04..dcf0497d 100644 --- a/apps/web-antd/src/utils/formatPrice.ts +++ b/apps/web-antd/src/utils/formatPrice.ts @@ -67,3 +67,35 @@ export function calculateChineseProductPriceLikeBackend( export function formatPriceDisplay(value: unknown): string { return formatPriceLikeBackend(value).toFixed(2); } + +type ProcessRuleLine = { + calc_method?: number; + price?: unknown; +}; + +/** + * 计算委托调剂加工费(与移动端 PrescriptionCalculator.calculateProcessingFee 一致) + * calc_method: 1=固定价格,2=按剂数,3=按数量 + */ +export function calculateProcessingFee( + processRule: ProcessRuleLine | null | undefined, + dosage = 7, + totalDrugQuantity = 0, +): number { + if (!processRule?.calc_method) { + return 0; + } + const price = parsePriceValue(processRule.price); + const dose = parsePriceValue(dosage); + const qty = parsePriceValue(totalDrugQuantity); + switch (processRule.calc_method) { + case 1: + return price; + case 2: + return price * dose; + case 3: + return price * dose * qty; + default: + return 0; + } +} diff --git a/apps/web-antd/src/views/business/chat/components/PrescriptionModal.vue b/apps/web-antd/src/views/business/chat/components/PrescriptionModal.vue index c940f0c8..4bc29baa 100644 --- a/apps/web-antd/src/views/business/chat/components/PrescriptionModal.vue +++ b/apps/web-antd/src/views/business/chat/components/PrescriptionModal.vue @@ -53,7 +53,8 @@ import CommonPrescriptionModal from '#/views/doctor/doctor-reception/components/ // 信息提示模态框 import InfoModal from '#/components/modal/InfoModal.vue'; // 药品搜索选择组件 -import { DrugSearchSelect } from '#/components/drug-search-select'; +import { formatPriceDisplay } from '#/utils/formatPrice'; +import ChineseMedicineConfig from '#/views/doctor/doctor-reception/components/ChineseMedicineConfig.vue'; const splitString = (input: string) => input.split(','); @@ -82,11 +83,6 @@ const categories = [ { label: '医疗器械', value: 7 }, ]; -const packageMethod = [ - { label: '味包', value: 1 }, - { label: '剂包', value: 2 }, -]; - // 使用 Pinia store const prescriptionStore = usePrescriptionStore(); @@ -1361,165 +1357,21 @@ const cancelSaveCommonPrescription = () => { /> - -
- - 自制剂 - 委托调剂 - - -
- -
- -
- - - - - -
- -
-
- 用量: -
- - - -
- 天 / {{ prescriptionStore.dosage }} 剂 -
- -
- 频次: -
- - - -
- 次/天 -
-
-
+
@@ -1539,10 +1391,10 @@ const cancelSaveCommonPrescription = () => {
- 加工费:¥{{ prescriptionStore.processingFee.toFixed(2) }} + 加工费:¥{{ formatPriceDisplay(prescriptionStore.processingFee) }}
- 商品价格:¥{{ prescriptionStore.totalProductCost.toFixed(2) }} + 商品价格:¥{{ formatPriceDisplay(prescriptionStore.totalProductCost) }} {
- 总计:¥{{ prescriptionStore.totalCost.toFixed(2) }} + 总计:¥{{ formatPriceDisplay(prescriptionStore.totalCost) }}
diff --git a/apps/web-antd/src/views/business/order/product-order/components/detail.vue b/apps/web-antd/src/views/business/order/product-order/components/detail.vue index 888a65cd..3b45118c 100644 --- a/apps/web-antd/src/views/business/order/product-order/components/detail.vue +++ b/apps/web-antd/src/views/business/order/product-order/components/detail.vue @@ -14,6 +14,7 @@ import { formatPriceDiscountLabel, normalizeQuickOptions } from '#/utils/pricePe import { expressDetailByOrderId, getOrderInfo } from '../api'; import SensitiveText from '#/components/sensitive-text/SensitiveText.vue'; +import { formatDoctorOrderText } from '#/utils/prescriptionDoctorOrder'; defineOptions({ name: 'DetailModal', @@ -414,7 +415,7 @@ function prescriptionStatusColor() { {{ data.prescription.content.clinical_diagnose }} - {{ data.prescription.content.doctor_order }} + {{ formatDoctorOrderText(data.prescription) }} {{ data.prescription.content.doctor.name }} diff --git a/apps/web-antd/src/views/doctor/doctor-reception/components/PrescriptionDetail.vue b/apps/web-antd/src/views/doctor/doctor-reception/components/PrescriptionDetail.vue index 96390e54..9517912a 100644 --- a/apps/web-antd/src/views/doctor/doctor-reception/components/PrescriptionDetail.vue +++ b/apps/web-antd/src/views/doctor/doctor-reception/components/PrescriptionDetail.vue @@ -6,6 +6,7 @@ import { Page, useVbenModal } from '@vben/common-ui'; import { Button } from 'ant-design-vue'; import { getPrescriptionInfoApi } from '#/views/doctor/doctor-reception/api'; +import { formatDoctorOrderText } from '#/utils/prescriptionDoctorOrder'; const item = ref>({}); @@ -228,7 +229,7 @@ function parseRecipeContent(content: string | Record) {