From f5f7596822a0044ba07d6903a897c96f86b52233 Mon Sep 17 00:00:00 2001 From: digua Date: Thu, 16 Jul 2026 11:05:54 +0800 Subject: [PATCH] feat(members): unify private member management --- src/components/common/member/MemberList.vue | 65 +++- .../common/member/member-select-utils.test.ts | 14 +- .../common/member/member-select-utils.ts | 4 + src/i18n/locales/en-US/members.json | 9 +- src/i18n/locales/ja-JP/members.json | 9 +- src/i18n/locales/zh-CN/members.json | 9 +- src/i18n/locales/zh-TW/members.json | 9 +- src/pages/group-chat/index.vue | 7 +- .../private-chat/components/MemberTab.vue | 342 ------------------ src/pages/private-chat/index.vue | 11 +- 10 files changed, 88 insertions(+), 391 deletions(-) delete mode 100644 src/pages/private-chat/components/MemberTab.vue diff --git a/src/components/common/member/MemberList.vue b/src/components/common/member/MemberList.vue index 517d9c9c..81742730 100644 --- a/src/components/common/member/MemberList.vue +++ b/src/components/common/member/MemberList.vue @@ -5,7 +5,7 @@ import { useI18n } from 'vue-i18n' import type { MemberWithStats } from '@/types/analysis' import OwnerEntryCard from '@/components/analysis/member/OwnerEntryCard.vue' import LazyAvatar from '@/components/common/avatar/LazyAvatar.vue' -import { filterAndSortMembers, type MemberSortField } from './member-select-utils' +import { filterAndSortMembers, shouldShowMemberMergeControls, type MemberSortField } from './member-select-utils' import { useDataService } from '@/services' import { useTableRowSelection, useTableSort, type TableSortDirection } from '@/composables/useTable' import { reportError } from '@/services/log-report' @@ -22,9 +22,11 @@ const props = withDefaults( defineProps<{ sessionId: string showHeader?: boolean + chatType?: 'group' | 'private' }>(), { showHeader: true, + chatType: 'group', } ) @@ -38,6 +40,11 @@ const members = ref([]) const isLoading = ref(false) const loadFailed = ref(false) const searchQuery = ref('') +const showMergeControls = computed(() => shouldShowMemberMergeControls(props.chatType, members.value.length)) +const memberTableGridClass = computed(() => { + if (props.chatType === 'group') return '' + return showMergeControls.value ? 'member-table-grid--private' : 'member-table-grid--private-without-selection' +}) // 删除确认状态 const deletingMember = ref(null) @@ -87,8 +94,8 @@ const { selectedIds: selectedMergeIds, setSelection: setSelectedMergeIds, clearSelection: clearMergeSelection, - handleRowClick: handleMemberRowClick, - handleRowMouseDown: handleMemberRowMouseDown, + handleRowClick: handleSelectionRowClick, + handleRowMouseDown: handleSelectionRowMouseDown, } = useTableRowSelection({ rows: filteredSortedMembers, getRowId: (member) => member.id, @@ -96,6 +103,16 @@ const { const selectedMergeMembers = computed(() => members.value.filter((member) => selectedMergeIds.value.has(member.id))) const canMergeSelected = computed(() => selectedMergeMembers.value.length === 2) +function handleMemberRowClick(index: number, memberId: number, event: MouseEvent) { + if (!showMergeControls.value) return + handleSelectionRowClick(index, memberId, event) +} + +function handleMemberRowMouseDown(event: MouseEvent) { + if (!showMergeControls.value) return + handleSelectionRowMouseDown(event) +} + const mergePlan = computed(() => { if (selectedMergeMembers.value.length !== 2) return null const [memberA, memberB] = selectedMergeMembers.value @@ -268,6 +285,9 @@ async function confirmMerge() { } watch([searchQuery, sortState], resetVirtualScroll) +watch(showMergeControls, (show) => { + if (!show) clearMergeSelection() +}) // 监听 sessionId 变化 watch( @@ -300,16 +320,22 @@ onUnmounted(() => {
-

{{ t('members.list.title') }}

+

+ {{ t(props.chatType === 'private' ? 'members.private.title' : 'members.list.title') }} +

- {{ t('members.list.description', { count: members.length }) }} + {{ + t(props.chatType === 'private' ? 'members.private.description' : 'members.list.description', { + count: members.length, + }) + }}

- +
@@ -323,7 +349,7 @@ onUnmounted(() => { -
+
{
-
+
-
- +
diff --git a/src/pages/private-chat/components/MemberTab.vue b/src/pages/private-chat/components/MemberTab.vue deleted file mode 100644 index 92677184..00000000 --- a/src/pages/private-chat/components/MemberTab.vue +++ /dev/null @@ -1,342 +0,0 @@ - - - diff --git a/src/pages/private-chat/index.vue b/src/pages/private-chat/index.vue index edf7fcac..374f2cd1 100644 --- a/src/pages/private-chat/index.vue +++ b/src/pages/private-chat/index.vue @@ -9,7 +9,7 @@ import { DebugTab } from '@/components/DebugTab' import { ChatExplorer } from '@/components/AIChat' import OverviewTab from './components/OverviewTab.vue' import ViewTab from './components/ViewTab.vue' -import MemberManagementPanel from './components/MemberTab.vue' +import MemberList from '@/components/common/member/MemberList.vue' import SessionAnalysisHeader from '@/components/layout/session/SessionAnalysisHeader.vue' import SemanticIndexSessionModal from '@/components/analysis/SemanticIndexSessionModal.vue' import OwnerPromptModal from '@/components/analysis/member/OwnerPromptModal.vue' @@ -271,8 +271,13 @@ const otherMemberAvatar = computed(() => {
-
- +
+