Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Close stale issues / stale (push) Has been cancelled
1047 lines
31 KiB
TypeScript
1047 lines
31 KiB
TypeScript
import { computed, nextTick, ref } from 'vue';
|
||
|
||
import { message, notification } from 'ant-design-vue';
|
||
import { debounce } from 'lodash-es';
|
||
import { defineStore } from 'pinia';
|
||
|
||
import { useChatStore } from '#/views/business/chat/stores/chat';
|
||
import { useUserStore } from '#/views/business/chat/stores/user';
|
||
import { sendMessage } from '#/views/business/chat/utils/request';
|
||
import {
|
||
addWestPrescription,
|
||
checkChineseMedicineConflictApi,
|
||
getDrugUseList,
|
||
getMyStoreListApi,
|
||
getPatientItem,
|
||
getProcessRuleList,
|
||
getProductListDoctorReception,
|
||
} from '#/views/doctor/doctor-reception/api';
|
||
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';
|
||
|
||
export const usePrescriptionStore = defineStore('prescription', () => {
|
||
// 基础数据
|
||
const patientInfo = ref<any | null>(null);
|
||
const userPatientHealthInquiry = ref<any | null>(null);
|
||
const prescriptionList = ref([]);
|
||
const currentRegisterId = ref<number | string>('');
|
||
const activePatient = ref<any | null>(null);
|
||
|
||
const userStore = useUserStore();
|
||
const chatStore = useChatStore();
|
||
|
||
// 药品使用相关数据
|
||
const drugUseNum = ref([]);
|
||
const drugUseFrequency = ref([]);
|
||
const drugUseType = ref([]);
|
||
const drugUnit = ref([]);
|
||
const drugTime = ref([]);
|
||
const drugUseWay = ref([]);
|
||
const myStoreList = ref([]);
|
||
|
||
// 处方状态
|
||
const myStoreId = ref(0);
|
||
const activeCategory = ref(2);
|
||
const diagnosis = ref('');
|
||
const medicalAdvice = ref('');
|
||
const treatmentPrice = ref(0);
|
||
const ruleType = ref(1);
|
||
const drugList = ref([]);
|
||
const currentDrugs = ref([]);
|
||
const category = ref(1);
|
||
const selectProductId = ref(0);
|
||
|
||
// 中药相关配置
|
||
const processRuleList = ref([]);
|
||
const childProcessRuleList = ref([]);
|
||
const processRuleNoteList = ref([]);
|
||
const processRuleId = ref();
|
||
const processRuleNoteId = ref();
|
||
const childProcessRuleId = ref();
|
||
const packageMethodId = ref(2);
|
||
const dosage = ref(7);
|
||
const dayDosage = ref(2);
|
||
|
||
// 新药品相关
|
||
const newDrugInfo = ref<any>({});
|
||
const selectChineseIndex = ref(-1);
|
||
const selectChineseId = ref(0);
|
||
|
||
// 二次签名相关
|
||
const doctorSecondSign = ref(0);
|
||
const checkData = ref<any>({});
|
||
|
||
// 初始化状态标记
|
||
const isInitialized = ref(false);
|
||
const isPatientInfoLoaded = ref(false);
|
||
|
||
const traditionalChineseMedicine = ref(traditionalJson);
|
||
const diseasesSelected = ref();
|
||
const methodSelected = ref();
|
||
const syndromeSelected = ref();
|
||
|
||
// 诊所选择相关状态
|
||
const registerStoreInfo = ref<any>(null); // 挂号诊所信息
|
||
const selectedStoreId = ref<number | null>(null); // 用户选择的诊所ID
|
||
const sendMode = ref(0); // 0=默认(使用医生当前诊所),1=自定义(使用挂号诊所)
|
||
|
||
// 存储前缀(用于区分在线复诊-药店和在线复诊-诊所)
|
||
const storagePrefix = ref('onlineConsultation-'); // 默认前缀
|
||
|
||
// 获取localStorage key(按类型分开存储)
|
||
const getStorageKey = (category?: number) => {
|
||
const cat = category ?? activeCategory.value;
|
||
return `${storagePrefix.value}prescriptionData_${cat}_${currentRegisterId.value}`;
|
||
};
|
||
|
||
// 计算属性
|
||
const totalProductCost = computed(() => {
|
||
if (currentDrugs.value.length === 0) {
|
||
return 0;
|
||
}
|
||
if (activeCategory.value === 1) {
|
||
return currentDrugs.value.reduce(
|
||
(sum, drug) => sum + drug.price * (drug.number || 1) * dosage.value,
|
||
0,
|
||
);
|
||
}
|
||
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;
|
||
|
||
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 totalCost = computed(() => {
|
||
return totalProductCost.value + processingFee.value;
|
||
});
|
||
|
||
// localStorage同步方法
|
||
const syncToLocalStorage = () => {
|
||
try {
|
||
const storageKey = getStorageKey();
|
||
localStorage.setItem(storageKey, JSON.stringify(currentDrugs.value));
|
||
console.log('已同步到localStorage:', storageKey, currentDrugs.value);
|
||
} catch (error) {
|
||
console.error('保存到localStorage失败:', error);
|
||
}
|
||
};
|
||
|
||
const loadFromLocalStorage = () => {
|
||
try {
|
||
const storageKey = getStorageKey();
|
||
const stored = localStorage.getItem(storageKey);
|
||
console.log('从localStorage加载:', storageKey, stored);
|
||
|
||
if (stored) {
|
||
const parsedData = JSON.parse(stored);
|
||
currentDrugs.value.splice(0, currentDrugs.value.length, ...parsedData);
|
||
} else {
|
||
currentDrugs.value.splice(0, currentDrugs.value.length);
|
||
}
|
||
} catch (error) {
|
||
console.error('从localStorage加载失败:', error);
|
||
currentDrugs.value.splice(0, currentDrugs.value.length);
|
||
}
|
||
};
|
||
|
||
// 更新currentDrugs并同步到localStorage
|
||
const updateCurrentDrugs = (newDrugs: any[]) => {
|
||
currentDrugs.value.splice(0, currentDrugs.value.length, ...newDrugs);
|
||
// 更新总价
|
||
syncToLocalStorage();
|
||
};
|
||
|
||
// 基础数据初始化(不包含患者信息)
|
||
const initializeBasicData = async () => {
|
||
if (isInitialized.value) {
|
||
console.log('基础数据已初始化,跳过重复请求');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
await Promise.all([
|
||
getMyStoreList(),
|
||
getDrugUseListData(),
|
||
getProcessRuleListData(),
|
||
]);
|
||
isInitialized.value = true;
|
||
console.log('基础数据初始化完成');
|
||
} catch (error) {
|
||
console.error('基础数据初始化失败:', error);
|
||
}
|
||
};
|
||
|
||
// 完整初始化(包含患者信息,仅用于 PrescriptionModal)
|
||
const initializePrescription = async (
|
||
registerId: number | string,
|
||
shouldFetchPatientInfo: boolean = false,
|
||
prefix: string = 'onlineConsultation-'
|
||
) => {
|
||
// 设置存储前缀
|
||
storagePrefix.value = prefix;
|
||
|
||
// 设置当前注册ID
|
||
currentRegisterId.value = registerId;
|
||
|
||
// 恢复之前保存的 activeCategory
|
||
const savedCategory = localStorage.getItem(
|
||
`${storagePrefix.value}activeCategory${registerId}`
|
||
);
|
||
if (savedCategory) {
|
||
activeCategory.value = Number.parseInt(savedCategory);
|
||
} else {
|
||
// 检查哪个存储键有数据
|
||
const chineseData = localStorage.getItem(
|
||
`${storagePrefix.value}prescriptionData_1_${registerId}`
|
||
);
|
||
const westData = localStorage.getItem(
|
||
`${storagePrefix.value}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();
|
||
|
||
// 如果基础数据未初始化,先初始化基础数据
|
||
if (!isInitialized.value) {
|
||
await initializeBasicData();
|
||
}
|
||
|
||
// 获取患者信息(只在需要时调用,如 PrescriptionModal)
|
||
if (shouldFetchPatientInfo) {
|
||
if (
|
||
!isPatientInfoLoaded.value ||
|
||
patientInfo.value?.register_id !== registerId
|
||
) {
|
||
await getPatientInfo();
|
||
isPatientInfoLoaded.value = true;
|
||
}
|
||
}
|
||
};
|
||
|
||
// 轻量级初始化(仅用于 WesternModal 等子组件)
|
||
const initializeForModal = async (registerId: number | string, prefix: string = 'onlineConsultation-') => {
|
||
console.log('轻量级初始化,registerId:', registerId);
|
||
|
||
// 设置存储前缀
|
||
storagePrefix.value = prefix;
|
||
|
||
// 设置当前注册ID
|
||
currentRegisterId.value = registerId;
|
||
|
||
// 恢复之前保存的 activeCategory
|
||
const savedCategory = localStorage.getItem(
|
||
`${storagePrefix.value}activeCategory${registerId}`
|
||
);
|
||
if (savedCategory) {
|
||
activeCategory.value = Number.parseInt(savedCategory);
|
||
} else {
|
||
// 检查哪个存储键有数据
|
||
const chineseData = localStorage.getItem(
|
||
`${storagePrefix.value}prescriptionData_1_${registerId}`
|
||
);
|
||
const westData = localStorage.getItem(
|
||
`${storagePrefix.value}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();
|
||
|
||
// 如果基础数据未初始化,先初始化基础数据
|
||
if (!isInitialized.value) {
|
||
await initializeBasicData();
|
||
}
|
||
};
|
||
|
||
const getMyStoreList = async () => {
|
||
try {
|
||
const res = await getMyStoreListApi();
|
||
myStoreList.value = res;
|
||
if (res.length > 0) {
|
||
myStoreId.value = res[0].id;
|
||
}
|
||
console.log('获取诊所列表成功');
|
||
} catch (error) {
|
||
console.error('获取诊所列表失败:', error);
|
||
}
|
||
};
|
||
|
||
const getDrugUseListData = async () => {
|
||
try {
|
||
const res = await getDrugUseList();
|
||
drugUseNum.value = res.drug_use_num;
|
||
drugUseFrequency.value = res.drug_use_frequency;
|
||
drugUseType.value = res.drug_use_type;
|
||
drugUnit.value = res.drug_unit;
|
||
drugTime.value = res.drug_time;
|
||
drugUseWay.value = res.drug_use_way;
|
||
console.log('获取药品使用列表成功');
|
||
} catch (error) {
|
||
console.error('获取药品使用列表失败:', error);
|
||
}
|
||
};
|
||
|
||
const getProcessRuleListData = async (pid = 0, ruleId = 0) => {
|
||
try {
|
||
const data = ruleId === 0 ? { pid } : { rule_id: ruleId };
|
||
const res = await getProcessRuleList(data);
|
||
|
||
if (ruleId !== 0) {
|
||
processRuleNoteList.value = res;
|
||
} else if (pid === 0) {
|
||
processRuleList.value = res;
|
||
} else {
|
||
childProcessRuleList.value = res;
|
||
}
|
||
console.log('获取加工规则成功');
|
||
} catch (error) {
|
||
console.error('获取加工规则失败:', error);
|
||
}
|
||
};
|
||
|
||
const getPatientInfo = async () => {
|
||
try {
|
||
console.log('开始获取患者信息,registerId:', currentRegisterId.value);
|
||
const res = await getPatientItem(currentRegisterId.value);
|
||
patientInfo.value = res;
|
||
activePatient.value = res.user_patient;
|
||
userPatientHealthInquiry.value = res.user_patient_health_inquiry;
|
||
prescriptionList.value = res.prescription;
|
||
console.log('获取患者信息成功:', activePatient.value);
|
||
} catch (error) {
|
||
console.error('获取患者信息失败:', error);
|
||
}
|
||
};
|
||
|
||
// 获取挂号诊所信息(同时包含当前诊所信息)
|
||
const fetchRegisterStoreInfo = async () => {
|
||
if (!currentRegisterId.value) {
|
||
console.warn('currentRegisterId为空,无法获取挂号诊所信息');
|
||
return;
|
||
}
|
||
try {
|
||
// 根据storagePrefix判断使用哪个API
|
||
const getRegisterStoreInfoFn = storagePrefix.value === 'onlineConsultationClinic-'
|
||
? getRegisterStoreInfoClinic
|
||
: getRegisterStoreInfoPharmacy;
|
||
|
||
const res = await getRegisterStoreInfoFn(Number(currentRegisterId.value));
|
||
registerStoreInfo.value = res;
|
||
|
||
// 如果是转诊挂号,自动使用承接方诊所ID(转接方开处方时)
|
||
if (res && res.is_from_transfer === 1 && res.delegate_store_id) {
|
||
// 转接方开处方时,自动设置store_id为承接方诊所ID
|
||
selectedStoreId.value = res.delegate_store_id;
|
||
sendMode.value = 1; // 使用自定义模式,但使用承接方诊所ID
|
||
} else if (res && res.store_id) {
|
||
// 非转诊挂号,默认选择挂号诊所
|
||
selectedStoreId.value = res.store_id;
|
||
// 如果挂号诊所与医生当前诊所不同,设置为自定义模式
|
||
if (res.can_change) {
|
||
sendMode.value = 1;
|
||
} else {
|
||
sendMode.value = 0;
|
||
}
|
||
}
|
||
console.log('获取挂号诊所信息成功:', res);
|
||
} catch (error) {
|
||
console.error('获取挂号诊所信息失败:', error);
|
||
}
|
||
};
|
||
|
||
// 切换诊所选择
|
||
const toggleStoreSelection = (useRegisterStore: boolean) => {
|
||
if (useRegisterStore && registerStoreInfo.value?.store_id) {
|
||
selectedStoreId.value = registerStoreInfo.value.store_id;
|
||
sendMode.value = 1;
|
||
} else {
|
||
selectedStoreId.value = null;
|
||
sendMode.value = 0;
|
||
}
|
||
};
|
||
|
||
// 计算当前诊所名称(医生所属诊所,优先使用后端返回的数据)
|
||
const currentStoreName = computed(() => {
|
||
// 优先使用后端返回的当前诊所名称
|
||
if (registerStoreInfo.value?.current_store_name) {
|
||
return registerStoreInfo.value.current_store_name;
|
||
}
|
||
// 回退到本地诊所列表
|
||
const currentStore = myStoreList.value.find((s: any) => s.id === myStoreId.value);
|
||
return currentStore?.name || '当前诊所';
|
||
});
|
||
|
||
// 计算目标诊所名称(根据发送模式决定)
|
||
const targetStoreName = computed(() => {
|
||
if (sendMode.value === 1 && registerStoreInfo.value?.store_name) {
|
||
return registerStoreInfo.value.store_name;
|
||
}
|
||
// 默认使用医生当前诊所
|
||
return currentStoreName.value;
|
||
});
|
||
|
||
// 是否可以更改诊所(转诊挂号时不允许更改,使用承接方诊所ID)
|
||
const canChangeStore = computed(() => {
|
||
// 如果是转诊挂号,不允许更改诊所(自动使用承接方诊所ID)
|
||
if (registerStoreInfo.value?.is_from_transfer === 1) {
|
||
return false;
|
||
}
|
||
// 非转诊挂号,使用后端返回的 can_change 字段
|
||
return registerStoreInfo.value?.can_change === true;
|
||
});
|
||
|
||
// 药品搜索
|
||
const getDrugList = debounce(async (searchText = '') => {
|
||
if (searchText === '' && activeCategory.value === 1) {
|
||
drugList.value = [];
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const res = await getProductListDoctorReception({
|
||
store_id: myStoreId.value,
|
||
type: activeCategory.value,
|
||
name: searchText,
|
||
});
|
||
|
||
drugList.value = res.map((item) => {
|
||
const matched = currentDrugs.value.find((v) => v.index_id === item.id);
|
||
return {
|
||
...item,
|
||
select_number: matched?.select_number || 0,
|
||
drug: {
|
||
...item.drug,
|
||
number: matched?.number || 1,
|
||
},
|
||
};
|
||
});
|
||
} catch (error) {
|
||
console.error('获取药品列表失败:', error);
|
||
message.error('获取药品列表失败');
|
||
}
|
||
}, 300);
|
||
|
||
// 药品操作
|
||
const addProducts = (data: any) => {
|
||
const existItem = currentDrugs.value.find(
|
||
(item) => item.index_id === data.id,
|
||
);
|
||
if (existItem) {
|
||
message.warn('已经存在了');
|
||
return false;
|
||
}
|
||
|
||
const newProduct = {
|
||
index_id: data.id,
|
||
id: data.drug.id,
|
||
drug_name: data.drug.drug_name,
|
||
number: data.drug.number,
|
||
use_num: drugTime.value.find((item) => item.id === data.drug.time_id),
|
||
use_type: drugUseType.value.find((item) => item.id === data.drug.type_id),
|
||
use_frequency: drugUseFrequency.value.find(
|
||
(item) => item.id === data.drug.frequency_id,
|
||
),
|
||
unit: drugUnit.value.find((item) => item.id === data.drug.unit_id),
|
||
price: data.price,
|
||
way_id: data.drug?.way_id,
|
||
use_ways: drugUseWay.value.find((item) => item.id === data.drug.way_id),
|
||
time_id: data.drug.time_id,
|
||
type_id: data.drug.type_id,
|
||
frequency_id: data.drug.frequency_id,
|
||
unit_id: data.drug.unit_id,
|
||
image: data.drug.image,
|
||
instruction: data.drug.instruction,
|
||
type: data.drug.type,
|
||
select_number: (() => {
|
||
const raw = Number(
|
||
data.select_number ?? data.purchase_quantity ?? data.purchase_number,
|
||
);
|
||
if (!Number.isFinite(raw) || raw < 1) return 1;
|
||
return Math.min(9999, Math.max(1, Math.floor(raw)));
|
||
})(),
|
||
};
|
||
|
||
const newDrugs = [...currentDrugs.value, newProduct];
|
||
updateCurrentDrugs(newDrugs);
|
||
|
||
message.success(`已将${newProduct.drug_name}添加到清单中!`);
|
||
return true;
|
||
};
|
||
|
||
const removeDrug = (index: number) => {
|
||
const newDrugs = currentDrugs.value.filter((_, i) => i !== index);
|
||
updateCurrentDrugs(newDrugs);
|
||
};
|
||
|
||
const updateDrugQuantity = (index: number, quantity: number) => {
|
||
if (quantity > 0) {
|
||
const newDrugs = [...currentDrugs.value];
|
||
newDrugs[index].select_number = quantity;
|
||
updateCurrentDrugs(newDrugs);
|
||
}
|
||
};
|
||
|
||
const increment = (index: number) => {
|
||
const newDrugs = [...currentDrugs.value];
|
||
newDrugs[index].select_number++;
|
||
updateCurrentDrugs(newDrugs);
|
||
};
|
||
|
||
const decrement = (index: number) => {
|
||
if (currentDrugs.value[index].select_number > 1) {
|
||
const newDrugs = [...currentDrugs.value];
|
||
newDrugs[index].select_number--;
|
||
updateCurrentDrugs(newDrugs);
|
||
}
|
||
};
|
||
|
||
// 切换药品用法编辑状态
|
||
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);
|
||
if (check) {
|
||
newDrugInfo.value.id = '';
|
||
message.error('该药品已经在处方中了!');
|
||
return;
|
||
}
|
||
|
||
const data = drugList.value.find((v) => v.drug_id === newDrugInfo.value.id);
|
||
if (data) {
|
||
newDrugInfo.value.price = data.price;
|
||
newDrugInfo.value.name = data.drug.drug_name;
|
||
nextTick(() => {
|
||
const input = document.querySelector(
|
||
'.new-number-input input',
|
||
) as HTMLElement;
|
||
input?.focus();
|
||
});
|
||
}
|
||
};
|
||
|
||
const selectOldDrugInfo = (id: number) => {
|
||
const check = currentDrugs.value.find((v) => v.id === id);
|
||
|
||
if (check) {
|
||
const newDrugs = [...currentDrugs.value];
|
||
newDrugs[selectChineseIndex.value].id = selectChineseId.value;
|
||
updateCurrentDrugs(newDrugs);
|
||
drugList.value = [];
|
||
message.error('该药品已经在处方中了!');
|
||
return;
|
||
}
|
||
|
||
const data = drugList.value.find((v) => v.drug_id === id);
|
||
if (data) {
|
||
const newProduct = {
|
||
index_id: data.id,
|
||
id: data.drug.id,
|
||
drug_name: data.drug.drug_name,
|
||
number: data.drug.number,
|
||
use_num: drugTime.value.find((item) => item.id === data.drug.time_id),
|
||
use_type: drugUseType.value.find(
|
||
(item) => item.id === data.drug.type_id,
|
||
),
|
||
use_frequency: drugUseFrequency.value.find(
|
||
(item) => item.id === data.drug.frequency_id,
|
||
),
|
||
unit: drugUnit.value.find((item) => item.id === data.drug.unit_id),
|
||
price: data.price,
|
||
way_id: data.drug?.way_id,
|
||
use_ways: drugUseWay.value.find((item) => item.id === data.drug.way_id),
|
||
time_id: data.drug.time_id,
|
||
type_id: data.drug.type_id,
|
||
frequency_id: data.drug.frequency_id,
|
||
unit_id: data.drug.unit_id,
|
||
image: data.drug.image,
|
||
instruction: data.drug.instruction,
|
||
type: data.drug.type,
|
||
};
|
||
|
||
const newDrugs = [...currentDrugs.value];
|
||
newDrugs[selectChineseIndex.value] = newProduct;
|
||
updateCurrentDrugs(newDrugs);
|
||
|
||
nextTick(() => {
|
||
const input = document.querySelector(
|
||
`.old-number-input-${selectChineseIndex.value} input`,
|
||
) as HTMLElement;
|
||
input?.focus();
|
||
});
|
||
}
|
||
};
|
||
|
||
const setSelectChineseIndex = (index: number, id: number) => {
|
||
selectChineseIndex.value = index;
|
||
selectChineseId.value = id;
|
||
};
|
||
|
||
const addDrugByChinese = () => {
|
||
const check = currentDrugs.value.find((v) => v.id === newDrugInfo.value.id);
|
||
if (check) {
|
||
message.error('该药品已经在处方中了!');
|
||
return false;
|
||
}
|
||
|
||
const data = drugList.value.find((v) => v.drug_id === newDrugInfo.value.id);
|
||
if (!data) {
|
||
message.error('请选择药品');
|
||
return false;
|
||
}
|
||
|
||
data.drug.number = newDrugInfo.value.number;
|
||
data.drug.way_id = newDrugInfo.value.way_id;
|
||
const success = addProducts(data);
|
||
if (success) {
|
||
newDrugInfo.value = {};
|
||
}
|
||
return success;
|
||
};
|
||
|
||
const selectDrugByNewDrugInfo = (
|
||
event: KeyboardEvent,
|
||
isNewDrug: boolean,
|
||
) => {
|
||
if (event.key === 'Enter') {
|
||
event.preventDefault();
|
||
if (isNewDrug) {
|
||
addDrugByChinese();
|
||
} else {
|
||
syncToLocalStorage();
|
||
}
|
||
nextTick(() => {
|
||
const input = document.querySelector(
|
||
'.new-select-drug-name input',
|
||
) as HTMLElement;
|
||
input?.focus();
|
||
});
|
||
}
|
||
};
|
||
|
||
const updateChineseNumber = () => {
|
||
syncToLocalStorage();
|
||
};
|
||
|
||
const updateChineseNumberGoNewDrug = (event: KeyboardEvent) => {
|
||
if (event.key === 'Enter') {
|
||
syncToLocalStorage();
|
||
nextTick(() => {
|
||
const input = document.querySelector(
|
||
'.new-select-drug-name input',
|
||
) as HTMLElement;
|
||
input?.focus();
|
||
});
|
||
}
|
||
};
|
||
|
||
// 药品用法选择
|
||
const selectProductChange = (id: number) => {
|
||
selectProductId.value = id;
|
||
};
|
||
|
||
const selectDrugUseWayChange = (id: number) => {
|
||
const newDrugs = currentDrugs.value.map((item) =>
|
||
item.index_id === selectProductId.value
|
||
? {
|
||
...item,
|
||
way_id: id,
|
||
use_ways: drugUseWay.value.find((value) => value.id === id),
|
||
}
|
||
: item,
|
||
);
|
||
updateCurrentDrugs(newDrugs);
|
||
};
|
||
|
||
// 加工规则操作
|
||
const selectProcessRule = (id: number) => {
|
||
processRuleId.value = id;
|
||
getProcessRuleListData(id);
|
||
};
|
||
|
||
const selectProcessRuleNot = (id: number) => {
|
||
childProcessRuleId.value = id;
|
||
getProcessRuleListData(0, id);
|
||
};
|
||
|
||
const selectProcessRuleNotCommit = (id: number) => {
|
||
processRuleNoteId.value = id;
|
||
};
|
||
|
||
const selectPackageMethod = (id: number) => {
|
||
packageMethodId.value = id;
|
||
};
|
||
|
||
// 中药相冲检查
|
||
const checkChineseMedicineConflict = async () => {
|
||
if (activeCategory.value === 2) {
|
||
return { hasConflict: false };
|
||
}
|
||
|
||
notification.info({
|
||
message: '正在检查药物相冲',
|
||
duration: 1,
|
||
description: '正在检查药物相冲,请稍等...',
|
||
});
|
||
|
||
try {
|
||
const names = currentDrugs.value.map((item) => item.drug_name);
|
||
const res = await checkChineseMedicineConflictApi({ names });
|
||
|
||
if (res.is_exist === true) {
|
||
checkData.value = { message: res.message };
|
||
return { hasConflict: true, message: res.message };
|
||
} else {
|
||
notification.success({
|
||
message: '检查成功',
|
||
duration: 3,
|
||
description: '暂无相冲药品',
|
||
});
|
||
return { hasConflict: false };
|
||
}
|
||
} catch (error) {
|
||
console.error('检查药物相冲失败:', error);
|
||
return { hasConflict: false };
|
||
}
|
||
};
|
||
|
||
// 发送处方
|
||
const sendPrescription = async (
|
||
doctorSecondSignValue = 0,
|
||
customSendMode: number = 0,
|
||
customStoreId: number | null = null,
|
||
) => {
|
||
if (currentDrugs.value.length === 0) {
|
||
message.error('请选择药品');
|
||
return false;
|
||
}
|
||
|
||
if (activeCategory.value === 1) {
|
||
if (ruleType.value === 1 && packageMethodId.value == null) {
|
||
message.error('请选择包法');
|
||
return false;
|
||
}
|
||
if (ruleType.value === 2) {
|
||
if (processRuleId.value == null) {
|
||
message.error('请选择制剂');
|
||
return false;
|
||
}
|
||
if (processRuleNoteId.value == null) {
|
||
message.error('请选择规格');
|
||
return false;
|
||
}
|
||
if (childProcessRuleId.value == null) {
|
||
message.error('请选择备注');
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!diagnosis.value) {
|
||
message.error('诊断结果不能为空');
|
||
return false;
|
||
}
|
||
|
||
if (!medicalAdvice.value) {
|
||
message.error('医嘱不能为空');
|
||
return false;
|
||
}
|
||
try {
|
||
// 如果是转诊挂号,自动使用承接方诊所ID(转接方开处方时)
|
||
let finalSendMode = customSendMode;
|
||
let finalStoreId = customStoreId;
|
||
|
||
if (registerStoreInfo.value?.is_from_transfer === 1 && registerStoreInfo.value?.delegate_store_id) {
|
||
// 转接方开处方时,自动使用承接方诊所ID,不需要在模态框选择
|
||
finalSendMode = 1;
|
||
finalStoreId = registerStoreInfo.value.delegate_store_id;
|
||
}
|
||
|
||
const response = await addWestPrescription({
|
||
patient: activePatient.value,
|
||
drugs: currentDrugs.value,
|
||
diagnosis: diagnosis.value,
|
||
medicalAdvice: medicalAdvice.value,
|
||
total: totalCost.value,
|
||
category: category.value,
|
||
drug_type: 2,
|
||
register_id: currentRegisterId.value,
|
||
treatment_price: treatmentPrice.value,
|
||
package_method_id: packageMethodId.value,
|
||
process_rule_id: processRuleId.value,
|
||
process_rule_note_id: processRuleNoteId.value,
|
||
child_process_rule_id: childProcessRuleId.value,
|
||
process_rule_type: ruleType.value,
|
||
prescription_type: activeCategory.value,
|
||
processing_fee: processRulePrice.value,
|
||
dosage: dosage.value,
|
||
day_dosage: dayDosage.value,
|
||
doctor_second_sign: doctorSecondSignValue,
|
||
// 中医在线问诊所需的东西
|
||
diseases_id: diseasesSelected.value,
|
||
method_id: methodSelected.value,
|
||
syndrome_id: syndromeSelected.value,
|
||
// 诊所选择参数(转诊挂号时自动使用承接方诊所ID)
|
||
send_mode: finalSendMode,
|
||
custom_store_id: finalSendMode === 1 ? finalStoreId : null,
|
||
});
|
||
|
||
const res = await response;
|
||
message.success('处方已发送');
|
||
sendMessage({
|
||
roomId: chatStore.currentFriend.room_id,
|
||
senderId: userStore.currentUser.doctor_id,
|
||
receiverId: chatStore.currentFriend.id,
|
||
type: 'prescription',
|
||
content: JSON.stringify(res),
|
||
});
|
||
chatStore.addMessage(
|
||
{
|
||
id: Date.now().toString(),
|
||
room_id: chatStore.currentFriend.room_id,
|
||
sender_user_id: `doctor-${userStore.currentUser.doctor_id}`,
|
||
receiver_user_id: chatStore.currentFriend.id,
|
||
message_type: 4,
|
||
message_content: JSON.stringify(res),
|
||
messageTypeName: 'prescription',
|
||
created_at: Date.now(),
|
||
created_at_text: new Date().toLocaleTimeString().slice(0, 5),
|
||
timestamp: Date.now(),
|
||
isSent: true,
|
||
read: true,
|
||
duration: 0,
|
||
},
|
||
userStore.currentUser.doctor_id,
|
||
);
|
||
resetForm();
|
||
|
||
// 返回包含转诊信息的响应数据
|
||
return {
|
||
success: true,
|
||
result: res?.result || res?.data || res,
|
||
need_transfer: res?.result?.need_transfer || res?.data?.need_transfer || res?.need_transfer,
|
||
transfer_prescription_id: res?.result?.transfer_prescription_id || res?.data?.transfer_prescription_id || res?.transfer_prescription_id,
|
||
};
|
||
} catch (error) {
|
||
console.error('发送处方失败:', error);
|
||
message.error('发送处方失败');
|
||
return false;
|
||
}
|
||
};
|
||
|
||
const resetForm = () => {
|
||
updateCurrentDrugs([]);
|
||
diagnosis.value = '';
|
||
medicalAdvice.value = '';
|
||
packageMethodId.value = 2;
|
||
processRulePrice.value = 0;
|
||
dosage.value = 7;
|
||
dayDosage.value = 2;
|
||
newDrugInfo.value = {};
|
||
doctorSecondSign.value = 0;
|
||
};
|
||
|
||
const changeCategory = (categoryValue: number) => {
|
||
// 先保存当前类型的药品数据
|
||
localStorage.setItem(
|
||
getStorageKey(activeCategory.value),
|
||
JSON.stringify(currentDrugs.value),
|
||
);
|
||
|
||
// 保存 Tab 类型
|
||
localStorage.setItem(
|
||
`${storagePrefix.value}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);
|
||
}
|
||
};
|
||
|
||
// 工具函数
|
||
const splitString = (str: string) => {
|
||
if (!str) return [];
|
||
return str.split(',');
|
||
};
|
||
|
||
const refreshCurrentDrugs = () => {
|
||
loadFromLocalStorage();
|
||
};
|
||
|
||
// 重置初始化状态(用于切换患者时)
|
||
const resetInitializationState = () => {
|
||
isInitialized.value = false;
|
||
isPatientInfoLoaded.value = false;
|
||
patientInfo.value = null;
|
||
activePatient.value = null;
|
||
userPatientHealthInquiry.value = null;
|
||
prescriptionList.value = [];
|
||
console.log('重置初始化状态');
|
||
};
|
||
|
||
return {
|
||
// 状态
|
||
patientInfo,
|
||
userPatientHealthInquiry,
|
||
prescriptionList,
|
||
currentRegisterId,
|
||
activePatient,
|
||
drugUseNum,
|
||
drugUseFrequency,
|
||
drugUseType,
|
||
drugUnit,
|
||
drugTime,
|
||
drugUseWay,
|
||
myStoreList,
|
||
myStoreId,
|
||
activeCategory,
|
||
diagnosis,
|
||
medicalAdvice,
|
||
treatmentPrice,
|
||
ruleType,
|
||
drugList,
|
||
currentDrugs,
|
||
category,
|
||
selectProductId,
|
||
processRuleList,
|
||
childProcessRuleList,
|
||
processRuleNoteList,
|
||
processRuleId,
|
||
processRuleNoteId,
|
||
childProcessRuleId,
|
||
packageMethodId,
|
||
dosage,
|
||
dayDosage,
|
||
newDrugInfo,
|
||
selectChineseIndex,
|
||
selectChineseId,
|
||
doctorSecondSign,
|
||
checkData,
|
||
|
||
// 计算属性
|
||
totalProductCost,
|
||
processingFee,
|
||
totalCost,
|
||
|
||
// 方法
|
||
initializePrescription,
|
||
initializeForModal,
|
||
initializeBasicData,
|
||
resetInitializationState,
|
||
getDrugList,
|
||
addProducts,
|
||
removeDrug,
|
||
updateDrugQuantity,
|
||
increment,
|
||
decrement,
|
||
toggleEditDrug,
|
||
saveEditDrug,
|
||
updateDrugUsage,
|
||
selectNewDrugInfo,
|
||
selectOldDrugInfo,
|
||
setSelectChineseIndex,
|
||
addDrugByChinese,
|
||
selectDrugByNewDrugInfo,
|
||
updateChineseNumber,
|
||
updateChineseNumberGoNewDrug,
|
||
selectProductChange,
|
||
selectDrugUseWayChange,
|
||
selectProcessRule,
|
||
selectProcessRuleNot,
|
||
selectProcessRuleNotCommit,
|
||
selectPackageMethod,
|
||
checkChineseMedicineConflict,
|
||
sendPrescription,
|
||
resetForm,
|
||
changeCategory,
|
||
getProcessRuleListData,
|
||
splitString,
|
||
refreshCurrentDrugs,
|
||
syncToLocalStorage,
|
||
loadFromLocalStorage,
|
||
updateCurrentDrugs,
|
||
traditionalChineseMedicine,
|
||
diseasesSelected,
|
||
methodSelected,
|
||
syndromeSelected,
|
||
// 诊所选择相关
|
||
registerStoreInfo,
|
||
selectedStoreId,
|
||
sendMode,
|
||
fetchRegisterStoreInfo,
|
||
toggleStoreSelection,
|
||
currentStoreName,
|
||
targetStoreName,
|
||
canChangeStore,
|
||
};
|
||
});
|