feat: 统一关系Tab

This commit is contained in:
digua
2026-04-21 22:47:35 +08:00
committed by digua
parent 62ab06d163
commit 231374e05f
7 changed files with 108 additions and 23 deletions
@@ -52,7 +52,7 @@ watch(
</script>
<template>
<div class="main-content mx-auto max-w-[920px] py-6">
<div class="main-content mx-auto max-w-[920px] space-y-6 p-6">
<LoadingState v-if="isLoading" :text="t('quotes.languagePreference.loading')" />
<EmptyState v-else-if="!hasData" :text="t('quotes.languagePreference.empty')" />
@@ -61,16 +61,16 @@ watch(
<LanguagePreferenceCard :data="data" @word-click="handleWordClick" />
<!-- Section 1: 口头禅 PK -->
<CatchphrasePKSection :members="data.members" class="mt-6" @word-click="handleWordClick" />
<CatchphrasePKSection :members="data.members" @word-click="handleWordClick" />
<!-- Section 2: 词性图谱 -->
<PosPortraitSection :members="data.members" class="mt-6" />
<PosPortraitSection :members="data.members" />
<!-- Section 3: 语气词画像 -->
<ModalParticleSection :members="data.members" class="mt-6" />
<ModalParticleSection :members="data.members" />
<!-- Section 4: 标点性格 -->
<PunctuationSection :members="data.members" class="mt-6" />
<PunctuationSection :members="data.members" />
</template>
</div>
</template>
+6
View File
@@ -55,6 +55,7 @@
"message": "Messages",
"topic": "Topics",
"interaction": "Interactions",
"groupRelationships": "Relationships",
"ranking": "Rankings",
"relationship": "Relationship",
"languagePreference": "Language Preference"
@@ -66,6 +67,11 @@
"keywordAnalysis": "Keyword Analysis",
"languagePreference": "Language"
},
"groupRelationships": {
"mentionGraph": "Mention Graph",
"mentionRanking": "Mention Ranking",
"proximity": "Proximity"
},
"member": {
"memberList": "Member List",
"relationships": "Relationships",
+6
View File
@@ -55,6 +55,7 @@
"message": "メッセージ",
"topic": "トピック",
"interaction": "インタラクション分析",
"groupRelationships": "グループ関係",
"ranking": "ランキング",
"relationship": "関係",
"languagePreference": "言語傾向"
@@ -66,6 +67,11 @@
"keywordAnalysis": "キーワード分析",
"languagePreference": "言語傾向"
},
"groupRelationships": {
"mentionGraph": "@ 関係図",
"mentionRanking": "@ ランキング",
"proximity": "発言の近接度"
},
"member": {
"memberList": "メンバー一覧",
"relationships": "関係性",
+6
View File
@@ -55,6 +55,7 @@
"message": "消息",
"topic": "话题",
"interaction": "互动分析",
"groupRelationships": "群关系",
"ranking": "榜单",
"relationship": "关系",
"languagePreference": "语言偏好"
@@ -66,6 +67,11 @@
"keywordAnalysis": "关键词分析",
"languagePreference": "语言偏好"
},
"groupRelationships": {
"mentionGraph": "@ 关系图",
"mentionRanking": "@ 排行",
"proximity": "发言临近度"
},
"member": {
"memberList": "成员列表",
"relationships": "群关系",
+6
View File
@@ -55,6 +55,7 @@
"message": "訊息",
"topic": "話題",
"interaction": "互動分析",
"groupRelationships": "群關係",
"ranking": "榜單",
"relationship": "關係",
"languagePreference": "語言偏好"
@@ -66,6 +67,11 @@
"keywordAnalysis": "關鍵字分析",
"languagePreference": "語言偏好"
},
"groupRelationships": {
"mentionGraph": "@ 關係圖",
"mentionRanking": "@ 排行",
"proximity": "發言臨近度"
},
"member": {
"memberList": "成員列表",
"relationships": "互動關係",
+4 -18
View File
@@ -4,10 +4,8 @@ import { useI18n } from 'vue-i18n'
import { SubTabs } from '@/components/UI'
import UserSelect from '@/components/common/UserSelect.vue'
import MessageView from '@openchatlab/chart-message/MessageView.vue'
import InteractionView from '@openchatlab/chart-interaction/InteractionView.vue'
import RankingView from '@openchatlab/chart-ranking/RankingView.vue'
import Relationships from './view/Relationships.vue'
import ClusterView from '@openchatlab/chart-cluster/ClusterView.vue'
import GroupRelationships from './view/GroupRelationships.vue'
import { WordcloudTab, CatchphraseTab, HotRepeatTab } from '@/components/analysis/quotes'
import { isFeatureSupported, type LocaleType } from '@/i18n'
@@ -29,9 +27,7 @@ const subTabs = computed(() => {
const tabs = [
{ id: 'message', label: t('analysis.subTabs.view.message'), icon: 'i-heroicons-chat-bubble-left-right' },
{ id: 'topic', label: t('analysis.subTabs.view.topic'), icon: 'i-heroicons-cloud' },
{ id: 'interaction', label: t('analysis.subTabs.view.interaction'), icon: 'i-heroicons-arrows-right-left' },
{ id: 'relationships', label: t('analysis.subTabs.member.relationships'), icon: 'i-heroicons-heart' },
{ id: 'cluster', label: t('analysis.subTabs.member.cluster'), icon: 'i-heroicons-user-group' },
{ id: 'group-relationships', label: t('analysis.subTabs.view.groupRelationships'), icon: 'i-heroicons-heart' },
{ id: 'hot-repeat', label: t('analysis.subTabs.quotes.hotRepeat'), icon: 'i-heroicons-fire' },
{
id: 'catchphrase',
@@ -81,18 +77,8 @@ const viewTimeFilter = computed(() => ({
:session-id="props.sessionId"
:time-filter="props.timeFilter"
/>
<InteractionView
v-else-if="activeSubTab === 'interaction'"
:session-id="props.sessionId"
:time-filter="viewTimeFilter"
/>
<Relationships
v-else-if="activeSubTab === 'relationships'"
:session-id="props.sessionId"
:time-filter="viewTimeFilter"
/>
<ClusterView
v-else-if="activeSubTab === 'cluster'"
<GroupRelationships
v-else-if="activeSubTab === 'group-relationships'"
:session-id="props.sessionId"
:time-filter="viewTimeFilter"
/>
@@ -0,0 +1,75 @@
<script setup lang="ts">
/**
* 群关系 - 合并视图
* 将 @ 关系图、@ 排行、发言临近度 三个分析整合到一个 Tab 中
*/
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { SubTabs } from '@/components/UI'
import InteractionView from '@openchatlab/chart-interaction/InteractionView.vue'
import Relationships from './Relationships.vue'
import ClusterView from '@openchatlab/chart-cluster/ClusterView.vue'
const { t } = useI18n()
interface TimeFilter {
startTs?: number
endTs?: number
memberId?: number | null
}
const props = defineProps<{
sessionId: string
timeFilter?: TimeFilter
}>()
const activeSubTab = ref('mention-graph')
const subTabs = computed(() => [
{
id: 'mention-graph',
label: t('analysis.subTabs.groupRelationships.mentionGraph'),
icon: 'i-heroicons-arrows-right-left',
},
{ id: 'mention-ranking', label: t('analysis.subTabs.groupRelationships.mentionRanking'), icon: 'i-heroicons-heart' },
{ id: 'proximity', label: t('analysis.subTabs.groupRelationships.proximity'), icon: 'i-heroicons-user-group' },
])
</script>
<template>
<div class="flex h-full flex-col">
<SubTabs v-model="activeSubTab" :items="subTabs" persist-key="groupRelationshipsTab" size="sm" />
<div class="min-h-0 flex-1 overflow-y-auto">
<Transition name="fade" mode="out-in">
<InteractionView
v-if="activeSubTab === 'mention-graph'"
:session-id="props.sessionId"
:time-filter="props.timeFilter"
/>
<Relationships
v-else-if="activeSubTab === 'mention-ranking'"
:session-id="props.sessionId"
:time-filter="props.timeFilter"
/>
<ClusterView
v-else-if="activeSubTab === 'proximity'"
:session-id="props.sessionId"
:time-filter="props.timeFilter"
/>
</Transition>
</div>
</div>
</template>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.15s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>