123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- <!--
- * @Author: fxs bjnsfxs@163.com
- * @Date: 2024-08-20 14:06:49
- * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-03 18:22:47
- * @FilePath: \Game-Backstage-Management-System\src\App.vue
- * @Description:
- *
- -->
- <script setup lang="ts">
- import { zhCn } from 'element-plus/es/locales.mjs'
- import { RouterView } from 'vue-router'
- import { onMounted, reactive, ref, nextTick } from 'vue'
- import { ElMessage } from 'element-plus'
- import { getAllGameInfo } from '@/utils/table/table'
- import router from '@/router'
- import type { DropDownInfo } from '@/types/dataAnalysis'
- import DropDownSelection from '@/components/dataAnalysis/DropDownSelection.vue'
- import { useCommonStore } from '@/stores/useCommon'
- import { initLoadResouce } from '@/utils/resource'
- const { selectInfo } = useCommonStore()
- const isCollapse = ref(false)
- const navBarSelect = ref<string>('Home')
- const siderBarOpened = ref<Array<string>>(['数据总览'])
- const siderBar = ref()
- const menuList = reactive<Array<any>>([])
- const defaultActive = ref<string>('0')
- const navBarMenuList = [
- {
- name: 'Home',
- title: '应用分析'
- },
- {
- name: 'AppManage',
- title: '应用管理'
- }
- ]
- /**
- * @description: 侧边栏折叠改变
- * @return {*}
- */
- const changeCollapse = () => {
- isCollapse.value = !isCollapse.value
- }
- // 登出
- const logOut = () => {
- ElMessage({
- type: 'success',
- message: '退出成功',
- duration: 1000
- })
- localStorage.removeItem('token')
- localStorage.removeItem('refreshToken')
- router.push('/login')
- }
- // 游戏下拉选择框需要的数据
- const gameSelectInfo = reactive<DropDownInfo>({
- defaultSelect: '1001',
- title: '请选择游戏',
- optionsList: []
- })
- // 游戏信息是否加载成功
- const gameinfoLoad = ref(false)
- /**
- * @description: 更新整个页面的游戏选择
- * @param {*} gid 游戏id
- * @return {*}
- */
- const changeGame = (gid: any) => {
- selectInfo.gid = gid
- }
- /**
- * @description: 头部导航栏改变
- * @param {*} val 对应的name
- * @return {*}
- */
- const changeNavBar = (val: string) => {
- navBarSelect.value = val
- router.push(`/${val}`)
- createdMenuList()
- let title = navBarMenuList.find((item) => item.name === val)?.title
- if (title) {
- siderBarOpened.value.splice(0, 1, title)
- }
- }
- /**
- * @description: 获取所有游戏列表
- * @return {*}
- */
- getAllGameInfo().then((data) => {
- if (data) {
- data.map((item) => {
- gameSelectInfo.optionsList.push({
- value: item.gid,
- label: item.gameName
- })
- })
- }
- gameinfoLoad.value = true
- })
- // 资源的加载路径
- const resourceInfo: Record<string, string> = {
- logo: `/img/logo.svg`,
- defaultHead: `/img/default/defaultHead.png`
- }
- // 使用blob的资源路径信息
- const blobUrlInfo = reactive<Record<string, string>>({})
- const basePath = ref<string | undefined>()
- /**
- * @description: 创建侧边栏menu
- * @param {*} let
- * @return {*}
- */
- const createdMenuList = () => {
- let routes = router.options.routes
- let activeMenu = routes.find((item) => {
- return item.name === navBarSelect.value
- })
- basePath.value = activeMenu?.path
- menuList.splice(0, menuList.length, ...(activeMenu?.children as Array<any>))
- defaultActive.value = '0' // 仍有问题
- }
- onMounted(() => {
- // 去加载所有需要的资源
- initLoadResouce(resourceInfo).then((data) => {
- Object.assign(blobUrlInfo, data)
- })
- createdMenuList()
- })
- </script>
- <template>
- <el-config-provider :locale="zhCn">
- <div class="body">
- <div class="navBarBox">
- <div class="logoBox">
- <el-image :fit="'fill'" class="logoImg" :src="blobUrlInfo.logo"></el-image>
- <span>淳皓科技</span>
- </div>
- <div class="gameSelect">
- <el-icon class="gameIcon" :size="20">
- <icon-icon-park-game-three></icon-icon-park-game-three>
- </el-icon>
- <DropDownSelection
- :default-select="gameSelectInfo.defaultSelect"
- :title="gameSelectInfo.title"
- :options-list="gameSelectInfo.optionsList"
- :size="'default'"
- @change-select="changeGame"
- ></DropDownSelection>
- </div>
- <div class="navBarMenu">
- <el-menu
- :default-active="navBarSelect"
- class="el-menu-demo"
- mode="horizontal"
- @select="changeNavBar"
- >
- <el-menu-item
- v-for="item in navBarMenuList"
- class="navBarMenuItem"
- :index="item.name"
- >{{ item.title }}</el-menu-item
- >
- </el-menu>
- </div>
- <div class="headPortraitBox">
- <el-popover popper-class="headPopper" placement="bottom-end" trigger="click">
- <template #reference>
- <el-image class="headPortrait" :src="blobUrlInfo.defaultHead"></el-image>
- </template>
- <div class="userTools">
- <span class="userToolsItem" @click="logOut">
- <icon-material-symbols-light-logout></icon-material-symbols-light-logout>
- <span> 退出登录</span>
- </span>
- </div>
- </el-popover>
- </div>
- </div>
- <div class="sideBarBox">
- <el-menu
- :default-active="defaultActive"
- class="sideBar"
- :collapse="isCollapse"
- ref="siderBar"
- >
- <template v-for="(item, index) in menuList">
- <el-sub-menu :index="`${index}`" v-if="item.children && item.showChild">
- <template #title>
- <el-icon><component :is="item.icon"></component></el-icon>
- <span>{{ item.cnName }}</span>
- </template>
- <!-- :to="{ name: val.name }" -->
- <router-link
- style="text-decoration: none"
- v-for="(val, subIndex) in item.children"
- :to="{ path: basePath + '/' + item.path + '/' + val.path }"
- :key="index"
- >
- <el-menu-item :index="index + '-' + subIndex">{{ val.cnName }}</el-menu-item>
- </router-link>
- </el-sub-menu>
- <router-link
- style="text-decoration: none"
- v-else
- :to="{ path: basePath + '/' + item.path }"
- :key="index"
- >
- <el-menu-item :index="`${index}`">
- <template #title>
- <el-icon><component :is="item.icon" /></el-icon>
- <span class="menuTitle">{{ item.cnName }}</span>
- </template>
- </el-menu-item>
- </router-link>
- </template>
- <div class="sideBarFold" @click="changeCollapse">
- <el-icon :size="25"><Fold /></el-icon>
- </div>
- </el-menu>
- </div>
- <!-- <div class="sideBarBox">
- <el-menu
- :router="true"
- :default-active="$route.name"
- class="sideBar"
- :collapse="isCollapse"
- ref="siderBar"
- >
- <template v-for="item in menuInfo[navBarSelect]">
- <el-sub-menu v-if="item.children" :index="item.title">
- <template #title>
- <el-icon><component :is="item.icon" /></el-icon>
- <span class="menuTitle">{{ item.title }}</span>
- </template>
- <el-menu-item v-for="v in item.children" :index="v.pathName">{{
- v.title
- }}</el-menu-item>
- </el-sub-menu>
- <el-menu-item v-else :index="item.pathName">
- <template #title>
- <el-icon><component :is="item.icon" /></el-icon>
- <span class="menuTitle">{{ item.title }}</span>
- </template>
- </el-menu-item>
- </template>
- <div class="sideBarFold" @click="changeCollapse">
- <el-icon :size="25"><Fold /></el-icon>
- </div>
- </el-menu>
- </div> -->
- <div class="content">
- <router-view v-slot="{ Component, route }">
- <keep-alive>
- <component
- :is="Component"
- :key="route.path"
- v-if="route.meta.needKeepAlive == true"
- ></component>
- </keep-alive>
- <component
- :is="Component"
- :key="route.path"
- v-if="route.meta.needKeepAlive == false"
- ></component>
- </router-view>
- </div>
- </div>
- </el-config-provider>
- </template>
- <style scoped>
- .body {
- width: 100%;
- display: flex;
- height: 100vh;
- }
- /* 设置宽度后,content无法适应宽度,只能去间接的调整内部元素的宽度 */
- .sideBarBox {
- position: relative;
- /* width: 12%; */
- z-index: 1;
- height: 93vh;
- margin-top: 7vh;
- top: 0;
- }
- .sideBar {
- /* width: 12vw; */
- height: 93vh;
- position: relative;
- overflow: scroll;
- }
- /* 设置弹出层的样式 */
- .el-popper > .logoText {
- width: 100px;
- font-size: 16px;
- /* color: red; */
- }
- .logoImg {
- display: flex;
- align-items: center;
- width: 33px;
- /* margin-right: 20px; */
- /* height: 50px; */
- }
- .logoText {
- width: 80%;
- height: 100%;
- margin-left: 15%;
- display: flex;
- font-size: 18px;
- align-items: center;
- /* background-color: lightcoral; */
- }
- /* 主要用来调整整个menu的宽度 */
- .menuTitle {
- margin-right: 40px;
- }
- .sideBarFold {
- width: 5%;
- height: 3%;
- position: absolute;
- right: 40px;
- bottom: 20px;
- }
- .navBarBox {
- position: fixed;
- display: flex;
- align-items: center;
- width: 100vw;
- z-index: 2;
- height: 7vh;
- top: 0;
- background-color: white;
- right: 0;
- border-bottom: 1px solid gainsboro;
- }
- /* 调整LOGO */
- .logoBox {
- box-sizing: border-box;
- left: 30px;
- position: relative;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .gameSelect {
- position: relative;
- height: 80%;
- display: flex;
- align-items: center;
- left: 5%;
- display: flex;
- align-items: center;
- }
- .gameIcon {
- /* box-sizing: border-box; */
- /* padding-right: 12px; */
- margin-right: 12px;
- }
- .navBarMenu {
- width: 60%;
- position: relative;
- left: 6%;
- }
- .headPortraitBox {
- position: absolute;
- right: 3%;
- top: 50%;
- transform: translateY(-50%);
- }
- .userTools {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- align-items: center;
- }
- .userToolsItem {
- cursor: pointer;
- width: 100%;
- height: 4vh;
- display: flex;
- align-items: center;
- justify-content: center;
- /* padding: 10px; */
- margin: 2%;
- }
- .userToolsItem > span {
- margin-left: 10%;
- }
- .userToolsItem:hover {
- background-color: #f2f3f5;
- }
- .headPortrait {
- cursor: pointer;
- width: 50px;
- }
- .content {
- /* flex-grow: 1; */
- /* position: absolute; */
- width: 100%;
- /* height: 93%; */
- margin-top: 7vh;
- overflow: scroll;
- background-color: #f2f3f5;
- right: 0vw;
- top: 0vh;
- }
- </style>
- <!-- 为了让popper-class生效,需要的单独写一份 -->
- <style>
- .headPopper {
- padding: 0px !important;
- border: 1px solid #e5e6eb;
- background-color: white;
- }
- .el-menu--horizontal.el-menu {
- border-bottom: none;
- }
- </style>
|