372 【住院医生站】医嘱录入执行科室显示ID乱码,且缺乏动态匹配逻辑
373 【住院医生站】医嘱搜索缺失“II级护理”项目(与诊疗目录配置不符)
This commit is contained in:
@@ -819,7 +819,8 @@ function selectAdviceBase(key, row) {
|
||||
combinationList.value[rowIndex.value].positionName = stock.locationName;
|
||||
}
|
||||
} else {
|
||||
combinationList.value[rowIndex.value].orgId = JSON.parse(JSON.stringify(row)).positionId;
|
||||
// 🔧 修复执行科室逻辑:优先使用项目维护的所属科室(row.orgId),其次使用positionId
|
||||
combinationList.value[rowIndex.value].orgId = row.orgId || JSON.parse(JSON.stringify(row)).positionId;
|
||||
combinationList.value[rowIndex.value].unitPrice = row.priceList[0].price;
|
||||
}
|
||||
expandOrder.value = [key];
|
||||
|
||||
@@ -702,7 +702,14 @@ async function selectAdviceBase(key, row) {
|
||||
};
|
||||
|
||||
// 后续字段处理保持原样
|
||||
prescriptionList.value[rowIndex.value].orgId = undefined;
|
||||
// 🔧 修复执行科室逻辑:诊疗项目优先使用项目维护的所属科室(row.orgId)
|
||||
// 如果所属科室为空,则回退到患者当前所在科室
|
||||
if (row.adviceType === 3 && row.orgId) {
|
||||
// 项目有所属科室,直接使用
|
||||
prescriptionList.value[rowIndex.value].orgId = row.orgId;
|
||||
} else {
|
||||
prescriptionList.value[rowIndex.value].orgId = undefined;
|
||||
}
|
||||
prescriptionList.value[rowIndex.value].dose = undefined;
|
||||
prescriptionList.value[rowIndex.value].unitCodeList = unitCodeList.value;
|
||||
prescriptionList.value[rowIndex.value].doseUnitCode =
|
||||
|
||||
@@ -3305,8 +3305,9 @@ function syncGroupFields(row) {
|
||||
}
|
||||
|
||||
// 同步执行科室
|
||||
if (row.positionId || row.orgId) {
|
||||
prescriptionList.value[rowIndex.value].orgId = row.positionId || row.orgId;
|
||||
if (row.orgId || row.positionId) {
|
||||
// 🔧 修复:优先使用项目所属科室(orgId),其次positionId
|
||||
prescriptionList.value[rowIndex.value].orgId = row.orgId || row.positionId;
|
||||
}
|
||||
|
||||
// 同步皮试标记
|
||||
@@ -3390,9 +3391,8 @@ function setValue(row) {
|
||||
showPopover: false, // 确保查询框关闭
|
||||
};
|
||||
console.log('[BugFix] setValue - prescriptionList[rowIndex].adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
||||
// 🔧 Bug #218 修复:保留组套中的值,不要强制设为undefined
|
||||
// 只有当值未定义时才使用默认值
|
||||
prescriptionList.value[rowIndex.value].orgId = row.positionId || row.orgId;
|
||||
// 🔧 修复执行科室逻辑:优先使用项目维护的所属科室(row.orgId),其次使用positionId,最后回退到患者科室
|
||||
prescriptionList.value[rowIndex.value].orgId = row.orgId || row.positionId || props.patientInfo?.orgId;
|
||||
prescriptionList.value[rowIndex.value].dose = row.dose || row.doseQuantity;
|
||||
prescriptionList.value[rowIndex.value].quantity = row.quantity || 1;
|
||||
prescriptionList.value[rowIndex.value].unitCodeList = unitCodeList.value;
|
||||
@@ -3619,8 +3619,8 @@ function handleSaveGroup(orderGroupList) {
|
||||
unitCode: item.unitCode,
|
||||
unitCode_dictText: item.unitCodeName || '',
|
||||
statusEnum: 1,
|
||||
// 🔧 Bug #218 修复:优先使用 item.positionId,其次使用 orderDetailInfos.positionId
|
||||
orgId: item.positionId || item.orderDetailInfos?.positionId || mergedDetail.positionId,
|
||||
// 🔧 修复执行科室逻辑:优先使用 orgId(所属科室),其次 positionId
|
||||
orgId: item.orderDetailInfos?.orgId || mergedDetail.orgId || item.positionId || item.orderDetailInfos?.positionId || mergedDetail.positionId,
|
||||
dbOpType: prescriptionList.value[rowIndex.value].requestId ? '2' : '1',
|
||||
conditionId: conditionId.value,
|
||||
conditionDefinitionId: conditionDefinitionId.value,
|
||||
|
||||
@@ -395,11 +395,12 @@
|
||||
clearable
|
||||
v-model="row.orgId"
|
||||
style="width: 200px"
|
||||
:data="config.organization"
|
||||
:data="orgTreeData"
|
||||
:props="{ value: 'id', label: 'name', children: 'children' }"
|
||||
value-key="id"
|
||||
check-strictly
|
||||
default-expand-all
|
||||
:fallback-option="orgFallbackOption"
|
||||
@change="handleOrgChange"
|
||||
placeholder="请选择执行科室"
|
||||
/>
|
||||
@@ -422,7 +423,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {getCurrentInstance, nextTick, onMounted, ref, watch} from 'vue';
|
||||
import {computed, getCurrentInstance, nextTick, onMounted, ref, watch} from 'vue';
|
||||
|
||||
interface Config {
|
||||
diagnosisName: string; // 仅用于显示
|
||||
@@ -569,6 +570,54 @@ const handleCancel = () => {
|
||||
const handleNumberClick = (item: any) =>
|
||||
props.handlers.handleNumberClick(item, props.index, props.row);
|
||||
const handleOrgChange = (value: any) => props.handlers.handleOrgChange(value, props.index);
|
||||
|
||||
// 🔧 关键修复:计算属性,确保当前行的 orgId 始终存在于树数据中
|
||||
// 当 orgId 不在科室树中时,注入一个临时节点,让 el-tree-select 能正确显示中文名称
|
||||
const orgTreeData = computed(() => {
|
||||
const tree = props.config.organization || [];
|
||||
const orgId = props.row?.orgId;
|
||||
const orgName = props.row?.orgName || props.row?.positionName;
|
||||
if (!orgId || !orgName) return tree;
|
||||
|
||||
// 检查 orgId 是否已在树中存在
|
||||
const existsInTree = findOrgName(orgId);
|
||||
if (existsInTree) return tree;
|
||||
|
||||
// 注入临时节点到树根层级
|
||||
return [...tree, { id: String(orgId), name: orgName, children: [] }];
|
||||
});
|
||||
|
||||
// 🔧 从 organization 树中根据 orgId 查找科室名称(供 fallback-option 使用)
|
||||
function findOrgName(orgId: any): string {
|
||||
if (!orgId || !props.config.organization || props.config.organization.length === 0) return '';
|
||||
const strId = String(orgId);
|
||||
function walk(nodes: any[]): string {
|
||||
if (!nodes) return '';
|
||||
for (const node of nodes) {
|
||||
if (String(node.id) === strId) return node.name;
|
||||
// 模糊匹配:处理大 Long 精度丢失的情况
|
||||
if (typeof node.id === 'string' && node.id.length >= 16 && strId.length >= 16
|
||||
&& node.id.substring(0, 15) === strId.substring(0, 15)) {
|
||||
return node.name;
|
||||
}
|
||||
if (node.children) {
|
||||
const found = walk(node.children);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
return walk(props.config.organization);
|
||||
}
|
||||
|
||||
// 🔧 el-tree-select 的 fallback-option:当 orgId 匹配不到树节点时,
|
||||
// 仍然显示对应的中文科室名称而非原始数字 ID
|
||||
// 优先从科室树查找,其次用 row 上保存的 orgName/positionName 兜底
|
||||
const orgFallbackOption = (value: any) => {
|
||||
const name = findOrgName(value);
|
||||
const fallbackName = props.row?.orgName || props.row?.positionName;
|
||||
return { label: name || fallbackName || value, value };
|
||||
};
|
||||
const convertValues = () => props.handlers.convertValue('doseQuantity', props.row, props.index);
|
||||
const convertDoseValues = () => props.handlers.convertValue('dose', props.row, props.index);
|
||||
const calculateTotalPrice = () => props.handlers.calculateTotal('price', props.row, props.index);
|
||||
|
||||
@@ -593,29 +593,45 @@ function getListInfo(addNewRow) {
|
||||
}, 180);
|
||||
isAdding.value = false;
|
||||
expandOrder.value = [];
|
||||
// 🔧 修复:先加载科室树,再处理处方数据
|
||||
// 确保 resolveOrgId 在 organization 树已加载的情况下执行
|
||||
// 避免因树为空导致 orgId 无法匹配,从而显示数字 ID 而非中文名称
|
||||
const orgTreePromise = getOrgTree().then((res) => {
|
||||
organization.value = res?.data?.records ?? res?.data ?? [];
|
||||
});
|
||||
getPrescriptionList(patientInfo.value.encounterId).then((res) => {
|
||||
console.log('getListInfo==========>', JSON.stringify(res.data));
|
||||
|
||||
loadingInstance.close();
|
||||
prescriptionList.value = res.data
|
||||
.map((item) => {
|
||||
const parsedContent = JSON.parse(item.contentJson);
|
||||
return {
|
||||
...parsedContent,
|
||||
...item,
|
||||
doseQuantity: parsedContent?.doseQuantity,
|
||||
doseUnitCode_dictText: parsedContent?.doseUnitCode_dictText,
|
||||
// 确保 therapyEnum 被正确设置,优先使用 contentJson 中的值
|
||||
therapyEnum: String(parsedContent?.therapyEnum ?? item.therapyEnum ?? '1'),
|
||||
};
|
||||
})
|
||||
.sort((a, b) => {
|
||||
return new Date(b.requestTime) - new Date(a.requestTime);
|
||||
});
|
||||
getGroupMarkers(); // 更新标记
|
||||
if (props.activeTab == 'prescription' && addNewRow) {
|
||||
handleAddPrescription();
|
||||
}
|
||||
// 等待科室树加载完成后再处理处方数据,确保 resolveOrgId 能正确匹配
|
||||
orgTreePromise.then(() => {
|
||||
loadingInstance.close();
|
||||
prescriptionList.value = res.data
|
||||
.map((item) => {
|
||||
const parsedContent = JSON.parse(item.contentJson);
|
||||
return {
|
||||
...parsedContent,
|
||||
...item,
|
||||
doseQuantity: parsedContent?.doseQuantity,
|
||||
doseUnitCode_dictText: parsedContent?.doseUnitCode_dictText,
|
||||
// 确保 therapyEnum 被正确设置,优先使用 contentJson 中的值
|
||||
therapyEnum: String(parsedContent?.therapyEnum ?? item.therapyEnum ?? '1'),
|
||||
// 🔧 修复:确保 orgId 为 String 类型,与 organization 树的 id 类型一致
|
||||
// 关键:优先使用 item.positionId(后端 @JsonSerialize 保证精度),
|
||||
// 而非 parsedContent.orgId(来自 JSON.parse,大 Long 可能精度丢失)
|
||||
// 使用 resolveOrgId 从组织树中匹配正确的 String id
|
||||
orgId: resolveOrgId(item.positionId || parsedContent?.orgId || item.orgId) || undefined,
|
||||
// 🔧 修复:同时保存 orgName,当 orgId 在科室树中匹配不到时作为兜底显示
|
||||
// 优先从科室树查找名称,其次用 positionName(后端已保存的科室名),最后用 contentJson 中的 orgName
|
||||
orgName: findOrgName(item.positionId || parsedContent?.orgId || item.orgId) || item.positionName || parsedContent?.orgName || undefined,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => {
|
||||
return new Date(b.requestTime) - new Date(a.requestTime);
|
||||
});
|
||||
getGroupMarkers(); // 更新标记
|
||||
if (props.activeTab == 'prescription' && addNewRow) {
|
||||
handleAddPrescription();
|
||||
}
|
||||
});
|
||||
});
|
||||
getContract({ encounterId: patientInfo.value.encounterId }).then((res) => {
|
||||
contractList.value = res.data;
|
||||
@@ -796,6 +812,27 @@ function clickRowDb(row, column, event) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔧 从 organization 树中根据 orgId 查找科室名称
|
||||
* 供 el-tree-select 的 fallback-option 使用
|
||||
*/
|
||||
function findOrgName(orgId) {
|
||||
if (!orgId || !organization.value || organization.value.length === 0) return '';
|
||||
const strId = String(orgId);
|
||||
function walk(nodes) {
|
||||
if (!nodes) return '';
|
||||
for (const node of nodes) {
|
||||
if (String(node.id) === strId) return node.name;
|
||||
if (node.children) {
|
||||
const found = walk(node.children);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
return walk(organization.value);
|
||||
}
|
||||
|
||||
function getFormConfig() {
|
||||
return {
|
||||
diagnosisName: diagnosisName.value,
|
||||
@@ -934,7 +971,74 @@ function selectAdviceBase(key, row) {
|
||||
|
||||
function getOrgList() {
|
||||
getOrgTree().then((res) => {
|
||||
organization.value = res.data.records;
|
||||
organization.value = res?.data?.records ?? res?.data ?? [];
|
||||
// 🔧 修复:组织树加载完成后,重新解析所有医嘱行的orgId
|
||||
// 确保orgId能匹配到树节点,解决精度丢失或类型不匹配的问题
|
||||
resolveAllOrgIds();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔧 从 organization 树中查找正确的 String 类型 id
|
||||
* 解决 JavaScript 大整数精度丢失问题:
|
||||
* 当 orgId 为 Number 且超过 Number.MAX_SAFE_INTEGER 时,String() 转换会丢失精度
|
||||
* 例:19072662242626273 (Long) → JS Number 19072662242626272 → String "19072662242626272" (错误)
|
||||
* 通过在 organization 树中模糊匹配找到正确的 String id
|
||||
*/
|
||||
function resolveOrgId(rawOrgId) {
|
||||
if (!rawOrgId) return undefined;
|
||||
const strOrgId = String(rawOrgId);
|
||||
|
||||
// 递归在树中查找匹配的节点
|
||||
function findInTree(nodes) {
|
||||
if (!nodes || !Array.isArray(nodes)) return null;
|
||||
for (const node of nodes) {
|
||||
// 精确匹配(正常情况:id 和 orgId 都是 String 且值一致)
|
||||
if (String(node.id) === strOrgId) return String(node.id);
|
||||
// 模糊匹配:精度丢失通常只影响最后1-2位数字
|
||||
// 比较前15位是否相同(2^53 约 9007199254740992,共16位,前15位稳定)
|
||||
// 🔧 修复:同时处理 Number 和 String 类型的精度丢失情况
|
||||
// 场景1:rawOrgId 是 Number(JS已丢失精度),node.id 是正确 String
|
||||
// 场景2:rawOrgId 是 String(从已丢失精度的 Number 转来),node.id 是正确 String
|
||||
if (typeof node.id === 'string' && node.id.length >= 16 && strOrgId.length >= 16
|
||||
&& node.id.substring(0, 15) === strOrgId.substring(0, 15)) {
|
||||
return String(node.id);
|
||||
}
|
||||
// 递归搜索子节点
|
||||
if (node.children) {
|
||||
const found = findInTree(node.children);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const resolved = findInTree(organization.value);
|
||||
if (!resolved) {
|
||||
console.warn(`🔧 resolveOrgId 未匹配: rawOrgId=${rawOrgId}, type=${typeof rawOrgId}, strOrgId=${strOrgId}, treeSize=${organization.value?.length}`);
|
||||
}
|
||||
return resolved || strOrgId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔧 组织树加载完成后,重新解析所有医嘱行的orgId
|
||||
* 确保已有的医嘱行 orgId 能匹配到树节点
|
||||
*/
|
||||
function resolveAllOrgIds() {
|
||||
if (!organization.value || organization.value.length === 0) return;
|
||||
prescriptionList.value.forEach((row) => {
|
||||
if (row.orgId && row.adviceType == 3) {
|
||||
const resolved = resolveOrgId(row.orgId);
|
||||
if (resolved !== String(row.orgId)) {
|
||||
console.log(`🔧 orgId精度修复: ${row.orgId} → ${resolved} (${row.adviceName})`);
|
||||
row.orgId = resolved;
|
||||
}
|
||||
// 🔧 修复:同步更新 orgName,确保科室树加载后能正确显示中文名称
|
||||
const treeName = findOrgName(row.orgId);
|
||||
if (treeName) {
|
||||
row.orgName = treeName;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1000,6 +1104,9 @@ function handleNumberClick(item, index, row) {
|
||||
// 选择执行科室处理
|
||||
function handleOrgChange(value, index) {
|
||||
prescriptionList.value[index].positionId = value;
|
||||
prescriptionList.value[index].orgId = value;
|
||||
// 🔧 修复:同步保存 orgName,确保树匹配不到时仍有中文名称可显示
|
||||
prescriptionList.value[index].orgName = findOrgName(value) || '';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1090,11 +1197,11 @@ function handleSave() {
|
||||
// 保存签发按钮
|
||||
isSaving.value = true;
|
||||
console.log('签发处方参数:', {
|
||||
organizationId: patientInfo.value.orgId,
|
||||
organizationId: patientInfo.value.inHospitalOrgId,
|
||||
adviceSaveList: list,
|
||||
});
|
||||
savePrescriptionSign({
|
||||
organizationId: patientInfo.value.orgId,
|
||||
organizationId: patientInfo.value.inHospitalOrgId,
|
||||
regAdviceSaveList: list,
|
||||
})
|
||||
.then((res) => {
|
||||
@@ -1391,7 +1498,14 @@ function setValue(row) {
|
||||
...prevRow,
|
||||
...baseRow,
|
||||
uniqueKey: currentUniqueKey, // 确保 uniqueKey 不被覆盖
|
||||
orgId: row.adviceType != 3 ? undefined : JSON.parse(JSON.stringify(row)).positionId,
|
||||
// 🔧 修复执行科室逻辑:
|
||||
// 1. 非诊疗类型(adviceType!=3)不需要执行科室,设为undefined
|
||||
// 2. 诊疗类型优先使用项目维护的所属科室(row.orgId),其次positionId
|
||||
// 3. 如果都为空,回退到患者当前所在科室(patientInfo.orgId)
|
||||
// 4. 使用 resolveOrgId 从组织树中匹配正确的 String id,解决大 Long 精度丢失问题
|
||||
orgId: row.adviceType != 3 ? undefined : (resolveOrgId(row.orgId || row.positionId || patientInfo.value?.inHospitalOrgId) || ''),
|
||||
// 🔧 修复:同时保存 orgName,当 orgId 在科室树中匹配不到时作为兜底显示
|
||||
orgName: row.adviceType != 3 ? undefined : (findOrgName(row.orgId || row.positionId || patientInfo.value?.inHospitalOrgId) || row.orgName || patientInfo.value?.inHospitalOrgName || ''),
|
||||
dose: undefined,
|
||||
unitCodeList: unitCodeList.value,
|
||||
doseUnitCode: row.doseUnitCode,
|
||||
@@ -1487,7 +1601,9 @@ function handleSaveGroup(orderGroupList) {
|
||||
unitCode: item.unitCode,
|
||||
unitCode_dictText: item.unitCodeName || '',
|
||||
statusEnum: 1,
|
||||
orgId: item.orderDetailInfos?.positionId || mergedDetail.positionId,
|
||||
orgId: resolveOrgId(item.orderDetailInfos?.orgId || mergedDetail.orgId || patientInfo.value?.inHospitalOrgId) || '',
|
||||
// 🔧 修复:同时保存 orgName,确保树匹配不到时仍有中文名称可显示
|
||||
orgName: findOrgName(item.orderDetailInfos?.orgId || mergedDetail.orgId || patientInfo.value?.inHospitalOrgId) || item.orderDetailInfos?.orgName || mergedDetail.orgName || patientInfo.value?.inHospitalOrgName || '',
|
||||
dbOpType: prescriptionList.value[rowIndex.value].requestId ? '2' : '1',
|
||||
conditionId: conditionId.value,
|
||||
conditionDefinitionId: conditionDefinitionId.value,
|
||||
|
||||
Reference in New Issue
Block a user