SocialNetworks_duan/src/App.vue

321 lines
8.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-container>
<el-header>
<div class="header-logo"></div>
</el-header>
<el-container>
<el-aside>
<nav class="menu">
<!-- 手动生成第一个菜单项 -->
<div v-for="item in menuItems" :key="item.index" class="el-sub-menu">
<div class="menu-title" :class="{ 'active-parent': hasActiveChild(item) }">
<!-- 激活状态的左侧青色图片 -->
<img
v-if="hasActiveChild(item)"
src="./assets/images/titleActiveLeftRec.png"
alt=""
class="title-active-left"
/>
<div class="tltlemenu-left">
<img
src="./assets/images/titlelogo.png"
style="width: 20px; height: 20px; margin-right: 12px"
/>
{{ item.title }}
</div>
<img
src="./assets/images/titleright.png"
alt=""
style="width: 66px; height: 16px"
/>
</div>
<ul class="menu-items">
<div
v-for="child in item.subItems"
:key="child.index"
style="text-decoration: none"
>
<li
:key="child.index"
class="el-menu-item"
@click="jumpPage(child.index)"
:class="{ active: isActive(child.index) }"
>
<div>
{{ child.title }}
</div>
</li>
</div>
</ul>
</div>
</nav>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
<el-dialog v-model="openDialog" width="500" align-center class="custom-dialog-prepare">
<div class="center-tips">
<img src="./assets/images/icon/pre-icon.png" alt="" class="pre-icon" />
<div class="tips-font">该案例正在开发中</div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { onMounted, ref, onUnmounted } from "vue"
import { useRoute, useRouter } from "vue-router"
const router = useRouter()
const route = useRoute()
const menuItems = [
{
index: "1",
title: "关键节点识别",
subItems: [
{ index: "/key-node-1", title: "重大舆情事件锚点推荐" },
{ index: "/key-node-2", title: "传播意见领袖识别" },
{ index: "/key-node-3", title: "传播桥梁节点识别" }
]
},
{
index: "2",
title: "链路预测",
subItems: [
{ index: "/link-prediction-1", title: "人物互动隐关系预测" },
{ index: "/link-prediction-2", title: "社交紧密团体识别" },
{ index: "/link-prediction-3", title: "人物社交隐关系预测" }
]
},
{
index: "3",
title: "群体演化分析",
subItems: [
{ index: "/group-evolution-1", title: "群体识别发现" },
{ index: "/group-evolution-2", title: "群体结构演化分析" },
{ index: "/group-evolution-3", title: "群体成员演化分析" },
{ index: "/group-evolution-4", title: "异常群体捕捉" }
]
}
]
const openDialog = ref(false)
// 判断当前路由是否激活菜单项
const isActive = (routePath) => {
return route.path === routePath
}
// 判断父菜单是否有激活的子项
const hasActiveChild = (item) => {
return item.subItems.some((child) => isActive(child.index))
}
//处理跳转页面逻辑
const jumpPage = (routePath) => {
const activedPaths = [
"/key-node-1",
"/key-node-2",
"/key-node-3",
"/link-prediction-1",
"/link-prediction-2",
"/link-prediction-3",
"/group-evolution-1",
"/group-evolution-2",
"/group-evolution-3",
"/group-evolution-4"
]
if (activedPaths.includes(routePath)) {
router.push({ path: routePath })
return
}
openDialog.value = true
}
const disableZoom = () => {
// 强制重置浏览器缩放为 100%
const resetZoom = () => {
document.body.style.zoom = "100%"
if (window.devicePixelRatio !== 1) {
const viewportMeta = document.querySelector('meta[name="viewport"]')
if (viewportMeta) {
viewportMeta.content =
"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
}
}
}
// 禁用快捷键Ctrl/Cmd + +/-/0 和 滚轮)
const keysToBlock = new Set(["+", "-", "=", "0"])
const codesToBlock = new Set(["Equal", "Minus", "NumpadAdd", "NumpadSubtract", "Digit0"])
const handleKeyDown = (e) => {
if ((e.ctrlKey || e.metaKey) && (keysToBlock.has(e.key) || codesToBlock.has(e.code))) {
e.preventDefault()
}
}
const handleWheel = (e) => {
if (e.ctrlKey) {
e.preventDefault()
}
}
// 初始化
resetZoom()
document.addEventListener("keydown", handleKeyDown)
document.addEventListener("wheel", handleWheel, { passive: false })
// 可选,用于组件卸载时移除监听
return () => {
document.removeEventListener("keydown", handleKeyDown)
document.removeEventListener("wheel", handleWheel)
}
}
onMounted(() => {
const cleanup = disableZoom()
onUnmounted(() => cleanup())
})
</script>
<style scoped lang="less">
.app-container {
width: 100vw;
height: 111vh;
background-image: url("./assets/images/bci.png");
background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-color: #02131f;
}
:deep(.custom-dialog-prepare) {
width: 480px;
height: 250px;
background: url("./assets/images/preparation.png") no-repeat center;
display: flex;
align-items: center;
justify-content: center;
}
:deep(.custom-dialog-prepare) .pre-icon {
width: 30px;
height: 30px;
margin-right: 10px;
}
:deep(.custom-dialog-prepare) .center-tips {
display: flex;
align-items: center;
}
:deep(.custom-dialog-prepare) .center-tips .tips-font {
font-size: 24px;
color: #fff;
opacity: 0.7;
}
.el-header {
width: 100%;
height: 115px;
padding: 0;
.header-logo {
width: 100%;
height: 100%;
background-image: url("./assets/images/head.png");
background-size: cover;
background-repeat: no-repeat;
}
}
.menu {
width: 320px;
height: 100%;
border-width: 2px;
border-style: solid;
border-image: linear-gradient(to bottom, #3aa1f8, #3aa1f833) 1;
background-image: linear-gradient(to right, #063d7133, #081e38cc);
.menu-title {
cursor: pointer;
padding: 10px;
width: 288px;
border-radius: 2px;
margin-top: 16px;
margin-left: 16px;
background-image: linear-gradient(270deg, rgba(6, 61, 113, 0.2) 0%, rgba(8, 30, 56, 0.8) 100%);
/* border-image: linear-gradient(to right, #225f9200, #3aa1f8) 1; */
border: 2px solid;
border-image-source: linear-gradient(90deg, #3aa1f8 0%, rgba(58, 161, 248, 0.2) 100%);
border-image-slice: 1;
display: flex;
align-items: center;
justify-content: space-between;
&:hover {
border-radius: 2px;
background: linear-gradient(270deg, rgba(14, 167, 213, 0) 0%, rgba(8, 118, 190, 0.24) 100%);
}
}
.menu-items {
padding: 0 15px;
}
}
.menu-title.active-parent {
/* 设置背景图片 */
background-image:
url("./assets/images/titleActiveMaskGroup.png"), Linear-gradient(to right, #0876be, #0ea7d500);
background-repeat: no-repeat;
background-size: contain;
position: relative;
border: none;
padding-left: 30px; /* 为左侧图片腾出空间 */
}
.title-active-left {
position: absolute;
left: 0;
top: 8%;
width: 3px; /* 根据实际图片大小调整 */
height: 88%;
z-index: 1;
}
.el-menu-item {
width: 100%;
height: 36px;
margin-top: 12px;
line-height: 36px;
cursor: pointer;
color: #fff;
padding-left: 40px;
border-radius: 2px;
}
.el-menu-item.active {
background-image: linear-gradient(270deg, rgba(14, 167, 213, 0) 0%, rgba(8, 118, 190, 0.24) 100%);
border-radius: 2px;
}
.tltlemenu-left {
display: flex;
align-items: center;
}
.sub-menu-items {
list-style-type: none;
padding: 0;
margin: 0;
margin-top: 5px;
}
.el-menu-item:hover {
background-image: linear-gradient(to right, #0876be, #0ea7d500);
}
.el-main {
padding: 0 0;
margin-left: 30px;
}
.el-aside {
overflow: visible;
color: aliceblue;
font-family: Arial, sans-serif;
margin-left: 20px;
}
</style>