add bi
This commit is contained in:
parent
438b409d6d
commit
ab94e78123
@ -101,6 +101,113 @@ const userStore = defineStore(
|
|||||||
children: [],
|
children: [],
|
||||||
props: true
|
props: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加除gm后台资源操作外的菜单
|
||||||
|
const biDashboardRoute = {
|
||||||
|
path: projectRoute.path + "/bi_dashboard",
|
||||||
|
name: projectRoute.name + "_bi_dashboard",
|
||||||
|
meta: {
|
||||||
|
desc: "看板",
|
||||||
|
projectId: project.project_id,
|
||||||
|
},
|
||||||
|
component: () => import('@/views/bi/dashboardIndex.vue'),
|
||||||
|
props: true
|
||||||
|
}
|
||||||
|
const biAnalyseRoutePath = projectRoute.path + "/bi_analyse"
|
||||||
|
const biAnalyseRoute = {
|
||||||
|
path: biAnalyseRoutePath,
|
||||||
|
name: projectRoute.name + "_bi_analyse",
|
||||||
|
meta: {
|
||||||
|
desc: "数据分析",
|
||||||
|
projectId: project.project_id,
|
||||||
|
},
|
||||||
|
component: () => import('@/views/bi/analyseIndex.vue'),
|
||||||
|
props: true,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/analyse",
|
||||||
|
name: biAnalyseRoutePath + "/analyse",
|
||||||
|
meta: {
|
||||||
|
desc: "分析"
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/analyse/event",
|
||||||
|
name: biAnalyseRoutePath + "/analyse/event",
|
||||||
|
meta: {
|
||||||
|
desc: "事件分析"
|
||||||
|
},
|
||||||
|
component: () => import('@/views/bi/components/event.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/analyse/retention",
|
||||||
|
name: biAnalyseRoutePath + "/analyse/retention",
|
||||||
|
meta: {
|
||||||
|
desc: "留存分析"
|
||||||
|
},
|
||||||
|
component: () => import('@/views/bi/components/retention.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/bi_user",
|
||||||
|
name: biAnalyseRoutePath + "/bi_user",
|
||||||
|
meta: {
|
||||||
|
desc: "用户"
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/bi_user/event",
|
||||||
|
name: biAnalyseRoutePath + "/bi_user/event",
|
||||||
|
meta: {
|
||||||
|
desc: "事件分析"
|
||||||
|
},
|
||||||
|
component: () => import('@/views/bi/components/event.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/bi_user/retention",
|
||||||
|
name: biAnalyseRoutePath + "/bi_user/retention",
|
||||||
|
meta: {
|
||||||
|
desc: "留存分析"
|
||||||
|
},
|
||||||
|
component: () => import('@/views/bi/components/retention.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/bi_data",
|
||||||
|
name: biAnalyseRoutePath + "/bi_data",
|
||||||
|
meta: {
|
||||||
|
desc: "数据"
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/bi_data/event",
|
||||||
|
name: biAnalyseRoutePath + "/bi_data/event",
|
||||||
|
meta: {
|
||||||
|
desc: "事件分析"
|
||||||
|
},
|
||||||
|
component: () => import('@/views/bi/components/event.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: biAnalyseRoutePath + "/bi_data/retention",
|
||||||
|
name: biAnalyseRoutePath + "/bi_data/retention",
|
||||||
|
meta: {
|
||||||
|
desc: "留存分析"
|
||||||
|
},
|
||||||
|
component: () => import('@/views/bi/components/retention.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
projectRoute.children.push(biDashboardRoute)
|
||||||
|
projectRoute.children.push(biAnalyseRoute)
|
||||||
|
this.pushDynamicRouteChildren(biDashboardRoute)
|
||||||
|
this.pushDynamicRouteChildren(biAnalyseRoute)
|
||||||
|
|
||||||
|
// 添加游戏后台gm管理资源菜单
|
||||||
const resourceList = project.resource_list
|
const resourceList = project.resource_list
|
||||||
resourceList.forEach((resource) => {
|
resourceList.forEach((resource) => {
|
||||||
const routePath = projectRoute.path + "/" + resource.resource
|
const routePath = projectRoute.path + "/" + resource.resource
|
||||||
|
@ -35,7 +35,7 @@ const handleMenuSelect = (clickResource) => {
|
|||||||
hasClickedMenu.value = true
|
hasClickedMenu.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCommand(command) {
|
function handleAvatarCommand(command) {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case "logout":
|
case "logout":
|
||||||
logout();
|
logout();
|
||||||
@ -67,13 +67,32 @@ function logout() {
|
|||||||
<div class="sidebar-content">
|
<div class="sidebar-content">
|
||||||
<!-- <el-avatar shape="square" :size="100" :src="avatarUrl"></el-avatar>-->
|
<!-- <el-avatar shape="square" :size="100" :src="avatarUrl"></el-avatar>-->
|
||||||
<div class="sidebar-logo" @click="handleEnterIndex">
|
<div class="sidebar-logo" @click="handleEnterIndex">
|
||||||
<img src="@/assets/logo.svg" class="logo" alt="Logo">
|
<!-- <img src="@/assets/logo.svg" class="logo" alt="Logo">-->
|
||||||
<span class="system-name">游戏后台管理系统</span>
|
<span class="system-name">游戏数据管理系统</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="avatar-container">
|
||||||
|
<el-dropdown class="avatar-dropdown" trigger="click" @command="handleAvatarCommand">
|
||||||
|
<span class="avatar">
|
||||||
|
<el-icon><User/></el-icon>
|
||||||
|
<p style="margin-left: 5px">{{ nickName }}</p>
|
||||||
|
<el-icon><ArrowDown/></el-icon>
|
||||||
|
</span>
|
||||||
|
<!-- 头像操作下拉菜单 -->
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<!-- <el-dropdown-item>个人中心</el-dropdown-item>-->
|
||||||
|
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<el-menu :default-active="activeMenu" class="el-menu-vertical-demo" :collapse="false">
|
<el-menu :default-active="activeMenu" class="el-menu-vertical-demo" :collapse="false">
|
||||||
|
|
||||||
<div style="border-bottom: 1px whitesmoke solid">
|
<div style="border-bottom: 1px whitesmoke solid;border-top: 1px whitesmoke solid;">
|
||||||
<!-- 静态菜单 -->
|
<!-- 静态菜单 -->
|
||||||
<el-sub-menu index="/user">
|
<el-sub-menu index="/user">
|
||||||
<template #title>
|
<template #title>
|
||||||
@ -116,40 +135,11 @@ function logout() {
|
|||||||
</div>
|
</div>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
|
||||||
<el-container class="app-container-right">
|
|
||||||
<el-header class="app-header">
|
|
||||||
<div class="header-content">
|
|
||||||
<div class="avatar-container">
|
|
||||||
<el-dropdown class="right-menu-item hover-effect" trigger="click" @command="handleCommand">
|
|
||||||
|
|
||||||
<!-- 头像 -->
|
|
||||||
<span style="font-size: 20px">
|
|
||||||
<el-icon>
|
|
||||||
<User/>
|
|
||||||
</el-icon>
|
|
||||||
{{ nickName }}
|
|
||||||
<el-icon color="black" size="10">
|
|
||||||
<arrow-down/>
|
|
||||||
</el-icon>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 头像操作下拉菜单 -->
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<!-- <el-dropdown-item>个人中心</el-dropdown-item>-->
|
|
||||||
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- <el-avatar shape="square" :size="100" :src="avatarUrl"></el-avatar>-->
|
|
||||||
</el-header>
|
|
||||||
<el-main class="app-main">
|
<el-main class="app-main">
|
||||||
<router-view :key="$route.fullPath"></router-view>
|
<router-view :key="$route.fullPath"></router-view>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
|
||||||
</el-container>
|
</el-container>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@ -178,37 +168,44 @@ h1 {
|
|||||||
box-shadow: 2px 0 6px rgba(0, 0, 0, 0.1);
|
box-shadow: 2px 0 6px rgba(0, 0, 0, 0.1);
|
||||||
background-color: #4d4f52;
|
background-color: #4d4f52;
|
||||||
|
|
||||||
|
.avatar-container {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
width: 200px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-content {
|
.sidebar-content {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-container-right {
|
.avatar {
|
||||||
min-height: 100vh;
|
display: flex;
|
||||||
margin-left: 200px;
|
justify-content: center;
|
||||||
flex-direction: column;
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
.app-header {
|
color: white;
|
||||||
height: 60px;
|
font-size: 20px;
|
||||||
background: #fff;
|
vertical-align: middle;
|
||||||
border-bottom: 1px solid #e6e6e6;
|
|
||||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-main {
|
.app-main {
|
||||||
height: calc(100vh - 70px);
|
min-height: 100vh;
|
||||||
|
margin-left: 200px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 20px;
|
flex-direction: column;
|
||||||
background: #f0f2f5;
|
background: #f0f2f5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.sidebar-logo {
|
.sidebar-logo {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
padding: 20px 0;
|
margin-top: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: transparent; /* 关键:透明背景 */
|
background: transparent; /* 关键:透明背景 */
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -218,14 +215,14 @@ h1 {
|
|||||||
.logo {
|
.logo {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 1px;
|
||||||
filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.5)); /* 添加微光效果 */
|
filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.5)); /* 添加微光效果 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.system-name {
|
.system-name {
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 15px;
|
font-size: 22px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); /* 文字阴影增强可读性 */
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); /* 文字阴影增强可读性 */
|
||||||
@ -268,30 +265,5 @@ h1 {
|
|||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-container {
|
|
||||||
height: 50px;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
float: right;
|
|
||||||
background: #fff;
|
|
||||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
|
||||||
|
|
||||||
margin-right: 40px;
|
|
||||||
|
|
||||||
.avatar-wrapper {
|
|
||||||
margin-top: 5px;
|
|
||||||
position: relative;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
i {
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
right: -20px;
|
|
||||||
top: 25px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
18
ui/src/views/bi/analyseIndex.vue
Normal file
18
ui/src/views/bi/analyseIndex.vue
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<script setup>
|
||||||
|
import {defineAsyncComponent} from 'vue';
|
||||||
|
|
||||||
|
const layoutHeader = defineAsyncComponent(() => import("./layout/header/index.vue"))
|
||||||
|
const layoutMain = defineAsyncComponent(() => import("./layout/main/index.vue"))
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-container class="bi_container" direction="vertical">
|
||||||
|
<layoutHeader/>
|
||||||
|
<layoutMain></layoutMain>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
11
ui/src/views/bi/components/event.vue
Normal file
11
ui/src/views/bi/components/event.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
事件分析
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
11
ui/src/views/bi/components/retention.vue
Normal file
11
ui/src/views/bi/components/retention.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
留存分析
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
11
ui/src/views/bi/dashboardIndex.vue
Normal file
11
ui/src/views/bi/dashboardIndex.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
看板界面
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
41
ui/src/views/bi/layout/header/horizonMenu.vue
Normal file
41
ui/src/views/bi/layout/header/horizonMenu.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
import LocalCache from "@/stores/localCache.js";
|
||||||
|
|
||||||
|
import {useRouter} from "vue-router";
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const analyseRouteInfo = LocalCache.getCache("resource")
|
||||||
|
|
||||||
|
console.log("analyse route info:", analyseRouteInfo)
|
||||||
|
|
||||||
|
// 处理菜单点击事件
|
||||||
|
const handleMenuSelect = (clickResource) => {
|
||||||
|
console.log("点击资源:", clickResource)
|
||||||
|
// LocalCache.setCache("resource", clickResource)
|
||||||
|
router.push({path: clickResource.path})
|
||||||
|
// hasClickedMenu.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-menu mode="horizontal">
|
||||||
|
<template v-for="subMenu in analyseRouteInfo.children">
|
||||||
|
<el-sub-menu :index="subMenu.path">
|
||||||
|
<template #title>
|
||||||
|
<span>{{ subMenu.meta.desc }}</span>
|
||||||
|
</template>
|
||||||
|
<el-menu-item v-for="resource in subMenu.children" :key="resource.path" :index="resource.path"
|
||||||
|
@click="handleMenuSelect(resource)">
|
||||||
|
{{ resource.meta.desc }}
|
||||||
|
</el-menu-item>
|
||||||
|
</el-sub-menu>
|
||||||
|
</template>
|
||||||
|
</el-menu>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
23
ui/src/views/bi/layout/header/index.vue
Normal file
23
ui/src/views/bi/layout/header/index.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script setup>
|
||||||
|
import {defineAsyncComponent} from 'vue';
|
||||||
|
import {useRouter} from "vue-router";
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const menuComp = defineAsyncComponent(() => import("./horizonMenu.vue"))
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-header class="bi_header">
|
||||||
|
<menuComp/>
|
||||||
|
</el-header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
.bi_header {
|
||||||
|
height: 60px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
24
ui/src/views/bi/layout/main/index.vue
Normal file
24
ui/src/views/bi/layout/main/index.vue
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<script setup>
|
||||||
|
import {useRoute, useRouter} from "vue-router";
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-main class="bi_main">
|
||||||
|
<router-view :key="$route.fullPath"></router-view>
|
||||||
|
</el-main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
.bi_main {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 0;
|
||||||
|
background-color: white;
|
||||||
|
height: calc(100vh - 110px);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
Loading…
x
Reference in New Issue
Block a user