fix(waybill-manage): 修复运单详情弹窗残留问题

- 页面形态状态(列表/独立表单页/独立详情页)在实例创建时锁定,避免随路由变化切换导致弹窗残留
- 模板中形态相关所有判定改为使用锁定状态变量,保证渲染一致性
- 修改 detailContainer、crudContainer、pageFormOption 等方法使用锁定状态,避免缓存实例 option 变形
- 新增 closeInnerDialogs 方法,在组件 deactivated 和 beforeUnmount 生命周期关闭所有 append-to-body 弹窗
- 解决标签页 keep-alive 机制下弹窗 Teleport 持续遗留导致界面异常的问题
- 对运单管理页面多处弹窗和视图控制做统一修复,提升页面稳定性和体验
This commit is contained in:
2026-09-18 11:17:50 +08:00
parent b4e12a671f
commit 3e7110ca8c
3 changed files with 74 additions and 17 deletions
@@ -3,21 +3,21 @@
:class="[
'waybill-manage-page',
{
'waybill-manage-page--form-page': isStandaloneWaybillFormPage,
'waybill-manage-page--detail-page': isStandaloneWaybillDetailPage,
'waybill-manage-page--form-page': formPageLocked,
'waybill-manage-page--detail-page': detailPageLocked,
},
]"
>
<component
v-if="!isStandaloneWaybillDetailPage"
v-if="!detailPageLocked"
:is="crudContainer"
:option="pageFormOption"
:form-page-title="isStandaloneWaybillFormPage ? formPageTitle : undefined"
:form-page-title="formPageLocked ? formPageTitle : undefined"
:table-loading="loading"
:data="data"
v-model:page="page"
v-model="form"
:status="isStandaloneWaybillFormPage ? dialogReadonly : undefined"
:status="formPageLocked ? dialogReadonly : undefined"
ref="crud"
:permission="permissionList"
:before-open="beforeOpen"
@@ -1546,7 +1546,7 @@
</el-link>
</div>
<div
v-if="isStandaloneWaybillFormPage"
v-if="formPageLocked"
class="waybill-manage-page__standalone-menu-actions"
>
<el-button class="waybill-manage-page__form-close" @click="closeCrudDialog">
@@ -1747,7 +1747,7 @@
</el-dialog>
<empty-pagination
v-show="!isStandaloneWaybillFormPage && !isStandaloneWaybillDetailPage"
v-show="!formPageLocked && !detailPageLocked"
:page="page"
@size-change="sizeChange"
@current-change="currentChange"
@@ -1758,18 +1758,18 @@
:is="detailContainer"
v-model="detailBox"
:title="`${config.title}详情`"
:append-to-body="!isStandaloneWaybillDetailPage"
:append-to-body="!detailPageLocked"
top="10px"
width="96%"
show-close
:class="[
'waybill-manage-page__detail-dialog',
{ 'waybill-manage-page__detail-page': isStandaloneWaybillDetailPage },
{ 'waybill-manage-page__detail-page': detailPageLocked },
$attrs.option?.dialogCustomClass,
]"
>
<div v-loading="detailLoading" class="waybill-manage-page__detail-content">
<template v-if="detailBox || isStandaloneWaybillDetailPage">
<template v-if="detailBox || detailPageLocked">
<section-card class="waybill-manage-page__waybill-detail-summary">
<div class="waybill-manage-page__waybill-heading">
<strong>运单详情</strong>
@@ -2223,10 +2223,10 @@
</div>
</template>
</div>
<div v-if="isStandaloneWaybillDetailPage" class="waybill-manage-page__detail-footer">
<div v-if="detailPageLocked" class="waybill-manage-page__detail-footer">
<el-button type="primary" @click="closeDetail">关闭</el-button>
</div>
<template v-if="!isStandaloneWaybillDetailPage" #footer>
<template v-if="!detailPageLocked" #footer>
<el-button type="primary" @click="closeDetail">关闭</el-button>
</template>
</component>
@@ -3518,9 +3518,21 @@ export default {
selectionList: [],
attachmentUploadMode: false,
standaloneFormKey: '',
// / / $route
// keep-alive deactivate $route
// / append-to-body el-dialog
// Teleport body KeepAlive.deactivate move DOM
// /
formPageLocked: false,
detailPageLocked: false,
// add / edit $route query option
formModeLocked: '',
};
},
created() {
this.formPageLocked = this.isStandaloneWaybillFormPage;
this.detailPageLocked = this.isStandaloneWaybillDetailPage;
this.formModeLocked = this.$route.query.mode || '';
if (this.config.enableAllDept && this.isAdmin) {
this.allDept = 1;
}
@@ -3544,6 +3556,14 @@ export default {
this.consumeTemplateCreatePayload();
}
},
// keep-alive append-to-body
// Teleport DOM body
deactivated() {
this.closeInnerDialogs();
},
beforeUnmount() {
this.closeInnerDialogs();
},
computed: {
...mapGetters(['permission', 'userInfo']),
permissionList() {
@@ -3579,8 +3599,9 @@ export default {
isStandaloneWaybillDetailPage() {
return this.standaloneDetailPage && this.$route.path === standaloneWaybillDetailRoute;
},
// $route data formPageLocked
detailContainer() {
return this.isStandaloneWaybillDetailPage ? 'PageDetail' : 'el-dialog';
return this.detailPageLocked ? 'PageDetail' : 'el-dialog';
},
formPageTitle() {
if (this.isStandaloneWaybillFormPage) {
@@ -3592,13 +3613,13 @@ export default {
return '';
},
crudContainer() {
return this.isStandaloneWaybillFormPage ? 'PageAvueForm' : 'avue-crud';
return this.formPageLocked ? 'PageAvueForm' : 'avue-crud';
},
pageFormOption() {
if (!this.isStandaloneWaybillFormPage) return this.option;
if (!this.formPageLocked) return this.option;
const base = {
...this.option,
boxType: this.$route.query.mode === 'edit' ? 'edit' : 'add',
boxType: this.formModeLocked === 'edit' ? 'edit' : 'add',
menuBtn: true,
submitBtn: true,
emptyBtn: false,
@@ -3862,6 +3883,25 @@ export default {
},
},
methods: {
// keep-alive / append-to-body
// Teleport DOM body data
closeInnerDialogs() {
this.detailBox = false;
this.mileageDialog.visible = false;
this.attachmentDocumentPreviewVisible = false;
this.attachmentImagePreviewVisible = false;
this.waybillRouteChangeBox = false;
this.waybillCommonAddressBox = false;
this.flowBox = false;
this.transportRouteBox = false;
this.transportAddressBox = false;
this.transportStationBox = false;
this.transportMapBox = false;
this.commonCargoBox = false;
this.cargoImportBox = false;
this.waybillProcessConfigBox = false;
this.excelBox = false;
},
initStandaloneFormPage() {
if (!this.isStandaloneWaybillFormPage) return;
const mode = this.$route.query.mode === 'edit' ? 'edit' : 'add';