模块3接口

This commit is contained in:
duanhao 2025-08-05 17:46:21 +08:00
parent 24e7884a42
commit 022bb34123
11 changed files with 369 additions and 190 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -19,3 +19,10 @@ export function getGroupEvolutionTimeLine() {
export function getPostByUtcTime(utcTime) {
return http.get(`/groupEvolution/identify/posts?date=${utcTime}`)
}
// 3.群体成员演化分析
// 3.1 群体成员演化信息列表信息
export function getGroupMemberInfoList() {
return http.get(`/groupEvolution/groupMember/infoList`)
}

View File

@ -11,7 +11,8 @@ import {
getGroupEvolutionGroupList,
getGroupEvolutionGroupScaleChart,
getGroupEvolutionTimeLine,
getPostByUtcTime
getPostByUtcTime,
getGroupMemberInfoList
} from "@/service/api/groupEvolution"
import { TansTimestamp } from "@/utils/transform"
@ -530,58 +531,13 @@ export const useGroupMemberStore = defineStore("groupMember", {
id: 1,
type: "群体一",
focusedTopic: "#中国海警首次登检菲律宾#",
series: [
{
type: "radar",
data: [
{
value: [10, 5, 15, 5],
symbol: "circle",
symbolSize: 5,
itemStyle: {
color: "#01D7DA" // 圆点颜色
},
areaStyle: {
color: "rgba(87, 196, 255, 0.3)" // 区域填充
},
// 点之间的连线
lineStyle: {
color: "#0374FE",
type: "dashed",
width: 1
}
}
]
}
]
},
{
id: 2,
type: "群体二",
focusedTopic: "#中国海警首次登检菲律宾#",
series: [
{
type: "radar",
data: [
{
value: [10, 20, 15, 5],
symbol: "circle",
symbolSize: 5,
itemStyle: {
color: "#01D7DA" // 圆点颜色
},
areaStyle: {
color: "rgba(87, 196, 255, 0.3)" // 区域填充
},
lineStyle: {
color: "#0374FE",
type: "dashed",
width: 1
}
}
]
}
]
}
],
groupMemberList: [
@ -956,12 +912,58 @@ export const useGroupMemberStore = defineStore("groupMember", {
{ text: "手指", top: 195.5, left: 287.5, width: 49, height: 19, fontSize: 12, opacity: 0.8 }
]
}),
actions: {},
actions: {
async initializeGroupList() {
const res = await getGroupMemberInfoList()
const groupList = res.data.map(item => ({
id: item.id,
type: item.type,
focusedTopic: item.focusedTopic,
value: item.value
}))
this.groupList = groupList
console.log("测试获取groupList:",res);
}
},
persist: false // 开启持久化
})
export const useAnomalousGroup = defineStore("anomalousGroup", {
state: () => ({
groupList: [
{
id:1,
type: "异常社团组一",
abnormalGroup: [
{
groupId: "G02",
nodeCount: 112,
postNum: 21
},
{
groupId: "G07",
nodeCount: 183,
postNum: 13
}
]
},
{
id:2,
type: "异常社团组二",
abnormalGroup: [
{
groupId: "G04",
nodeCount: 86,
postNum: 12
},
{
groupId: "G08",
nodeCount: 143,
postNum: 7
}
]
}
],
wordCloudData: [
{
text: "局座",

View File

@ -51,23 +51,6 @@
</div>
</div>
</div>
<!-- 用户区域 -->
<div class="content-item-users">
<!-- 评论人 -->
<div class="user-item">
<img :src="content.commenter.userAvatar" alt="" class="user-avatar" />
<div class="user-name">{{ content.commenter.userName }}</div>
</div>
<!-- 评论接受人 -->
<div class="user-item">
<img :src="content.commentRecipient.userAvatar" alt="" class="user-avatar" />
<div class="user-name">{{ content.commentRecipient.userName }}</div>
</div>
</div>
<!-- 评论的内容 -->
<div class="content-item-comment">
<!-- <div class="post-content">{{ content.commentContent }}</div> -->
</div>
</div>
</template>
@ -88,12 +71,8 @@ const props = defineProps({
.title {
margin-top: -7px;
}
.content-item {
width: 100%;
height: 100%;
.anomalousContent-list {
width: 100%;
height: 500px;
height: 490px;
overflow: auto;
.content-item {
width: 100%;
@ -102,83 +81,80 @@ const props = defineProps({
.content-item-title {
position: relative;
.content-item-title-icon {
width: 160px;
width: 130px;
}
.content-item-title-text {
position: absolute;
top: 7px;
top: 3px;
color: #8efbff;
left: 12px;
font-size: 14px;
}
}
.content-item-users {
padding-top: 16px;
padding-bottom: 16px;
display: flex;
justify-content: flex-start;
gap: 16px;
.user-item {
display: flex;
align-items: center;
margin-top: 16px;
padding-right: 20px;
color: #fff;
font-family: PingFang SC;
font-weight: 400;
font-style: Bold;
font-size: 16px;
.user-avatar {
margin-right: 6px;
width: 20px;
height: 20px;
margin-right: 6px;
}
.user-name {
font-family: "PingFang SC";
color: #fff;
font-size: 16px;
font-style: Bold;
font-weight: 400;
}
}
}
.commit-item {
margin-top: 14px;
padding-bottom: 12px;
width: 304px;
height: 100%;
padding-top: 14px;
padding-left: 10px;
padding-right: 10px;
padding-bottom: 14px;
background: linear-gradient(0deg, rgba(13, 39, 67, 0.66), rgba(13, 39, 67, 0.66)),
linear-gradient(270deg, rgba(147, 210, 255, 0.06) 0%, rgba(147, 210, 255, 0.16) 100%);
.commit-content-text {
color: #fff;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 14px;
background: linear-gradient(0deg, rgba(13, 39, 67, 0.66), rgba(13, 39, 67, 0.66)),
linear-gradient(270deg, rgba(147, 210, 255, 0.06) 0%, rgba(147, 210, 255, 0.16) 100%);
.commit-content {
width: 284px;
margin-left: 10px;
padding-top: 12px;
padding-bottom: 8px;
}
.commit-statistic {
display: flex;
padding-left: 10px;
padding-right: 10px;
align-items: center;
gap: 16px;
padding-top: 8px;
.like-item {
display: flex;
align-items: center;
margin-right: 20px;
.like-count {
margin-left: 8px;
}
justify-content: center;
gap: 8px;
width: 54px;
color: #fff;
}
.comment-num-item {
display: flex;
align-items: center;
margin-right: 16px;
.comment-count {
margin-left: 8px;
}
justify-content: center;
gap: 8px;
width: 54px;
color: #fff;
}
.transmit-item {
display: flex;
align-items: center;
.transmit-count {
margin-left: 8px;
}
}
gap: 8px;
justify-content: center;
width: 54px;
color: #fff;
}
}
}
@ -189,13 +165,11 @@ const props = defineProps({
width: 5px; /* 垂直滚动条宽度 */
height: 5px; /* 水平滚动条高度 */
}
/* 滚动条滑块 */
.anomalousContent-list::-webkit-scrollbar-thumb {
background: rgba(147, 210, 255, 0.3); /* 蓝色半透明滑块 */
border-radius: 4px;
}
/* 鼠标悬停在滑块上的效果 */
.anomalousContent-list::-webkit-scrollbar-thumb:hover {
background: rgba(147, 210, 255, 0.5); /* 更明显的蓝色 */

View File

@ -0,0 +1,165 @@
<template>
<div class="groupPanel-component">
<img :src="title" alt="" class="title" />
<div class="groupPanel-list">
<div class="group-item" v-for="group in props.groupList" :key="group.id">
<div class="group-item-title">
<img
class="group-item-title-icon"
src="@/assets/images/abnormalGroup/abnormal-group-item-title.png"
alt=""
/>
<div class="group-item-title-type">{{ group.type }}</div>
</div>
<div class="item-info" v-for="abnormalGroup in group.abnormalGroup">
<div class="anbormalGroupId">社团ID:&nbsp;&nbsp;{{ abnormalGroup.groupId }}</div>
<div class="statistics-item">
<div class="node-item">
<img class="node-icon" src="@/assets/images/abnormalGroup/abnormal-user-group-node-icon.png" alt="">
<div class="node-content">
<div class="node-content-title">
节点数
</div>
<div class="node-content-count">{{ abnormalGroup.nodeCount }}</div>
</div>
</div>
<div class="post-item">
<img class="post-icon" src="@/assets/images/abnormalGroup/abnormal-user-group-post-icon.png" alt="">
<div class="post-content">
<div class="post-content-title">
发帖总数
</div>
<div class="post-content-count">{{ abnormalGroup.postNum }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineProps } from "vue"
const props = defineProps({
groupList: {
type: Array,
default: () => []
},
title: {
type: String,
default: ""
}
})
</script>
<style lang="less">
.groupPanel-component {
width: 100%;
height: 100%;
.title {
margin-top: -1px;
margin-left: -2px;
}
.groupPanel-list {
width: 100%;
height: 470px;
padding: 20px 20px;
overflow: auto;
&::-webkit-scrollbar {
width: 3px; /* 垂直滚动条宽度 */
height: 5px; /* 水平滚动条高度 */
}
&::-webkit-scrollbar-thumb {
background: rgba(147, 210, 255, 0.3); /* 蓝色半透明滑块 */
border-radius: 4px;
}
&::-webkit-scrollbar-thumb:hover {
background: rgba(147, 210, 255, 0.5); /* 更明显的蓝色 */
}
.group-item {
width: 100%;
padding-bottom: 20px;
border-bottom: 0.5px solid rgba(0, 113, 188, 0.5);
.group-item-title {
position: relative;
.group-item-title-type {
position: absolute;
top: 3px;
color: #8efbff;
left: 8px;
font-size: 14px;
}
}
.item-info {
margin-top: 10px;
.anbormalGroupId {
color: #fff;
font-family: PingFang SC;
font-weight: 400;
font-style: Medium;
font-size: 14px;
}
.statistics-item {
margin-top: 16px;
display: flex;
gap: 40px;
.node-item {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
.node-content {
display: flex;
flex-direction: column;
.node-content-title {
color: #fff;
font-family: MiSanb;
font-weight: 400;
font-style: Medium;
font-size: 14px;
}
.node-content-count {
color: #fff;
font-family: MiSans;
font-weight: 630;
font-style: Bold;
font-size: 18px;
}
}
}
.post-item {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
.post-content {
display: flex;
flex-direction: column;
.post-content-title {
color: #fff;
font-family: MiSanb;
font-weight: 400;
font-style: Medium;
font-size: 14px;
}
.post-content-count {
color: #fff;
font-family: MiSans;
font-weight: 630;
font-style: Bold;
font-size: 18px;
}
}
}
}
}
}
}
}
</style>

View File

@ -5,7 +5,9 @@
</div>
<div class="content">
<div class="left-container">
<div class="userPanel"></div>
<div class="userPanel">
<GroupPanel :groupList="anomalousGroupStore.groupList" :title="userGroupTitle"></GroupPanel>
</div>
<div class="userChart">
<GroupChart
:title="userChartTitleImg"
@ -23,7 +25,7 @@
</div>
<div class="right-container">
<div class="anlysisPanel">
<!-- <AnomalousContentInfo :contentList="anomalousGroupStore.abnormalContentList"></AnomalousContentInfo> -->
<AnomalousContentInfo :contentList="anomalousGroupStore.abnormalContentList"></AnomalousContentInfo>
</div>
<div class="cloudWords">
<WordsCloud :wordsCloudList="anomalousGroupStore.wordCloudData"></WordsCloud>
@ -57,12 +59,14 @@
<script setup>
import { ref } from "vue";
import userGroupTitle from "@/assets/images/abnormalGroup/abnormal-user-group-title.png"
import userChartTitleImg from "@/assets/images/abnormalGroup/abnormal-group-hudo-time-chart.png"
import { Icon } from "@iconify/vue";
import WordsCloud from "../component/wordsCloud.vue"
import GroupPanel from "./components/groupPanel.vue"
import GroupPost from "../component/groupPost.vue"
import GroupChart from "../component/groupChart.vue"
// import AnomalousContentInfo from "./components/anomalousContentInfo.vue"
import AnomalousContentInfo from "./components/anomalousContentInfo.vue"
import { useAnomalousGroup } from "@/store/groupEvolution/index";
const anomalousGroupStore = useAnomalousGroup();

View File

@ -46,7 +46,7 @@ const indicator = [
const initChart = (groupList) => {
groupList.forEach(group => {
const chartDom = document.getElementById(`group-chart-${group.id}`);
if (chartDom && group.series) {
if (chartDom && group.value) {
const myChart = echarts.init(chartDom);
chartInstances.set(group.id, myChart);
const option = {
@ -83,7 +83,30 @@ const initChart = (groupList) => {
}
},
},
series: group.series
series: [
{
type: 'radar',
data: [
{
value: group.value,
symbol: "circle",
symbolSize: 5,
itemStyle: {
color: "#01D7DA" //
},
areaStyle: {
color: "rgba(87, 196, 255, 0.3)" //
},
// 线
lineStyle: {
color: "#0374FE",
type: "dashed",
width: 1
}
}
]
}
]
};
myChart.setOption(option);

View File

@ -72,7 +72,7 @@
</template>
<script setup>
import { ref } from "vue";
import { onMounted, ref } from "vue";
import GroupPanel from "./components/groupPanel.vue";
import GroupPost from "../component/groupPost.vue";
import GroupAnalysis from "./components/groupAnalysis.vue";
@ -103,6 +103,10 @@ const handleOpenPostDialog = (post) => {
postDialog.value = true;
currentPostPost.value = post;
};
onMounted(async () => {
await groupMemberStore.initializeGroupList()
})
</script>
<style scoped lang="less">