fix(router): 修复运单管理详情路由及合同详情路由重复定义问题

- 为 waybill-manage-page、transport-plan-page 等组件增加 routePathLocked 变量锁定路由路径
- 添加 isOwnedRouteActive 计算属性,防止缓存实例错误读取其它路由的 detailId 导致误请求
- watcher 和 openDetail 方法中添加路由守卫,避免多余的请求和误开详情标签
- 修改宿主视图绑定 detailId,避免直接绑定全局 $route.query 导致缓存污染
- 删除 router/views/index.js 中合同管理详情路由重复定义,防止内容区空白问题
- 优化 waybill-import-dialog 组件样式和结构,增加 section-card 包裹表单区域
- 调整相关组件 data、computed、watch 使用,确保第一次立即 watcher 正确读取路由数据
- 验证所有改动后相关页面 HTTP 200,标签页行为正常,解决「运单管理不存在」和合同详情空白问题
This commit is contained in:
2026-09-18 12:22:25 +08:00
parent 986feff7b7
commit ff9fb9168b
9 changed files with 150 additions and 44 deletions
@@ -3518,6 +3518,11 @@ export default {
selectionList: [],
attachmentUploadMode: false,
standaloneFormKey: '',
// 实例所属路由的路径快照:用于判断当前 $route 是否还是「本实例自己的路由」。
// 必须在 data 里初始化,不能放 created —— Vue 的 Options API 执行顺序是
// data → computed → watch(immediate) → created,放 created 会被首个
// immediate watcher 读到空值,把本该执行的首次加载也挡掉。
routePathLocked: this.$route.path,
// 页面形态(列表 / 独立表单页 / 独立详情页)在实例创建时锁定一次,之后不再随 $route 变化。
// 原因:标签页 keep-alive 只会让实例 deactivate,实例仍会随 $route(全局响应式)重新渲染;
// 若形态跟着路由翻回列表/弹窗态,缓存实例会渲染出 append-to-body 的 el-dialog —— 弹窗被
@@ -3600,6 +3605,12 @@ export default {
return this.standaloneDetailPage && this.$route.path === standaloneWaybillDetailRoute;
},
// 容器形态读实例创建时锁定的标志,不随 $route 翻转(详见 data 中 formPageLocked 的说明)
// 当前路由是否仍属于本实例(tab.js 按 fullPath 建实例,一个实例只对应一个 path)。
// 被 keep-alive 缓存后如果 $route 已经跑到别的页面上,就不该再用「当前页面的 id」
// 去触发本实例的请求或跳转,否则会拿别的单据 id 查自己的接口。
isOwnedRouteActive() {
return this.$route.path === this.routePathLocked;
},
detailContainer() {
return this.detailPageLocked ? 'PageDetail' : 'el-dialog';
},
@@ -3867,6 +3878,10 @@ export default {
detailId: {
immediate: true,
handler(id) {
// 宿主 view 传的是全局 $route.query.id / detailId,实例被缓存后仍会被重渲染,
// 必须确认当前路由还是自己的:否则跳到别的详情页时会把「别的单据 id」灌进来,
// 触发 openDetail 用错 id 查运单 → 报「运单管理不存在」。
if (!this.isOwnedRouteActive) return;
if (id !== undefined && id !== null && id !== '') {
this.$nextTick(() => this.openDetail({ id }));
}
@@ -4449,6 +4464,9 @@ export default {
},
openDetail(row) {
if (!this.isStandaloneWaybillDetailPage) {
// 已不在自己的路由上(被缓存后路由切走):此时 row.id 极可能是别的单据的 id,
// 再 push 会生成一堆错误的「运单管理详情」标签
if (!this.isOwnedRouteActive) return;
this.$router.push({ path: standaloneWaybillDetailRoute, query: { id: row.id } });
return;
}