import { IndexViewController } from '@ibiz-template/controller'; import { ref, watch } from 'vue'; import { useRouter, useRoute } from '@ibiz-template/vue-util'; import { ViewModel } from '@ibiz-template/model'; import { Route } from 'vue-router'; export interface RouteMsg { key: string; fullPath: string; modelPath?: string; caption?: string; appView?: ViewModel; } export const getView2Value = (route: Route) => { const { view2, params2, params1 } = route.params; if (!view2) { return ''; } // 清除params2里的srfnav let _params2 = (params2 as String).replace( /;srfnav=[^;=]*$|(?:;)srfnav=[^;=]*;|^srfnav=[^;=]*;|^srfnav=[^;=]*$/g, '', ); _params2 = _params2 || ibiz.env.routePlaceholder; return `/${params1}/${view2}/${_params2}`; }; // 获取首页一级路径的空白地址 export const getView1Value = (route: Route) => { const { view1, appContext } = route.params; return `/${appContext}/${view1}/${ibiz.env.routePlaceholder}`; }; export function useIndexExpRouteManage( proxy: Vue, controller: IndexViewController, ) { const router = useRouter(proxy); /** 当前的路由标识,只由二级路由组成,二级路由一致则就是同一个视图 */ const currentKey = ref(''); /** 留一份首页的Path */ const indexPath = ref(''); /** key操作记录,只维护当前缓存的key,且每个key在集合里唯一,最新操作的排在最前面 */ const keyHistory = ref<string[]>([]); /** 路由信息,每个key对应的全路由和标题之类的信息 */ const routeMsgs = ref<RouteMsg[]>([]); /** * 删除路由缓存数据 * * @author lxm * @date 2022-09-22 10:09:11 * @param {string[]} keys 要删除的keys */ const deleteRouteCache = (keys: string[]) => { keys.forEach(key => { const index = keyHistory.value.indexOf(key); if (index !== -1) { keyHistory.value.splice(index, 1); } const msgIndex = routeMsgs.value.findIndex(item => item.key === key); if (msgIndex !== -1) { routeMsgs.value.splice(msgIndex, 1); } }); }; // 监听路由 watch( () => proxy.$route.path, (newVal, oldVal) => { // 只处理有二级路由,只有首页的时候不需要, if (newVal !== oldVal) { const route = useRoute(proxy); currentKey.value = getView2Value(route); indexPath.value = getView1Value(route); // 更新或新建对应key的全路由信息,主要是三级路由变更时会用 const find = routeMsgs.value.find( item => item.key === currentKey.value, ); if (find) { if (route.matched.length === 2) { // 如果有缓存,并且现在matched为2说明少了参数,这样直接Push原来的路径即可 router.push(find.fullPath); } else { find.fullPath = route.fullPath; } } else { // 全关闭后到首页只显示空白不需要加入到routeMsgs里 if (newVal === indexPath.value) { return; } routeMsgs.value.push({ key: currentKey.value, fullPath: route.fullPath, modelPath: '', caption: '', }); } } }, { deep: true, immediate: true }, ); // 监听当前的key,维护数据 watch( currentKey, (newVal, oldVal) => { if (newVal !== oldVal && newVal) { const index = keyHistory.value.indexOf(newVal); // 历史记录里没有的新建信息,放入开头 if (index === -1) { keyHistory.value.unshift(newVal); } else { // 已存在的调整顺序至开头 keyHistory.value.splice(index, 1); keyHistory.value.unshift(newVal); } } }, { immediate: true }, ); /** * 更新路由信息 * * @author lxm * @date 2022-09-01 16:09:51 * @param {string} key * @param {IData} opts */ const updateRouteMsg = async (key: string, opts: Partial<RouteMsg>) => { const find = routeMsgs.value.find(item => item.key === currentKey.value); if (find) { if (opts.caption) find.caption = opts.caption; if (opts.modelPath) { find.modelPath = opts.modelPath; } } }; /** * 关闭视图回调 * * @author lxm * @date 2022-09-22 10:09:59 * @param {string} [key=currentKey.value] */ const closeView = (key: string = currentKey.value) => { // 找出删除的key在历史记录里的位置 deleteRouteCache([key]); const toKey = keyHistory.value[0]; if (!toKey) { if (controller.model.source.blankMode) { window.close(); } else { currentKey.value = ''; router.push(indexPath.value); } } else { const find = routeMsgs.value.find(item => item.key === toKey); router.push(find!.fullPath); } }; /** * 处理标签页点击 * */ const handleTabClick = (index: number) => { const routeMsg = routeMsgs.value[index]; if (routeMsg) { router.push(routeMsg.fullPath); } }; /** * 跳转首页 * */ const redirectToIndex = () => { const route = useRoute(proxy); const fullPath = route.fullPath; let index = fullPath.indexOf('/'); for (let i = 0; i < 2; i++) { index = fullPath.indexOf('/', index + 1); } const path = `${fullPath.substring(0, index)}/-`; router.push(path); }; /** * 跳转页面 * */ const goToPage = () => { if (keyHistory.value.length > 0) { const currentMsg = routeMsgs.value.find( item => item.key === keyHistory.value[0], ); if (currentMsg) { router.push(currentMsg.fullPath); } } else { redirectToIndex(); } }; /** * 处理标签页删除 * */ const handleTabDelete = (name: number) => { const routeMsg = routeMsgs.value[name]; if (routeMsg) { deleteRouteCache([routeMsg.key]); goToPage(); } }; /** * 处理全部关闭标签页 * */ const handleCloseAll = () => { if (routeMsgs.value.length > 0) { const allKeyArr: string[] = []; routeMsgs.value.forEach(msg => { allKeyArr.push(msg.key); }); deleteRouteCache(allKeyArr); goToPage(); } }; /** * 处理关闭其他标签页 * */ const handleCloseOther = () => { if (routeMsgs.value.length > 0) { const allKeyArr: string[] = []; routeMsgs.value.forEach(msg => { if (msg.key !== currentKey.value) { allKeyArr.push(msg.key); } }); deleteRouteCache(allKeyArr); goToPage(); } }; return { currentKey, keyHistory, routeMsgs, updateRouteMsg, closeView, deleteRouteCache, handleTabClick, handleTabDelete, handleCloseAll, handleCloseOther, }; }