From bd5b0b2de18146137bfad9396ded4249b55c1dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=90=A6?= Date: Wed, 5 Aug 2026 16:22:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=97=85=E5=8E=86=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/store/prescription.ts | 44 ++- .../chat/components/PrescriptionModal.vue | 59 ++-- .../doctor/doctor-reception/api/index.ts | 2 + .../views/doctor/doctor-reception/index.vue | 194 ++++++++++--- .../medical-record/MedicalRecordPanel.vue | 262 ++++++++++++++---- .../views/doctor/medical-record/api/index.ts | 18 ++ .../components/CommonDxOrderChips.vue | 95 +++++-- .../components/EntryKeywordBubble.vue | 33 ++- .../components/TextareaExpandModal.vue | 63 ++++- .../src/views/doctor/settings/index.vue | 60 ++++ .../src/views/system/pharmacy/config/table.ts | 7 + .../src/views/system/pharmacy/index.vue | 44 +++ .../src/views/system/store/api/index.ts | 11 + .../components/BindPrescriptionTypesModal.vue | 151 ++++++++++ .../config/prescription-type-constants.ts | 17 ++ .../src/views/system/store/config/table.ts | 7 + .../web-antd/src/views/system/store/index.vue | 44 +++ 17 files changed, 971 insertions(+), 140 deletions(-) create mode 100644 apps/web-antd/src/views/system/store/components/BindPrescriptionTypesModal.vue create mode 100644 apps/web-antd/src/views/system/store/config/prescription-type-constants.ts diff --git a/apps/web-antd/src/store/prescription.ts b/apps/web-antd/src/store/prescription.ts index 62e9a19d..a649178f 100644 --- a/apps/web-antd/src/store/prescription.ts +++ b/apps/web-antd/src/store/prescription.ts @@ -65,6 +65,11 @@ export const usePrescriptionStore = defineStore('prescription', () => { { label: '医疗器械', value: 7, icon: '', icon_text: '' }, ]); const prescriptionTypeDefault = ref(2); + /** 开方种类权限校验中(进入开方页先 loading) */ + const prescriptionTypeLoading = ref(false); + /** 当前门店是否有可开方种类 */ + const prescriptionTypeAllowed = ref(true); + const prescriptionTypeDenyMessage = ref(''); const diagnosis = ref(''); const medicalAdvice = ref(''); const treatmentPrice = ref(0); @@ -204,9 +209,10 @@ export const usePrescriptionStore = defineStore('prescription', () => { }; /** - * 拉取后端处方类型列表与默认选中 + * 拉取后端处方类型列表与默认选中;无绑定时清空 list 并返回 false */ const loadPrescriptionTypeOptions = async (registerId?: number | string) => { + prescriptionTypeLoading.value = true; try { const params: { register_id?: number; store_id?: number } = {}; const rid = Number(registerId || currentRegisterId.value); @@ -214,19 +220,34 @@ export const usePrescriptionStore = defineStore('prescription', () => { if (myStoreId.value) params.store_id = myStoreId.value; const res = await getPrescriptionTypeOptionsApi(params); const list = Array.isArray(res?.list) ? res.list : []; - if (list.length) { - categories.value = list.map((item) => ({ - value: Number(item.value), - label: item.label || '', - icon: item.icon || '', - icon_text: item.icon_text || '', - })); + categories.value = list.map((item) => ({ + value: Number(item.value), + label: item.label || '', + icon: item.icon || '', + icon_text: item.icon_text || '', + })); + const def = Number(res?.default) || 0; + prescriptionTypeDefault.value = def; + const allowed = + res?.allowed !== false && list.length > 0; + prescriptionTypeAllowed.value = allowed; + prescriptionTypeDenyMessage.value = allowed + ? '' + : (res?.message || '当前门店未开通开方权限'); + // 当前 Tab 不在 allowed 内时强制切到 default + if (allowed && def && !categories.value.some((c) => c.value === activeCategory.value)) { + activeCategory.value = def; } - const def = Number(res?.default); - if (def) prescriptionTypeDefault.value = def; + return allowed; } catch (error) { console.error('加载处方类型失败:', error); + categories.value = []; + prescriptionTypeAllowed.value = false; + prescriptionTypeDenyMessage.value = '处方类型加载失败,请稍后重试'; message.warning('处方类型加载失败,请稍后重试'); + return false; + } finally { + prescriptionTypeLoading.value = false; } }; @@ -1249,6 +1270,9 @@ export const usePrescriptionStore = defineStore('prescription', () => { activeCategory, categories, prescriptionTypeDefault, + prescriptionTypeLoading, + prescriptionTypeAllowed, + prescriptionTypeDenyMessage, diagnosis, medicalAdvice, treatmentPrice, 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 3566bad1..0f9414a9 100644 --- a/apps/web-antd/src/views/business/chat/components/PrescriptionModal.vue +++ b/apps/web-antd/src/views/business/chat/components/PrescriptionModal.vue @@ -29,6 +29,7 @@ import { Row, Select, SelectOption, + Spin, Tag, Tabs, TabPane, @@ -180,6 +181,8 @@ watch(allowInsuranceCategory, (allow) => { }, { immediate: true }); const submittingType = ref(false); +/** 弹窗内容区 loading(先校验开方种类权限) */ +const contentLoading = ref(false); const [Modal, modalApi] = useVbenModal({ draggable: true, confirmText: '发送处方', @@ -200,22 +203,44 @@ const [Modal, modalApi] = useVbenModal({ if (modalData.value?.registerId) { // 获取存储前缀,默认为在线复诊-药店 const storagePrefix = modalData.value?.storagePrefix || 'onlineConsultation-'; - - // 使用完整初始化,包含患者信息(传递 true 以获取患者信息) - await prescriptionStore.initializePrescription( - modalData.value.registerId, - true, - storagePrefix, - ); - prescriptionStore.loadFromLocalStorage(); - // 开方弹窗打开时再拉一次类型,确保 Network 可见且数据最新 - await prescriptionStore.loadPrescriptionTypeOptions(modalData.value.registerId); - // 获取挂号诊所信息 - await prescriptionStore.fetchRegisterStoreInfo(); - - // 如果恢复的处方类型是中药,检测并显示转诊提示 - if (prescriptionStore.activeCategory === 1) { - await checkAndShowTransferTip(); + contentLoading.value = true; + try { + // 先校验开方种类权限,再加载完整开方数据 + const allowed = await prescriptionStore.loadPrescriptionTypeOptions( + modalData.value.registerId, + ); + if (!allowed) { + message.error( + prescriptionStore.prescriptionTypeDenyMessage || + '当前门店未开通开方权限', + ); + modalApi.close(); + return; + } + await prescriptionStore.initializePrescription( + modalData.value.registerId, + true, + storagePrefix, + ); + prescriptionStore.loadFromLocalStorage(); + // 再拉一次类型,确保与门店一致并校正 Tab + await prescriptionStore.loadPrescriptionTypeOptions( + modalData.value.registerId, + ); + if (!prescriptionStore.prescriptionTypeAllowed) { + message.error( + prescriptionStore.prescriptionTypeDenyMessage || + '当前门店未开通开方权限', + ); + modalApi.close(); + return; + } + await prescriptionStore.fetchRegisterStoreInfo(); + if (prescriptionStore.activeCategory === 1) { + await checkAndShowTransferTip(); + } + } finally { + contentLoading.value = false; } } else { console.warn('未提供registerId'); @@ -934,6 +959,7 @@ const cancelSaveCommonPrescription = () => {