diff --git a/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue b/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue index d0d34308..7c763f07 100755 --- a/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue +++ b/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue @@ -314,6 +314,7 @@ >
¥{{ item.price }}/{{ item.unit || "次" }}
+
+ 加载中... +
@@ -517,6 +521,7 @@ const rules = { const categoryList = ref([]); // 原始分类+项目数据 const dictSearchKey = ref(''); const activeNames = ref(''); // 当前展开的折叠项 +const categoryLoadingSet = ref(new Set()); // Bug #500: 正在加载方法的分类集合 const allMethods = ref([]); @@ -632,16 +637,21 @@ const availableMethods = computed(() => { // 当可选方法列表改变时,如果当前选中的方法不在新列表中,则清空 // #428: 分类展开时联动加载检查方法 +// Bug #500: 使用 categoryLoadingSet 替代 dictLoading,避免切换分类时整个区域闪烁 async function handleCategoryExpand(cat) { if (!cat || !cat.typeName) return; - + + // 如果已加载过或正在加载中,跳过 + if ((cat.methods && cat.methods.length > 0) || categoryLoadingSet.value.has(cat.typeId)) return; + + categoryLoadingSet.value.add(cat.typeId); try { const res = await searchCheckMethod({ checkType: cat.typeName }); let data = res?.data?.data || res?.data || res?.rows || res; if (!Array.isArray(data) && res?.data && Array.isArray(res.data.data)) { data = res.data.data; } - + if (Array.isArray(data) && data.length > 0) { cat.methods = data.map(m => ({ id: m.id, @@ -655,14 +665,16 @@ async function handleCategoryExpand(cat) { } } catch (err) { console.error('加载分类检查方法失败', err); + } finally { + categoryLoadingSet.value.delete(cat.typeId); } } -async function handleCollapseChange(activeName) { - // 当折叠面板展开时,加载对应分类的检查方法 +// Bug #500: 改为非 async 函数,避免 el-collapse 的 @change 等待异步完成导致抖动 +function handleCollapseChange(activeName) { if (activeName) { const cat = filteredCategoryList.value.find(c => c.typeId == activeName); if (cat && (!cat.methods || cat.methods.length === 0)) { - await handleCategoryExpand(cat); + handleCategoryExpand(cat); // 异步加载,不 await } } } @@ -1309,6 +1321,20 @@ defineExpose({ getList }); font-weight: 500; color: #303133; } +/* Bug #500: 分类加载中的小圆点动画 */ +.loading-dot { + display: inline-block; + width: 6px; + height: 6px; + border-radius: 50%; + background: #409eff; + margin-left: 6px; + animation: dotPulse 1s ease-in-out infinite; +} +@keyframes dotPulse { + 0%, 100% { opacity: 0.3; transform: scale(0.8); } + 50% { opacity: 1; transform: scale(1.2); } +} .item-row { display: flex; align-items: center; @@ -1448,10 +1474,24 @@ defineExpose({ getList }); height: auto; line-height: 1.5; } +/* Bug #500: 折叠内容添加平滑过渡动画,避免切换时高度跳变 */ :deep(.el-collapse-item__content) { padding-bottom: 4px; + transition: all 0.3s ease; } +/* Bug #500: 折叠面板展开/收起动画使用 will-change 优化性能 */ :deep(.el-collapse-item__wrap) { border: none; + will-change: height; +} +:deep(.el-collapse-item) { + transition: margin 0.2s ease; +} +/* Bug #500: 分类加载中提示样式 */ +.category-loading-hint { + color: #909399; + font-size: 12px; + text-align: center; + padding: 8px 0; }