bug 703 - 708

This commit is contained in:
Ranyunqiao
2026-06-10 14:39:14 +08:00
parent e9d09e69c9
commit bbf4c8441b
9 changed files with 186 additions and 62 deletions

View File

@@ -277,7 +277,7 @@
currentDetail.createTime || '-'
}}
</el-descriptions-item>
<el-descriptions-item label="处方号">
<el-descriptions-item label="手术单号">
{{
currentDetail.prescriptionNo || '-'
}}
@@ -574,13 +574,7 @@ const handleEdit = async (row) => {
editFormRef.value?.getLocationInfo?.();
editFormRef.value?.getDiagnosisList?.();
editFormRef.value?.loadDoctorOptions?.();
if (row.requestFormDetailList?.length > 0) {
editFormRef.value?.fillForm?.(
JSON.parse(row.descJson || '{}'),
row.requestFormDetailList,
row.requestFormId
);
}
// fillForm 由 SurgeryForm 内部 editData watcher 在 getList 完成后自动调用
};
const handleEditSubmitOk = async () => {

View File

@@ -356,6 +356,7 @@ let surgeryRecordsCache = null; // 原始 API 记录
let surgeryMappedCache = null; // 映射后的 el-transfer 数据
let doctorCache = null; // 医生列表(含默认主刀医生 ID
const transferRef = ref(null);
const listLoaded = ref(false); // 手术项目列表是否已加载完成
const dbTotal = ref(0); // 数据库中的手术项目总数
const checkedCount = computed(() => transferValue.value.length);
const leftPanelFormat = computed(() => ({
@@ -417,6 +418,7 @@ const getList = async (key) => {
applicationList.value = surgeryMappedCache;
applicationListAll.value = surgeryRecordsCache;
dbTotal.value = surgeryRecordsCache.length;
listLoaded.value = true;
return;
}
loading.value = true;
@@ -436,12 +438,14 @@ const getList = async (key) => {
surgeryMappedCache = applicationList.value;
}
loading.value = false;
listLoaded.value = true;
})
.catch((e) => {
console.error('手术项目加载失败:', e);
applicationList.value = [];
dbTotal.value = 0;
loading.value = false;
listLoaded.value = true;
});
};
@@ -471,7 +475,7 @@ const mapToTransferItem = (item) => ({
const fillForm = (descJson, details, formId) => {
editingRequestFormId.value = formId || '';
// 回填已选手术项目到穿梭框
const ids = (details || []).map((d) => String(d.adviceDefinitionId));
const ids = (details || []).map((d) => String(d.activityId));
transferValue.value = ids;
// 回填表单字段
if (descJson) {
@@ -536,6 +540,27 @@ onMounted(() => {
loadDoctorOptions();
});
// 编辑模式:等手术项目列表加载完成后回填穿梭框
watch(() => props.editData, (val) => {
if (!val) return;
const doFill = () => {
if (val.requestFormDetailList?.length > 0) {
fillForm(
JSON.parse(val.descJson || '{}'),
val.requestFormDetailList,
val.requestFormId
);
}
};
if (listLoaded.value) {
doFill();
} else {
const unwatch = watch(listLoaded, (loaded) => {
if (loaded) { unwatch(); doFill(); }
});
}
}, { immediate: true });
/**
* 加载字典选项
*/

View File

@@ -63,8 +63,8 @@
</div>
<div class="operate-btns" style="display: flex; align-items: center; gap: 12px;">
<el-radio-group v-model="therapyEnum">
<el-radio-button>全部</el-radio-button>
<el-radio-button>长期</el-radio-button>
<el-radio-button value="">全部</el-radio-button>
<el-radio-button value="1">长期</el-radio-button>
<el-radio-button value="2">临时</el-radio-button>
</el-radio-group>
<el-select v-model="orderClassCode" placeholder="医嘱类型" style="width: 240px" clearable>
@@ -864,7 +864,15 @@ const filterPrescriptionList = computed(() => {
const pList = prescriptionList.value.filter((item) => {
return (
(!therapyEnum.value || therapyEnum.value == item.therapyEnum) &&
(!orderClassCode.value || orderClassCode.value == item.adviceType) &&
(() => {
if (!orderClassCode.value) return true;
const code = String(orderClassCode.value);
if (code.includes('-')) {
const [aType, cCode] = code.split('-');
return item.adviceType == aType && item.categoryCode == cCode;
}
return orderClassCode.value == item.adviceType;
})() &&
(!orderStatus.value || (orderStatus.value == item.statusEnum && item.requestId))
);
});
@@ -2742,16 +2750,25 @@ function calculateTotalAmount(row, index) {
}
// 选择框改变时的处理
// 防止 toggleCheckboxRow 触发 @checkbox-change 导致递归
let _groupSelectLock = false;
function handleSelectionChange({ selection, row }) {
if (_groupSelectLock) return;
if (!row || !selection) return;
if (!row.groupId) return;
const isSelected = selection.some((item) => item.uniqueKey === row.uniqueKey);
prescriptionList.value
.filter((item) => {
return item.groupId && item.groupId == row?.groupId;
})
.forEach((row) => {
prescriptionRef.value.toggleCheckboxRow(row, isSelected);
const siblings = prescriptionList.value.filter(
(item) => item.groupId && item.groupId == row.groupId
);
if (siblings.length <= 1) return;
_groupSelectLock = true;
try {
siblings.forEach((sibling) => {
prescriptionRef.value.setCheckboxRow([sibling], isSelected);
});
} finally {
nextTick(() => { _groupSelectLock = false; });
}
}
/**

View File

@@ -174,8 +174,8 @@
:data="item"
border
:header-cell-style="{ background: '#eef9fd !important' }"
@checkbox-change="({ selection, row }) => handleRowSelect(selection, row, index)"
@checkbox-all="({ selection }) => handleSelectAll(selection, index)"
@checkbox-change="({ records, row }) => handleRowSelect(records, row, index)"
@checkbox-all="({ records }) => handleSelectAll(records, index)"
>
<vxe-column
type="checkbox"
@@ -413,6 +413,8 @@ function normalizeDayTimeHm(part) {
function handleGetPrescription(skipAutoSelectAll = false) {
if (patientInfoList.value.length > 0) {
// 刷新前保存当前选中状态,刷新后恢复(用于执行/不执行后的列表更新)
const previousSelectedIds = skipAutoSelectAll ? new Set(selectedRowIds.value) : null;
loading.value = true;
let encounterIds = patientInfoList.value.map((i) => i.encounterId).join(',');
getPrescriptionList({
@@ -451,17 +453,21 @@ function handleGetPrescription(skipAutoSelectAll = false) {
prescription.procedureIds = [];
// 添加复选框状态管理
prescription.checkedRates = {};
// 已执行时间点列表
// 已执行时间点列表只取日期部分忽略时间——全局ObjectMapper的setDateFormat
// 会丢失时区导致时间部分恒为00:00:00与前端dateStr中的HH:mm无法匹配
let exeTimeList = prescription.exePerformRecordList.map((item) => {
return formatDateStr(item.occurrenceTime, 'YYYY-MM-DD HH:mm:ss');
return formatDateStr(item.occurrenceTime, 'YYYY-MM-DD');
});
if (exeTimeList.length > 0) {
console.log('[DEBUG] requestId:', prescription.requestId, 'exeTimeList:', exeTimeList, 'raw:', prescription.exePerformRecordList.map(i => i.occurrenceTime));
}
// 不执行时间点列表
let stopTimeList = prescription.stopPerformRecordList.map((item) => {
return formatDateStr(item.occurrenceTime, 'YYYY-MM-DD HH:mm:ss');
return formatDateStr(item.occurrenceTime, 'YYYY-MM-DD');
});
// 取消执行时间点列表
let cancelTimeList = prescription.cancelPerformRecordList.map((item) => {
return formatDateStr(item.occurrenceTime, 'YYYY-MM-DD HH:mm:ss');
return formatDateStr(item.occurrenceTime, 'YYYY-MM-DD');
});
if (rate) {
// 拼成日期加全部时间点的形式显示示例03-01 [09:00, 10:00, 11:00]
@@ -475,10 +481,12 @@ function handleGetPrescription(skipAutoSelectAll = false) {
let rateItems = [];
rate.forEach((rateItem) => {
let dateStr = prescription.year + '-' + time + ' ' + rateItem + ':00';
// 日期部分,用于与 exeTimeList/stopTimeList/cancelTimeList 匹配(后者只含日期,无时间)
let dateOnly = prescription.year + '-' + time;
switch (props.exeStatus) {
case 1: // 待执行tab
// 如果该时间点未执行并且不在不执行列表中,则加入待选中列表
if (!exeTimeList.includes(dateStr) && !stopTimeList.includes(dateStr)) {
// 如果该日期未执行并且不在不执行列表中,则加入待选中列表
if (!exeTimeList.includes(dateOnly) && !stopTimeList.includes(dateOnly)) {
rateItems.push({
rate: rateItem,
});
@@ -488,7 +496,7 @@ function handleGetPrescription(skipAutoSelectAll = false) {
break;
case 6: // 已执行tab
let index = exeTimeList.findIndex((item) => {
return item == dateStr;
return item == dateOnly;
});
if (index != -1) {
// 显示执行人practitionerName
@@ -504,9 +512,9 @@ function handleGetPrescription(skipAutoSelectAll = false) {
break;
case 5: // 不执行tab
let index1 = stopTimeList.findIndex((item) => {
return item == dateStr;
return item == dateOnly;
});
if (stopTimeList.includes(dateStr)) {
if (stopTimeList.includes(dateOnly)) {
// 显示执行人practitionerName
rateItems.push({
practitionerName: prescription.stopPerformRecordList[index1].practitionerName,
@@ -517,9 +525,9 @@ function handleGetPrescription(skipAutoSelectAll = false) {
break;
case 9: // 取消执行tab
let index2 = cancelTimeList.findIndex((item) => {
return item == dateStr;
return item == dateOnly;
});
if (cancelTimeList.includes(dateStr)) {
if (cancelTimeList.includes(dateOnly)) {
rateItems.push({
practitionerName:
prescription.cancelPerformRecordList[index2].practitionerName,
@@ -547,7 +555,10 @@ function handleGetPrescription(skipAutoSelectAll = false) {
prescription.checkedRates = newCheckedRates;
// 处理已执行记录拿到全部的执行人id取消执行时候要传id
prescription.exePerformRecordList.forEach((item) => {
if (prescription.executeTimes.includes(item.occurrenceTime)) {
// occurrenceTime 经全局 ObjectMapper 序列化后时间部分为 00:00:00
// 用日期部分匹配 executeTimes 中的完整时间字符串
const occDateOnly = formatDateStr(item.occurrenceTime, 'YYYY-MM-DD');
if (prescription.executeTimes.some((t) => t.startsWith(occDateOnly))) {
prescription.procedureIds.push(item.procedureId);
}
});
@@ -571,8 +582,29 @@ function handleGetPrescription(skipAutoSelectAll = false) {
// 将分组结果转换为数组形式
prescriptionList.value = Object.values(groupedPrescriptions);
// 默认选中全部行(执行后刷新时不自动全选,保持用户操作状态)
if (!skipAutoSelectAll) {
if (skipAutoSelectAll && previousSelectedIds) {
// 执行/不执行后刷新只恢复父checkbox行选中子checkbox保持未选中
nextTick(() => {
selectedRowIds.value.clear();
prescriptionList.value.forEach((item, index) => {
const tableRef = proxy.$refs['tableRef' + index];
item.forEach((row) => {
if (previousSelectedIds.has(row.requestId)) {
selectedRowIds.value.add(row.requestId);
if (tableRef && tableRef[0]) {
tableRef[0].setCheckboxRow([row], true);
}
}
// 清空子checkbox选中状态避免刷新后自动勾选
row.checkedRates = {};
row.executeTimes = [];
row.procedureIds = [];
});
});
updateChooseAllStatus();
});
} else {
// 初次加载或手动刷新:默认全选
nextTick(() => {
defaultSelectAllRows();
});
@@ -588,7 +620,6 @@ function handleGetPrescription(skipAutoSelectAll = false) {
prescriptionList.value = [];
loading.value = false;
});
chooseAll.value = false;
} else {
prescriptionList.value = [];
selectedRowIds.value.clear();
@@ -794,21 +825,17 @@ function handelSwicthChange(value) {
prescriptionList.value.forEach((item, index) => {
const tableRef = proxy.$refs['tableRef' + index];
if (tableRef && tableRef[0]) {
if (value) {
// 全选选中所有行并联动checkbox
item.forEach((row) => {
// 批量设置选中/取消选中setCheckboxRow 显式设置,比 toggleCheckboxRow 更可靠)
tableRef[0].setCheckboxRow(item, value);
item.forEach((row) => {
if (value) {
selectedRowIds.value.add(row.requestId);
tableRef[0].toggleCheckboxRow(row, true);
selectAllCheckboxesInRow(row);
});
} else {
// 取消全选取消选中所有行并联动checkbox
item.forEach((row) => {
} else {
selectedRowIds.value.delete(row.requestId);
tableRef[0].toggleCheckboxRow(row, false);
unselectAllCheckboxesInRow(row);
});
}
}
});
}
});
}
@@ -820,10 +847,10 @@ function defaultSelectAllRows() {
prescriptionList.value.forEach((item, index) => {
const tableRef = proxy.$refs['tableRef' + index];
if (tableRef && tableRef[0]) {
// 选中该表格的所有行
// 批量选中该表格的所有行setCheckboxRow 显式设置选中状态,比 toggleCheckboxRow 更可靠)
tableRef[0].setCheckboxRow(item, true);
item.forEach((row) => {
selectedRowIds.value.add(row.requestId);
tableRef[0].toggleCheckboxRow(row, true);
// 同时选中该行内部的所有checkbox
selectAllCheckboxesInRow(row);
});
@@ -904,31 +931,45 @@ function checkAndToggleRowSelection(row) {
const isAllSelected = isAllCheckboxesSelected(row);
const isCurrentlySelected = selectedRowIds.value.has(row.requestId);
// 根据checkbox状态更新表格行选中状态
// 根据checkbox状态更新表格行选中状态(使用 setCheckboxRow 显式设置,避免 toggleCheckboxRow 翻转方向不确定)
if (isAllSelected && !isCurrentlySelected) {
selectedRowIds.value.add(row.requestId);
tableRef[0].toggleCheckboxRow(row, true);
tableRef[0].setCheckboxRow([row], true);
} else if (!isAllSelected && isCurrentlySelected) {
selectedRowIds.value.delete(row.requestId);
tableRef[0].toggleCheckboxRow(row, false);
tableRef[0].setCheckboxRow([row], false);
}
}
}
});
}
// 根据 requestId 从 prescriptionList 中查找原始行数据引用
// vxe-table 事件回调传出的 row 可能是内部代理对象,直接修改其属性不会触发 Vue 响应式更新
function findOriginalRow(requestId) {
for (const group of prescriptionList.value) {
const found = group.find((r) => r.requestId === requestId);
if (found) return found;
}
return null;
}
// 处理表格行选中事件
function handleRowSelect(selection, row, tableIndex) {
// 回查原始行引用,避免修改 vxe-table 代理对象导致 el-checkbox 不更新
const originalRow = findOriginalRow(row.requestId);
if (!originalRow) return;
const isSelected = selection.some((item) => item.requestId === row.requestId);
if (isSelected) {
selectedRowIds.value.add(row.requestId);
// 选中行时选中该行内部的所有checkbox
selectAllCheckboxesInRow(row);
selectAllCheckboxesInRow(originalRow);
} else {
selectedRowIds.value.delete(row.requestId);
// 取消选中行时取消选中该行内部的所有checkbox
unselectAllCheckboxesInRow(row);
unselectAllCheckboxesInRow(originalRow);
}
// 更新全选开关状态