diff --git a/apps/web-antd/src/components/drug-search-select/drug-search-select.vue b/apps/web-antd/src/components/drug-search-select/drug-search-select.vue new file mode 100644 index 00000000..53e39816 --- /dev/null +++ b/apps/web-antd/src/components/drug-search-select/drug-search-select.vue @@ -0,0 +1,498 @@ + + + + + diff --git a/apps/web-antd/src/components/drug-search-select/index.ts b/apps/web-antd/src/components/drug-search-select/index.ts new file mode 100644 index 00000000..14751ae5 --- /dev/null +++ b/apps/web-antd/src/components/drug-search-select/index.ts @@ -0,0 +1,9 @@ +/** + * 药品搜索选择组件 + * + * @description 封装药品搜索下拉选择器,展示药品详细信息 + * @author 系统 + * @date 2024 + */ +export { default as DrugSearchSelect } from './drug-search-select.vue'; + diff --git a/apps/web-antd/src/store/prescription.ts b/apps/web-antd/src/store/prescription.ts index 6d21ec54..29c8b214 100644 --- a/apps/web-antd/src/store/prescription.ts +++ b/apps/web-antd/src/store/prescription.ts @@ -85,9 +85,11 @@ export const usePrescriptionStore = defineStore('prescription', () => { const selectedStoreId = ref(null); // 用户选择的诊所ID const sendMode = ref(0); // 0=默认(使用医生当前诊所),1=自定义(使用挂号诊所) - // 获取localStorage key(修改为在线复诊前缀) - const getStorageKey = () => - `onlineConsultation-prescriptionData${currentRegisterId.value}`; + // 获取localStorage key(按类型分开存储) + const getStorageKey = (category?: number) => { + const cat = category ?? activeCategory.value; + return `onlineConsultation-prescriptionData_${cat}_${currentRegisterId.value}`; + }; // 计算属性 const totalProductCost = computed(() => { @@ -201,6 +203,27 @@ export const usePrescriptionStore = defineStore('prescription', () => { // 设置当前注册ID currentRegisterId.value = registerId; + // 恢复之前保存的 activeCategory + const savedCategory = localStorage.getItem( + `onlineConsultation-activeCategory${registerId}` + ); + if (savedCategory) { + activeCategory.value = Number.parseInt(savedCategory); + } else { + // 检查哪个存储键有数据 + const chineseData = localStorage.getItem( + `onlineConsultation-prescriptionData_1_${registerId}` + ); + const westData = localStorage.getItem( + `onlineConsultation-prescriptionData_2_${registerId}` + ); + if (chineseData && JSON.parse(chineseData).length > 0) { + activeCategory.value = 1; + } else if (westData && JSON.parse(westData).length > 0) { + activeCategory.value = 2; + } + } + // 加载localStorage数据 loadFromLocalStorage(); @@ -228,6 +251,27 @@ export const usePrescriptionStore = defineStore('prescription', () => { // 设置当前注册ID currentRegisterId.value = registerId; + // 恢复之前保存的 activeCategory + const savedCategory = localStorage.getItem( + `onlineConsultation-activeCategory${registerId}` + ); + if (savedCategory) { + activeCategory.value = Number.parseInt(savedCategory); + } else { + // 检查哪个存储键有数据 + const chineseData = localStorage.getItem( + `onlineConsultation-prescriptionData_1_${registerId}` + ); + const westData = localStorage.getItem( + `onlineConsultation-prescriptionData_2_${registerId}` + ); + if (chineseData && JSON.parse(chineseData).length > 0) { + activeCategory.value = 1; + } else if (westData && JSON.parse(westData).length > 0) { + activeCategory.value = 2; + } + } + // 加载localStorage数据 loadFromLocalStorage(); @@ -458,6 +502,33 @@ export const usePrescriptionStore = defineStore('prescription', () => { } }; + // 切换药品用法编辑状态 + const toggleEditDrug = (index: number) => { + const newDrugs = [...currentDrugs.value]; + newDrugs[index].isEditing = !newDrugs[index].isEditing; + updateCurrentDrugs(newDrugs); + }; + + // 保存药品用法编辑 + const saveEditDrug = (index: number) => { + const newDrugs = [...currentDrugs.value]; + const drug = newDrugs[index]; + // 更新 ID 字段 + drug.type_id = drug.use_type?.id; + drug.frequency_id = drug.use_frequency?.id; + drug.time_id = drug.use_num?.id; + drug.unit_id = drug.unit?.id; + drug.isEditing = false; + updateCurrentDrugs(newDrugs); + }; + + // 更新药品用法字段 + const updateDrugUsage = (index: number, field: string, value: any) => { + const newDrugs = [...currentDrugs.value]; + newDrugs[index][field] = value; + updateCurrentDrugs(newDrugs); + }; + // 新药品操作 const selectNewDrugInfo = () => { const check = currentDrugs.value.find((v) => v.id === newDrugInfo.value.id); @@ -791,12 +862,26 @@ export const usePrescriptionStore = defineStore('prescription', () => { }; const changeCategory = (categoryValue: number) => { - activeCategory.value = categoryValue; - updateCurrentDrugs([]); + // 先保存当前类型的药品数据 + localStorage.setItem( + getStorageKey(activeCategory.value), + JSON.stringify(currentDrugs.value), + ); + + // 保存 Tab 类型 localStorage.setItem( `onlineConsultation-activeCategory${currentRegisterId.value}`, categoryValue.toString(), ); + activeCategory.value = categoryValue; + + // 加载新类型对应的药品数据 + const stored = localStorage.getItem(getStorageKey(categoryValue)); + if (stored) { + currentDrugs.value.splice(0, currentDrugs.value.length, ...JSON.parse(stored)); + } else { + currentDrugs.value.splice(0, currentDrugs.value.length); + } }; // 工具函数 @@ -875,6 +960,9 @@ export const usePrescriptionStore = defineStore('prescription', () => { updateDrugQuantity, increment, decrement, + toggleEditDrug, + saveEditDrug, + updateDrugUsage, selectNewDrugInfo, selectOldDrugInfo, setSelectChineseIndex, diff --git a/apps/web-antd/src/views/business/chat/api/index.ts b/apps/web-antd/src/views/business/chat/api/index.ts index 99c0035e..2f2d4e29 100644 --- a/apps/web-antd/src/views/business/chat/api/index.ts +++ b/apps/web-antd/src/views/business/chat/api/index.ts @@ -1,6 +1,8 @@ import { requestClient } from '#/api/request'; const prefix = 'chat-friends/'; +const commonPrescriptionPrefix = 'common-prescription/'; + /** * 获取当前登录的诊所信息 * @param data @@ -26,3 +28,143 @@ export async function getChatMessageRegisterInfoApi(data: any = {}) { // return requestClient.post(`${prefix}messages-by-room-id`, { params: data }); return requestClient.get(`${prefix}chat-register-info`, { params: data }); } + +// ==================== 常用方管理 API ==================== + +/** + * 常用方药品数据结构(西药/中成药) + * @description 西药药品的详细信息 + */ +export interface CommonPrescriptionWestDrug { + /** 药品ID */ + drug_id?: number; + /** 药品ID(兼容字段) */ + id?: number; + /** 药品名称 */ + drug_name: string; + /** 每次用量 */ + number?: number; + /** 购买数量 */ + select_number?: number; + /** 单价 */ + price?: number; + /** 使用时间ID */ + time_id?: number; + /** 使用类型ID */ + type_id?: number; + /** 使用频率ID */ + frequency_id?: number; + /** 单位ID */ + unit_id?: number; + /** 药品图片 */ + image?: string; + /** 说明书 */ + instruction?: string; + /** 使用时间信息 */ + use_num?: { name?: string }; + /** 使用类型信息 */ + use_type?: { name?: string }; + /** 使用频率信息 */ + use_frequency?: { name?: string }; + /** 单位信息 */ + unit?: { name?: string }; +} + +/** + * 常用方药品数据结构(中药/颗粒药) + * @description 中药/颗粒药药品的详细信息 + */ +export interface CommonPrescriptionChineseDrug { + /** 药品ID */ + drug_id?: number; + /** 药品ID(兼容字段) */ + id?: number; + /** 药品名称 */ + drug_name: string; + /** 克数/用量 */ + number?: number; + /** 单价 */ + price?: number; + /** 用法ID */ + way_id?: number; +} + +/** + * 保存西药常用方 + * @description 将当前处方保存为西药常用方模板,后端会自动创建 recipe 记录 + * @param data 常用方数据 + */ +export async function saveWestCommonPrescriptionApi(data: { + /** 常用方名称 */ + name: string; + /** 药品详细信息数组 */ + drugs: CommonPrescriptionWestDrug[]; + /** 诊所ID */ + store_id: number; + /** 临床诊断(可选) */ + clinical_diagnose?: string; + /** 医嘱(可选) */ + doctor_order?: string; + /** 类别 1-自费 2-医保(可选) */ + category?: string; +}) { + return requestClient.post(`${commonPrescriptionPrefix}save-west`, data); +} + +/** + * 保存中药常用方 + * @description 将当前处方保存为中药常用方模板,后端会自动创建 recipe 记录 + * @param data 常用方数据 + */ +export async function saveChineseCommonPrescriptionApi(data: { + /** 常用方名称 */ + name: string; + /** 药品详细信息数组 */ + drugs: CommonPrescriptionChineseDrug[]; + /** 诊所ID */ + store_id: number; + /** 临床诊断(可选) */ + clinical_diagnose?: string; + /** 医嘱(可选) */ + doctor_order?: string; + /** 类别 1-自费 2-医保(可选) */ + category?: string; + /** 剂量/天数(可选,默认7) */ + dosage?: number; + /** 每日次数(可选,默认2) */ + day_dosage?: number; +}) { + return requestClient.post( + `${commonPrescriptionPrefix}save-chinese`, + data, + ); +} + +/** + * 保存颗粒药常用方 + * @description 将当前处方保存为颗粒药常用方模板,后端会自动创建 recipe 记录 + * @param data 常用方数据 + */ +export async function saveGranularCommonPrescriptionApi(data: { + /** 常用方名称 */ + name: string; + /** 药品详细信息数组 */ + drugs: CommonPrescriptionChineseDrug[]; + /** 诊所ID */ + store_id: number; + /** 临床诊断(可选) */ + clinical_diagnose?: string; + /** 医嘱(可选) */ + doctor_order?: string; + /** 类别 1-自费 2-医保(可选) */ + category?: string; + /** 剂量/天数(可选,默认7) */ + dosage?: number; + /** 每日次数(可选,默认2) */ + day_dosage?: number; +}) { + return requestClient.post( + `${commonPrescriptionPrefix}save-granular`, + data, + ); +} 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 d296f4ec..67d2e88f 100644 --- a/apps/web-antd/src/views/business/chat/components/PrescriptionModal.vue +++ b/apps/web-antd/src/views/business/chat/components/PrescriptionModal.vue @@ -8,6 +8,7 @@ import { DownOutlined, MinusOutlined, PlusOutlined, + SaveOutlined, UpOutlined, } from '@ant-design/icons-vue'; import { @@ -18,6 +19,7 @@ import { Descriptions, Image, ImagePreviewGroup, + Input, InputNumber, message, RadioButton, @@ -31,6 +33,10 @@ import { TimelineItem, } from 'ant-design-vue'; +import { + saveChineseCommonPrescriptionApi, + saveWestCommonPrescriptionApi, +} from '#/views/business/chat/api'; import { usePrescriptionStore } from '#/store/prescription'; // import { getTraditionalChineseMedicineAllApi } from '#/views/doctor/doctor-reception/api'; // 导入子组件 @@ -38,6 +44,8 @@ import DiagnosisModal from '#/views/doctor/doctor-reception/components/Diagnosis import DoctorOrderModal from '#/views/doctor/doctor-reception/components/DoctorOrderModal.vue'; import PrescriptionDetail from '#/views/doctor/doctor-reception/components/PrescriptionDetail.vue'; import WesternModal from '#/views/doctor/doctor-reception/components/WesternModal.vue'; +// 常用方选择弹窗组件 +import CommonPrescriptionModal from '#/views/doctor/doctor-reception/components/CommonPrescriptionModal.vue'; import StoreConfirmModal from './StoreConfirmModal.vue'; const splitString = (input: string) => input.split(','); @@ -49,6 +57,14 @@ const previewImage = ref([]); const showNewDrugModal = ref(false); const doctorSecondSignModal = ref(false); +// ==================== 保存常用方相关状态 ==================== +/** 保存常用方弹窗是否显示 */ +const showSaveCommonPrescriptionModal = ref(false); +/** 常用方名称输入 */ +const commonPrescriptionName = ref(''); +/** 是否正在保存常用方 */ +const isSavingCommonPrescription = ref(false); + const categories = [ { label: '中药', value: 1 }, { label: '中成(西)药', value: 2 }, @@ -124,6 +140,11 @@ const [StoreConfirmModalComponent, storeConfirmModalApi] = useVbenModal({ connectedComponent: StoreConfirmModal, }); +// ==================== 常用方选择弹窗 ==================== +const [CommonPrescriptionModals, CommonPrescriptionModalApi] = useVbenModal({ + connectedComponent: CommonPrescriptionModal, +}); + const setVisible = (value: boolean, instruction = ''): void => { previewImage.value = []; if (instruction === '') { @@ -293,6 +314,204 @@ const filterOption = (input: string, option: any) => { option.code.includes(input) ); }; + +// ==================== 选择常用方相关方法 ==================== + +/** + * 打开常用方选择弹窗 + * @description 打开常用方弹窗,选择后自动填充药品到处方中 + */ +function openCommonPrescriptionModal() { + CommonPrescriptionModalApi.setData({ + type: prescriptionStore.activeCategory, + onSelect: handleSelectCommonPrescription, + }); + CommonPrescriptionModalApi.open(); +} + +/** + * 处理选择常用方 + * @param data 常用方数据,包含prescription和recipes + * @param type 类型:1-中药,2-西药,3-颗粒药 + * @description 选择常用方后,将药品列表填充到当前处方中 + */ +function handleSelectCommonPrescription(data: any, type: number) { + const { prescription, recipes } = data; + + // 根据类型处理不同的药品数据 + if (type === 2) { + // 西药(中成药)处方 + recipes.forEach((recipe: any) => { + const newProduct = { + index_id: recipe.drug_id || recipe.id, + id: recipe.drug_id || recipe.id, + drug_name: recipe.drug_name, + number: recipe.number || 1, + use_num: recipe.use_time, + use_type: recipe.use_type, + use_frequency: recipe.use_frequency, + unit: recipe.west_unit, + price: recipe.price || 0, + time_id: recipe.time_id, + type_id: recipe.type_id, + frequency_id: recipe.frequency_id, + unit_id: recipe.unit_id, + image: recipe.image, + instruction: recipe.instruction, + type: recipe.type, + select_number: recipe.select_number || 1, + }; + // 检查是否已存在 + const existItem = prescriptionStore.currentDrugs.find( + (item: any) => item.id === newProduct.id, + ); + if (!existItem) { + prescriptionStore.currentDrugs.push(newProduct); + } + }); + } else { + // 中药/颗粒药处方 + recipes.forEach((recipe: any) => { + const newProduct = { + index_id: recipe.drug_id || recipe.id, + id: recipe.drug_id || recipe.id, + drug_name: recipe.drug_name || recipe.name, + number: recipe.number || 1, + price: recipe.price || 0, + way_id: recipe.way_id || 0, + select_number: 1, + }; + // 检查是否已存在 + const existItem = prescriptionStore.currentDrugs.find( + (item: any) => item.id === newProduct.id, + ); + if (!existItem) { + prescriptionStore.currentDrugs.push(newProduct); + } + }); + } + + // 更新诊断和医嘱 + if (prescription.clinical_diagnose) { + prescriptionStore.diagnosis = prescription.clinical_diagnose; + } + if (prescription.doctor_order) { + prescriptionStore.medicalAdvice = prescription.doctor_order; + } + + // 保存到本地存储 + prescriptionStore.saveToLocalStorage(); + message.success('已选择常用方,药品已填充到处方中'); +} + +// ==================== 保存常用方相关方法 ==================== + +/** + * 打开保存常用方弹窗 + * @description 检查是否有药品可保存,然后打开弹窗 + */ +const openSaveCommonPrescriptionModal = () => { + // 检查是否有药品 + if (prescriptionStore.currentDrugs.length === 0) { + message.warning('请先添加药品后再保存为常用方'); + return; + } + // 清空输入框 + commonPrescriptionName.value = ''; + // 打开弹窗 + showSaveCommonPrescriptionModal.value = true; +}; + +/** + * 保存当前处方为常用方 + * @description 根据当前药品类型(中药/西药)调用不同的保存接口 + * 后端会自动根据药品详细信息创建 recipe 记录 + */ +const saveAsCommonPrescription = async () => { + // 验证名称 + if (!commonPrescriptionName.value.trim()) { + message.warning('请输入常用方名称'); + return; + } + + // 验证是否有药品 + if (prescriptionStore.currentDrugs.length === 0) { + message.warning('没有可保存的药品'); + return; + } + + isSavingCommonPrescription.value = true; + + try { + // 根据处方类型选择不同的保存接口 + if (prescriptionStore.activeCategory === 1) { + // 中药处方 - 构建药品详细信息数组 + const drugs = prescriptionStore.currentDrugs.map((drug) => ({ + drug_id: drug.id, + drug_name: drug.drug_name, + number: drug.number || 1, + price: drug.price || 0, + way_id: drug.way_id || 0, + })); + + await saveChineseCommonPrescriptionApi({ + name: commonPrescriptionName.value.trim(), + drugs, + store_id: prescriptionStore.myStoreId, + clinical_diagnose: prescriptionStore.diagnosis || '', + doctor_order: prescriptionStore.medicalAdvice || '', + category: String(prescriptionStore.category), + dosage: prescriptionStore.dosage || 7, + day_dosage: prescriptionStore.dayDosage || 2, + }); + } else { + // 西药(中成药)处方 - 构建药品详细信息数组 + const drugs = prescriptionStore.currentDrugs.map((drug) => ({ + drug_id: drug.id, + drug_name: drug.drug_name, + number: drug.number || 1, + select_number: drug.select_number || 1, + price: drug.price || 0, + time_id: drug.time_id || 0, + type_id: drug.type_id || 0, + frequency_id: drug.frequency_id || 0, + unit_id: drug.unit_id || 0, + image: drug.image || '', + instruction: drug.instruction || '', + use_num: drug.use_num, + use_type: drug.use_type, + use_frequency: drug.use_frequency, + unit: drug.unit, + })); + + await saveWestCommonPrescriptionApi({ + name: commonPrescriptionName.value.trim(), + drugs, + store_id: prescriptionStore.myStoreId, + clinical_diagnose: prescriptionStore.diagnosis || '', + doctor_order: prescriptionStore.medicalAdvice || '', + category: String(prescriptionStore.category), + }); + } + + message.success('常用方保存成功'); + showSaveCommonPrescriptionModal.value = false; + commonPrescriptionName.value = ''; + } catch (error) { + console.error('保存常用方失败:', error); + message.error('保存常用方失败,请稍后重试'); + } finally { + isSavingCommonPrescription.value = false; + } +}; + +/** + * 取消保存常用方 + */ +const cancelSaveCommonPrescription = () => { + showSaveCommonPrescriptionModal.value = false; + commonPrescriptionName.value = ''; +}; diff --git a/apps/web-antd/src/views/doctor/doctor-reception/api/index.ts b/apps/web-antd/src/views/doctor/doctor-reception/api/index.ts index 3051e45b..5f19a1bd 100644 --- a/apps/web-antd/src/views/doctor/doctor-reception/api/index.ts +++ b/apps/web-antd/src/views/doctor/doctor-reception/api/index.ts @@ -143,3 +143,188 @@ export async function getTraditionalChineseMedicineAllApi() { `${prefix}get-traditional-chinese-medicine-all`, ); } + +// ==================== 常用方管理 API ==================== + +const commonPrescriptionPrefix = 'common-prescription/'; + +/** + * 常用方列表响应数据结构 + * @description 包含西药、中药、颗粒药三种类型的常用方 + */ +export interface CommonPrescriptionData { + /** 西药常用方列表 */ + west_prescription: any[]; + /** 西药详细药品信息 */ + west: any[][]; + /** 中药常用方列表 */ + chin_prescription: any[]; + /** 中药详细药品信息 */ + chinese: any[][]; + /** 颗粒药常用方列表 */ + granular_prescription: any[]; + /** 颗粒药详细药品信息 */ + granular: any[][]; +} + +/** + * 获取常用方列表 + * @description 获取当前医生的所有常用方(西药/中药/颗粒药) + * @param storeId 诊所ID(可选) + */ +export async function getCommonPrescriptionListApi(storeId?: number) { + return requestClient.get( + `${commonPrescriptionPrefix}list`, + { params: { store_id: storeId } }, + ); +} + +/** + * 获取常用方详情 + * @description 根据ID和类型获取常用方的详细信息 + * @param id 常用方ID + * @param type 类型:west-西药,chinese-中药,granular-颗粒药 + */ +export async function getCommonPrescriptionDetailApi( + id: number, + type: string, +) { + return requestClient.get(`${commonPrescriptionPrefix}detail`, { + params: { id, type }, + }); +} + +/** + * 常用方药品数据结构(西药/中成药) + * @description 西药药品的详细信息 + */ +export interface CommonPrescriptionWestDrug { + /** 药品ID */ + drug_id?: number; + /** 药品ID(兼容字段) */ + id?: number; + /** 药品名称 */ + drug_name: string; + /** 每次用量 */ + number?: number; + /** 购买数量 */ + select_number?: number; + /** 单价 */ + price?: number; + /** 使用时间ID */ + time_id?: number; + /** 使用类型ID */ + type_id?: number; + /** 使用频率ID */ + frequency_id?: number; + /** 单位ID */ + unit_id?: number; + /** 药品图片 */ + image?: string; + /** 说明书 */ + instruction?: string; + /** 使用时间信息 */ + use_num?: { name?: string }; + /** 使用类型信息 */ + use_type?: { name?: string }; + /** 使用频率信息 */ + use_frequency?: { name?: string }; + /** 单位信息 */ + unit?: { name?: string }; +} + +/** + * 常用方药品数据结构(中药/颗粒药) + * @description 中药/颗粒药药品的详细信息 + */ +export interface CommonPrescriptionChineseDrug { + /** 药品ID */ + drug_id?: number; + /** 药品ID(兼容字段) */ + id?: number; + /** 药品名称 */ + drug_name: string; + /** 克数/用量 */ + number?: number; + /** 单价 */ + price?: number; + /** 用法ID */ + way_id?: number; +} + +/** + * 保存西药常用方 + * @description 将当前处方保存为西药常用方模板,后端会自动创建 recipe 记录 + */ +export async function saveWestCommonPrescriptionApi(data: { + /** 常用方名称 */ + name: string; + /** 药品详细信息数组 */ + drugs: CommonPrescriptionWestDrug[]; + /** 诊所ID */ + store_id: number; + /** 临床诊断(可选) */ + clinical_diagnose?: string; + /** 医嘱(可选) */ + doctor_order?: string; + /** 类别 1-自费 2-医保(可选) */ + category?: string; +}) { + return requestClient.post(`${commonPrescriptionPrefix}save-west`, data); +} + +/** + * 保存中药常用方 + * @description 将当前处方保存为中药常用方模板,后端会自动创建 recipe 记录 + */ +export async function saveChineseCommonPrescriptionApi(data: { + /** 常用方名称 */ + name: string; + /** 药品详细信息数组 */ + drugs: CommonPrescriptionChineseDrug[]; + /** 诊所ID */ + store_id: number; + /** 临床诊断(可选) */ + clinical_diagnose?: string; + /** 医嘱(可选) */ + doctor_order?: string; + /** 类别 1-自费 2-医保(可选) */ + category?: string; + /** 剂量/天数(可选,默认7) */ + dosage?: number; + /** 每日次数(可选,默认2) */ + day_dosage?: number; +}) { + return requestClient.post( + `${commonPrescriptionPrefix}save-chinese`, + data, + ); +} + +/** + * 保存颗粒药常用方 + * @description 将当前处方保存为颗粒药常用方模板,后端会自动创建 recipe 记录 + */ +export async function saveGranularCommonPrescriptionApi(data: { + /** 常用方名称 */ + name: string; + /** 药品详细信息数组 */ + drugs: CommonPrescriptionChineseDrug[]; + /** 诊所ID */ + store_id: number; + /** 临床诊断(可选) */ + clinical_diagnose?: string; + /** 医嘱(可选) */ + doctor_order?: string; + /** 类别 1-自费 2-医保(可选) */ + category?: string; + /** 剂量/天数(可选,默认7) */ + dosage?: number; + /** 每日次数(可选,默认2) */ + day_dosage?: number; +}) { + return requestClient.post( + `${commonPrescriptionPrefix}save-granular`, + data, + ); +} diff --git a/apps/web-antd/src/views/doctor/doctor-reception/components/CommonPrescriptionModal.vue b/apps/web-antd/src/views/doctor/doctor-reception/components/CommonPrescriptionModal.vue new file mode 100644 index 00000000..add67cb5 --- /dev/null +++ b/apps/web-antd/src/views/doctor/doctor-reception/components/CommonPrescriptionModal.vue @@ -0,0 +1,347 @@ + + + + + + diff --git a/apps/web-antd/src/views/doctor/doctor-reception/index.vue b/apps/web-antd/src/views/doctor/doctor-reception/index.vue index c8225b67..43fbfecf 100644 --- a/apps/web-antd/src/views/doctor/doctor-reception/index.vue +++ b/apps/web-antd/src/views/doctor/doctor-reception/index.vue @@ -52,6 +52,8 @@ import PrescriptionDetail from './components/PrescriptionDetail.vue'; import WesternModal from './components/WesternModal.vue'; import RefusalOfTreatmentModal from "#/views/doctor/doctor-reception/components/RefusalOfTreatmentModal.vue"; +// 常用方选择弹窗组件 +import CommonPrescriptionModal from './components/CommonPrescriptionModal.vue'; interface Patient { id: number; @@ -320,6 +322,23 @@ const selectPatient = (patient: Patient, isUpdateTabType = true) => { } } activePatient.value = patient.user_patient; + + // 恢复之前保存的 activeCategory + const savedCategory = localStorage.getItem(`activeCategory${patient.user_patient?.id}`); + if (savedCategory) { + activeCategory.value = Number.parseInt(savedCategory); + } else { + // 如果没有保存的值,检查两个存储键哪个有数据 + const chineseData = localStorage.getItem(`prescriptionData_1_${patient.user_patient?.id}`); + const westData = localStorage.getItem(`prescriptionData_2_${patient.user_patient?.id}`); + if (chineseData && JSON.parse(chineseData).length > 0) { + activeCategory.value = 1; + } else if (westData && JSON.parse(westData).length > 0) { + activeCategory.value = 2; + } + // 否则保持默认值 + } + getPatientItem(patient.id).then((value) => { patientInfo.value = value; userPatientHealthInquiry.value = value.user_patient_health_inquiry; @@ -348,10 +367,41 @@ const decrement = (index: number) => { } }; -// 保存到本地存储 +// 切换药品用法编辑状态 +const toggleEditDrug = (index: number) => { + currentDrugs.value[index].isEditing = !currentDrugs.value[index].isEditing; +}; + +// 保存药品用法编辑 +const saveEditDrug = (index: number) => { + const drug = currentDrugs.value[index]; + // 更新 ID 字段 + drug.type_id = drug.use_type?.id; + drug.frequency_id = drug.use_frequency?.id; + drug.time_id = drug.use_num?.id; + drug.unit_id = drug.unit?.id; + drug.isEditing = false; + updateLocalStorage(); +}; + +// 更新药品用法字段 +const updateDrugUsage = (index: number, field: string, value: any) => { + currentDrugs.value[index][field] = value; +}; + +/** + * 获取药品数据的存储key(按类型分开存储) + * @param patientId 患者ID + * @param category 类型:1-中药,2-西药 + */ +const getStorageKey = (patientId: number | string | undefined, category: number) => { + return `prescriptionData_${category}_${patientId}`; +}; + +// 保存到本地存储(按类型分开存储) const saveToLocalStorage = () => { localStorage.setItem( - `prescriptionData${activePatient.value?.id}`, + getStorageKey(activePatient.value?.id, activeCategory.value), JSON.stringify(currentDrugs.value), ); }; @@ -364,11 +414,11 @@ const removeDrug = (index: number) => { updateLocalStorage(); }; /** - * 修改缓存的处方信息 + * 修改缓存的处方信息(按类型分开存储) */ const updateLocalStorage = () => { localStorage.setItem( - `prescriptionData${activePatient.value?.id}`, + getStorageKey(activePatient.value?.id, activeCategory.value), JSON.stringify(currentDrugs.value), ); getCurrentDrugs(); @@ -376,11 +426,11 @@ const updateLocalStorage = () => { const currentDrugs = ref([]); /** - * 获取缓存的处方信息 + * 获取缓存的处方信息(按类型分开存储) */ const getCurrentDrugs = () => { currentDrugs.value = JSON.parse( - localStorage.getItem(`prescriptionData${activePatient.value?.id}`) || '[]', + localStorage.getItem(getStorageKey(activePatient.value?.id, activeCategory.value)) || '[]', ); }; getCurrentDrugs(); @@ -606,6 +656,98 @@ const [PrescriptionDetailModal, PrescriptionDetailModalApi] = useVbenModal({ const [RefusalOfTreatmentModals, RefusalOfTreatmentModalApi] = useVbenModal({ connectedComponent: RefusalOfTreatmentModal, }); + +// ==================== 常用方弹窗 ==================== +const [CommonPrescriptionModals, CommonPrescriptionModalApi] = useVbenModal({ + connectedComponent: CommonPrescriptionModal, +}); + +/** + * 打开常用方选择弹窗 + * @description 打开常用方弹窗,选择后自动填充药品到处方中 + */ +function openCommonPrescriptionModal() { + CommonPrescriptionModalApi.setData({ + type: activeCategory.value, + onSelect: handleSelectCommonPrescription, + }); + CommonPrescriptionModalApi.open(); +} + +/** + * 处理选择常用方 + * @param data 常用方数据,包含prescription和recipes + * @param type 类型:1-西药,2-中药,3-颗粒药 + * @description 选择常用方后,将药品列表填充到当前处方中 + */ +function handleSelectCommonPrescription(data: any, type: number) { + const { prescription, recipes } = data; + + // 根据类型处理不同的药品数据 + if (type === 1) { + // 西药处方 + recipes.forEach((recipe: any) => { + const newProduct = { + index_id: recipe.id, + id: recipe.id, + drug_name: recipe.drug_name, + number: recipe.number || 1, + use_num: recipe.use_time, + use_type: recipe.use_type, + use_frequency: recipe.use_frequency, + unit: recipe.west_unit, + price: recipe.price || 0, + time_id: recipe.time_id, + type_id: recipe.type_id, + frequency_id: recipe.frequency_id, + unit_id: recipe.unit_id, + image: recipe.image, + instruction: recipe.instruction, + type: recipe.type, + select_number: 1, + }; + // 检查是否已存在 + const existItem = currentDrugs.value.find( + (item) => item.id === recipe.id, + ); + if (!existItem) { + currentDrugs.value.push(newProduct); + } + }); + } else { + // 中药/颗粒药处方 - 使用 drug_id 作为唯一标识 + recipes.forEach((recipe: any) => { + const drugId = recipe.drug_id || recipe.id; + const newProduct = { + index_id: drugId, + id: drugId, + drug_name: recipe.drug_name || recipe.name, + number: recipe.number || 1, + price: recipe.price || 0, + way_id: recipe.way_id || 0, + select_number: 1, + }; + // 检查是否已存在 - 使用 drug_id 比对 + const existItem = currentDrugs.value.find( + (item) => item.id === drugId, + ); + if (!existItem) { + currentDrugs.value.push(newProduct); + } + }); + } + + // 更新诊断和医嘱 + if (prescription.clinical_diagnose) { + diagnosis.value = prescription.clinical_diagnose; + } + if (prescription.doctor_order) { + medicalAdvice.value = prescription.doctor_order; + } + + // 保存到本地存储 + updateLocalStorage(); +} const openWesternModal = () => { // 打开西药处方模态框逻辑 WesternDrugModalApi.setData({ @@ -632,14 +774,28 @@ function splitString(str: string) { } /** - * 切换tab - * @param id + * 切换tab(中药/西药切换) + * @param id 类型:1-中药,2-西药 + * @description 切换Tab时: + * 1. 先保存当前Tab的药品数据 + * 2. 更新activeCategory + * 3. 加载新Tab对应的药品数据 */ function tabChange(id) { + // 先保存当前Tab的药品数据 + localStorage.setItem( + getStorageKey(activePatient.value?.id, activeCategory.value), + JSON.stringify(currentDrugs.value), + ); + + // 更新Tab类型 localStorage.setItem(`activeCategory${activePatient.value?.id}`, id); - currentDrugs.value = []; - updateLocalStorage(); activeCategory.value = id; + + // 加载新Tab对应的药品数据 + currentDrugs.value = JSON.parse( + localStorage.getItem(getStorageKey(activePatient.value?.id, id)) || '[]', + ); } /** @@ -887,7 +1043,7 @@ const selectChineseId = ref(0); */ function selectOldDrugInfo(id) { const check = JSON.parse( - localStorage.getItem(`prescriptionData${activePatient.value?.id}`) || '[]', + localStorage.getItem(getStorageKey(activePatient.value?.id, activeCategory.value)) || '[]', ).find((v) => v.id === id); if (check) { currentDrugs.value[selectChineseIndex.value].id = selectChineseId.value; @@ -1392,9 +1548,17 @@ watch( > 添加商品 + + 自费 医保 @@ -1750,11 +1914,62 @@ watch(

药品名称:{{ drug.drug_name }}

-

+ +

用法:{{ `${drug.use_type?.name},${drug.use_frequency?.name},${drug.use_num?.name},每次${drug.number}${drug.unit?.name}` }}

+
+ 用法: + + + + 每次 + + +
@@ -1774,6 +1989,17 @@ watch(
{{ drug.price }}
+ + +