import { defineComponent, getCurrentInstance, onUnmounted, ref, toRaw, watch, } from 'vue'; import { ModelUtil } from '@ibiz-template/model'; import { parseRouteViewData, useRoute, useRouter, } from '@ibiz-template/vue-util'; import { Route } from 'vue-router'; import { IBizContext } from '@ibiz-template/core'; import { ViewMode } from '@ibiz-template/runtime'; export default defineComponent({ name: 'RouterShell', props: { level: { type: Number, default: 0, }, }, setup(props, ctx) { const { proxy } = getCurrentInstance()!; const router = useRouter(proxy); const viewData = ref<{ viewPath?: string; viewType?: string; context?: IContext; params?: IParams; srfnav?: string; }>({}); const isLoaded = ref(false); // 销毁视图上下文 onUnmounted(() => { if (viewData.value.context) { const context = toRaw(viewData.value).context; if (context) context.destroy(); } }); // 视图初始化事件,往上抛 const onNeuronInit = (...args: IData[]) => { ctx.emit('neuronInit', ...args); }; const viewModal = { mode: ViewMode.ROUTE, level: props.level, }; /** 计算视图是否有权限访问 */ const calcViewAccess = ( accUserMode?: number | 0 | 2 | 3 | 4, accessKey?: string, ) => { // 未指定直接返回true if (accUserMode === 0) { return true; } // 2:登录用户、 3:匿名用户及登录用户,看有没有用户登录 const hasLogin = !!ibiz.appData?.context.srfuserid; if (accUserMode === 3 || accUserMode === 2) { return hasLogin; } // 登录用户且拥有指定资源能力,配了资源标识要有资源标识,否则看是否登录 if (accUserMode === 4) { if (accessKey) { const unires: string[] = ibiz.appData?.unires; return hasLogin && unires.includes(accessKey); } return hasLogin; } return true; }; // 根据应用模型解析视图参数 const calcViewData = async () => { const service = await ModelUtil.getModelService(); const appModel = service.app; if (appModel) { // 获取视图 try { const route = useRoute(proxy) as Route; const _viewData = await parseRouteViewData( appModel, route, props.level, ); const accessAble = calcViewAccess( _viewData.accUserMode, _viewData.accessKey, ); if (!accessAble) { // 没权限跳转403页面 router.push({ name: `403View${props.level}` }); return; } const _context = IBizContext.create(_viewData.context); viewData.value = { ..._viewData, context: _context, }; // 确定视图组件 isLoaded.value = true; ctx.emit('viewFound', { modelPath: viewData.value.viewPath }); } catch (error) { router.push({ name: `404View${props.level}` }); } } }; calcViewData(); watch( () => proxy.$route.params.view1, () => { if (props.level === 1) { // 第一级路由壳监测到view1变化后,就重新计算一遍viewData calcViewData(); } }, ); return { viewData, isLoaded, onNeuronInit, viewModal, }; }, render(h) { if (!this.isLoaded) { return null; } return h('ViewShell', { attrs: { context: this.viewData.context, params: this.viewData.params, modelPath: this.viewData.viewPath, srfnav: this.viewData.srfnav, modal: this.viewModal, isRouter: true, }, key: this.viewData.viewPath, on: { neuronInit: this.onNeuronInit, }, }); }, });