2025-07-17 10:28:56 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="keyNode3-container">
|
|
|
|
|
|
<div class="top-container"></div>
|
|
|
|
|
|
<div class="content">
|
|
|
|
|
|
<div class="left-container">
|
|
|
|
|
|
<div class="userPanel">
|
|
|
|
|
|
<UserPanel
|
|
|
|
|
|
:tabsSwitch="KeyNodeOneStore.tabsSwitch"
|
|
|
|
|
|
:tabsList="filterShowUserList"
|
|
|
|
|
|
@click:switchTab="handleSwitchTab"
|
|
|
|
|
|
></UserPanel>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="anchorChart">
|
|
|
|
|
|
<UserChart
|
|
|
|
|
|
:anchorInfoList="KeyNodeOneStore.anchorChartInfoList"
|
|
|
|
|
|
:chartTab="['注册时间', '行为模式']"
|
|
|
|
|
|
@click:switchChartTab="handleSwitchChartTab"
|
|
|
|
|
|
></UserChart>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="middle-container">
|
|
|
|
|
|
<div class="anchorGraph">
|
|
|
|
|
|
<AnchorGraph
|
|
|
|
|
|
:statisticsList="KeyNodeOneStore.statisticsList"
|
|
|
|
|
|
@click:openAnchorDialog="handleOpenAnchorDialog"
|
|
|
|
|
|
></AnchorGraph>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="anchorGrap-statistics">
|
|
|
|
|
|
<AnchorPost
|
|
|
|
|
|
:posts="KeyNodeOneStore.posts"
|
|
|
|
|
|
@click:openDialog="handlePostDialog"
|
|
|
|
|
|
></AnchorPost>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="right-container">
|
|
|
|
|
|
<div class="attention-topic">
|
|
|
|
|
|
<AttentionTopic
|
|
|
|
|
|
:topicList="KeyNodeOneStore.tooltipList"
|
|
|
|
|
|
@click:hotTopic="handleGotTopicDialog"
|
|
|
|
|
|
></AttentionTopic>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="monitoring-situation">
|
|
|
|
|
|
<Monitoring :anchorMonitorList="KeyNodeOneStore.anchorMonitorList"></Monitoring>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<el-dialog v-model="postDialog" width="640" align-center class="custom-dialog">
|
|
|
|
|
|
<img src="@/assets/images/head/post-dialog-title.png" alt="" class="postTitleImage" />
|
|
|
|
|
|
<div class="dialog-content">
|
|
|
|
|
|
<div class="post-content">{{ currentPostPost.content }}</div>
|
|
|
|
|
|
<div class="heat">
|
|
|
|
|
|
<div class="item-heat-detail">
|
|
|
|
|
|
<div class="item-heat-like">
|
|
|
|
|
|
<Icon icon="ei:like" width="25" height="25" /> {{ currentPostPost.like }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="item-heat-comment">
|
|
|
|
|
|
<Icon icon="la:comment-dots" width="25" height="25" /> {{ currentPostPost.comment }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="item-heat-transmit">
|
|
|
|
|
|
<Icon icon="mdi:share-outline" width="25" height="25" /> {{
|
|
|
|
|
|
currentPostPost.transmit
|
|
|
|
|
|
}}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
|
|
<el-dialog v-model="topicDialog" width="591" align-center class="custom-dialog">
|
|
|
|
|
|
<img src="@/assets/images/head/anchorTopicDetail.png" alt="" class="postTitleImage" />
|
|
|
|
|
|
<div class="dialog-content topic-dialog-content">
|
|
|
|
|
|
<div class="dialog-title">{{ currentTopic.title }}</div>
|
|
|
|
|
|
<div class="event-forecast-container">
|
|
|
|
|
|
<div class="event-title">
|
|
|
|
|
|
<img src="@/assets/images/icon/eventTitleLeftIcon.png" alt="" />
|
|
|
|
|
|
<div class="title-font">事件热度预测</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="event-hotChart-container" id="hotChart"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="event-keyUser-container">
|
|
|
|
|
|
<div class="event-title">
|
|
|
|
|
|
<img src="@/assets/images/icon/eventTitleLeftIcon.png" alt="" />
|
|
|
|
|
|
<div class="title-font">事件关键用户</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="key-user-info-list">
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="diamond"></div>
|
|
|
|
|
|
<div class="user-label">
|
|
|
|
|
|
<div class="label-key">最初首发者:</div>
|
|
|
|
|
|
<div class="label-value">{{ currentTopic.earler }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="diamond"></div>
|
|
|
|
|
|
<div class="user-label">
|
|
|
|
|
|
<div class="label-key">积极转发者:</div>
|
|
|
|
|
|
<div class="label-value">{{ currentTopic.switcher }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="diamond"></div>
|
|
|
|
|
|
<div class="user-label">
|
|
|
|
|
|
<div class="label-key">积极评论者:</div>
|
|
|
|
|
|
<div class="label-value">{{ currentTopic.comenter }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="diamond"></div>
|
|
|
|
|
|
<div class="user-label">
|
|
|
|
|
|
<div class="label-key">高效扩散者:</div>
|
|
|
|
|
|
<div class="label-value">梨涡远点</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="info-item">
|
|
|
|
|
|
<div class="diamond"></div>
|
|
|
|
|
|
<div class="user-label">
|
|
|
|
|
|
<div class="label-key">锚点用户:</div>
|
2025-08-14 14:42:11 +08:00
|
|
|
|
|
|
|
|
|
|
<el-tooltip
|
|
|
|
|
|
class="box-item"
|
|
|
|
|
|
effect="light"
|
|
|
|
|
|
:content="currentTopic.keyuser"
|
|
|
|
|
|
placement="bottom"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="label-value">{{ cutOutTheFirstTwo(currentTopic.keyuser) }}</div>
|
|
|
|
|
|
</el-tooltip>
|
2025-07-17 10:28:56 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
|
|
<el-dialog v-model="anchorDialog" width="640" align-center class="custom-dialog">
|
|
|
|
|
|
<img src="@/assets/images/head/anchorDialogTitle.png" alt="" class="dialogTitleImg" />
|
|
|
|
|
|
<div class="dialog-content">
|
|
|
|
|
|
<div class="dialog-content-leaderInfo">
|
|
|
|
|
|
<img class="leaderInfo-avatar" :src="currentSelectedAnchorItem.avatar" alt="" />
|
|
|
|
|
|
<div class="leaderInfo-message">
|
2025-08-14 14:42:11 +08:00
|
|
|
|
<div class="leader-name">{{ currentSelectedAnchorItem.nodeName }}</div>
|
2025-07-17 10:28:56 +08:00
|
|
|
|
<div class="leader-heat">
|
|
|
|
|
|
<div class="fancy">粉丝量: {{ currentSelectedAnchorItem.fancy }}</div>
|
|
|
|
|
|
<div class="post-number">
|
|
|
|
|
|
关注量: {{ currentSelectedAnchorItem.atten }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="dialog-content-post">
|
|
|
|
|
|
<div class="leader-post-detail-content">
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="content-item"
|
|
|
|
|
|
v-for="item in currentSelectedAnchorItem.postList"
|
|
|
|
|
|
:key="item.id"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="item-type">{{ contentType(item.postContent) }}</div>
|
|
|
|
|
|
<div class="item-content">
|
|
|
|
|
|
{{ item.postContent }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="item-heat">
|
|
|
|
|
|
<div class="item-time">{{ item.postTime }}</div>
|
|
|
|
|
|
<div class="item-heat-detail">
|
|
|
|
|
|
<div class="item-heat-like">
|
|
|
|
|
|
<Icon icon="ei:like" width="25" height="25" /> {{ item.like }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="item-heat-comment">
|
|
|
|
|
|
<Icon icon="la:comment-dots" width="25" height="25" /> {{ item.comment }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="item-heat-transmit">
|
|
|
|
|
|
<Icon icon="mdi:share-outline" width="25" height="25" /> {{ item.transmit }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="dialog-content-heat-degree">
|
|
|
|
|
|
<div class="heat-item">
|
|
|
|
|
|
<p class="diamond"></p>
|
|
|
|
|
|
发帖总数: {{ currentSelectedAnchorItem.postTotal }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="heat-item">
|
|
|
|
|
|
<p class="diamond"></p>
|
|
|
|
|
|
贴文被转总数: {{ currentSelectedAnchorItem.postTransmitedTotal }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="heat-item">
|
|
|
|
|
|
<p class="diamond"></p>
|
|
|
|
|
|
参与互动次数: {{ currentSelectedAnchorItem.interaction }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="heat-item">
|
|
|
|
|
|
<p class="diamond"></p>
|
2025-07-22 17:40:11 +08:00
|
|
|
|
首次活跃时间: {{ currentSelectedAnchorItem.earlistTime }}
|
2025-07-17 10:28:56 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-07-28 15:59:40 +08:00
|
|
|
|
import { computed, ref, watch, nextTick } from "vue"
|
|
|
|
|
|
import UserPanel from "./components/userPanel.vue"
|
|
|
|
|
|
import UserChart from "./components/userChart.vue"
|
|
|
|
|
|
import AnchorGraph from "./components/anchorGraph.vue"
|
|
|
|
|
|
import AnchorPost from "./components/anchorPost.vue"
|
|
|
|
|
|
import AttentionTopic from "./components/attentionTopic.vue"
|
|
|
|
|
|
import Monitoring from "./components/monitoring.vue"
|
|
|
|
|
|
import { Icon } from "@iconify/vue"
|
|
|
|
|
|
import * as echarts from "echarts"
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
2025-07-28 15:59:40 +08:00
|
|
|
|
import { useKeyNodeRecognitionStore } from "@/store/keyNodeRecognition/index"
|
|
|
|
|
|
const KeyNodeOneStore = useKeyNodeRecognitionStore()
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
//控制弹窗
|
2025-07-28 15:59:40 +08:00
|
|
|
|
const postDialog = ref(false)
|
|
|
|
|
|
const topicDialog = ref(false)
|
|
|
|
|
|
const anchorDialog = ref(false)
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
//当前选中的贴文数据
|
2025-07-28 15:59:40 +08:00
|
|
|
|
const currentPostPost = ref(null)
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
//当前选中的热度事件
|
2025-07-28 15:59:40 +08:00
|
|
|
|
const currentTopic = ref(null)
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
//当前选中的锚点数据
|
2025-07-28 15:59:40 +08:00
|
|
|
|
const currentSelectedAnchorItem = ref(null)
|
2025-07-17 10:28:56 +08:00
|
|
|
|
//筛选tabs展示条件
|
|
|
|
|
|
const filterShowUserList = computed(() => {
|
|
|
|
|
|
if (KeyNodeOneStore.currentTabType == "全部") {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
return KeyNodeOneStore.mediaData
|
2025-07-17 10:28:56 +08:00
|
|
|
|
} else {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
return KeyNodeOneStore.mediaData.filter((item) => item.type === KeyNodeOneStore.currentTabType)
|
2025-07-17 10:28:56 +08:00
|
|
|
|
}
|
2025-07-28 15:59:40 +08:00
|
|
|
|
})
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
const contentType = computed(() => {
|
|
|
|
|
|
return (content) => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
if (content.startsWith("//@")) return "转发"
|
|
|
|
|
|
return "原发"
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
//直接截取前两个关键用户
|
|
|
|
|
|
const cutOutTheFirstTwo = computed(() => {
|
|
|
|
|
|
return (keyUserString) => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
return keyUserString.split(",").slice(0, 2).join(",")
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
watch(filterShowUserList, (newList) => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
if (!newList?.length) return
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
2025-07-28 15:59:40 +08:00
|
|
|
|
const { anchorChartInfoList } = KeyNodeOneStore
|
|
|
|
|
|
const find = (name) => anchorChartInfoList.find((item) => item.name === name)
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
// 安全数值转换函数
|
2025-07-28 15:59:40 +08:00
|
|
|
|
const safeNumber = (val) => (isNaN(+val) ? 0 : +val)
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
// 更新各项数据
|
2025-07-28 15:59:40 +08:00
|
|
|
|
find("锚点数量").number = newList.length
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
find("平均粉丝数量").number = `${(
|
|
|
|
|
|
newList.reduce((acc, cur) => acc + safeNumber(cur.number?.replace("w", "")), 0) / newList.length
|
2025-07-28 15:59:40 +08:00
|
|
|
|
).toFixed(1)}w`
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
find("平均发帖频率").number = `${Math.round(
|
|
|
|
|
|
newList.reduce((acc, cur) => acc + safeNumber(cur.transmit?.replace("h/1次", "")), 0) /
|
|
|
|
|
|
newList.length
|
2025-07-28 15:59:40 +08:00
|
|
|
|
)}h/1次`
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
find("平均参与互动次数").number = Math.floor(
|
|
|
|
|
|
newList.reduce((acc, cur) => acc + safeNumber(cur.interaction), 0) / newList.length
|
2025-07-28 15:59:40 +08:00
|
|
|
|
)
|
|
|
|
|
|
})
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
const handleSwitchTab = (tabName) => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
KeyNodeOneStore.currentTabType = tabName
|
|
|
|
|
|
}
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
const handleSwitchChartTab = (tabName) => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
KeyNodeOneStore.currentChartTabType = tabName
|
|
|
|
|
|
}
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
const handlePostDialog = (post) => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
postDialog.value = true
|
|
|
|
|
|
currentPostPost.value = post
|
|
|
|
|
|
}
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
const handleGotTopicDialog = (topic) => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
topicDialog.value = true
|
|
|
|
|
|
currentTopic.value = topic
|
|
|
|
|
|
}
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
2025-07-28 15:59:40 +08:00
|
|
|
|
let hotChartInstance = null
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
const renderHotChart = () => {
|
|
|
|
|
|
nextTick(() => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
const chartDom = document.getElementById("hotChart")
|
|
|
|
|
|
if (!chartDom) return
|
2025-07-17 10:28:56 +08:00
|
|
|
|
if (hotChartInstance) {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
hotChartInstance.dispose()
|
2025-07-17 10:28:56 +08:00
|
|
|
|
}
|
2025-07-28 15:59:40 +08:00
|
|
|
|
hotChartInstance = echarts.init(chartDom)
|
2025-07-17 10:28:56 +08:00
|
|
|
|
const option = {
|
|
|
|
|
|
backgroundColor: "transparent",
|
|
|
|
|
|
tooltip: { trigger: "axis" },
|
|
|
|
|
|
legend: {
|
|
|
|
|
|
data: ["实际热度", "预测热度"],
|
|
|
|
|
|
right: 20,
|
|
|
|
|
|
top: 10,
|
|
|
|
|
|
textStyle: { color: "#B6D6F7" }
|
|
|
|
|
|
},
|
|
|
|
|
|
grid: { left: 0, right: 20, top: 50, bottom: 30, containLabel: true },
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
type: "category",
|
|
|
|
|
|
boundaryGap: false,
|
|
|
|
|
|
axisLine: { show: false },
|
|
|
|
|
|
axisTick: { show: false },
|
|
|
|
|
|
axisLabel: { color: "#B6D6F7", fontSize: 13 },
|
2025-07-28 15:59:40 +08:00
|
|
|
|
data: ["6.25", "6.26", "6.27", "6.28", "6.29", "6.30", "7.1", "7.2"]
|
2025-07-17 10:28:56 +08:00
|
|
|
|
},
|
|
|
|
|
|
yAxis: {
|
|
|
|
|
|
type: "value",
|
|
|
|
|
|
name: "数量",
|
|
|
|
|
|
nameLocation: "end",
|
|
|
|
|
|
interval: 2000, // 固定间隔2000
|
|
|
|
|
|
|
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
|
color: "#B6D6F7",
|
|
|
|
|
|
fontSize: 13,
|
|
|
|
|
|
align: "left",
|
|
|
|
|
|
padding: [0, 0, 10, -50] // 负值让文字更靠左
|
|
|
|
|
|
},
|
|
|
|
|
|
axisLine: { show: false },
|
|
|
|
|
|
axisTick: { show: false },
|
|
|
|
|
|
axisLabel: { color: "#B6D6F7", fontSize: 13, margin: 25 },
|
|
|
|
|
|
splitLine: { show: true, lineStyle: { color: "rgba(182,214,247,0.15)" } }
|
|
|
|
|
|
},
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "实际热度",
|
|
|
|
|
|
type: "line",
|
|
|
|
|
|
data: currentTopic.value.chart.realityData,
|
|
|
|
|
|
symbol: "circle",
|
|
|
|
|
|
symbolSize: 8,
|
|
|
|
|
|
showSymbol: true,
|
|
|
|
|
|
itemStyle: { color: "#4AC6FF", borderColor: "#fff", borderWidth: 2 },
|
|
|
|
|
|
lineStyle: { color: "#4AC6FF", width: 2 },
|
|
|
|
|
|
areaStyle: { color: "rgba(74,198,255,0.15)" },
|
2025-08-13 16:43:36 +08:00
|
|
|
|
label: { show: true, position: "bottom", color: "#4AC6FF", fontSize: 12 },
|
2025-07-17 10:28:56 +08:00
|
|
|
|
padding: [0, 0, 0, 30]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "预测热度",
|
|
|
|
|
|
type: "line",
|
|
|
|
|
|
data: currentTopic.value.chart.predictedData,
|
|
|
|
|
|
symbol: "circle",
|
|
|
|
|
|
symbolSize: 8,
|
|
|
|
|
|
showSymbol: true,
|
|
|
|
|
|
itemStyle: { color: "#00E5FF", borderColor: "#fff", borderWidth: 2 },
|
|
|
|
|
|
lineStyle: { color: "#00E5FF", width: 2, type: "dashed" },
|
|
|
|
|
|
label: { show: true, position: "top", color: "#00E5FF", fontSize: 12 },
|
|
|
|
|
|
padding: [0, 0, 0, 30]
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2025-07-28 15:59:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
hotChartInstance.setOption(option)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2025-07-17 10:28:56 +08:00
|
|
|
|
|
|
|
|
|
|
const handleOpenAnchorDialog = (params) => {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
anchorDialog.value = params.anchorDialog
|
|
|
|
|
|
currentSelectedAnchorItem.value = params.currentSelectAnchorNode
|
|
|
|
|
|
console.log(currentSelectedAnchorItem.value)
|
|
|
|
|
|
}
|
2025-07-17 10:28:56 +08:00
|
|
|
|
watch(topicDialog, (val) => {
|
|
|
|
|
|
if (val) {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
renderHotChart()
|
2025-07-17 10:28:56 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
if (hotChartInstance) {
|
2025-07-28 15:59:40 +08:00
|
|
|
|
hotChartInstance.dispose()
|
|
|
|
|
|
hotChartInstance = null
|
2025-07-17 10:28:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-28 15:59:40 +08:00
|
|
|
|
})
|
2025-07-17 10:28:56 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="less">
|
|
|
|
|
|
:deep(.custom-dialog) {
|
|
|
|
|
|
width: 640px;
|
|
|
|
|
|
border-width: 0px, 0px, 0px, 0px;
|
|
|
|
|
|
border-style: solid;
|
|
|
|
|
|
border-image-source: linear-gradient(180deg, #3aa1f8 0%, rgba(58, 161, 248, 0.2) 100%);
|
|
|
|
|
|
background-color: rgba(6, 45, 90, 1);
|
|
|
|
|
|
border: 1px solid #1a8bff;
|
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
|
padding: 0 0;
|
|
|
|
|
|
z-index: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep(.post-dialog) {
|
|
|
|
|
|
height: 300px;
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep(.custom-dialog) .postTitleImage {
|
|
|
|
|
|
margin-top: -24px;
|
|
|
|
|
|
margin-left: -2px;
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep(.custom-dialog) .dialog-content {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
padding: 25px 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.custom-dialog) .dialog-content .content {
|
|
|
|
|
|
color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
|
font-family: "PingFang SC";
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-style: normal;
|
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
|
}
|
|
|
|
|
|
.heat {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
.item-heat-detail {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
div {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
width: 70px;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.keyNode3-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
.top-container {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 88px;
|
|
|
|
|
|
background-image: url(@/assets/images/head/bigTitle2.png);
|
|
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
|
|
background-size: cover;
|
|
|
|
|
|
fill: linear-gradient(270deg, rgba(6, 61, 113, 0.1) 0%, rgba(8, 30, 56, 0.38) 100%);
|
|
|
|
|
|
stroke-width: 1px;
|
|
|
|
|
|
stroke: #3aa1f8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.content {
|
|
|
|
|
|
height: 805px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
gap: 15px;
|
|
|
|
|
|
.left-container {
|
2025-08-13 16:40:18 +08:00
|
|
|
|
flex: 10%;
|
2025-07-17 10:28:56 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 15px;
|
|
|
|
|
|
.userPanel {
|
|
|
|
|
|
height: 540px;
|
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
background-color: rgba(6, 45, 90, 0.3);
|
|
|
|
|
|
border: 1px solid rgba(0, 113, 188, 0.705);
|
|
|
|
|
|
}
|
|
|
|
|
|
.anchorChart {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
|
background-color: rgba(6, 45, 90, 0.3);
|
|
|
|
|
|
border: 1px solid rgba(0, 113, 188, 0.705);
|
|
|
|
|
|
overflow: auto;
|
|
|
|
|
|
-ms-overflow-style: none; /* IE 和 Edge */
|
|
|
|
|
|
scrollbar-width: none; /* Firefox */
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.middle-container {
|
2025-08-13 16:40:18 +08:00
|
|
|
|
flex: 60%;
|
2025-07-17 10:28:56 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 15px;
|
|
|
|
|
|
.anchorGraph {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 541px;
|
|
|
|
|
|
background-color: #070a22;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
background-color: rgba(6, 45, 90, 0.3);
|
|
|
|
|
|
border: 1px solid rgba(0, 113, 188, 0.705);
|
|
|
|
|
|
}
|
|
|
|
|
|
.anchorGrap-statistics {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
background-color: rgba(6, 45, 90, 0.3);
|
|
|
|
|
|
border: 1px solid rgba(0, 113, 188, 0.705);
|
|
|
|
|
|
fill: linear-gradient(270deg, rgba(6, 61, 113, 0.1) 0%, rgba(8, 30, 56, 0.38) 100%);
|
|
|
|
|
|
stroke-width: 1px;
|
|
|
|
|
|
stroke: #3aa1f8;
|
|
|
|
|
|
overflow: auto;
|
|
|
|
|
|
padding: 10px 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.right-container {
|
2025-08-13 16:40:18 +08:00
|
|
|
|
flex: 25%;
|
2025-07-17 10:28:56 +08:00
|
|
|
|
height: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 15px;
|
|
|
|
|
|
.attention-topic {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 540px;
|
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
background-color: rgba(6, 45, 90, 0.3);
|
|
|
|
|
|
border: 1px solid rgba(0, 113, 188, 0.705);
|
|
|
|
|
|
}
|
|
|
|
|
|
.monitoring-situation {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
background-color: rgba(6, 45, 90, 0.3);
|
|
|
|
|
|
border: 1px solid rgba(0, 113, 188, 0.705);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.topic-dialog-content {
|
|
|
|
|
|
.dialog-title {
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-family: "PingFang SC";
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
font-style: normal;
|
|
|
|
|
|
}
|
|
|
|
|
|
.event-title {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
.title-font {
|
|
|
|
|
|
margin-left: 8px;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-family: "PingFang SC";
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-style: normal;
|
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.event-forecast-container {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 300px;
|
|
|
|
|
|
|
|
|
|
|
|
margin-top: 22px;
|
|
|
|
|
|
.event-hotChart-container {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 400px;
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.event-keyUser-container {
|
|
|
|
|
|
margin-top: 150px;
|
|
|
|
|
|
.key-user-info-list {
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
.info-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
.diamond {
|
|
|
|
|
|
width: 6px;
|
|
|
|
|
|
height: 6px;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
|
box-shadow: 0 4px 8px rgb(0, 123, 255);
|
|
|
|
|
|
}
|
|
|
|
|
|
.user-label {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
|
|
.label-key {
|
|
|
|
|
|
color: #c6e3f5;
|
|
|
|
|
|
font-family: "PingFang SC";
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-style: normal;
|
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
|
}
|
|
|
|
|
|
.label-value {
|
|
|
|
|
|
width: 170px;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-family: "PingFang SC";
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-style: normal;
|
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
2025-08-14 14:42:11 +08:00
|
|
|
|
cursor: pointer;
|
2025-07-17 10:28:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.dialogTitleImg {
|
|
|
|
|
|
margin-top: -23px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.post-content {
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
|
}
|
|
|
|
|
|
.dialog-content-leaderInfo {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 70px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
}
|
|
|
|
|
|
.leaderInfo-avatar {
|
|
|
|
|
|
width: 70px;
|
|
|
|
|
|
height: 70px;
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.leaderInfo-message {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
padding-left: 15px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
}
|
|
|
|
|
|
.leader-name {
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
}
|
|
|
|
|
|
.leader-heat {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.post-number {
|
|
|
|
|
|
margin-left: 30px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.dialog-content-post {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
padding: 25px 0px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.leader-post-detail-content {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
background:
|
|
|
|
|
|
linear-gradient(0deg, #0d2743, #0d2743),
|
|
|
|
|
|
linear-gradient(270deg, rgba(147, 210, 255, 0.06) 0%, rgba(147, 210, 255, 0.16) 100%);
|
|
|
|
|
|
margin-top: 30px;
|
|
|
|
|
|
height: 262px;
|
|
|
|
|
|
overflow: auto;
|
|
|
|
|
|
padding: 10px 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.leader-post-detail-content::-webkit-scrollbar {
|
|
|
|
|
|
width: 5px;
|
|
|
|
|
|
height: 5px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.leader-post-detail-content::-webkit-scrollbar-thumb {
|
|
|
|
|
|
background: rgba(147, 210, 255, 0.3);
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.leader-post-detail-content::-webkit-scrollbar-thumb:hover {
|
|
|
|
|
|
background: rgba(147, 210, 255, 0.5);
|
|
|
|
|
|
}
|
|
|
|
|
|
.item-type {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
}
|
|
|
|
|
|
.item-content {
|
|
|
|
|
|
color: #ffffffcc;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.content-item div {
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.item-heat {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
color: #ffffffcc;
|
|
|
|
|
|
}
|
|
|
|
|
|
.item-heat-detail {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
}
|
|
|
|
|
|
.item-heat-detail div {
|
|
|
|
|
|
width: 60px;
|
|
|
|
|
|
margin-right: 20px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.dialog-content-heat-degree {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
|
|
row-gap: 15px;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.heat-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.heat-item .diamond {
|
|
|
|
|
|
width: 6px;
|
|
|
|
|
|
height: 6px;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
|
box-shadow: 0 4px 8px rgb(0, 123, 255);
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|