fix: prevent order list tab cache mix-up and service channel layout
Remove Transition wrapper around KeepAlive, disable cache on my orders and waybill pages, tighten dynamic route index matching, and fix service channel page root layout plus left menu.
This commit is contained in:
parent
6441ca6543
commit
0a2ff6993d
@ -1,67 +1,34 @@
|
||||
<template>
|
||||
<div class="page-layout-root">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<Transition
|
||||
:name="transitionName || 'page-none'"
|
||||
:css="Boolean(transitionName)"
|
||||
:mode="transitionName ? 'out-in' : undefined"
|
||||
>
|
||||
<keep-alive :include="cacheList" :max="keepAliveMax">
|
||||
<component
|
||||
:is="Component"
|
||||
v-if="Component"
|
||||
:key="getComponentKey(route)"
|
||||
/>
|
||||
</keep-alive>
|
||||
</Transition>
|
||||
<keep-alive :include="cacheList" :max="keepAliveMax">
|
||||
<component
|
||||
:is="Component"
|
||||
v-if="Component"
|
||||
:key="getComponentKey(route)"
|
||||
/>
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { computed, watch } from 'vue';
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useTabBarStore } from '@/store';
|
||||
import { MAX_KEEP_ALIVE_TABS } from '@/store/modules/tab-bar';
|
||||
import { consumeSkipPageTransition } from '@/utils/page-transition-flag';
|
||||
|
||||
const route = useRoute();
|
||||
const tabBarStore = useTabBarStore();
|
||||
const cacheList = computed(() => tabBarStore.getCacheList);
|
||||
const keepAliveMax = MAX_KEEP_ALIVE_TABS;
|
||||
|
||||
/** 已访问过的路由:Tab 回访关掉 CSS 过渡 */
|
||||
const visitedNames = ref(new Set<string>(tabBarStore.getCacheList));
|
||||
/** '' = 无 CSS 过渡;page-fade = 首次进入 */
|
||||
const transitionName = ref('page-fade');
|
||||
|
||||
watch(
|
||||
() => String(route.name || route.path),
|
||||
(name) => {
|
||||
if (!name) return;
|
||||
// LRU:回访时刷新缓存顺序
|
||||
if (tabBarStore.getCacheList.includes(name) || !route.meta?.ignoreCache) {
|
||||
if (!route.meta?.ignoreCache) {
|
||||
tabBarStore.touchCache(name);
|
||||
}
|
||||
}
|
||||
const refreshToken = route.query._r ?? route.query._refresh;
|
||||
if (consumeSkipPageTransition()) {
|
||||
transitionName.value = '';
|
||||
} else if (refreshToken != null && String(refreshToken) !== '') {
|
||||
transitionName.value = 'page-fade';
|
||||
} else if (
|
||||
visitedNames.value.has(name) ||
|
||||
tabBarStore.getCacheList.includes(name)
|
||||
) {
|
||||
transitionName.value = '';
|
||||
} else {
|
||||
transitionName.value = 'page-fade';
|
||||
}
|
||||
nextTick(() => {
|
||||
visitedNames.value.add(name);
|
||||
});
|
||||
if (!name || route.meta?.ignoreCache) return;
|
||||
tabBarStore.touchCache(name);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
@ -89,22 +56,4 @@
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.page-fade-enter-active {
|
||||
transition: opacity 0.18s ease-out, transform 0.18s ease-out;
|
||||
}
|
||||
|
||||
.page-fade-leave-active {
|
||||
transition: opacity 0.1s ease-in, transform 0.1s ease-in;
|
||||
}
|
||||
|
||||
.page-fade-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateY(6px);
|
||||
}
|
||||
|
||||
.page-fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -174,16 +174,19 @@ export const initDynamicRouter = async (options?: {
|
||||
if (normalizedKey.endsWith(`${last2}.vue`)) return true;
|
||||
}
|
||||
|
||||
// 策略4: 包含匹配(检查是否包含路径的关键部分)
|
||||
// 策略4: 非 index 文件名才做宽松匹配,避免 order/myOrders/index 与 order/waybillManage/index 串页
|
||||
const keyParts = normalizedKey.split('/').filter(Boolean);
|
||||
if (pathSegments.length > 0) {
|
||||
// 检查最后一段是否匹配(文件名)
|
||||
const lastSegment = pathSegments[pathSegments.length - 1];
|
||||
if (lastSegment === 'index') {
|
||||
return false;
|
||||
}
|
||||
const keyLastPart = keyParts[keyParts.length - 1];
|
||||
if (keyLastPart && keyLastPart.replace('.vue', '') === lastSegment) {
|
||||
// 检查前面的路径段是否也匹配
|
||||
if (pathSegments.length === 1 ||
|
||||
keyParts.slice(0, -1).join('/').includes(pathSegments.slice(0, -1).join('/'))) {
|
||||
if (
|
||||
pathSegments.length === 1
|
||||
|| keyParts.slice(0, -1).join('/').includes(pathSegments.slice(0, -1).join('/'))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,6 +48,7 @@ const ORDER: AppRouteRecordRaw = {
|
||||
meta: {
|
||||
locale: 'menu.order.myOrders',
|
||||
requiresAuth: true,
|
||||
ignoreCache: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -59,6 +60,7 @@ const ORDER: AppRouteRecordRaw = {
|
||||
requiresAuth: true,
|
||||
adminPortalOnly: true,
|
||||
permission: 'Order.WaybillManage',
|
||||
ignoreCache: true,
|
||||
order: 3,
|
||||
icon: 'icon-storage',
|
||||
},
|
||||
|
||||
@ -37,10 +37,6 @@
|
||||
</a-doption>
|
||||
</template>
|
||||
<template #node-menu="{ nodeData }">
|
||||
<a-doption @click="() => handleLeftMenuLeafEdit(nodeData)">
|
||||
<icon-edit style="margin-right: 6px" />
|
||||
{{ t('channel.serviceChannels.leftMenu.editChannel') }}
|
||||
</a-doption>
|
||||
<a-doption @click="() => handleLeftMenuLeafDelete(nodeData)">
|
||||
<icon-delete style="margin-right: 6px" />
|
||||
{{ t('channel.serviceChannels.actions.delete') }}
|
||||
@ -382,7 +378,6 @@
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑价格配置弹窗 -->
|
||||
<a-modal
|
||||
@ -1120,6 +1115,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -1602,14 +1598,6 @@ function handleLeftMenuBranchAddChannel(nodeData: any) {
|
||||
if (g) handleAddChannelToGroup(g)
|
||||
}
|
||||
|
||||
function handleLeftMenuLeafEdit(nodeData: any) {
|
||||
const ch = findChannelById(nodeData?.id)
|
||||
if (ch) {
|
||||
void selectChannel(ch)
|
||||
activeTab.value = 'config'
|
||||
}
|
||||
}
|
||||
|
||||
function handleLeftMenuLeafDelete(nodeData: any) {
|
||||
const ch = findChannelById(nodeData?.id)
|
||||
if (ch) handleDeleteChannel(ch)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user