207 lines
6.6 KiB
Vue
207 lines
6.6 KiB
Vue
<script setup lang="ts">
|
||
import { ref, onMounted, reactive, provide, computed, nextTick } from "vue";
|
||
import Basic from "@/api/BaseApi";
|
||
|
||
import { RouteRecordRaw, useRoute, useRouter } from "vue-router";
|
||
import ContextMenu from "@/components/ContextMenu.vue";
|
||
import { useDefaultStore } from "@/store/index.js";
|
||
import { Message } from "view-ui-plus";
|
||
import LeftMenu from "@/components/LeftMenu.vue";
|
||
import MyHeader from "@/components/Header.vue";
|
||
import BschIframe from "@/components/BschIframe.vue";
|
||
import SearchPanel from "@/components/SearchPanel.vue";
|
||
import UserInfoModal from "@/components/UserInfoModal.vue";
|
||
import LightPageModal from "@/components/LightPageModal.vue";
|
||
|
||
import BaseApi from "@/api/BaseApi";
|
||
import { BschIframeType, IframePageParmas, RoleInfo, StateEnum } from "./types";
|
||
import { storeToRefs } from "pinia";
|
||
import UserSettingApi from "./api/UserSettingApi";
|
||
import { useCompRef } from "./utils/hook/useCompRef";
|
||
import mittBus from "@/utils/mitt";
|
||
import MenuBarApi from "./api/MenuBarApi";
|
||
import { isTickeRoterByName } from "./utils/bschLinkPage";
|
||
import Utils from "./utils";
|
||
|
||
const store = useDefaultStore();
|
||
const route = useRoute();
|
||
const router = useRouter();
|
||
|
||
const isRouterAlive = ref(false),
|
||
StateType = ref<StateEnum>(StateEnum.Loading);
|
||
|
||
const refBschIframe = useCompRef(BschIframe);
|
||
|
||
const isBaseMask = computed(() => route.name !== "index");
|
||
const isHeader = computed(() => !(route.meta.isHeader === false));
|
||
|
||
mittBus.on("reload", () => {
|
||
isRouterAlive.value = false;
|
||
setTimeout(() => {
|
||
isRouterAlive.value = true;
|
||
}, 100);
|
||
});
|
||
|
||
mittBus.on("updateState", (state: StateEnum) => (StateType.value = state));
|
||
mittBus.on("switchRole", switchRole);
|
||
mittBus.on("reloadUserSettings", loadUserSettings);
|
||
|
||
mittBus.on("openBschIframePage", async (params: IframePageParmas) => {
|
||
StateType.value = StateEnum.Iframe;
|
||
await nextTick();
|
||
refBschIframe.value?.openPage(params);
|
||
});
|
||
|
||
(async () => {
|
||
console.time("init");
|
||
const userinfo = await BaseApi.getUserInfo();
|
||
const p1 = BaseApi.getUserRole();
|
||
const p2 = BaseApi.findUserRole();
|
||
try {
|
||
const [r1, r2] = await Promise.all([p1, p2]);
|
||
store.$state.userInfo = userinfo;
|
||
if (r1.length == 0) {
|
||
store.$state.userRoleList = [
|
||
{
|
||
roleId: 0,
|
||
roleName: "",
|
||
schId: 0,
|
||
schName: "",
|
||
childId: 0,
|
||
childName: "",
|
||
},
|
||
];
|
||
} else store.$state.userRoleList = r1.filter(x => [1, 2, 3, 4, 5, 7].includes(x.roleId));
|
||
store.setCurRoleInfo(r2 as RoleInfo);
|
||
// 已移除 bsch SSO ticket 获取(登录改走 CAS)
|
||
await switchRole();
|
||
} catch (error) {
|
||
Message.error("内部服务错误");
|
||
console.error(error);
|
||
return false;
|
||
}
|
||
|
||
isRouterAlive.value = true;
|
||
StateType.value = StateEnum.Desktop;
|
||
console.timeEnd("init");
|
||
})();
|
||
|
||
/**切换角色 */
|
||
async function switchRole() {
|
||
await loadUserMenuBarList();
|
||
await loadUserSettings();
|
||
store.curRoleUid = Utils.uuid();
|
||
// const p1 = BaseApi.getUsedApp(store.getCurRoleId, store.getCurSchId),
|
||
// p2 = BaseApi.getUserApp(store.getCurUserId, store.getCurSchId);
|
||
// const [r1, r2] = await Promise.all([p1, p2]);
|
||
|
||
// store.$state.curUsedAppList = r1;
|
||
// store.$state.curUserAppList = r2.filter(x => x.app.length > 0);
|
||
}
|
||
async function loadUserSettings() {
|
||
const userSettings = await UserSettingApi.getUserSettings();
|
||
store.setCurUserSettingsInfo(userSettings);
|
||
}
|
||
|
||
async function loadUserMenuBarList() {
|
||
const menuList = await MenuBarApi.getMenuBarUserList();
|
||
store.setCurUserMenuList(menuList);
|
||
let findIndex = -1;
|
||
if (isTickeRoterByName(route.name as string)) {
|
||
let menuId = route.params.menuId as string;
|
||
findIndex = menuList.findIndex(x => x.id == menuId);
|
||
} else {
|
||
findIndex = menuList.findIndex(x => x.url === route.path);
|
||
}
|
||
// /msg、/settings 由后台「边栏设置」配置后即进入菜单表;未配置时也允许直达/刷新,不被弹回桌面
|
||
if (findIndex === -1 && !["/msg", "/settings"].includes(route.path)) router.push({ name: "index" });
|
||
}
|
||
|
||
const getRouterKey: (route: any) => string = route => {
|
||
let str = route?.name;
|
||
// if (str === "clocklist") str += "-" + route.params.id;
|
||
return str;
|
||
};
|
||
const { menuVisible } = storeToRefs(store);
|
||
|
||
const mainStyle = computed(() => `background-image: url(${store.getCurWallPaperUrl})`);
|
||
</script>
|
||
|
||
<template>
|
||
<div
|
||
:class="['app-desktop app-desktop__animation', !menuVisible ? 'app-desktop__full' : '']"
|
||
:style="mainStyle"
|
||
v-show="StateType > StateEnum.Loading"
|
||
>
|
||
<LeftMenu />
|
||
<div :class="{ 'app-main-wrap': true, 'base-mask': isBaseMask }" v-if="StateType === StateEnum.Desktop">
|
||
<MyHeader v-if="isHeader" />
|
||
<router-view v-if="!!isRouterAlive" v-slot="{ Component, route }">
|
||
<template v-if="isBaseMask">
|
||
<component :is="Component" :key="route?.name" />
|
||
</template>
|
||
<transition v-else name="fade" mode="out-in">
|
||
<div class="app-main-wrap">
|
||
<component :is="Component" :key="route?.name" />
|
||
</div>
|
||
</transition>
|
||
</router-view>
|
||
</div>
|
||
<template v-if="StateType === StateEnum.Iframe">
|
||
<BschIframe ref="refBschIframe" />
|
||
</template>
|
||
</div>
|
||
<div class="app-loading" v-if="StateType == StateEnum.Loading">
|
||
<div class="loadEffect">
|
||
<span></span>
|
||
<span></span>
|
||
<span></span>
|
||
<span></span>
|
||
<span></span>
|
||
<span></span>
|
||
<span></span>
|
||
<span></span>
|
||
</div>
|
||
</div>
|
||
<!-- <SearchPanel class="app-search" v-show="StateType == StateEnum.Search" /> -->
|
||
<UserInfoModal />
|
||
<LightPageModal />
|
||
</template>
|
||
|
||
<style lang="scss">
|
||
/* 开始过渡阶段,动画出去阶段 */
|
||
.fade-enter-active,
|
||
.fade-leave-active {
|
||
transition: all 1ms cubic-bezier(0, 0.99, 1, 0.03);
|
||
}
|
||
/* 进入开始 */
|
||
.fade-enter {
|
||
// transform: translateY(10px);
|
||
opacity: 0;
|
||
}
|
||
/* 出去终点 */
|
||
.fade-leave-active {
|
||
// transform: translateY(-10px);
|
||
// opacity: 0;
|
||
}
|
||
|
||
.back-enter-active,
|
||
.back-leave-active {
|
||
transition: all 1ms cubic-bezier(0, 0.99, 1, 0.03);
|
||
}
|
||
/* 进入开始 */
|
||
.back-enter {
|
||
display: none;
|
||
}
|
||
/* 出去终点 */
|
||
.back-leave-active {
|
||
display: none;
|
||
}
|
||
#app {
|
||
height: 100%;
|
||
}
|
||
.base-wrap-main .main-wrapper {
|
||
height: 100%;
|
||
}
|
||
</style>
|