HomeView.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. <script setup lang="ts">
  2. import { RouterView } from 'vue-router'
  3. import { onMounted, reactive, ref } from 'vue'
  4. import { ElMessage } from 'element-plus'
  5. import { getAllGameInfo } from '@/utils/table/table'
  6. import router from '@/router'
  7. import type { DropDownInfo } from '@/types/dataAnalysis'
  8. import DropDownSelection from '@/components/dataAnalysis/DropDownSelection.vue'
  9. import { useCommonStore } from '@/stores/useCommon'
  10. import { initLoadResouce } from '@/utils/resource'
  11. const { selectInfo } = useCommonStore()
  12. const isCollapse = ref(false)
  13. const menuList = [
  14. {
  15. title: '数据总览',
  16. icon: 'PieChart',
  17. children: [
  18. {
  19. pathName: 'OverView',
  20. title: '工作台'
  21. }
  22. ]
  23. },
  24. {
  25. title: '信息管理',
  26. icon: 'Histogram',
  27. children: [
  28. {
  29. pathName: 'GameManageView',
  30. title: '游戏管理'
  31. },
  32. {
  33. pathName: 'PlayerManageView',
  34. title: '玩家管理'
  35. }
  36. ]
  37. },
  38. {
  39. title: '数据分析',
  40. icon: 'DataAnalysis',
  41. children: [
  42. {
  43. pathName: 'KeepView',
  44. title: '留存分析'
  45. },
  46. {
  47. pathName: 'UserTrendView',
  48. title: '用户趋势'
  49. }
  50. ]
  51. }
  52. ]
  53. const changeCollapse = () => {
  54. isCollapse.value = !isCollapse.value
  55. }
  56. // 登出
  57. const logOut = () => {
  58. ElMessage({
  59. type: 'success',
  60. message: '退出成功',
  61. duration: 1000
  62. })
  63. localStorage.removeItem('token')
  64. localStorage.removeItem('refreshToken')
  65. router.push('/login')
  66. }
  67. // 游戏下拉选择框需要的数据
  68. const gameSelectInfo = reactive<DropDownInfo>({
  69. defaultSelect: '1001',
  70. title: '请选择游戏',
  71. optionsList: []
  72. })
  73. const gameinfoLoad = ref(false)
  74. /**
  75. * @description: 更新整个页面的游戏选择
  76. * @param {*} gid 游戏id
  77. * @return {*}
  78. */
  79. const changeGame = (gid: any) => {
  80. selectInfo.gid = gid
  81. }
  82. getAllGameInfo().then((data) => {
  83. if (data) {
  84. data.map((item) => {
  85. gameSelectInfo.optionsList.push({
  86. value: item.gid,
  87. label: item.gameName
  88. })
  89. })
  90. }
  91. gameinfoLoad.value = true
  92. })
  93. // 资源的加载路径
  94. const resourceInfo: Record<string, string> = {
  95. logo: `/img/logo.svg`,
  96. defaultHead: `/img/default/defaultHead.png`
  97. }
  98. // 使用blob的资源路径信息
  99. const blobUrlInfo = reactive<Record<string, string>>({})
  100. onMounted(() => {
  101. // 去加载所有需要的资源
  102. initLoadResouce(resourceInfo).then((data) => {
  103. Object.assign(blobUrlInfo, data)
  104. })
  105. })
  106. </script>
  107. <template>
  108. <div class="body">
  109. <div class="sideBarBox">
  110. <el-menu :router="true" :default-active="$route.name" class="sideBar" :collapse="isCollapse">
  111. <el-menu-item index="/" class="logoBox">
  112. <el-image :fit="'fill'" class="logoImg" :src="blobUrlInfo.logo"></el-image>
  113. <template #title><span class="logoText">淳皓科技</span></template>
  114. </el-menu-item>
  115. <el-sub-menu v-for="item in menuList" :index="item.title">
  116. <template #title>
  117. <el-icon><component :is="item.icon" /></el-icon>
  118. <span class="menuTitle">{{ item.title }}</span>
  119. </template>
  120. <el-menu-item v-for="v in item.children" :index="v.pathName">{{ v.title }}</el-menu-item>
  121. </el-sub-menu>
  122. <div class="sideBarFold" @click="changeCollapse">
  123. <el-icon :size="25"><Fold /></el-icon>
  124. </div>
  125. </el-menu>
  126. </div>
  127. <div class="navBarBox">
  128. <div class="gameSelect">
  129. <el-icon class="gameIcon" :size="20">
  130. <icon-icon-park-game-three></icon-icon-park-game-three>
  131. </el-icon>
  132. <DropDownSelection
  133. :default-select="gameSelectInfo.defaultSelect"
  134. :title="gameSelectInfo.title"
  135. :options-list="gameSelectInfo.optionsList"
  136. :size="'default'"
  137. @change-select="changeGame"
  138. ></DropDownSelection>
  139. </div>
  140. <div class="headPortraitBox">
  141. <el-popover popper-class="headPopper" placement="bottom-end" trigger="click">
  142. <template #reference>
  143. <el-image class="headPortrait" :src="blobUrlInfo.defaultHead"></el-image>
  144. </template>
  145. <div class="userTools">
  146. <span class="userToolsItem" @click="logOut">
  147. <icon-material-symbols-light-logout></icon-material-symbols-light-logout>
  148. <span> 退出登录</span>
  149. </span>
  150. </div>
  151. </el-popover>
  152. </div>
  153. </div>
  154. <!-- <div class="content">
  155. <RouterView v-if="gameinfoLoad" />
  156. </div> -->
  157. <div class="content">
  158. <router-view v-slot="{ Component, route }">
  159. <keep-alive>
  160. <component
  161. :is="Component"
  162. :key="route.path"
  163. v-if="route.meta.needKeepAlive == true"
  164. ></component>
  165. </keep-alive>
  166. <component
  167. :is="Component"
  168. :key="route.path"
  169. v-if="route.meta.needKeepAlive == false"
  170. ></component>
  171. </router-view>
  172. </div>
  173. </div>
  174. </template>
  175. <style scoped>
  176. .body {
  177. width: 100%;
  178. display: flex;
  179. height: 100vh;
  180. }
  181. .gameSelect {
  182. position: absolute;
  183. top: 50%;
  184. transform: translateY(-50%);
  185. /* width: 10%; */
  186. height: 80%;
  187. display: flex;
  188. align-items: center;
  189. right: 10%;
  190. display: flex;
  191. align-items: center;
  192. /* background-color: lightblue; */
  193. }
  194. .gameIcon {
  195. /* box-sizing: border-box; */
  196. /* padding-right: 12px; */
  197. margin-right: 12px;
  198. }
  199. /* 设置宽度后,content无法适应宽度,只能去间接的调整内部元素的宽度 */
  200. .sideBarBox {
  201. position: relative;
  202. /* width: 12%; */
  203. z-index: 2;
  204. height: 100vh;
  205. top: 0;
  206. }
  207. .sideBar {
  208. /* width: 12vw; */
  209. height: 100vh;
  210. position: relative;
  211. overflow: scroll;
  212. }
  213. /* 设置弹出层的样式 */
  214. .el-popper > .logoText {
  215. width: 100px;
  216. font-size: 16px;
  217. /* color: red; */
  218. }
  219. /* 调整LOGO */
  220. .logoBox {
  221. display: flex;
  222. justify-content: space-between;
  223. align-items: center;
  224. }
  225. .logoImg {
  226. display: flex;
  227. align-items: center;
  228. width: 33px;
  229. /* margin-right: 20px; */
  230. /* height: 50px; */
  231. }
  232. .logoText {
  233. width: 80%;
  234. height: 100%;
  235. margin-left: 15%;
  236. display: flex;
  237. font-size: 18px;
  238. align-items: center;
  239. /* background-color: lightcoral; */
  240. }
  241. /* 主要用来调整整个menu的宽度 */
  242. .menuTitle {
  243. margin-right: 40px;
  244. }
  245. .sideBarFold {
  246. width: 5%;
  247. height: 3%;
  248. position: absolute;
  249. right: 40px;
  250. bottom: 20px;
  251. }
  252. .navBarBox {
  253. position: fixed;
  254. width: 100vw;
  255. z-index: 1;
  256. height: 7vh;
  257. top: 0;
  258. background-color: white;
  259. right: 0;
  260. border-bottom: 1px solid gainsboro;
  261. }
  262. .headPortraitBox {
  263. position: absolute;
  264. right: 3%;
  265. top: 50%;
  266. transform: translateY(-50%);
  267. }
  268. .userTools {
  269. width: 100%;
  270. height: 100%;
  271. display: flex;
  272. flex-direction: column;
  273. justify-content: space-around;
  274. align-items: center;
  275. }
  276. .userToolsItem {
  277. cursor: pointer;
  278. width: 100%;
  279. height: 4vh;
  280. display: flex;
  281. align-items: center;
  282. justify-content: center;
  283. /* padding: 10px; */
  284. margin: 2%;
  285. }
  286. .userToolsItem > span {
  287. margin-left: 10%;
  288. }
  289. .userToolsItem:hover {
  290. background-color: #f2f3f5;
  291. }
  292. .headPortrait {
  293. cursor: pointer;
  294. width: 50px;
  295. }
  296. .content {
  297. /* flex-grow: 1; */
  298. /* position: absolute; */
  299. width: 100%;
  300. /* height: 93%; */
  301. margin-top: 7vh;
  302. overflow: scroll;
  303. background-color: #f2f3f5;
  304. right: 0vw;
  305. top: 0vh;
  306. }
  307. </style>
  308. <!-- 为了让popper-class生效,需要的单独写一份 -->
  309. <style>
  310. .headPopper {
  311. padding: 0px !important;
  312. border: 1px solid #e5e6eb;
  313. background-color: white;
  314. }
  315. </style>