router-shell.tsx 3.9 KB
Newer Older
1 2 3 4 5 6 7 8
import {
  defineComponent,
  getCurrentInstance,
  onUnmounted,
  ref,
  toRaw,
  watch,
} from 'vue';
9 10 11 12 13 14 15
import { ModelUtil } from '@ibiz-template/model';
import {
  parseRouteViewData,
  useRoute,
  useRouter,
} from '@ibiz-template/vue-util';
import { Route } from 'vue-router';
16 17
import { IBizContext } from '@ibiz-template/core';
import { ViewMode } from '@ibiz-template/runtime';
18 19 20 21 22 23 24 25 26 27 28 29

export default defineComponent({
  name: 'RouterShell',
  props: {
    level: {
      type: Number,
      default: 0,
    },
  },
  setup(props, ctx) {
    const { proxy } = getCurrentInstance()!;
    const router = useRouter(proxy);
30 31 32 33 34 35 36
    const viewData = ref<{
      viewPath?: string;
      viewType?: string;
      context?: IContext;
      params?: IParams;
      srfnav?: string;
    }>({});
37 38
    const isLoaded = ref(false);

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    // 销毁视图上下文
    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,
    };

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
    /** 计算视图是否有权限访问 */
    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;
    };

85
    // 根据应用模型解析视图参数
86 87
    const calcViewData = async () => {
      const service = await ModelUtil.getModelService();
88 89 90 91
      const appModel = service.app;
      if (appModel) {
        // 获取视图
        try {
92
          const route = useRoute(proxy) as Route;
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
          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;
          }

109 110 111 112 113 114
          const _context = IBizContext.create(_viewData.context);

          viewData.value = {
            ..._viewData,
            context: _context,
          };
115 116 117 118
          // 确定视图组件
          isLoaded.value = true;
          ctx.emit('viewFound', { modelPath: viewData.value.viewPath });
        } catch (error) {
119
          router.push({ name: `404View${props.level}` });
120 121 122
        }
      }
    };
123 124 125
    calcViewData();

    watch(
126
      () => proxy.$route.params.view1,
127 128 129 130 131 132 133 134
      () => {
        if (props.level === 1) {
          // 第一级路由壳监测到view1变化后,就重新计算一遍viewData
          calcViewData();
        }
      },
    );

135 136 137 138
    return {
      viewData,
      isLoaded,
      onNeuronInit,
139
      viewModal,
140 141 142 143 144 145 146
    };
  },
  render(h) {
    if (!this.isLoaded) {
      return null;
    }
    return h('ViewShell', {
147
      attrs: {
148 149 150
        context: this.viewData.context,
        params: this.viewData.params,
        modelPath: this.viewData.viewPath,
151 152 153
        srfnav: this.viewData.srfnav,
        modal: this.viewModal,
        isRouter: true,
154
      },
155
      key: this.viewData.viewPath,
156 157 158 159 160 161
      on: {
        neuronInit: this.onNeuronInit,
      },
    });
  },
});